001/* 002 * $Id: RealAlgebraicTest.java 5688 2017-01-03 08:45:09Z kredel $ 003 */ 004 005package edu.jas.root; 006 007 008import java.util.ArrayList; 009import java.util.List; 010 011import org.apache.log4j.BasicConfigurator; 012 013import edu.jas.arith.BigDecimal; 014import edu.jas.arith.BigRational; 015import edu.jas.poly.GenPolynomial; 016import edu.jas.poly.GenPolynomialRing; 017import edu.jas.structure.NotInvertibleException; 018import edu.jas.structure.Power; 019 020import junit.framework.Test; 021import junit.framework.TestCase; 022import junit.framework.TestSuite; 023 024 025/** 026 * RealAlgebraicNumber Test using JUnit. 027 * @author Heinz Kredel 028 */ 029 030public class RealAlgebraicTest extends TestCase { 031 032 033 /** 034 * main. 035 */ 036 public static void main(String[] args) { 037 BasicConfigurator.configure(); 038 junit.textui.TestRunner.run(suite()); 039 } 040 041 042 /** 043 * Constructs a <CODE>RealAlgebraicTest</CODE> object. 044 * @param name String. 045 */ 046 public RealAlgebraicTest(String name) { 047 super(name); 048 } 049 050 051 /** 052 * suite. 053 */ 054 public static Test suite() { 055 TestSuite suite = new TestSuite(RealAlgebraicTest.class); 056 return suite; 057 } 058 059 060 //private final static int bitlen = 100; 061 062 RealAlgebraicRing<BigRational> fac; 063 064 065 GenPolynomialRing<BigRational> mfac; 066 067 068 RealAlgebraicNumber<BigRational> a; 069 070 071 RealAlgebraicNumber<BigRational> b; 072 073 074 RealAlgebraicNumber<BigRational> c; 075 076 077 RealAlgebraicNumber<BigRational> d; 078 079 080 RealAlgebraicNumber<BigRational> e; 081 082 083 RealAlgebraicNumber<BigRational> alpha; 084 085 086 int rl = 1; 087 088 089 int kl = 10; 090 091 092 int ll = 10; 093 094 095 int el = ll; 096 097 098 float q = 0.5f; 099 100 101 @Override 102 protected void setUp() { 103 a = b = c = d = e = null; 104 BigRational l = new BigRational(1); 105 BigRational r = new BigRational(2); 106 Interval<BigRational> positiv = new Interval<BigRational>(l, r); 107 String[] vars = new String[] { "alpha" }; 108 mfac = new GenPolynomialRing<BigRational>(new BigRational(1), rl, vars); 109 GenPolynomial<BigRational> mo = mfac.univariate(0, 2); 110 mo = mo.subtract(mfac.fromInteger(2)); // alpha^2 -2 111 fac = new RealAlgebraicRing<BigRational>(mo, positiv); 112 alpha = fac.getGenerator(); 113 } 114 115 116 @Override 117 protected void tearDown() { 118 a = b = c = d = e = null; 119 fac = null; 120 alpha = null; 121 } 122 123 124 /** 125 * Test constructor and toString. 126 * 127 */ 128 public void testConstruction() { 129 c = fac.getONE(); 130 //System.out.println("c = " + c); 131 //System.out.println("c.getVal() = " + c.getVal()); 132 assertTrue("length( c ) = 1", c.number.getVal().length() == 1); 133 assertTrue("isZERO( c )", !c.isZERO()); 134 assertTrue("isONE( c )", c.isONE()); 135 136 d = fac.getZERO(); 137 //System.out.println("d = " + d); 138 //System.out.println("d.getVal() = " + d.getVal()); 139 assertTrue("length( d ) = 0", d.number.getVal().length() == 0); 140 assertTrue("isZERO( d )", d.isZERO()); 141 assertTrue("isONE( d )", !d.isONE()); 142 } 143 144 145 /** 146 * Test random polynomial. 147 * 148 */ 149 public void testRandom() { 150 for (int i = 0; i < 7; i++) { 151 a = fac.random(el); 152 //System.out.println("a = " + a); 153 if (a.isZERO() || a.isONE()) { 154 continue; 155 } 156 // fac.random(rl+i, kl*(i+1), ll+2*i, el+i, q ); 157 assertTrue("length( a" + i + " ) <> 0", a.number.getVal().length() >= 0); 158 assertTrue(" not isZERO( a" + i + " )", !a.isZERO()); 159 assertTrue(" not isONE( a" + i + " )", !a.isONE()); 160 } 161 } 162 163 164 /** 165 * Test addition. 166 * 167 */ 168 public void testAddition() { 169 a = fac.random(ll); 170 b = fac.random(ll); 171 172 c = a.sum(b); 173 d = c.subtract(b); 174 assertEquals("a+b-b = a", a, d); 175 176 c = a.sum(b); 177 d = b.sum(a); 178 assertEquals("a+b = b+a", c, d); 179 180 c = fac.random(ll); 181 d = c.sum(a.sum(b)); 182 e = c.sum(a).sum(b); 183 assertEquals("c+(a+b) = (c+a)+b", d, e); 184 185 186 c = a.sum(fac.getZERO()); 187 d = a.subtract(fac.getZERO()); 188 assertEquals("a+0 = a-0", c, d); 189 190 c = fac.getZERO().sum(a); 191 d = fac.getZERO().subtract(a.negate()); 192 assertEquals("0+a = 0+(-a)", c, d); 193 } 194 195 196 /** 197 * Test object multiplication. 198 * 199 */ 200 public void testMultiplication() { 201 a = fac.random(ll); 202 assertTrue("not isZERO( a )", !a.isZERO()); 203 204 b = fac.random(ll); 205 assertTrue("not isZERO( b )", !b.isZERO()); 206 207 c = b.multiply(a); 208 d = a.multiply(b); 209 assertTrue("not isZERO( c )", !c.isZERO()); 210 assertTrue("not isZERO( d )", !d.isZERO()); 211 212 //System.out.println("a = " + a); 213 //System.out.println("b = " + b); 214 e = d.subtract(c); 215 assertTrue("isZERO( a*b-b*a ) " + e, e.isZERO()); 216 217 assertTrue("a*b = b*a", c.equals(d)); 218 assertEquals("a*b = b*a", c, d); 219 220 c = fac.random(ll); 221 //System.out.println("c = " + c); 222 d = a.multiply(b.multiply(c)); 223 e = (a.multiply(b)).multiply(c); 224 225 //System.out.println("d = " + d); 226 //System.out.println("e = " + e); 227 228 //System.out.println("d-e = " + d.subtract(c) ); 229 230 assertEquals("a(bc) = (ab)c", d, e); 231 assertTrue("a(bc) = (ab)c", d.equals(e)); 232 233 c = a.multiply(fac.getONE()); 234 d = fac.getONE().multiply(a); 235 assertEquals("a*1 = 1*a", c, d); 236 237 238 c = a.inverse(); 239 d = c.multiply(a); 240 //System.out.println("a = " + a); 241 //System.out.println("c = " + c); 242 //System.out.println("d = " + d); 243 assertEquals("a*1/a = 1", fac.getONE(), d); 244 245 try { 246 a = fac.getZERO().inverse(); 247 } catch (NotInvertibleException expected) { 248 return; 249 } 250 fail("0 invertible"); 251 } 252 253 254 /** 255 * Test distributive law. 256 * 257 */ 258 public void testDistributive() { 259 a = fac.random(ll); 260 b = fac.random(ll); 261 c = fac.random(ll); 262 263 d = a.multiply(b.sum(c)); 264 e = a.multiply(b).sum(a.multiply(c)); 265 266 assertEquals("a(b+c) = ab+ac", d, e); 267 } 268 269 270 /** 271 * Test sign of real algebraic numbers. 272 * 273 */ 274 public void testSignum() { 275 a = fac.random(ll); 276 b = fac.random(ll); 277 c = fac.random(ll); 278 279 int sa = a.signum(); 280 int sb = b.signum(); 281 int sc = c.signum(); 282 283 d = a.multiply(b); 284 e = a.multiply(c); 285 286 int sd = d.signum(); 287 int se = e.signum(); 288 289 assertEquals("sign(a*b) = sign(a)*sign(b) ", sa * sb, sd); 290 assertEquals("sign(a*c) = sign(a)*sign(c) ", sa * sc, se); 291 292 b = a.negate(); 293 sb = b.signum(); 294 assertEquals("sign(-a) = -sign(a) ", -sa, sb); 295 } 296 297 298 /** 299 * Test compareTo of real algebraic numbers. 300 * 301 */ 302 public void testCompare() { 303 a = fac.random(ll).abs(); 304 b = a.sum(fac.getONE()); 305 c = b.sum(fac.getONE()); 306 307 int ab = a.compareTo(b); 308 int bc = b.compareTo(c); 309 int ac = a.compareTo(c); 310 311 assertTrue("a < a+1 ", ab < 0); 312 assertTrue("a+1 < a+2 ", bc < 0); 313 assertTrue("a < a+2 ", ac < 0); 314 315 a = a.negate(); 316 b = a.sum(fac.getONE()); 317 c = b.sum(fac.getONE()); 318 319 ab = a.compareTo(b); 320 bc = b.compareTo(c); 321 ac = a.compareTo(c); 322 323 assertTrue("a < a+1 ", ab < 0); 324 assertTrue("a+1 < a+2 ", bc < 0); 325 assertTrue("a < a+2 ", ac < 0); 326 } 327 328 329 /** 330 * Test arithmetic of magnitude of real algebraic numbers. 331 * 332 */ 333 public void testMagnitude() { 334 a = fac.random(ll); 335 b = fac.random(ll); 336 c = fac.random(ll); 337 338 //BigDecimal ad = new BigDecimal(a.magnitude()); 339 //BigDecimal bd = new BigDecimal(b.magnitude()); 340 //BigDecimal cd = new BigDecimal(c.magnitude()); 341 342 d = a.multiply(b); 343 e = a.sum(b); 344 345 BigDecimal dd = new BigDecimal(d.magnitude()); 346 BigDecimal ed = new BigDecimal(e.magnitude()); 347 348 BigDecimal dd1 = new BigDecimal(a.magnitude().multiply(b.magnitude())); 349 BigDecimal ed1 = new BigDecimal(a.magnitude().sum(b.magnitude())); 350 351 //System.out.println("ad = " + ad); 352 //System.out.println("bd = " + bd); 353 //System.out.println("cd = " + cd); 354 //System.out.println("dd = " + dd); 355 //System.out.println("dd1 = " + dd1); 356 //System.out.println("ed = " + ed); 357 //System.out.println("ed1 = " + ed1); 358 359 //BigRational eps = Power.positivePower(new BigRational(1L,10L),BigDecimal.DEFAULT_PRECISION); 360 BigRational eps = Power.positivePower(new BigRational(1L, 10L), 8); 361 BigDecimal epsd = new BigDecimal(eps); 362 363 assertTrue("mag(a*b) = mag(a)*mag(b): " + dd + ", " + dd1, 364 dd.subtract(dd1).abs().compareTo(epsd) <= 0); 365 assertTrue("mag(a+b) = mag(a)+mag(b): " + ed + ", " + ed1, 366 ed.subtract(ed1).abs().compareTo(epsd) <= 0); 367 368 369 d = a.divide(b); 370 e = a.subtract(b); 371 372 dd = new BigDecimal(d.magnitude()); 373 ed = new BigDecimal(e.magnitude()); 374 375 dd1 = new BigDecimal(a.magnitude().divide(b.magnitude())); 376 ed1 = new BigDecimal(a.magnitude().subtract(b.magnitude())); 377 378 //System.out.println("dd = " + dd); 379 //System.out.println("dd1 = " + dd1); 380 //System.out.println("ed = " + ed); 381 //System.out.println("ed1 = " + ed1); 382 383 assertTrue("mag(a/b) = mag(a)/mag(b)", dd.subtract(dd1).abs().compareTo(epsd) <= 0); 384 assertTrue("mag(a-b) = mag(a)-mag(b)", ed.subtract(ed1).abs().compareTo(epsd) <= 0); 385 } 386 387 388 /** 389 * Test real root isolation. Tests nothing. 390 */ 391 public void notestRealRootIsolation() { 392 System.out.println(); 393 GenPolynomialRing<RealAlgebraicNumber<BigRational>> dfac; 394 dfac = new GenPolynomialRing<RealAlgebraicNumber<BigRational>>(fac, 1); 395 396 GenPolynomial<RealAlgebraicNumber<BigRational>> ar; 397 //RealAlgebraicNumber<BigRational> epsr; 398 399 ar = dfac.random(3, 5, 7, q); 400 System.out.println("ar = " + ar); 401 402 RealRoots<RealAlgebraicNumber<BigRational>> rrr = new RealRootsSturm<RealAlgebraicNumber<BigRational>>(); 403 404 List<Interval<RealAlgebraicNumber<BigRational>>> R = rrr.realRoots(ar); 405 System.out.println("R = " + R); 406 407 //assertTrue("#roots >= 0 ", R.size() >= 0 ); 408 409 BigRational eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION); 410 //BigRational eps = Power.positivePower(new BigRational(1L,10L),10); 411 412 R = rrr.refineIntervals(R, ar, eps); 413 //System.out.println("R = " + R); 414 for (Interval<RealAlgebraicNumber<BigRational>> v : R) { 415 BigDecimal dd = v.toDecimal(); //.sum(eps1); 416 System.out.println("v = " + dd); 417 // assertTrue("|dd - di| < eps ", dd.compareTo(di) == 0); 418 } 419 } 420 421 422 /** 423 * Test real root isolation for Wilkinson like polynomials. 424 * product_{i=1..n}( x - i * alpha ) 425 * 426 */ 427 public void testRealRootIsolationWilkinson() { 428 //System.out.println(); 429 GenPolynomialRing<RealAlgebraicNumber<BigRational>> dfac; 430 dfac = new GenPolynomialRing<RealAlgebraicNumber<BigRational>>(fac, 1); 431 432 GenPolynomial<RealAlgebraicNumber<BigRational>> ar, br, cr, dr, er; 433 434 RealRoots<RealAlgebraicNumber<BigRational>> rrr = new RealRootsSturm<RealAlgebraicNumber<BigRational>>(); 435 436 final int N = 3; 437 dr = dfac.getONE(); 438 er = dfac.univariate(0); 439 440 List<Interval<RealAlgebraicNumber<BigRational>>> Rn = new ArrayList<Interval<RealAlgebraicNumber<BigRational>>>( 441 N); 442 ar = dr; 443 for (int i = 0; i < N; i++) { 444 cr = dfac.fromInteger(i).multiply(alpha); // i * alpha 445 Rn.add(new Interval<RealAlgebraicNumber<BigRational>>(cr.leadingBaseCoefficient())); 446 br = er.subtract(cr); // ( x - i * alpha ) 447 ar = ar.multiply(br); 448 } 449 //System.out.println("ar = " + ar); 450 451 List<Interval<RealAlgebraicNumber<BigRational>>> R = rrr.realRoots(ar); 452 //System.out.println("R = " + R); 453 454 assertTrue("#roots = " + N + " ", R.size() == N); 455 456 BigRational eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION); 457 //BigRational eps = Power.positivePower(new BigRational(1L,10L),10); 458 //System.out.println("eps = " + eps); 459 460 R = rrr.refineIntervals(R, ar, eps); 461 //System.out.println("R = " + R); 462 int i = 0; 463 for (Interval<RealAlgebraicNumber<BigRational>> v : R) { 464 BigDecimal dd = v.toDecimal();//.sum(eps1); 465 BigDecimal di = Rn.get(i++).toDecimal(); 466 //System.out.println("v = " + dd); 467 //System.out.println("vi = " + di); 468 assertTrue("|dd - di| < eps ", dd.compareTo(di) == 0); 469 } 470 } 471 472}