001 002/* 003 * $Id$ 004 */ 005 006package edu.jas.ufd; 007 008 009import java.util.SortedMap; 010import java.util.List; 011 012import edu.jas.arith.BigRational; 013import edu.jas.kern.ComputerThreads; 014import edu.jas.kern.PrettyPrint; 015import edu.jas.poly.GenPolynomialRing; 016import edu.jas.poly.TermOrder; 017import edu.jas.vector.GenMatrix; 018import edu.jas.vector.GenMatrixRing; 019import edu.jas.vector.GenVector; 020import edu.jas.vector.LinAlg; 021 022import junit.framework.Test; 023import junit.framework.TestCase; 024import junit.framework.TestSuite; 025 026 027/** 028 * Quotient over BigRational GenPolynomial tests with JUnit. 029 * @author Heinz Kredel 030 */ 031 032public class QuotientRatTest extends TestCase { 033 034 035 /** 036 * main. 037 */ 038 public static void main(String[] args) { 039 junit.textui.TestRunner.run(suite()); 040 } 041 042 043 /** 044 * Constructs a <CODE>QuotientRatTest</CODE> object. 045 * @param name String. 046 */ 047 public QuotientRatTest(String name) { 048 super(name); 049 } 050 051 052 /** 053 * suite. 054 */ 055 public static Test suite() { 056 TestSuite suite = new TestSuite(QuotientRatTest.class); 057 return suite; 058 } 059 060 061 //private final static int bitlen = 100; 062 063 QuotientRing<BigRational> zFac, efac; 064 065 066 GenPolynomialRing<BigRational> mfac; 067 068 069 Quotient<BigRational> a, b, c, d, e; 070 071 072 Quotient<BigRational> az, bz, cz, dz, ez; 073 074 075 int rl = 3; 076 077 078 int kl = 5; 079 080 081 int ll = 3; //6; 082 083 084 int el = 2; 085 086 087 float q = 0.4f; 088 089 090 @Override 091 protected void setUp() { 092 a = b = c = d = e = null; 093 TermOrder to = new TermOrder(TermOrder.INVLEX); 094 mfac = new GenPolynomialRing<BigRational>(new BigRational(1), rl, to); 095 efac = new QuotientRing<BigRational>(mfac); 096 zFac = new QuotientRing<BigRational>(mfac, false); 097 } 098 099 100 @Override 101 protected void tearDown() { 102 a = b = c = d = e = null; 103 //efac.terminate(); 104 efac = null; 105 zFac = null; 106 ComputerThreads.terminate(); 107 } 108 109 110 /** 111 * Test constructor and toString. 112 */ 113 public void testConstruction() { 114 c = efac.getONE(); 115 //System.out.println("c = " + c); 116 //System.out.println("c.val = " + c.val); 117 assertTrue("length( c ) = 1", c.num.length() == 1); 118 assertTrue("isZERO( c )", !c.isZERO()); 119 assertTrue("isONE( c )", c.isONE()); 120 121 d = efac.getZERO(); 122 //System.out.println("d = " + d); 123 //System.out.println("d.val = " + d.val); 124 assertTrue("length( d ) = 0", d.num.length() == 0); 125 assertTrue("isZERO( d )", d.isZERO()); 126 assertTrue("isONE( d )", !d.isONE()); 127 } 128 129 130 /** 131 * Test random polynomial. 132 */ 133 public void testRandom() { 134 for (int i = 0; i < 7; i++) { 135 //a = efac.random(ll+i); 136 a = efac.random(kl * (i + 1), ll + 2 + 2 * i, el, q); 137 //System.out.println("a = " + a); 138 if (a.isZERO() || a.isONE()) { 139 continue; 140 } 141 assertTrue("length( a" + i + " ) <> 0", a.num.length() >= 0); 142 assertTrue(" not isZERO( a" + i + " )", !a.isZERO()); 143 assertTrue(" not isONE( a" + i + " )", !a.isONE()); 144 } 145 } 146 147 148 /** 149 * Test addition. 150 */ 151 public void testAddition() { 152 a = efac.random(kl, ll, el, q); 153 b = efac.random(kl, ll, el, q); 154 //System.out.println("a = " + a); 155 //System.out.println("b = " + b); 156 157 c = a.sum(b); 158 d = c.subtract(b); 159 //System.out.println("c = " + c); 160 //System.out.println("d = " + d); 161 d = d.monic(); 162 //System.out.println("d = " + d); 163 assertEquals("a+b-b = a", a, d); 164 165 c = a.sum(b); 166 d = b.sum(a); 167 //System.out.println("c = " + c); 168 //System.out.println("d = " + d); 169 assertEquals("a+b = b+a", c, d); 170 171 //System.out.println("monic(d) = " + d.monic()); 172 173 c = efac.random(kl, ll, el, q); 174 //System.out.println("c = " + c); 175 d = c.sum(a.sum(b)); 176 e = c.sum(a).sum(b); 177 //System.out.println("d = " + d); 178 //System.out.println("e = " + e); 179 assertEquals("c+(a+b) = (c+a)+b", d, e); 180 181 182 c = a.sum(efac.getZERO()); 183 d = a.subtract(efac.getZERO()); 184 assertEquals("a+0 = a-0", c, d); 185 186 c = efac.getZERO().sum(a); 187 d = efac.getZERO().subtract(a.negate()); 188 assertEquals("0+a = 0+(-a)", c, d); 189 } 190 191 192 /** 193 * Test object multiplication. 194 */ 195 public void testMultiplication() { 196 a = efac.random(kl, ll, el, q); 197 //assertTrue("not isZERO( a )", !a.isZERO() ); 198 199 b = efac.random(kl, ll, el, q); 200 //assertTrue("not isZERO( b )", !b.isZERO() ); 201 202 c = b.multiply(a); 203 d = a.multiply(b); 204 //assertTrue("not isZERO( c )", !c.isZERO() ); 205 //assertTrue("not isZERO( d )", !d.isZERO() ); 206 207 //System.out.println("a = " + a); 208 //System.out.println("b = " + b); 209 e = d.subtract(c); 210 assertTrue("isZERO( a*b-b*a ) " + e, e.isZERO()); 211 212 assertTrue("a*b = b*a", c.equals(d)); 213 assertEquals("a*b = b*a", c, d); 214 215 c = efac.random(kl, ll, el, q); 216 //System.out.println("c = " + c); 217 d = a.multiply(b.multiply(c)); 218 e = (a.multiply(b)).multiply(c); 219 220 //System.out.println("d = " + d); 221 //System.out.println("e = " + e); 222 223 //System.out.println("d-e = " + d.subtract(c) ); 224 225 assertEquals("a(bc) = (ab)c", d, e); 226 assertTrue("a(bc) = (ab)c", d.equals(e)); 227 228 c = a.multiply(efac.getONE()); 229 d = efac.getONE().multiply(a); 230 assertEquals("a*1 = 1*a", c, d); 231 232 if (a.isUnit()) { 233 c = a.inverse(); 234 d = c.multiply(a); 235 //System.out.println("a = " + a); 236 //System.out.println("c = " + c); 237 //System.out.println("d = " + d); 238 assertTrue("a*1/a = 1", d.isONE()); 239 } 240 } 241 242 243 /** 244 * Test addition with syzygy gcd and euclids gcd. 245 */ 246 public void xtestAdditionGcd() { 247 long te, tz; 248 249 a = efac.random(kl, ll, el, q); 250 b = efac.random(kl, ll, el, q); 251 //System.out.println("a = " + a); 252 //System.out.println("b = " + b); 253 254 az = new Quotient<BigRational>(zFac, a.num, a.den, true); 255 bz = new Quotient<BigRational>(zFac, b.num, b.den, true); 256 257 te = System.currentTimeMillis(); 258 c = a.sum(b); 259 d = c.subtract(b); 260 d = d.monic(); 261 te = System.currentTimeMillis() - te; 262 assertEquals("a+b-b = a", a, d); 263 264 tz = System.currentTimeMillis(); 265 cz = az.sum(bz); 266 dz = cz.subtract(bz); 267 dz = dz.monic(); 268 tz = System.currentTimeMillis() - tz; 269 assertEquals("a+b-b = a", az, dz); 270 271 System.out.println("te = " + te); 272 System.out.println("tz = " + tz); 273 274 c = a.sum(b); 275 d = b.sum(a); 276 //System.out.println("c = " + c); 277 //System.out.println("d = " + d); 278 assertEquals("a+b = b+a", c, d); 279 280 c = efac.random(kl, ll, el, q); 281 cz = new Quotient<BigRational>(zFac, c.num, c.den, true); 282 283 284 te = System.currentTimeMillis(); 285 d = c.sum(a.sum(b)); 286 e = c.sum(a).sum(b); 287 te = System.currentTimeMillis() - te; 288 assertEquals("c+(a+b) = (c+a)+b", d, e); 289 290 tz = System.currentTimeMillis(); 291 dz = cz.sum(az.sum(bz)); 292 ez = cz.sum(az).sum(bz); 293 tz = System.currentTimeMillis() - tz; 294 assertEquals("c+(a+b) = (c+a)+b", dz, ez); 295 296 System.out.println("te = " + te); 297 System.out.println("tz = " + tz); 298 299 c = a.sum(efac.getZERO()); 300 d = a.subtract(efac.getZERO()); 301 assertEquals("a+0 = a-0", c, d); 302 303 c = efac.getZERO().sum(a); 304 d = efac.getZERO().subtract(a.negate()); 305 assertEquals("0+a = 0+(-a)", c, d); 306 } 307 308 309 /** 310 * Test parse(). 311 */ 312 public void testParse() { 313 a = efac.random(kl * 2, ll * 2, el * 2, q * 2); 314 //assertTrue("not isZERO( a )", !a.isZERO() ); 315 316 //PrettyPrint.setInternal(); 317 //System.out.println("a = " + a); 318 PrettyPrint.setPretty(); 319 //System.out.println("a = " + a); 320 String p = a.toString(); 321 //System.out.println("p = " + p); 322 b = efac.parse(p); 323 //System.out.println("b = " + b); 324 325 //c = a.subtract(b); 326 //System.out.println("c = " + c); 327 assertEquals("parse(a.toSting()) = a", a, b); 328 } 329 330 331 /** 332 * Test factorization. 333 */ 334 public void testFactors() { 335 a = efac.random(kl, ll, el, q); 336 b = efac.random(kl, ll, el, q); 337 b = b.multiply(b); 338 //System.out.println("a = " + a); 339 //System.out.println("b = " + b); 340 341 c = a.multiply(b); 342 //System.out.println("c = " + c); 343 344 SortedMap<Quotient<BigRational>, Long> factors = PolyUfdUtil.<BigRational> factors(c); 345 //System.out.println("factors = " + factors); 346 347 boolean t = PolyUfdUtil.<BigRational> isFactorization(c, factors); 348 //System.out.println("t = " + t); 349 assertTrue("c == prod(factors): " + c + ", " + factors, t); 350 } 351 352 353 /** 354 * Test symbolic row echelon form and LU decomposition. Using an example from 355 * <a href="https://github.com/kredel/java-algebra-system/issues/21">Issue #21</a>. 356 */ 357 public void testLinAlg() { 358 BigRational cfac = new BigRational(11); 359 GenPolynomialRing<BigRational> pfac = new GenPolynomialRing<BigRational>(cfac, new String[]{ "a" }); 360 //System.out.println("pfac = " + pfac.toScript()); 361 QuotientRing<BigRational> qfac = new QuotientRing<BigRational>(pfac); 362 //System.out.println("qfac = " + qfac.toScript()); 363 Quotient<BigRational> a = new Quotient<BigRational>(qfac,pfac.univariate(0)); 364 //System.out.println("a: " + a.toScript()); 365 int n = 3; 366 GenMatrixRing<Quotient<BigRational>> mfac = new GenMatrixRing<Quotient<BigRational>>(qfac, n, n); 367 //System.out.println("mfac = " + mfac.toScript()); 368 GenMatrixRing<Quotient<BigRational>> tfac = mfac.transpose(); 369 @SuppressWarnings("unchecked") 370 Quotient<BigRational>[][] mm = new Quotient[n][n]; 371 // ( {{1, a, 2}, {0, 1, 1}, {-1, 1, 1}} ) 372 mm[0][0] = qfac.fromInteger(1); 373 mm[0][1] = a; 374 mm[0][2] = qfac.fromInteger(2); 375 376 mm[1][0] = qfac.getZERO(); 377 mm[1][1] = qfac.fromInteger(1); 378 mm[1][2] = qfac.fromInteger(1); 379 380 mm[2][0] = qfac.fromInteger(-1); 381 mm[2][1] = qfac.fromInteger(1); 382 mm[2][2] = qfac.fromInteger(1); 383 384 GenMatrix<Quotient<BigRational>> A = new GenMatrix<Quotient<BigRational>>(mfac, mm); 385 //System.out.println("A: " + A); 386 387 LinAlg<Quotient<BigRational>> lu = new LinAlg<Quotient<BigRational>>(); 388 389 // test rowEchelonForm and rowEchelonFormSparse 390 GenMatrix<Quotient<BigRational>> B = lu.rowEchelonForm(A); 391 //System.out.println("B: " + B); 392 long r = lu.rankRE(B); 393 GenMatrix<Quotient<BigRational>> D = lu.rowEchelonFormSparse(B); 394 //System.out.println("D: " + D); 395 assertTrue("rank1 == rank2: ", lu.rankRE(D) == r); 396 397 // test LU decomposition 398 A = new GenMatrix<Quotient<BigRational>>(mfac, mm); 399 List<Integer> P = lu.decompositionLU(A); 400 //System.out.println("P : " + P); 401 //System.out.println("A : " + A.toScript()); 402 //System.out.println("U : " + A.getUpper().toScript()); 403 404 // test LU inverse 405 GenMatrix<Quotient<BigRational>> I = lu.inverseLU(A,P); 406 //System.out.println("I : " + I.toScript()); 407 408 GenMatrix<Quotient<BigRational>> C = new GenMatrix<Quotient<BigRational>>(mfac, mm); 409 GenMatrix<Quotient<BigRational>> CI = C.multiply(I); 410 //System.out.println("C*I: " + CI.toScript()); 411 assertTrue("C*I == 1: ", CI.isONE()); 412 413 GenMatrix<Quotient<BigRational>> C2 = C.sum(C); 414 GenMatrix<Quotient<BigRational>> CA = A.divide(C2); 415 GenMatrix<Quotient<BigRational>> AC = A.divideLeft(C2); 416 //System.out.println("C/A : " + CA); 417 //System.out.println("A\\C : " + AC); 418 assertFalse("C/A != A\\C: ", CA.equals(AC)); 419 } 420 421}