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