001/* 002 * $Id: BigQuaternionIntegerTest.java 5940 2018-10-19 08:53:13Z 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 = a.norm(); 239 //assertEquals("abs() == norm(): " + b, b, c); // wrong 240 241 //c = b.inverse(); // not entier 242 //d = b.multiply(c); 243 //assertTrue("abs(a)*1/abs(a) = 1", d.isONE()); 244 //assertTrue("isEntier(a)", a.isEntier()); 245 246 b = a.norm(); 247 c = a.conjugate(); 248 d = a.multiply(c); 249 assertTrue("isEntier(a)", a.isEntier()); 250 assertEquals("abs(a)^2 = a a^", b, d); 251 assertTrue("isEntier(b)", b.isEntier()); 252 assertTrue("isEntier(c)", c.isEntier()); 253 assertTrue("isEntier(d)", d.isEntier()); 254 } 255 256 257 /** 258 * Test multiplication axioms. 259 */ 260 public void testMultiplicationAxioms() { 261 a = fac.random(10); 262 b = fac.random(10); 263 264 c = a.multiply(b); 265 d = b.multiply(a); 266 assertFalse("a*b != b*a", c.equals(d)); 267 268 assertTrue("isEntier(a)", a.isEntier()); 269 assertTrue("isEntier(b)", b.isEntier()); 270 assertTrue("isEntier(c)", c.isEntier()); 271 assertTrue("isEntier(d)", d.isEntier()); 272 273 c = fac.random(10); 274 275 d = a.multiply(b.multiply(c)); 276 e = a.multiply(b).multiply(c); 277 assertTrue("a(bc) = (ab)c", e.equals(d)); 278 assertTrue("isEntier(c)", c.isEntier()); 279 assertTrue("isEntier(d)", d.isEntier()); 280 assertTrue("isEntier(e)", e.isEntier()); 281 } 282 283 284 /** 285 * Test distributive law. 286 */ 287 public void testDistributive() { 288 a = fac.random(20); 289 b = fac.random(20); 290 c = fac.random(20); 291 292 d = a.multiply(b.sum(c)); 293 e = a.multiply(b).sum(a.multiply(c)); 294 assertEquals("a(b+c) = ab+ac", d, e); 295 296 assertTrue("isEntier(a)", a.isEntier()); 297 assertTrue("isEntier(b)", b.isEntier()); 298 assertTrue("isEntier(c)", c.isEntier()); 299 assertTrue("isEntier(d)", d.isEntier()); 300 assertTrue("isEntier(e)", e.isEntier()); 301 } 302 303 304 /** 305 * Test divide entier elements. 306 */ 307 public void testDivideEntier() { 308 a = new BigQuaternionInteger(fac, "3 i 4 j 5 k 2"); 309 assertTrue("a is entier", a.isEntier()); 310 //System.out.println("a = " + a); 311 312 b = new BigQuaternionInteger(fac, "-3/2 i -5/2 j -1/2 k -7/2"); 313 assertTrue("b is entier", b.isEntier()); 314 //System.out.println("b = " + b); 315 316 c = a.multiply(a); 317 //System.out.println("c = " + c); 318 assertTrue("c is entier", c.isEntier()); 319 320 c = b.multiply(b); 321 //System.out.println("c = " + c); 322 assertTrue("c is entier", c.isEntier()); 323 324 c = a.multiply(b); 325 //System.out.println("c = " + c); 326 assertTrue("c is entier", c.isEntier()); 327 328 c = b.multiply(a); 329 //System.out.println("c = " + c); 330 assertTrue("c is entier", c.isEntier()); 331 332 d = a.norm(); 333 //System.out.println("norm(a) = " + d); 334 assertTrue("d is entier", d.isEntier()); 335 336 d = b.norm(); 337 //System.out.println("norm(b) = " + d); 338 assertTrue("d is entier", d.isEntier()); 339 340 BigQuaternionInteger ai, bi; 341 ai = new BigQuaternionInteger(fac, a); 342 bi = new BigQuaternionInteger(fac, b); 343 // quotient and remainder 344 //System.out.println("ai = " + ai.toScript()); 345 //System.out.println("bi = " + bi.toScript()); 346 BigQuaternion[] qr = ai.leftQuotientAndRemainder(bi); 347 c = qr[0]; 348 d = qr[1]; 349 //System.out.println("q = " + c.toScript()); 350 //System.out.println("d = " + d.toScript()); 351 assertTrue("c is entier", c.isEntier()); 352 assertTrue("d is entier", d.isEntier()); 353 //System.out.println("norm(b) = " + b.norm()); 354 //System.out.println("norm(r) = " + d.norm()); 355 assertEquals("a == b * q + r: ", a, b.multiply(c).sum(d)); 356 assertTrue("norm(r) < norm(b): ", d.norm().re.compareTo(b.norm().re) < 0); 357 358 qr = ai.rightQuotientAndRemainder(bi); 359 c = qr[0]; 360 d = qr[1]; 361 //System.out.println("q = " + c.toScript()); 362 //System.out.println("d = " + d.toScript()); 363 assertTrue("c is entier", c.isEntier()); 364 assertTrue("d is entier", d.isEntier()); 365 //System.out.println("norm(b) = " + b.norm()); 366 //System.out.println("norm(r) = " + d.norm()); 367 assertEquals("a == q * b + r: ", a, c.multiply(b).sum(d)); 368 assertTrue("norm(r) < norm(b): ", d.norm().re.compareTo(b.norm().re) < 0); 369 } 370 371 372 /** 373 * Test gcd entier elements. 374 */ 375 public void testGcdEntier() { 376 a = fac.random(10); 377 b = fac.random(10); 378 BigQuaternionInteger ai, bi; 379 ai = new BigQuaternionInteger(fac, a); 380 bi = new BigQuaternionInteger(fac, b); 381 382 BigQuaternion g = ai.leftGcd(bi); 383 //System.out.println("g = " + g.toScript()); 384 //System.out.println("norm(g) = " + g.norm()); 385 assertTrue("g is entier", g.isEntier()); 386 BigQuaternion r = ai.leftQuotientAndRemainder(g)[1]; 387 //System.out.println("r = " + r.toScript()); 388 assertTrue("r == 0: ", r.isZERO()); 389 r = bi.leftQuotientAndRemainder(g)[1]; 390 //System.out.println("r = " + r.toScript()); 391 assertTrue("r == 0: " + r, r.isZERO()); 392 393 BigQuaternion h = ai.rightGcd(bi); 394 //System.out.println("h = " + h.toScript()); 395 //System.out.println("norm(h) = " + h.norm()); 396 assertTrue("h is entier", h.isEntier()); 397 r = ai.rightQuotientAndRemainder(h)[1]; 398 //System.out.println("r = " + r.toScript()); 399 assertTrue("r == 0: ", r.isZERO()); 400 r = bi.rightQuotientAndRemainder(h)[1]; 401 //System.out.println("r = " + r.toScript()); 402 assertTrue("r == 0: ", r.isZERO()); 403 404 // round to entier and factor norm 405 a = fac.random(20).roundToLipschitzian(); 406 //a = fac.random(20).roundToHurwitzian(); 407 //System.out.println("a = " + a.toScript()); 408 b = a.norm(); 409 //System.out.println("b = " + b.toScript()); 410 java.math.BigInteger pp = b.re.floor(); 411 //System.out.println("pp = " + pp); 412 long pl = pp.longValue(); 413 414 SortedMap<Long, Integer> P = PrimeInteger.factors(pl); 415 //System.out.println("P = " + P); 416 for (Long p : P.keySet()) { 417 c = new BigQuaternion(fac, new BigRational(p)); 418 //System.out.println("c = " + c); 419 d = a.leftGcd(c); 420 //System.out.println("d = " + d.toScript()); 421 e = d.norm(); 422 //System.out.println("e = " + e); 423 assertTrue("norm(gcd) == c: " + c + " : " + e, 424 c.equals(e) || c.equals(e.power(2)) || c.power(2).equals(e)); 425 } 426 } 427 428}