001 /* 002 * $Id: ModLongRing.java 3355 2010-10-23 16:01:52Z kredel $ 003 */ 004 005 package edu.jas.arith; 006 007 008 import java.io.Reader; 009 import java.util.ArrayList; 010 import java.util.List; 011 import java.util.Random; 012 import java.util.Iterator; 013 014 import edu.jas.kern.StringUtil; 015 016 017 /** 018 * ModLongRing factory with RingFactory interface. Effectively immutable. 019 * @author Heinz Kredel 020 */ 021 022 public final class ModLongRing implements ModularRingFactory<ModLong>, Iterable<ModLong> { 023 024 025 /** 026 * Module part of the factory data structure. 027 */ 028 public final long modul; 029 030 031 /** 032 * Random number generator. 033 */ 034 private final static Random random = new Random(); 035 036 037 /** 038 * Indicator if this ring is a field. 039 */ 040 protected int isField = -1; // initially unknown 041 042 043 /** 044 * Certainty if module is probable prime. 045 */ 046 protected int certainty = 10; 047 048 049 /** 050 * maximal representable integer. 051 */ 052 public final static java.math.BigInteger MAX_LONG 053 = new java.math.BigInteger(String.valueOf(Integer.MAX_VALUE)); // not larger! 054 055 056 /** 057 * The constructor creates a ModLongRing object from a long integer as 058 * module part. 059 * @param m long integer. 060 */ 061 public ModLongRing(long m) { 062 modul = m; 063 } 064 065 066 /** 067 * The constructor creates a ModLongRing object from a long integer as 068 * module part. 069 * @param m long integer. 070 * @param isField indicator if m is prime. 071 */ 072 public ModLongRing(long m, boolean isField) { 073 modul = m; 074 this.isField = (isField ? 1 : 0); 075 } 076 077 078 /** 079 * The constructor creates a ModLongRing object from a Long integer as 080 * module part. 081 * @param m Long integer. 082 */ 083 public ModLongRing(Long m) { 084 this(m.longValue()); 085 } 086 087 088 /** 089 * The constructor creates a ModLongRing object from a Long integer as 090 * module part. 091 * @param m Long integer. 092 * @param isField indicator if m is prime. 093 */ 094 public ModLongRing(Long m, boolean isField) { 095 this(m.longValue(), isField); 096 } 097 098 099 /** 100 * The constructor creates a ModLongRing object from a BigInteger converted 101 * to long as module part. 102 * @param m java.math.BigInteger. 103 */ 104 public ModLongRing(java.math.BigInteger m) { 105 this(m.longValue()); 106 if (MAX_LONG.compareTo(m) <= 0) { // m >= max 107 System.out.println("modul to large for long " + m + ",max=" + MAX_LONG); 108 throw new IllegalArgumentException("modul to large for long " + m); 109 } 110 } 111 112 113 /** 114 * The constructor creates a ModLongRing object from a BigInteger converted 115 * to long as module part. 116 * @param m java.math.BigInteger. 117 * @param isField indicator if m is prime. 118 */ 119 public ModLongRing(java.math.BigInteger m, boolean isField) { 120 this(m.longValue(), isField); 121 if (MAX_LONG.compareTo(m) <= 0) { // m >= max 122 System.out.println("modul to large for long " + m + ",max=" + MAX_LONG); 123 throw new IllegalArgumentException("modul to large for long " + m); 124 } 125 } 126 127 128 /** 129 * The constructor creates a ModLongRing object from a String object as 130 * module part. 131 * @param m String. 132 */ 133 public ModLongRing(String m) { 134 this(new Long(m.trim())); 135 } 136 137 138 /** 139 * The constructor creates a ModLongRing object from a String object as 140 * module part. 141 * @param m String. 142 * @param isField indicator if m is prime. 143 */ 144 public ModLongRing(String m, boolean isField) { 145 this(new Long(m.trim()), isField); 146 } 147 148 149 /** 150 * Get the module part as BigInteger. 151 * @return modul. 152 */ 153 public java.math.BigInteger getModul() { 154 return new java.math.BigInteger("" + modul); 155 } 156 157 158 /** 159 * Get the module part as long. 160 * @return modul. 161 */ 162 public long getLongModul() { 163 return modul; 164 } 165 166 167 /** 168 * Get the module part as BigInteger. 169 * @return modul. 170 */ 171 public BigInteger getIntegerModul() { 172 return new BigInteger(modul); 173 } 174 175 176 /** 177 * Create ModLong element c. 178 * @param c 179 * @return a ModLong of c. 180 */ 181 public ModLong create(java.math.BigInteger c) { 182 return new ModLong(this, c); 183 } 184 185 186 /** 187 * Create ModLong element c. 188 * @param c 189 * @return a ModLong of c. 190 */ 191 public ModLong create(long c) { 192 return new ModLong(this, c); 193 } 194 195 196 /** 197 * Create ModLong element c. 198 * @param c 199 * @return a ModLong of c. 200 */ 201 public ModLong create(String c) { 202 return parse(c); 203 } 204 205 206 /** 207 * Copy ModLong element c. 208 * @param c 209 * @return a copy of c. 210 */ 211 public ModLong copy(ModLong c) { 212 return new ModLong(this, c.val); 213 } 214 215 216 /** 217 * Get the zero element. 218 * @return 0 as ModLong. 219 */ 220 public ModLong getZERO() { 221 return new ModLong(this, 0L); 222 } 223 224 225 /** 226 * Get the one element. 227 * @return 1 as ModLong. 228 */ 229 public ModLong getONE() { 230 return new ModLong(this, 1L); 231 } 232 233 234 /** 235 * Get a list of the generating elements. 236 * @return list of generators for the algebraic structure. 237 * @see edu.jas.structure.ElemFactory#generators() 238 */ 239 public List<ModLong> generators() { 240 List<ModLong> g = new ArrayList<ModLong>(1); 241 g.add(getONE()); 242 return g; 243 } 244 245 246 /** 247 * Is this structure finite or infinite. 248 * @return true if this structure is finite, else false. 249 * @see edu.jas.structure.ElemFactory#isFinite() 250 */ 251 public boolean isFinite() { 252 return true; 253 } 254 255 256 /** 257 * Query if this ring is commutative. 258 * @return true. 259 */ 260 public boolean isCommutative() { 261 return true; 262 } 263 264 265 /** 266 * Query if this ring is associative. 267 * @return true. 268 */ 269 public boolean isAssociative() { 270 return true; 271 } 272 273 274 /** 275 * Query if this ring is a field. 276 * @return true if module is prime, else false. 277 */ 278 public boolean isField() { 279 if (isField > 0) { 280 return true; 281 } 282 if (isField == 0) { 283 return false; 284 } 285 //System.out.println("isProbablePrime " + modul + " = " + modul.isProbablePrime(certainty)); 286 java.math.BigInteger m = new java.math.BigInteger("" + modul); 287 if (m.isProbablePrime(m.bitLength())) { 288 isField = 1; 289 return true; 290 } 291 isField = 0; 292 return false; 293 } 294 295 296 /** 297 * Characteristic of this ring. 298 * @return characteristic of this ring. 299 */ 300 public java.math.BigInteger characteristic() { 301 return new java.math.BigInteger("" + modul); 302 } 303 304 305 /** 306 * Get a ModLong element from a BigInteger value. 307 * @param a BigInteger. 308 * @return a ModLong. 309 */ 310 public ModLong fromInteger(java.math.BigInteger a) { 311 return new ModLong(this, a); 312 } 313 314 315 /** 316 * Get a ModLong element from a long value. 317 * @param a long. 318 * @return a ModLong. 319 */ 320 public ModLong fromInteger(long a) { 321 return new ModLong(this, a); 322 } 323 324 325 /** 326 * Get the String representation. 327 * @see java.lang.Object#toString() 328 */ 329 @Override 330 public String toString() { 331 return " mod(" + modul + ")"; //",max=" + MAX_LONG + ")"; 332 } 333 334 335 /** 336 * Get a scripting compatible string representation. 337 * @return script compatible representation for this ElemFactory. 338 * @see edu.jas.structure.ElemFactory#toScript() 339 */ 340 //JAVA6only: @Override 341 public String toScript() { 342 // Python case 343 return "ZL(" + modul + ")"; 344 } 345 346 347 /** 348 * Comparison with any other object. 349 * @see java.lang.Object#equals(java.lang.Object) 350 */ 351 @Override 352 public boolean equals(Object b) { 353 if (!(b instanceof ModLongRing)) { 354 return false; 355 } 356 ModLongRing m = (ModLongRing) b; 357 return (modul == m.modul); 358 } 359 360 361 /** 362 * Hash code for this ModLongRing. 363 * @see java.lang.Object#hashCode() 364 */ 365 @Override 366 public int hashCode() { 367 return (int) modul; 368 } 369 370 371 /** 372 * ModLong random. 373 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 374 * @return a random integer mod modul. 375 */ 376 public ModLong random(int n) { 377 return random(n, random); 378 } 379 380 381 /** 382 * ModLong random. 383 * @param n such that 0 ≤ v ≤ (2<sup>n</sup>-1). 384 * @param rnd is a source for random bits. 385 * @return a random integer mod modul. 386 */ 387 public ModLong random(int n, Random rnd) { 388 java.math.BigInteger v = new java.math.BigInteger(n, rnd); 389 return new ModLong(this, v); // rnd.nextLong() not ok 390 } 391 392 393 /** 394 * Parse ModLong from String. 395 * @param s String. 396 * @return ModLong from s. 397 */ 398 public ModLong parse(String s) { 399 return new ModLong(this, s); 400 } 401 402 403 /** 404 * Parse ModLong from Reader. 405 * @param r Reader. 406 * @return next ModLong from r. 407 */ 408 public ModLong parse(Reader r) { 409 return parse(StringUtil.nextString(r)); 410 } 411 412 413 /** 414 * ModLong chinese remainder algorithm. This is a factory method. Assert 415 * c.modul >= a.modul and c.modul * a.modul = this.modul. 416 * @param c ModLong. 417 * @param ci inverse of c.modul in ring of a. 418 * @param a other ModLong. 419 * @return S, with S mod c.modul == c and S mod a.modul == a. 420 */ 421 public ModLong chineseRemainder(ModLong c, ModLong ci, ModLong a) { 422 if (true) { // debug 423 if (c.ring.modul < a.ring.modul) { 424 System.out.println("ModLong error " + c.ring + ", " + a.ring); 425 } 426 } 427 ModLong b = a.ring.fromInteger(c.val); // c mod a.modul 428 ModLong d = a.subtract(b); // a-c mod a.modul 429 if (d.isZERO()) { 430 return new ModLong(this, c.val); 431 } 432 b = d.multiply(ci); // b = (a-c)*ci mod a.modul 433 // (c.modul*b)+c mod this.modul = c mod c.modul = 434 // (c.modul*ci*(a-c)+c) mod a.modul = a mod a.modul 435 long s = c.ring.modul * b.val; 436 s = s + c.val; 437 return new ModLong(this, s); 438 } 439 440 441 /** Get a ModLong iterator. 442 * @return a iterator over all modular integers in this ring. 443 */ 444 public Iterator<ModLong> iterator() { 445 return new ModLongIterator(this); 446 } 447 448 } 449 450 451 /** 452 * Modular integer iterator. 453 * @author Heinz Kredel 454 */ 455 class ModLongIterator implements Iterator<ModLong> { 456 457 458 /** 459 * data structure. 460 */ 461 long curr; 462 463 464 final ModLongRing ring; 465 466 467 /** 468 * ModLong iterator constructor. 469 * @param fac modular integer factory; 470 */ 471 public ModLongIterator(ModLongRing fac) { 472 curr = 0L; 473 ring = fac; 474 } 475 476 477 /** 478 * Test for availability of a next element. 479 * @return true if the iteration has more elements, else false. 480 */ 481 public synchronized boolean hasNext() { 482 return curr < ring.modul; 483 } 484 485 486 /** 487 * Get next integer. 488 * @return next integer. 489 */ 490 public synchronized ModLong next() { 491 ModLong i = new ModLong(ring,curr); 492 curr++; 493 return i; 494 } 495 496 497 /** 498 * Remove an element if allowed. 499 */ 500 public void remove() { 501 throw new UnsupportedOperationException("cannnot remove elements"); 502 } 503 }