001/* 002 * $Id: BigQuaternionIntegerTest.java 5731 2017-02-11 11:38:15Z kredel $ 003 */ 004 005package edu.jas.arith; 006 007 008import java.util.SortedMap; 009 010import junit.framework.Test; 011import junit.framework.TestCase; 012import junit.framework.TestSuite; 013 014 015/** 016 * BigQuaternionInteger tests with JUnit. 017 * @author Heinz Kredel 018 */ 019 020public class BigQuaternionIntegerTest extends TestCase { 021 022 023 /** 024 * main. 025 */ 026 public static void main(String[] args) { 027 junit.textui.TestRunner.run(suite()); 028 } 029 030 031 /** 032 * Constructs a <CODE>BigQuaternionIntegerTest</CODE> object. 033 * @param name String. 034 */ 035 public BigQuaternionIntegerTest(String name) { 036 super(name); 037 } 038 039 040 /** 041 * @return suite. 042 */ 043 public static Test suite() { 044 TestSuite suite = new TestSuite(BigQuaternionIntegerTest.class); 045 return suite; 046 } 047 048 049 BigQuaternion a, b, c, d, e, f; 050 051 052 BigQuaternionRing fac; 053 054 055 @Override 056 protected void setUp() { 057 a = b = c = d = e = null; 058 fac = new BigQuaternionRing(true); 059 } 060 061 062 @Override 063 protected void tearDown() { 064 a = b = c = d = e = null; 065 fac = null; 066 } 067 068 069 /** 070 * Test static initialization and constants. 071 */ 072 public void testConstants() { 073 a = fac.getZERO(); 074 b = fac.getONE(); 075 c = b.subtract(b); 076 assertEquals("1-1 = 0", c, a); 077 assertTrue("1-1 = 0", c.isZERO()); 078 assertTrue("1 = 1", b.isONE()); 079 080 assertTrue("isEntier(0)", a.isEntier()); 081 assertTrue("isEntier(1)", b.isEntier()); 082 assertTrue("isEntier(c)", c.isEntier()); 083 } 084 085 086 /** 087 * Test bitLength. 088 */ 089 public void testBitLength() { 090 a = fac.ZERO; 091 b = fac.ONE; 092 c = fac.random(100); 093 //System.out.println("c = " + c); 094 //System.out.println("len(c) = " + c.bitLength()); 095 096 assertEquals("len(0) = 12", 12, a.bitLength()); 097 assertEquals("len(1) = 13", 13, b.bitLength()); 098 assertEquals("len(-1) = 13", 13, b.negate().bitLength()); 099 assertTrue("len(random) >= 12", 12 <= c.bitLength()); 100 101 d = fac.I; 102 assertEquals("len(i) = 13", 13, d.bitLength()); 103 assertEquals("len(-i) = 13", 13, d.negate().bitLength()); 104 105 d = fac.J; 106 assertEquals("len(j) = 13", 13, d.bitLength()); 107 assertEquals("len(-j) = 13", 13, d.negate().bitLength()); 108 109 d = fac.K; 110 assertEquals("len(k) = 13", 13, d.bitLength()); 111 assertEquals("len(-k) = 13", 13, d.negate().bitLength()); 112 } 113 114 115 /** 116 * Test constructor and toString. 117 */ 118 public void testConstructor() { 119 a = new BigQuaternionInteger(fac, "6/8"); 120 b = new BigQuaternionInteger(fac, "3/4"); 121 122 assertEquals("6/8 = 3/4", a, b); 123 assertFalse("isEntier(a)", a.isEntier()); 124 assertFalse("isEntier(b)", b.isEntier()); 125 126 a = new BigQuaternionInteger(fac, "3/4 i 4/5 j 1/5 k 2/5"); 127 b = new BigQuaternionInteger(fac, "-3/4 i -4/5 j -1/5 k -2/5"); 128 assertEquals("3/4 + i 4/5 + j 1/5 + k 2/5", a, b.negate()); 129 assertFalse("isEntier(a)", a.isEntier()); 130 assertFalse("isEntier(b)", b.isEntier()); 131 132 String s = "6/1111111111111111111111111111111111111111111"; 133 a = new BigQuaternionInteger(fac, s); 134 String t = a.toString(); 135 136 assertFalse("isEntier(a)", a.isEntier()); 137 assertEquals("stringConstr = toString", s, t); 138 139 a = new BigQuaternionInteger(fac, 1); 140 b = new BigQuaternionInteger(fac, -1); 141 c = b.sum(a); 142 assertTrue("isEntier(a)", a.isEntier()); 143 assertTrue("isEntier(b)", b.isEntier()); 144 assertTrue("isEntier(c)", c.isEntier()); 145 146 assertTrue("1 = 1", a.isONE()); 147 assertEquals("1+(-1) = 0", c, fac.ZERO); 148 } 149 150 151 /** 152 * Test random rationals. 153 */ 154 public void testRandom() { 155 a = fac.random(50); 156 b = new BigQuaternionInteger(fac, a.getRe(), a.getIm(), a.getJm(), a.getKm()); 157 c = b.subtract(a); 158 assertTrue("isEntier(a)", a.isEntier()); 159 assertTrue("isEntier(b)", b.isEntier()); 160 assertTrue("isEntier(c)", c.isEntier()); 161 162 assertEquals("a-b = 0", fac.ZERO, c); 163 164 d = new BigQuaternionInteger(fac, b); 165 assertEquals("sign(a-a) = 0", 0, b.compareTo(d)); 166 assertTrue("isEntier(d)", d.isEntier()); 167 } 168 169 170 /** 171 * Test addition. 172 */ 173 public void testAddition() { 174 a = fac.random(10); 175 b = a.sum(a); 176 c = b.subtract(a); 177 assertEquals("a+a-a = a", c, a); 178 assertEquals("a+a-a = a", 0, c.compareTo(a)); 179 180 assertTrue("isEntier(a)", a.isEntier()); 181 assertTrue("isEntier(b)", b.isEntier()); 182 assertTrue("isEntier(c)", c.isEntier()); 183 184 d = a.sum(fac.ZERO); 185 assertEquals("a+0 = a", d, a); 186 187 d = a.subtract(fac.ZERO); 188 assertEquals("a-0 = a", d, a); 189 190 d = a.subtract(a); 191 assertEquals("a-a = 0", d, fac.ZERO); 192 assertTrue("isEntier(d)", d.isEntier()); 193 } 194 195 196 /** 197 * Test multiplication. 198 */ 199 public void testMultiplication() { 200 a = fac.random(10); 201 b = a.multiply(a); 202 c = b.leftDivide(a); 203 BigQuaternionInteger bi = new BigQuaternionInteger(fac, b); 204 d = bi.leftDivide(a); 205 //System.out.println("a = " + a); 206 //System.out.println("b = " + b); 207 //System.out.println("c = " + c); 208 //System.out.println("d = " + d); 209 assertTrue("isEntier(a)", a.isEntier()); 210 assertTrue("isEntier(b)", b.isEntier()); 211 assertTrue("isEntier(c)", c.isEntier()); 212 assertTrue("isEntier(d)", d.isEntier()); 213 214 //if (! d.equals(a)) { 215 // e = a.multiply(d); 216 // System.out.println("e = " + e + ", e==b: " + e.equals(bi)); 217 // e = d.multiply(a); 218 // System.out.println("e = " + e + ", e==b: " + e.equals(bi)); 219 //} 220 assertEquals("a*a/a = a", d, a); // || !d.isZERO()); 221 222 d = a.multiply(fac.ONE); 223 assertEquals("a*1 = a", d, a); 224 d = a.divide(fac.ONE); 225 assertEquals("a/1 = a", d, a); 226 227 //a = fac.random(10); 228 //b = a.inverse(); // not entier 229 //c = a.multiply(b); 230 //assertTrue("a*1/a = 1", c.isONE()); 231 //c = b.multiply(a); 232 //assertTrue("1/a*a = 1", c.isONE()); 233 //assertTrue("isEntier(a)", a.isEntier()); 234 //assertTrue("isEntier(b)", b.isEntier()); 235 //assertTrue("isEntier(c)", c.isEntier()); 236 237 //b = a.abs(); 238 //c = b.inverse(); // not entier 239 //d = b.multiply(c); 240 //assertTrue("abs(a)*1/abs(a) = 1", d.isONE()); 241 //assertTrue("isEntier(a)", a.isEntier()); 242 243 b = a.abs(); 244 c = a.conjugate(); 245 d = a.multiply(c); 246 assertTrue("isEntier(a)", a.isEntier()); 247 assertEquals("abs(a)^2 = a a^", b, d); 248 assertTrue("isEntier(b)", b.isEntier()); 249 assertTrue("isEntier(c)", c.isEntier()); 250 assertTrue("isEntier(d)", d.isEntier()); 251 } 252 253 254 /** 255 * Test multiplication axioms. 256 */ 257 public void testMultiplicationAxioms() { 258 a = fac.random(10); 259 b = fac.random(10); 260 261 c = a.multiply(b); 262 d = b.multiply(a); 263 assertFalse("a*b != b*a", c.equals(d)); 264 265 assertTrue("isEntier(a)", a.isEntier()); 266 assertTrue("isEntier(b)", b.isEntier()); 267 assertTrue("isEntier(c)", c.isEntier()); 268 assertTrue("isEntier(d)", d.isEntier()); 269 270 c = fac.random(10); 271 272 d = a.multiply(b.multiply(c)); 273 e = a.multiply(b).multiply(c); 274 assertTrue("a(bc) = (ab)c", e.equals(d)); 275 assertTrue("isEntier(c)", c.isEntier()); 276 assertTrue("isEntier(d)", d.isEntier()); 277 assertTrue("isEntier(e)", e.isEntier()); 278 } 279 280 281 /** 282 * Test distributive law. 283 */ 284 public void testDistributive() { 285 a = fac.random(20); 286 b = fac.random(20); 287 c = fac.random(20); 288 289 d = a.multiply(b.sum(c)); 290 e = a.multiply(b).sum(a.multiply(c)); 291 assertEquals("a(b+c) = ab+ac", d, e); 292 293 assertTrue("isEntier(a)", a.isEntier()); 294 assertTrue("isEntier(b)", b.isEntier()); 295 assertTrue("isEntier(c)", c.isEntier()); 296 assertTrue("isEntier(d)", d.isEntier()); 297 assertTrue("isEntier(e)", e.isEntier()); 298 } 299 300 301 /** 302 * Test divide entier elements. 303 */ 304 public void testDivideEntier() { 305 a = new BigQuaternionInteger(fac, "3 i 4 j 5 k 2"); 306 assertTrue("a is entier", a.isEntier()); 307 //System.out.println("a = " + a); 308 309 b = new BigQuaternionInteger(fac, "-3/2 i -5/2 j -1/2 k -7/2"); 310 assertTrue("b is entier", b.isEntier()); 311 //System.out.println("b = " + b); 312 313 c = a.multiply(a); 314 //System.out.println("c = " + c); 315 assertTrue("c is entier", c.isEntier()); 316 317 c = b.multiply(b); 318 //System.out.println("c = " + c); 319 assertTrue("c is entier", c.isEntier()); 320 321 c = a.multiply(b); 322 //System.out.println("c = " + c); 323 assertTrue("c is entier", c.isEntier()); 324 325 c = b.multiply(a); 326 //System.out.println("c = " + c); 327 assertTrue("c is entier", c.isEntier()); 328 329 d = a.norm(); 330 //System.out.println("norm(a) = " + d); 331 assertTrue("d is entier", d.isEntier()); 332 333 d = b.norm(); 334 //System.out.println("norm(b) = " + d); 335 assertTrue("d is entier", d.isEntier()); 336 337 BigQuaternionInteger ai, bi; 338 ai = new BigQuaternionInteger(fac, a); 339 bi = new BigQuaternionInteger(fac, b); 340 // quotient and remainder 341 //System.out.println("ai = " + ai.toScript()); 342 //System.out.println("bi = " + bi.toScript()); 343 BigQuaternion[] qr = ai.leftQuotientAndRemainder(bi); 344 c = qr[0]; 345 d = qr[1]; 346 //System.out.println("q = " + c.toScript()); 347 //System.out.println("d = " + d.toScript()); 348 assertTrue("c is entier", c.isEntier()); 349 assertTrue("d is entier", d.isEntier()); 350 //System.out.println("norm(b) = " + b.norm()); 351 //System.out.println("norm(r) = " + d.norm()); 352 assertEquals("a == b * q + r: ", a, b.multiply(c).sum(d)); 353 assertTrue("norm(r) < norm(b): ", d.norm().re.compareTo(b.norm().re) < 0); 354 355 qr = ai.rightQuotientAndRemainder(bi); 356 c = qr[0]; 357 d = qr[1]; 358 //System.out.println("q = " + c.toScript()); 359 //System.out.println("d = " + d.toScript()); 360 assertTrue("c is entier", c.isEntier()); 361 assertTrue("d is entier", d.isEntier()); 362 //System.out.println("norm(b) = " + b.norm()); 363 //System.out.println("norm(r) = " + d.norm()); 364 assertEquals("a == q * b + r: ", a, c.multiply(b).sum(d)); 365 assertTrue("norm(r) < norm(b): ", d.norm().re.compareTo(b.norm().re) < 0); 366 } 367 368 369 /** 370 * Test gcd entier elements. 371 */ 372 public void testGcdEntier() { 373 a = fac.random(10); 374 b = fac.random(10); 375 BigQuaternionInteger ai, bi; 376 ai = new BigQuaternionInteger(fac, a); 377 bi = new BigQuaternionInteger(fac, b); 378 379 BigQuaternion g = ai.leftGcd(bi); 380 //System.out.println("g = " + g.toScript()); 381 //System.out.println("norm(g) = " + g.norm()); 382 assertTrue("g is entier", g.isEntier()); 383 BigQuaternion r = ai.leftQuotientAndRemainder(g)[1]; 384 //System.out.println("r = " + r.toScript()); 385 assertTrue("r == 0: ", r.isZERO()); 386 r = bi.leftQuotientAndRemainder(g)[1]; 387 //System.out.println("r = " + r.toScript()); 388 assertTrue("r == 0: " + r, r.isZERO()); 389 390 BigQuaternion h = ai.rightGcd(bi); 391 //System.out.println("h = " + h.toScript()); 392 //System.out.println("norm(h) = " + h.norm()); 393 assertTrue("h is entier", h.isEntier()); 394 r = ai.rightQuotientAndRemainder(h)[1]; 395 //System.out.println("r = " + r.toScript()); 396 assertTrue("r == 0: ", r.isZERO()); 397 r = bi.rightQuotientAndRemainder(h)[1]; 398 //System.out.println("r = " + r.toScript()); 399 assertTrue("r == 0: ", r.isZERO()); 400 401 // round to entier and factor norm 402 a = fac.random(20).roundToLipschitzian(); 403 //a = fac.random(20).roundToHurwitzian(); 404 //System.out.println("a = " + a.toScript()); 405 b = a.norm(); 406 //System.out.println("b = " + b.toScript()); 407 java.math.BigInteger pp = b.re.floor(); 408 //System.out.println("pp = " + pp); 409 long pl = pp.longValue(); 410 411 SortedMap<Long, Integer> P = PrimeInteger.factors(pl); 412 //System.out.println("P = " + P); 413 for (Long p : P.keySet()) { 414 c = new BigQuaternion(fac, new BigRational(p)); 415 //System.out.println("c = " + c); 416 d = a.leftGcd(c); 417 //System.out.println("d = " + d.toScript()); 418 e = d.norm(); 419 //System.out.println("e = " + e); 420 assertTrue("norm(gcd) == c: " + c + " : " + e, 421 c.equals(e) || c.equals(e.power(2)) || c.power(2).equals(e)); 422 } 423 } 424 425}