001 /* 002 * $Id: RealRootTest.java 3037 2010-03-12 21:09:15Z kredel $ 003 */ 004 005 package edu.jas.root; 006 007 008 import java.util.ArrayList; 009 import java.util.Collections; 010 import java.util.List; 011 012 import junit.framework.Test; 013 import junit.framework.TestCase; 014 import junit.framework.TestSuite; 015 016 import edu.jas.arith.BigDecimal; 017 import edu.jas.arith.BigRational; 018 import edu.jas.poly.GenPolynomial; 019 import edu.jas.poly.GenPolynomialRing; 020 import edu.jas.poly.TermOrder; 021 import edu.jas.structure.Power; 022 023 024 /** 025 * RealRoot tests with JUnit. 026 * @author Heinz Kredel. 027 */ 028 029 public class RealRootTest 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>RealRootTest</CODE> object. 042 * @param name String. 043 */ 044 public RealRootTest(String name) { 045 super(name); 046 } 047 048 049 /** 050 */ 051 public static Test suite() { 052 TestSuite suite = new TestSuite(RealRootTest.class); 053 return suite; 054 } 055 056 057 //private final static int bitlen = 100; 058 059 TermOrder to = new TermOrder(TermOrder.INVLEX); 060 061 062 GenPolynomialRing<BigRational> dfac; 063 064 065 BigRational ai; 066 067 068 BigRational bi; 069 070 071 BigRational ci; 072 073 074 BigRational di; 075 076 077 BigRational ei; 078 079 080 BigRational eps; 081 082 083 GenPolynomial<BigRational> a; 084 085 086 GenPolynomial<BigRational> b; 087 088 089 GenPolynomial<BigRational> c; 090 091 092 GenPolynomial<BigRational> d; 093 094 095 GenPolynomial<BigRational> e; 096 097 098 int rl = 1; 099 100 101 int kl = 5; 102 103 104 int ll = 7; 105 106 107 int el = 7; 108 109 110 float q = 0.7f; 111 112 113 @Override 114 protected void setUp() { 115 a = b = c = d = e = null; 116 ai = bi = ci = di = ei = null; 117 String[] vars = new String[] { "x" }; 118 dfac = new GenPolynomialRing<BigRational>(new BigRational(1), rl, to, vars); 119 // eps = new BigRational(1L,1000000L*1000000L*1000000L); 120 eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION); 121 } 122 123 124 @Override 125 protected void tearDown() { 126 a = b = c = d = e = null; 127 ai = bi = ci = di = ei = null; 128 dfac = null; 129 eps = null; 130 } 131 132 133 /** 134 * Test Sturm sequence. 135 * 136 */ 137 public void testSturmSequence() { 138 a = dfac.random(kl, ll, el, q); 139 //System.out.println("a = " + a); 140 141 RealRootsSturm<BigRational> rrs = new RealRootsSturm<BigRational>(); 142 143 List<GenPolynomial<BigRational>> S = rrs.sturmSequence(a); 144 //System.out.println("S = " + S); 145 146 try { 147 b = a.remainder(S.get(0)); 148 } catch (Exception e) { 149 fail("not S(0)|f " + e); 150 } 151 assertTrue("a mod S(0) == 0 ", b.isZERO()); 152 153 assertTrue("S(-1) == 1 ", S.get(S.size() - 1).isConstant()); 154 } 155 156 157 /** 158 * Test root bound. 159 * 160 */ 161 public void testRootBound() { 162 a = dfac.random(kl, ll, el, q); 163 //System.out.println("a = " + a); 164 165 RealRoots<BigRational> rr = new RealRootsSturm<BigRational>(); 166 167 BigRational M = rr.realRootBound(a); 168 169 //System.out.println("M = " + M); 170 assertTrue("M >= 1 ", M.compareTo(BigRational.ONE) >= 0); 171 172 a = a.monic(); 173 //System.out.println("a = " + a); 174 M = rr.realRootBound(a); 175 176 //System.out.println("M = " + M); 177 assertTrue("M >= 1 ", M.compareTo(BigRational.ONE) >= 0); 178 } 179 180 181 /** 182 * Test real root isolation. 183 * 184 */ 185 public void testRealRootIsolation() { 186 a = dfac.random(kl, ll * 2, el * 2, q); 187 //a = a.multiply( dfac.univariate(0) ); 188 //System.out.println("a = " + a); 189 190 RealRoots<BigRational> rr = new RealRootsSturm<BigRational>(); 191 192 List<Interval<BigRational>> R = rr.realRoots(a); 193 //System.out.println("R = " + R); 194 assertTrue("#roots >= 0 ", R.size() >= 0); 195 } 196 197 198 /** 199 * Test real root isolation Wilkinson polynomials. 200 * p = (x-0)*(x-1)*(x-2)*(x-3)*...*(x-n) 201 */ 202 public void testRealRootIsolationWilkinson() { 203 final int N = 10; 204 d = dfac.getONE(); 205 e = dfac.univariate(0); 206 207 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 208 a = d; 209 for (int i = 0; i < N; i++) { 210 c = dfac.fromInteger(i); 211 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 212 b = e.subtract(c); 213 a = a.multiply(b); 214 } 215 //System.out.println("a = " + a); 216 217 RealRoots<BigRational> rr = new RealRootsSturm<BigRational>(); 218 219 List<Interval<BigRational>> R = rr.realRoots(a); 220 //System.out.println("R = " + R); 221 222 assertTrue("#roots = " + N + " ", R.size() == N); 223 224 //System.out.println("eps = " + eps); 225 BigDecimal eps1 = new BigDecimal(eps); 226 //System.out.println("eps1 = " + eps1); 227 228 R = rr.refineIntervals(R, a, eps); 229 //System.out.println("R = " + R); 230 int i = 0; 231 for (Interval<BigRational> v : R) { 232 BigDecimal dd = v.toDecimal(); //.sum(eps1); 233 BigDecimal di = Rn.get(i++).toDecimal(); 234 //System.out.println("v = " + dd); 235 //System.out.println("vi = " + di); 236 assertTrue("|dd - di| < eps ", dd.compareTo(di) == 0); 237 } 238 } 239 240 241 /** 242 * Test real root isolation Wilkinson polynomials inverse. 243 * p = (x-1)*(x-1/2)*(x-1/3)*...*(x-1/n) 244 */ 245 public void testRealRootIsolationWilkinsonInverse() { 246 final int N = 9; 247 d = dfac.getONE(); 248 e = dfac.univariate(0); 249 250 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 251 a = d; 252 for (int i = 1; i < N; i++) { // use only for i > 0, since reverse 253 c = dfac.fromInteger(i); 254 if (i != 0) { 255 c = d.divide(c); 256 } 257 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 258 b = e.subtract(c); 259 a = a.multiply(b); 260 } 261 //System.out.println("a = " + a); 262 //System.out.println("Rn = " + Rn); 263 Collections.reverse(Rn); 264 //System.out.println("Rn = " + Rn); 265 266 RealRoots<BigRational> rr = new RealRootsSturm<BigRational>(); 267 268 List<Interval<BigRational>> R = rr.realRoots(a); 269 //System.out.println("R = " + R); 270 271 assertTrue("#roots = " + (N - 1) + " ", R.size() == (N - 1)); 272 273 //System.out.println("eps = " + eps); 274 BigDecimal eps1 = new BigDecimal(eps); 275 //System.out.println("eps1 = " + eps1); 276 277 R = rr.refineIntervals(R, a, eps); 278 //System.out.println("R = " + R); 279 int i = 0; 280 for (Interval<BigRational> v : R) { 281 BigDecimal dd = v.toDecimal(); //.sum(eps1); 282 BigDecimal di = Rn.get(i++).toDecimal(); 283 //System.out.println("v = " + dd); 284 //System.out.println("vi = " + di); 285 assertTrue("|dd - di| < eps ", dd.compareTo(di) == 0); 286 } 287 } 288 289 290 /** 291 * Test real algebraic number sign. 292 * 293 */ 294 public void testRealAlgebraicNumberSign() { 295 d = dfac.fromInteger(2); 296 e = dfac.univariate(0); 297 298 a = e.multiply(e); 299 // a = a.multiply(e).multiply(e).multiply(e); 300 a = a.subtract(d); // x^2 -2 301 //System.out.println("a = " + a); 302 303 RealRoots<BigRational> rr = new RealRootsSturm<BigRational>(); 304 305 ai = new BigRational(1); 306 bi = new BigRational(2); 307 Interval<BigRational> iv = new Interval<BigRational>(ai, bi); 308 //System.out.println("iv = " + iv); 309 assertTrue("sign change", rr.signChange(iv, a)); 310 311 b = dfac.random(kl, (int) a.degree() + 1, (int) a.degree(), 1.0f); 312 //b = dfac.getZERO(); 313 //b = dfac.random(kl,ll,el,q); 314 //b = b.multiply(b); 315 //b = b.abs().negate(); 316 //System.out.println("b = " + b); 317 if (b.isZERO()) { 318 int s = rr.realSign(iv, a, b); 319 assertTrue("algebraic sign", s == 0); 320 return; 321 } 322 323 int as = rr.realSign(iv, a, b); 324 //System.out.println("as = " + as); 325 // how to test? 326 int asn = rr.realSign(iv, a, b.negate()); 327 //System.out.println("asn = " + asn); 328 assertTrue("algebraic sign", as != asn); 329 330 iv = new Interval<BigRational>(bi.negate(), ai.negate()); 331 //System.out.println("iv = " + iv); 332 assertTrue("sign change", rr.signChange(iv, a)); 333 334 int as1 = rr.realSign(iv, a, b); 335 //System.out.println("as1 = " + as1); 336 // how to test? 337 int asn1 = rr.realSign(iv, a, b.negate()); 338 //System.out.println("asn1 = " + asn1); 339 assertTrue("algebraic sign", as1 != asn1); 340 341 assertTrue("algebraic sign", as * as1 == asn * asn1); 342 } 343 344 345 /** 346 * Test real root isolation and decimal refinement of Wilkinson polynomials. 347 * p = (x-0)*(x-1)*(x-2)*(x-3)*...*(x-n) 348 */ 349 public void testRealRootIsolationDecimalWilkinson() { 350 final int N = 10; 351 d = dfac.getONE(); 352 e = dfac.univariate(0); 353 354 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 355 a = d; 356 for (int i = 0; i < N; i++) { 357 c = dfac.fromInteger(i); 358 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 359 b = e.subtract(c); 360 a = a.multiply(b); 361 } 362 //System.out.println("a = " + a); 363 364 RealRootAbstract<BigRational> rr = new RealRootsSturm<BigRational>(); 365 366 List<Interval<BigRational>> R = rr.realRoots(a); 367 //System.out.println("R = " + R); 368 369 assertTrue("#roots = " + N + " ", R.size() == N); 370 371 eps = eps.multiply(new BigRational(10000)); 372 //System.out.println("eps = " + eps); 373 BigDecimal eps1 = new BigDecimal(eps); 374 BigDecimal eps2 = eps1.multiply(new BigDecimal("100")); 375 //System.out.println("eps1 = " + eps1); 376 //System.out.println("eps2 = " + eps2); 377 378 try { 379 int i = 0; 380 for (Interval<BigRational> v : R) { 381 //System.out.println("v = " + v); 382 BigDecimal dd = rr.approximateRoot(v,a,eps); 383 BigDecimal di = Rn.get(i++).toDecimal(); 384 //System.out.println("di = " + di); 385 //System.out.println("dd = " + dd); 386 assertTrue("|dd - di| < eps ", dd.subtract(di).abs().compareTo(eps2) <= 0); 387 } 388 } catch (NoConvergenceException e) { 389 fail(e.toString()); 390 } 391 } 392 393 394 /** 395 * Test real root isolation and decimal refinement of Wilkinson polynomials, inverse roots. 396 * p = (x-1)*(x-1/2)*(x-1/3)*...*(x-1/n) 397 */ 398 public void testRealRootIsolationDecimalWilkinsonInverse() { 399 final int N = 10; 400 d = dfac.getONE(); 401 e = dfac.univariate(0); 402 403 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 404 a = d; 405 for (int i = 1; i < N; i++) { // use only for i > 0, since reverse 406 c = dfac.fromInteger(i); 407 if (i != 0) { 408 c = d.divide(c); 409 } 410 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 411 b = e.subtract(c); 412 a = a.multiply(b); 413 } 414 //System.out.println("a = " + a); 415 //System.out.println("Rn = " + Rn); 416 Collections.reverse(Rn); 417 //System.out.println("Rn = " + Rn); 418 419 RealRootAbstract<BigRational> rr = new RealRootsSturm<BigRational>(); 420 421 List<Interval<BigRational>> R = rr.realRoots(a); 422 //System.out.println("R = " + R); 423 424 assertTrue("#roots = " + (N - 1) + " ", R.size() == (N - 1)); 425 426 eps = eps.multiply(new BigRational(1000000)); 427 //System.out.println("eps = " + eps); 428 BigDecimal eps1 = new BigDecimal(eps); 429 BigDecimal eps2 = eps1.multiply(new BigDecimal("10")); 430 //System.out.println("eps1 = " + eps1); 431 //System.out.println("eps2 = " + eps2); 432 433 try { 434 int i = 0; 435 for (Interval<BigRational> v : R) { 436 //System.out.println("v = " + v); 437 BigDecimal dd = rr.approximateRoot(v,a,eps); 438 BigDecimal di = Rn.get(i++).toDecimal(); 439 //System.out.println("di = " + di); 440 //System.out.println("dd = " + dd); 441 assertTrue("|dd - di| < eps ", dd.subtract(di).abs().compareTo(eps2) <= 0); 442 } 443 } catch (NoConvergenceException e) { 444 fail(e.toString()); 445 } 446 } 447 448 449 /** 450 * Test real root isolation and decimal refinement of Wilkinson polynomials, all roots. 451 * p = (x-0)*(x-1)*(x-2)*(x-3)*...*(x-n) 452 */ 453 public void testRealRootIsolationDecimalWilkinsonAll() { 454 final int N = 10; 455 d = dfac.getONE(); 456 e = dfac.univariate(0); 457 458 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 459 a = d; 460 for (int i = 0; i < N; i++) { 461 c = dfac.fromInteger(i); 462 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 463 b = e.subtract(c); 464 a = a.multiply(b); 465 } 466 //System.out.println("a = " + a); 467 468 RealRootAbstract<BigRational> rr = new RealRootsSturm<BigRational>(); 469 470 eps = eps.multiply(new BigRational(10000)); 471 //System.out.println("eps = " + eps); 472 BigDecimal eps1 = new BigDecimal(eps); 473 BigDecimal eps2 = eps1.multiply(new BigDecimal("100")); 474 //System.out.println("eps1 = " + eps1); 475 //System.out.println("eps2 = " + eps2); 476 477 List<BigDecimal> R = null; 478 R = rr.approximateRoots(a,eps); 479 //System.out.println("R = " + R); 480 assertTrue("#roots = " + N + " ", R.size() == N); 481 482 int i = 0; 483 for (BigDecimal dd : R) { 484 //System.out.println("dd = " + dd); 485 BigDecimal di = Rn.get(i++).toDecimal(); 486 //System.out.println("di = " + di); 487 assertTrue("|dd - di| < eps ", dd.subtract(di).abs().compareTo(eps2) <= 0); 488 } 489 boolean t = rr.isApproximateRoot(R,a,eps); 490 assertTrue("some |a(dd)| < eps ", t); 491 } 492 493 494 /** 495 * Test real root isolation and decimal refinement of Wilkinson polynomials, inverse roots, all roots. 496 * p = (x-1)*(x-1/2)*(x-1/3)*...*(x-1/n) 497 */ 498 public void testRealRootIsolationDecimalWilkinsonInverseAll() { 499 final int N = 10; 500 d = dfac.getONE(); 501 e = dfac.univariate(0); 502 503 List<Interval<BigRational>> Rn = new ArrayList<Interval<BigRational>>(N); 504 a = d; 505 for (int i = 1; i < N; i++) { // use only for i > 0, since reverse 506 c = dfac.fromInteger(i); 507 if (i != 0) { 508 c = d.divide(c); 509 } 510 Rn.add(new Interval<BigRational>(c.leadingBaseCoefficient())); 511 b = e.subtract(c); 512 a = a.multiply(b); 513 } 514 //System.out.println("a = " + a); 515 //System.out.println("Rn = " + Rn); 516 Collections.reverse(Rn); 517 //System.out.println("Rn = " + Rn); 518 519 RealRootAbstract<BigRational> rr = new RealRootsSturm<BigRational>(); 520 521 eps = eps.multiply(new BigRational(1000000)); 522 //System.out.println("eps = " + eps); 523 BigDecimal eps1 = new BigDecimal(eps); 524 BigDecimal eps2 = eps1.multiply(new BigDecimal("10")); 525 //System.out.println("eps1 = " + eps1); 526 //System.out.println("eps2 = " + eps2); 527 528 List<BigDecimal> R = null; 529 R = rr.approximateRoots(a,eps); 530 //System.out.println("R = " + R); 531 assertTrue("#roots = " + (N - 1) + " ", R.size() == (N - 1)); 532 533 int i = 0; 534 for (BigDecimal dd : R) { 535 //System.out.println("dd = " + dd); 536 BigDecimal di = Rn.get(i++).toDecimal(); 537 //System.out.println("di = " + di); 538 assertTrue("|dd - di| < eps ", dd.subtract(di).abs().compareTo(eps2) <= 0); 539 } 540 boolean t = rr.isApproximateRoot(R,a,eps); 541 assertTrue("some |a(dd)| < eps ", t); 542 } 543 544 }