001/* 002 * $Id: ModIntegerTest.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; 011import java.util.SortedMap; 012 013import edu.jas.kern.PrettyPrint; 014import edu.jas.structure.NotInvertibleException; 015 016import junit.framework.Test; 017import junit.framework.TestCase; 018import junit.framework.TestSuite; 019 020 021/** 022 * ModInteger tests with JUnit. 023 * @author Heinz Kredel 024 */ 025 026public class ModIntegerTest extends TestCase { 027 028 029 /** 030 * main. 031 */ 032 public static void main(String[] args) { 033 junit.textui.TestRunner.run(suite()); 034 } 035 036 037 /** 038 * Constructs a <CODE>ModIntegerTest</CODE> object. 039 * @param name String 040 */ 041 public ModIntegerTest(String name) { 042 super(name); 043 } 044 045 046 /** 047 */ 048 public static Test suite() { 049 TestSuite suite = new TestSuite(ModIntegerTest.class); 050 return suite; 051 } 052 053 054 ModIntegerRing zm, z1, z2; 055 056 057 ModInteger a, b, c, d, e; 058 059 060 @Override 061 protected void setUp() { 062 zm = z1 = z2 = null; 063 a = b = c = d = e = null; 064 } 065 066 067 @Override 068 protected void tearDown() { 069 zm = z1 = z2 = null; 070 a = b = c = d = e = null; 071 } 072 073 074 protected static java.math.BigInteger getPrime1() { 075 long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390) 076 for (int i = 1; i < 60; i++) { 077 prime *= 2; 078 } 079 prime -= 93; 080 //prime = 37; 081 //System.out.println("p1 = " + prime); 082 return new java.math.BigInteger("" + prime); 083 } 084 085 086 protected static java.math.BigInteger getPrime2() { 087 long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390) 088 for (int i = 1; i < 30; i++) { 089 prime *= 2; 090 } 091 prime -= 35; 092 //prime = 19; 093 //System.out.println("p2 = " + prime); 094 return new java.math.BigInteger("" + prime); 095 } 096 097 098 /** 099 * Test static initialization and constants. 100 */ 101 public void testConstants() { 102 zm = new ModIntegerRing(5); 103 d = new ModInteger(zm, 11); 104 a = zm.getZERO(); 105 b = zm.getONE(); 106 c = ModInteger.MIDIF(b, b); 107 108 assertEquals("1-1 = 0", c, a); 109 assertTrue("1-1 = 0", c.isZERO()); 110 assertTrue("1 = 1", b.isONE()); 111 } 112 113 114 /** 115 * Test bitLength. 116 */ 117 public void testBitLength() { 118 zm = new ModIntegerRing(163); 119 a = zm.getZERO(); 120 b = zm.getONE(); 121 c = zm.random(30); 122 //System.out.println("c = " + c); 123 //System.out.println("len(c) = " + c.bitLength()); 124 125 assertEquals("len(0) = 1", 1, a.bitLength()); 126 assertEquals("len(1) = 2", 2, b.bitLength()); 127 assertEquals("len(-1) = len(mod)", zm.modul.bitLength() + 1, b.negate().bitLength()); 128 assertTrue("len(random) >= 1", 1 <= c.bitLength()); 129 } 130 131 132 /** 133 * Test constructor and toString. 134 */ 135 public void testConstructor() { 136 zm = new ModIntegerRing("5"); 137 a = new ModInteger(zm, "64"); 138 b = new ModInteger(zm, "34"); 139 140 assertEquals("64(5) = 34(5)", a, b); 141 142 zm = new ModIntegerRing("7"); 143 a = new ModInteger(zm, "-4"); 144 b = new ModInteger(zm, "3"); 145 146 assertEquals("-4(7) = 3(7)", a, b); 147 148 String s = "61111111111111111111111111111111111111111111"; 149 zm = new ModIntegerRing("10"); 150 a = new ModInteger(zm, s); 151 String t = a.toString(); 152 153 if (PrettyPrint.isTrue()) { 154 String st = "1"; 155 assertEquals("stringConstr = toString", st, t); 156 } else { 157 String st = "1 mod(10)"; 158 assertEquals("stringConstr = toString", st, t); 159 } 160 161 zm = new ModIntegerRing(7); 162 a = new ModInteger(zm, 1); 163 b = new ModInteger(zm, -1); 164 c = ModInteger.MISUM(b, a); 165 166 assertTrue("1 = 1", a.isONE()); 167 assertTrue("1 = 1", b.isUnit()); 168 assertEquals("1+(-1) = 0", c, zm.getZERO()); 169 170 zm = new ModIntegerRing(5); 171 a = new ModInteger(zm, 3); 172 b = new ModInteger(zm, 0); 173 c = zm.parse(" 13 "); 174 assertEquals("3(5) = 3(5)", a, c); 175 176 StringReader sr = new StringReader(" 13\n w "); 177 c = zm.parse(sr); 178 assertEquals("3(5) = 3(5)", a, c); 179 //System.out.println("c = " + c); 180 } 181 182 183 /** 184 * Test random modular integers. 185 */ 186 public void testRandom() { 187 zm = new ModIntegerRing(19); 188 a = zm.random(500); 189 b = a.copy(); 190 c = ModInteger.MIDIF(b, a); 191 192 assertEquals("a-b = 0", c, zm.getZERO()); 193 194 d = new ModInteger(new ModIntegerRing(b.getModul()), b.getVal()); 195 assertEquals("sign(a-a) = 0", 0, b.compareTo(d)); 196 } 197 198 199 /** 200 * Test addition. 201 */ 202 public void testAddition() { 203 zm = new ModIntegerRing(19); 204 205 a = zm.random(100); 206 b = ModInteger.MISUM(a, a); 207 c = ModInteger.MIDIF(b, a); 208 209 assertEquals("a+a-a = a", c, a); 210 assertEquals("a+a-a = a", 0, ModInteger.MICOMP(c, a)); 211 212 d = ModInteger.MISUM(a, zm.getZERO()); 213 assertEquals("a+0 = a", d, a); 214 d = ModInteger.MIDIF(a, zm.getZERO()); 215 assertEquals("a-0 = a", d, a); 216 d = ModInteger.MIDIF(a, 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 ModIntegerRing(5); 227 d = new ModInteger(zm, 11); 228 229 a = zm.random(100); 230 if (a.isZERO()) { 231 a = d; 232 } 233 b = ModInteger.MIPROD(a, a); 234 c = ModInteger.MIQ(b, a); 235 236 assertEquals("a*a/a = a", c, a); 237 assertEquals("a*a/a = a", 0, c.compareTo(a)); 238 239 d = ModInteger.MIPROD(a, zm.getONE()); 240 assertEquals("a*1 = a", d, a); 241 d = ModInteger.MIQ(a, 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 = ModInteger.MIINV(a); 249 c = ModInteger.MIPROD(a, 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 ModIntegerRing(5 * 3); 261 a = new ModInteger(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 ModIntegerRing(19 * 13); 286 a = zm.random(9); 287 //System.out.println("a = " + a); 288 z1 = new ModIntegerRing(19); 289 b = new ModInteger(z1, a.getVal().longValue()); 290 //System.out.println("b = " + b); 291 z2 = new ModIntegerRing(13); 292 c = new ModInteger(z2, a.getVal().longValue()); 293 //System.out.println("c = " + c); 294 d = new ModInteger(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 = getPrime1(); 304 java.math.BigInteger p2 = getPrime2(); 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 ModIntegerRing(p1p2); 311 z1 = new ModIntegerRing(p1); 312 z2 = new ModIntegerRing(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 ModInteger(z1, a.getVal()); 318 //System.out.println("b = " + b); 319 c = new ModInteger(z2, a.getVal()); 320 //System.out.println("c = " + c); 321 ModInteger di = new ModInteger(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 java.math.BigInteger p1 = getPrime1(); 338 java.math.BigInteger p2 = getPrime2(); 339 java.math.BigInteger p1p2 = p1.multiply(p2); 340 zm = new ModIntegerRing(p1p2); 341 z1 = new ModIntegerRing(p1); 342 z2 = new ModIntegerRing(p2); 343 344 List<ModInteger> L1 = new ArrayList<ModInteger>(); 345 List<ModInteger> L2 = new ArrayList<ModInteger>(); 346 List<ModInteger> L; 347 348 for (int i = 0; i < 5; i++) { 349 a = zm.random(17); 350 //System.out.println("a = " + a); 351 b = new ModInteger(z1, a.getVal()); 352 //System.out.println("b = " + b); 353 c = new ModInteger(z2, a.getVal()); 354 //System.out.println("c = " + c); 355 L1.add(b); 356 L2.add(c); 357 } 358 //System.out.println("L1 = " + L1); 359 //System.out.println("L2 = " + L2); 360 361 L = ModIntegerRing.chineseRemainder(z1.getONE(), z2.getONE(), L1, L2); 362 //System.out.println("L = " + L); 363 assertEquals("p1 * p2) = a.modul: ", zm, L.get(0).ring); 364 365 for (ModInteger d : L) { 366 b = new ModInteger(z1, d.getVal()); 367 //System.out.println("b = " + b); 368 c = new ModInteger(z2, d.getVal()); 369 //System.out.println("c = " + c); 370 assertTrue("cra(a mod p1, a mod p2) = a: ", L1.contains(b)); 371 assertTrue("cra(a mod p1, a mod p2) = a: ", L2.contains(c)); 372 } 373 } 374 375 376 /** 377 * Test iterator. 378 */ 379 public void testIterator() { 380 int m = 5 * 2; 381 zm = new ModIntegerRing(m); 382 ModInteger j = null; 383 for (ModInteger i : zm) { 384 //System.out.println("i = " + i); 385 j = i; 386 } 387 ModInteger end = new ModInteger(zm, m - 1); 388 assertTrue("j == m-1 ", j.equals(end)); 389 } 390 391}