001/* 002 * $Id: ModLongTest.java 5688 2017-01-03 08:45:09Z kredel $ 003 */ 004 005package edu.jas.arith; 006 007 008import java.io.StringReader; 009import java.util.ArrayList; 010import java.util.List; 011 012import edu.jas.kern.PrettyPrint; 013import edu.jas.structure.NotInvertibleException; 014 015import junit.framework.Test; 016import junit.framework.TestCase; 017import junit.framework.TestSuite; 018 019 020/** 021 * ModLong tests with JUnit. 022 * @author Heinz Kredel 023 */ 024 025public class ModLongTest extends TestCase { 026 027 028 /** 029 * main. 030 */ 031 public static void main(String[] args) { 032 junit.textui.TestRunner.run(suite()); 033 } 034 035 036 /** 037 * Constructs a <CODE>ModLongTest</CODE> object. 038 * @param name String 039 */ 040 public ModLongTest(String name) { 041 super(name); 042 } 043 044 045 /** 046 */ 047 public static Test suite() { 048 TestSuite suite = new TestSuite(ModLongTest.class); 049 return suite; 050 } 051 052 053 ModLongRing zm, z1, z2; 054 055 056 ModLong a, b, c, d, e; 057 058 059 @Override 060 protected void setUp() { 061 zm = z1 = z2 = null; 062 a = b = c = d = e = null; 063 } 064 065 066 @Override 067 protected void tearDown() { 068 zm = z1 = z2 = null; 069 a = b = c = d = e = null; 070 } 071 072 073 protected static java.math.BigInteger getPrime1() { 074 long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390) 075 for (int i = 1; i < 30; i++) { 076 prime *= 2; 077 } 078 //prime -= 93; 079 prime -= 35; 080 //System.out.println("p1 = " + prime); 081 return new java.math.BigInteger("" + prime); 082 } 083 084 085 protected static java.math.BigInteger getPrime2() { 086 long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390) 087 for (int i = 1; i < 30; i++) { 088 prime *= 2; 089 } 090 //prime -= 35; 091 prime = 37; 092 //System.out.println("p2 = " + prime); 093 return new java.math.BigInteger("" + prime); 094 } 095 096 097 /** 098 * Test static initialization and constants. 099 */ 100 public void testConstants() { 101 zm = new ModLongRing(5); 102 d = new ModLong(zm, 11); 103 a = zm.getZERO(); 104 b = zm.getONE(); 105 c = b.subtract(b); 106 107 assertEquals("1-1 = 0", c, a); 108 assertTrue("1-1 = 0", c.isZERO()); 109 assertTrue("1 = 1", b.isONE()); 110 } 111 112 113 /** 114 * Test bitLength. 115 */ 116 public void testBitLength() { 117 zm = new ModLongRing(163); 118 a = zm.getZERO(); 119 b = zm.getONE(); 120 c = zm.random(30); 121 //System.out.println("c = " + c); 122 //System.out.println("len(c) = " + c.bitLength()); 123 124 assertEquals("len(0) = 1", 1L, a.bitLength()); 125 assertEquals("len(1) = 2", 2, b.bitLength()); 126 assertEquals("len(-1) = len(mod)", BigInteger.bitLength(zm.modul), b.negate().bitLength()); 127 assertTrue("len(random) >= 1", 1 <= c.bitLength()); 128 } 129 130 131 /** 132 * Test constructor and toString. 133 */ 134 public void testConstructor() { 135 zm = new ModLongRing("5"); 136 a = new ModLong(zm, "64"); 137 b = new ModLong(zm, "34"); 138 139 assertEquals("64(5) = 34(5)", a, b); 140 141 zm = new ModLongRing("7"); 142 a = new ModLong(zm, "-4"); 143 b = new ModLong(zm, "3"); 144 145 assertEquals("-4(7) = 3(7)", a, b); 146 147 String s = "61111111111111111"; 148 zm = new ModLongRing("10"); 149 a = new ModLong(zm, s); 150 String t = a.toString(); 151 152 if (PrettyPrint.isTrue()) { 153 String st = "1"; 154 assertEquals("stringConstr = toString", st, t); 155 } else { 156 String st = "1 mod(10)"; 157 assertEquals("stringConstr = toString", st, t); 158 } 159 160 zm = new ModLongRing(7); 161 a = new ModLong(zm, 1); 162 b = new ModLong(zm, -1); 163 c = b.sum(a); 164 165 assertTrue("1 = 1", a.isONE()); 166 assertTrue("1 = 1", b.isUnit()); 167 assertEquals("1+(-1) = 0", c, zm.getZERO()); 168 169 zm = new ModLongRing(5); 170 a = new ModLong(zm, 3); 171 b = new ModLong(zm, 0); 172 c = zm.parse(" 13 "); 173 assertEquals("3(5) = 3(5)", a, c); 174 175 StringReader sr = new StringReader(" 13\n w "); 176 c = zm.parse(sr); 177 assertEquals("3(5) = 3(5)", a, c); 178 //System.out.println("c = " + c); 179 } 180 181 182 /** 183 * Test random modular integers. 184 */ 185 public void testRandom() { 186 zm = new ModLongRing(19); 187 a = zm.random(500); 188 b = a.copy(); 189 c = b.subtract(a); 190 191 assertEquals("a-b = 0", c, zm.getZERO()); 192 193 d = new ModLong(new ModLongRing(b.getModul()), b.getVal()); 194 assertEquals("sign(a-a) = 0", 0, b.compareTo(d)); 195 } 196 197 198 /** 199 * Test addition. 200 * 201 */ 202 public void testAddition() { 203 zm = new ModLongRing(19); 204 205 a = zm.random(100); 206 b = a.sum(a); 207 c = b.subtract(a); 208 209 assertEquals("a+a-a = a", c, a); 210 assertEquals("a+a-a = a", 0, c.compareTo(a)); 211 212 d = a.sum(zm.getZERO()); 213 assertEquals("a+0 = a", d, a); 214 d = a.subtract(zm.getZERO()); 215 assertEquals("a-0 = a", d, a); 216 d = a.subtract(a); 217 assertEquals("a-a = 0", d, zm.getZERO()); 218 219 } 220 221 222 /** 223 * Test multiplication. 224 */ 225 public void testMultiplication() { 226 zm = new ModLongRing(5); 227 d = new ModLong(zm, 11); 228 229 a = zm.random(100); 230 if (a.isZERO()) { 231 a = d; 232 } 233 b = a.multiply(a); 234 c = b.divide(a); 235 236 assertEquals("a*a/a = a", c, a); 237 assertEquals("a*a/a = a", 0, c.compareTo(a)); 238 239 d = a.multiply(zm.getONE()); 240 assertEquals("a*1 = a", d, a); 241 d = a.divide(zm.getONE()); 242 assertEquals("a/1 = a", d, a); 243 244 a = zm.random(100); 245 if (a.isZERO()) { 246 a = d; 247 } 248 b = a.inverse(); 249 c = a.multiply(b); 250 251 assertTrue("a*1/a = 1", c.isONE()); 252 253 try { 254 a = zm.getZERO().inverse(); 255 fail("0 invertible"); 256 } catch (NotInvertibleException expected) { 257 //ok 258 } 259 260 zm = new ModLongRing(5 * 3); 261 a = new ModLong(zm, 5); 262 assertFalse("5 !unit mod 15", a.isUnit()); 263 264 try { 265 b = a.inverse(); 266 fail("5 invertible"); 267 } catch (ModularNotInvertibleException expected) { 268 //ok 269 //expected.printStackTrace(); 270 assertTrue("f = 15 ", expected.f.equals(new BigInteger(15))); 271 assertTrue("f1 = 5 ", expected.f1.equals(new BigInteger(5))); 272 assertTrue("f2 = 3 ", expected.f2.equals(new BigInteger(3))); 273 assertTrue("f = f1*f2 ", expected.f.equals(expected.f1.multiply(expected.f2))); 274 } catch (NotInvertibleException e) { 275 //e.printStackTrace(); 276 fail("wrong exception " + e); 277 } 278 } 279 280 281 /** 282 * Test chinese remainder. 283 */ 284 public void testChineseRemainder() { 285 zm = new ModLongRing(19 * 13); 286 a = zm.random(9); 287 //System.out.println("a = " + a); 288 z1 = new ModLongRing(19); 289 b = new ModLong(z1, a.getVal()); 290 //System.out.println("b = " + b); 291 z2 = new ModLongRing(13); 292 c = new ModLong(z2, a.getVal()); 293 //System.out.println("c = " + c); 294 d = new ModLong(z2, 19); 295 d = d.inverse(); 296 //System.out.println("d = " + d); 297 298 e = zm.chineseRemainder(b, d, c); 299 //System.out.println("e = " + e); 300 301 assertEquals("cra(a mod 19,a mod 13) = a", a, e); 302 303 java.math.BigInteger p1 = getPrime2(); 304 java.math.BigInteger p2 = new java.math.BigInteger("19"); //getPrime1(); 305 java.math.BigInteger p1p2 = p1.multiply(p2); 306 //System.out.println("p1p2 = " + p1p2); 307 //System.out.println("prime p1 ? = " + p1.isProbablePrime(66)); 308 //System.out.println("prime p2 ? = " + p2.isProbablePrime(33)); 309 //System.out.println("prime p1p1 ? = " + p1p2.isProbablePrime(3)); 310 zm = new ModLongRing(p1p2); 311 z1 = new ModLongRing(p1); 312 z2 = new ModLongRing(p2); 313 314 for (int i = 0; i < 5; i++) { 315 a = zm.random((59 + 29) / 2); //60+30 ); 316 //System.out.println("a = " + a); 317 b = new ModLong(z1, a.getVal()); 318 //System.out.println("b = " + b); 319 c = new ModLong(z2, a.getVal()); 320 //System.out.println("c = " + c); 321 ModLong di = new ModLong(z2, p1); 322 d = di.inverse(); 323 //System.out.println("d = " + d); 324 325 e = zm.chineseRemainder(b, d, c); 326 //System.out.println("e = " + e); 327 328 assertEquals("cra(a mod p1,a mod p2) = a ", a, e); 329 } 330 } 331 332 333 /** 334 * Test chinese remainder of lists. 335 */ 336 public void testChineseRemainderLists() { 337 zm = new ModLongRing(19 * 13); 338 z1 = new ModLongRing(19); 339 z2 = new ModLongRing(13); 340 341 List<ModLong> L1 = new ArrayList<ModLong>(); 342 List<ModLong> L2 = new ArrayList<ModLong>(); 343 List<ModLong> L; 344 345 for (int i = 0; i < 7; i++) { 346 a = zm.random(9); 347 //System.out.println("a = " + a); 348 b = new ModLong(z1, a.getVal()); 349 //System.out.println("b = " + b); 350 c = new ModLong(z2, a.getVal()); 351 //System.out.println("c = " + c); 352 L1.add(b); 353 L2.add(c); 354 } 355 //System.out.println("L1 = " + L1); 356 //System.out.println("L2 = " + L2); 357 358 L = ModLongRing.chineseRemainder(z1.getONE(), z2.getONE(), L1, L2); 359 //System.out.println("L = " + L); 360 assertEquals("19 * 13) = a.modul: ", zm, L.get(0).ring); 361 362 for (ModLong d : L) { 363 b = new ModLong(z1, d.getVal()); 364 //System.out.println("b = " + b); 365 c = new ModLong(z2, d.getVal()); 366 //System.out.println("c = " + c); 367 assertTrue("cra(a mod 19, a mod 13) = a: ", L1.contains(b)); 368 assertTrue("cra(a mod 19, a mod 13) = a: ", L2.contains(c)); 369 } 370 } 371 372 373 /** 374 * Test timing ModLong to ModInteger. 375 */ 376 public void testTiming() { 377 zm = new ModLongRing(getPrime1()); 378 a = zm.random(9); 379 //System.out.println("a = " + a); 380 b = zm.random(9); 381 //System.out.println("b = " + b); 382 c = zm.getONE(); 383 //System.out.println("c = " + c); 384 385 ModIntegerRing ZM = new ModIntegerRing(zm.modul); 386 ModInteger A = new ModInteger(ZM, a.getVal()); 387 ModInteger B = new ModInteger(ZM, b.getVal()); 388 ModInteger C = ZM.getONE(); 389 390 int run = 1000; //000; 391 long t = System.currentTimeMillis(); 392 for (int i = 0; i < run; i++) { 393 if (c.isZERO()) { 394 c = zm.getONE(); 395 } 396 c = a.sum(b.divide(c)); 397 } 398 t = System.currentTimeMillis() - t; 399 //System.out.println("long time = " + t); 400 401 ModInteger D = new ModInteger(ZM, c.getVal()); 402 t = System.currentTimeMillis(); 403 for (int i = 0; i < run; i++) { 404 if (C.isZERO()) { 405 C = ZM.getONE(); 406 } 407 C = A.sum(B.divide(C)); 408 } 409 t = System.currentTimeMillis() - t; 410 //System.out.println("BigInteger time = " + t); 411 412 assertEquals("C == D ", C, D); 413 } 414 415 416 /** 417 * Test iterator. 418 */ 419 public void testIterator() { 420 int m = 5 * 2; 421 zm = new ModLongRing(m); 422 ModLong j = null; 423 for (ModLong i : zm) { 424 //System.out.println("i = " + i); 425 j = i; 426 } 427 ModLong end = new ModLong(zm, m - 1); 428 assertTrue("j == m-1 ", j.equals(end)); 429 } 430 431}