001/* 002 * $Id: ComplexRootTest.java 5863 2018-07-20 11:13:34Z kredel $ 003 */ 004 005package edu.jas.root; 006 007 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.List; 011 012import junit.framework.Test; 013import junit.framework.TestCase; 014import junit.framework.TestSuite; 015 016import edu.jas.arith.BigDecimal; 017import edu.jas.arith.BigRational; 018import edu.jas.kern.ComputerThreads; 019import edu.jas.poly.Complex; 020import edu.jas.poly.ComplexRing; 021import edu.jas.poly.GenPolynomial; 022import edu.jas.poly.GenPolynomialRing; 023import edu.jas.poly.PolyUtil; 024import edu.jas.poly.TermOrder; 025import edu.jas.structure.Power; 026import edu.jas.ufd.Squarefree; 027import edu.jas.ufd.SquarefreeFactory; 028 029 030/** 031 * RootUtil tests with JUnit. 032 * @author Heinz Kredel 033 */ 034 035public class ComplexRootTest extends TestCase { 036 037 038 /** 039 * main. 040 */ 041 public static void main(String[] args) { 042 junit.textui.TestRunner.run(suite()); 043 ComputerThreads.terminate(); 044 } 045 046 047 /** 048 * Constructs a <CODE>ComplexRootTest</CODE> object. 049 * @param name String. 050 */ 051 public ComplexRootTest(String name) { 052 super(name); 053 } 054 055 056 /** 057 */ 058 public static Test suite() { 059 TestSuite suite = new TestSuite(ComplexRootTest.class); 060 return suite; 061 } 062 063 064 TermOrder to = new TermOrder(TermOrder.INVLEX); 065 066 067 GenPolynomialRing<Complex<BigRational>> dfac; 068 069 070 ComplexRing<BigRational> cfac; 071 072 073 BigRational eps; 074 075 076 Complex<BigRational> ceps; 077 078 079 GenPolynomial<Complex<BigRational>> a; 080 081 082 GenPolynomial<Complex<BigRational>> b; 083 084 085 GenPolynomial<Complex<BigRational>> c; 086 087 088 GenPolynomial<Complex<BigRational>> d; 089 090 091 GenPolynomial<Complex<BigRational>> e; 092 093 094 int rl = 1; 095 096 097 int kl = 3; 098 099 100 int ll = 3; 101 102 103 int el = 5; 104 105 106 float q = 0.7f; 107 108 109 @Override 110 protected void setUp() { 111 a = b = c = d = e = null; 112 cfac = new ComplexRing<BigRational>(new BigRational(1)); 113 String[] vars = new String[] { "x" }; 114 dfac = new GenPolynomialRing<Complex<BigRational>>(cfac, rl, to, vars); 115 eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION); 116 ceps = new Complex<BigRational>(cfac, eps); 117 } 118 119 120 @Override 121 protected void tearDown() { 122 a = b = c = d = e = null; 123 dfac = null; 124 cfac = null; 125 eps = null; 126 } 127 128 129 /** 130 * Test root bound. 131 * 132 */ 133 public void testRootBound() { 134 //a = dfac.random(kl, ll, el, q); 135 a = dfac.univariate(0, 2L).sum(dfac.getONE()); // x^2 + 1 136 //System.out.println("a = " + a); 137 138 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 139 140 Complex<BigRational> Mb = cr.rootBound(a); 141 BigRational M = Mb.getRe(); 142 143 //System.out.println("M = " + M); 144 assertTrue("M >= 1 ", M.compareTo(BigRational.ONE) >= 0); 145 146 //a = a.monic(); 147 a = a.multiply(dfac.fromInteger(5)); 148 //System.out.println("a = " + a); 149 M = cr.rootBound(a).getRe(); 150 151 //System.out.println("M = " + M); 152 assertTrue("M >= 1 ", M.compareTo(BigRational.ONE) >= 0); 153 } 154 155 156 /** 157 * Test Cauchy index. 158 * 159 */ 160 public void testCauchyIndex() { 161 a = dfac.random(kl, ll, el, q); 162 b = dfac.random(kl, ll, el, q); 163 //a = dfac.univariate(0,2L).sum(dfac.getONE()); // x^2 + 1 164 //System.out.println("a = " + a); 165 //System.out.println("b = " + b); 166 167 BigRational l = new BigRational(0); 168 BigRational r = new BigRational(1); 169 GenPolynomialRing<BigRational> fac = new GenPolynomialRing<BigRational>(l, dfac); 170 171 ComplexRootsSturm<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 172 173 GenPolynomial<BigRational> f = PolyUtil.<BigRational> realPartFromComplex(fac, a); 174 GenPolynomial<BigRational> g = PolyUtil.<BigRational> imaginaryPartFromComplex(fac, b); 175 //System.out.println("re(a) = " + f); 176 //System.out.println("im(b) = " + g); 177 178 long ci = cr.indexOfCauchy(l, r, g, f); 179 //System.out.println("ci = " + ci); 180 181 assertTrue("ci >= 0 ", ci >= -a.degree(0)); 182 } 183 184 185 /** 186 * Test Routh. 187 * 188 */ 189 public void testRouth() { 190 ComplexRootsSturm<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 191 192 //a = dfac.random(kl, ll, el, q); 193 //b = dfac.random(kl, ll, el, q); 194 Complex<BigRational> I = cfac.getIMAG(); 195 GenPolynomial<Complex<BigRational>> X = dfac.univariate(0); 196 //System.out.println("I = " + I); 197 //System.out.println("X = " + X); 198 199 //a = dfac.univariate(0,2L).sum( dfac.getONE().multiply(I) ); // x^2 + i 200 201 //b = X.subtract( dfac.getONE().multiply( I ) ); // x - i 202 b = X.subtract(dfac.getONE().multiply(I.negate())); // x + i 203 c = X.subtract(dfac.getONE().multiply(I.multiply(cfac.fromInteger(3)))); // x - 3i 204 d = X.subtract(dfac.getONE().multiply(I.multiply(cfac.fromInteger(4)))); // x - 4i 205 e = X.subtract(dfac.getONE().multiply(I.multiply(cfac.fromInteger(5)))); // x - 5i 206 207 a = b.multiply(c).multiply(d).multiply(e); 208 //System.out.println("a = " + a.toScript()); 209 //System.out.println("i = " + cfac.getIMAG()); 210 211 Complex<BigRational> Mb = cr.rootBound(a); 212 BigRational M = Mb.getRe(); 213 //System.out.println("M = " + M); 214 215 BigRational minf = M.negate(); // - infinity 216 BigRational pinf = M; // + infinity 217 GenPolynomialRing<BigRational> fac = new GenPolynomialRing<BigRational>(pinf, dfac); 218 219 GenPolynomial<BigRational> f = PolyUtil.<BigRational> realPartFromComplex(fac, a); 220 GenPolynomial<BigRational> g = PolyUtil.<BigRational> imaginaryPartFromComplex(fac, a); 221 //System.out.println("re(a) = " + f.toScript()); 222 //System.out.println("im(a) = " + g.toScript()); 223 224 long[] ri = cr.indexOfRouth(minf, pinf, f, g); 225 //System.out.println("ri = [" + ri[0] + ", " + ri[1] + " ]"); 226 long deg = ri[0] + ri[1]; 227 assertTrue("sum(ri) == deg(a) ", deg >= a.degree(0)); 228 } 229 230 231 /** 232 * Test winding number. 233 * 234 */ 235 @SuppressWarnings("unchecked") 236 public void testWindingNumber() { 237 ComplexRootsSturm<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 238 //Complex<BigRational> I = cfac.getIMAG(); 239 240 a = dfac.univariate(0, 2L).sum(cfac.fromInteger(1)); // x^2 + 1 241 //a = dfac.random(kl, ll, el, q); 242 //a = dfac.univariate(0,2L).subtract(cfac.getONE()); // x^2 - 1 243 //a = dfac.univariate(0,2L).subtract(I); // x^2 - I 244 //a = dfac.univariate(0,1L); // x 245 //System.out.println("a = " + a); 246 247 Complex<BigRational> Mb = cr.rootBound(a); 248 BigRational M = Mb.getRe(); 249 //System.out.println("M = " + M); 250 BigRational eps = new BigRational(1, 1000); 251 //System.out.println("eps = " + eps); 252 253 Complex<BigRational>[] corner = new Complex[4]; 254 255 corner[0] = new Complex<BigRational>(cfac, M.negate(), M); // nw 256 corner[1] = new Complex<BigRational>(cfac, M.negate(), M.negate()); // sw 257 corner[2] = new Complex<BigRational>(cfac, M, M.negate()); // se 258 corner[3] = new Complex<BigRational>(cfac, M, M); // ne 259 260 long v = 0; 261 try { 262 v = cr.windingNumber(new Rectangle<BigRational>(corner), a); 263 } catch (InvalidBoundaryException e) { 264 fail("" + e); 265 } 266 //System.out.println("winding number = " + v); 267 assertTrue("wind(rect,a) == 2 ", v == 2); 268 269 //if ( true ) return; 270 271 corner[0] = new Complex<BigRational>(cfac, M.negate(), M); // nw 272 corner[1] = new Complex<BigRational>(cfac, M.negate(), eps); // sw 273 corner[2] = new Complex<BigRational>(cfac, M, eps); // se 274 corner[3] = new Complex<BigRational>(cfac, M, M); // ne 275 276 try { 277 v = cr.windingNumber(new Rectangle<BigRational>(corner), a); 278 } catch (InvalidBoundaryException e) { 279 fail("" + e); 280 } 281 //System.out.println("winding number = " + v); 282 assertTrue("wind(rect,a) == 1 ", v == 1); 283 284 corner[0] = new Complex<BigRational>(cfac, eps.negate(), eps); // nw 285 corner[1] = new Complex<BigRational>(cfac, eps.negate(), eps.negate()); // sw 286 corner[2] = new Complex<BigRational>(cfac, eps, eps.negate()); // se 287 corner[3] = new Complex<BigRational>(cfac, eps, eps); // ne 288 289 try { 290 v = cr.windingNumber(new Rectangle<BigRational>(corner), a); 291 } catch (InvalidBoundaryException e) { 292 fail("" + e); 293 } 294 //System.out.println("winding number = " + v); 295 assertTrue("wind(rect,a) == 0 ", v == 0); 296 } 297 298 299 /** 300 * Test complex roots, sqrt(-1). 301 * 302 */ 303 @SuppressWarnings("unchecked") 304 public void testComplexRootsImag() { 305 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 306 //Complex<BigRational> I = cfac.getIMAG(); 307 308 a = dfac.univariate(0, 2L).sum(cfac.fromInteger(1)); // x^2 + 1 309 //a = dfac.univariate(0,2L).subtract(cfac.getONE()); // x^2 - 1 310 //a = dfac.univariate(0,2L).subtract(I); // x^2 - I 311 //a = dfac.univariate(0,1L); // x 312 //System.out.println("a = " + a); 313 314 Complex<BigRational> Mb = cr.rootBound(a); 315 BigRational M = Mb.getRe(); 316 //System.out.println("M = " + M); 317 318 Complex<BigRational>[] corner = new Complex[4]; 319 320 corner[0] = new Complex<BigRational>(cfac, M.negate(), M); // nw 321 corner[1] = new Complex<BigRational>(cfac, M.negate(), M.negate()); // sw 322 corner[2] = new Complex<BigRational>(cfac, M, M.negate()); // se 323 corner[3] = new Complex<BigRational>(cfac, M, M); // ne 324 325 Rectangle<BigRational> rect = new Rectangle<BigRational>(corner); 326 327 List<Rectangle<BigRational>> roots = null; 328 try { 329 roots = cr.complexRoots(rect, a); 330 } catch (InvalidBoundaryException e) { 331 fail("" + e); 332 } 333 //System.out.println("roots = " + roots); 334 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 335 } 336 337 338 /** 339 * Test complex roots. 340 */ 341 @SuppressWarnings("unchecked") 342 public void testComplexRootsRand() { 343 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 344 //Complex<BigRational> I = cfac.getIMAG(); 345 346 a = dfac.random(kl, ll, el, q); 347 Squarefree<Complex<BigRational>> engine = SquarefreeFactory 348 .<Complex<BigRational>> getImplementation(cfac); 349 a = engine.squarefreePart(a); 350 351 //a = dfac.univariate(0,2L).subtract(cfac.getONE()); // x^2 - 1 352 //a = dfac.univariate(0,2L).sum(cfac.fromInteger(1)); // x^2 + 1 353 //a = dfac.univariate(0,2L).subtract(I); // x^2 - I 354 //a = dfac.univariate(0,1L); // x 355 //System.out.println("a = " + a); 356 357 Complex<BigRational> Mb = cr.rootBound(a); 358 BigRational M = Mb.getRe(); 359 //System.out.println("M = " + M); 360 361 Complex<BigRational>[] corner = new Complex[4]; 362 363 corner[0] = new Complex<BigRational>(cfac, M.negate(), M); // nw 364 corner[1] = new Complex<BigRational>(cfac, M.negate(), M.negate()); // sw 365 corner[2] = new Complex<BigRational>(cfac, M, M.negate()); // se 366 corner[3] = new Complex<BigRational>(cfac, M, M); // ne 367 368 Rectangle<BigRational> rect = new Rectangle<BigRational>(corner); 369 370 371 List<Rectangle<BigRational>> roots = null; 372 try { 373 roots = cr.complexRoots(rect, a); 374 } catch (InvalidBoundaryException e) { 375 fail("" + e); 376 } 377 //System.out.println("a = " + a); 378 //System.out.println("roots = " + roots); 379 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 380 } 381 382 383 /** 384 * Test complex roots. 385 */ 386 public void testComplexRoots() { 387 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 388 389 a = dfac.random(kl, ll, el + 1, q); 390 //System.out.println("a = " + a); 391 392 List<Rectangle<BigRational>> roots = cr.complexRoots(a); 393 //System.out.println("a = " + a); 394 //System.out.println("roots = " + roots); 395 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 396 } 397 398 399 /** 400 * Test complex root refinement. 401 */ 402 public void testComplexRootRefinement() { 403 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 404 405 a = dfac.random(kl, ll, el - 1, q); 406 //a = dfac.parse("( (x-1)^3 )"); 407 Squarefree<Complex<BigRational>> engine = SquarefreeFactory 408 .<Complex<BigRational>> getImplementation(cfac); 409 //System.out.println("a = " + a); 410 a = engine.squarefreePart(a); 411 //System.out.println("a = " + a); 412 413 List<Rectangle<BigRational>> roots = cr.complexRoots(a); 414 //System.out.println("a = " + a); 415 //System.out.println("roots = " + roots); 416 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 417 418 BigRational len = new BigRational(1, 1000); 419 //System.out.println("len = " + len); 420 421 for (Rectangle<BigRational> root : roots) { 422 try { 423 Rectangle<BigRational> refine = cr.complexRootRefinement(root, a, len); 424 //System.out.println("refine = " + refine); 425 assertFalse("refine != null", refine == null); 426 } catch (InvalidBoundaryException e) { 427 fail("" + e); 428 } 429 } 430 } 431 432 433 /** 434 * Test complex root refinement full. 435 */ 436 public void testComplexRootRefinementFull() { 437 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 438 439 a = dfac.random(kl, ll, el - 1, q); 440 //a = dfac.parse("( (x-1)^3 )"); 441 //a = dfac.parse("( x^4-2 )"); 442 //System.out.println("a = " + a); 443 444 BigRational len = new BigRational(1, 1000); 445 //System.out.println("len = " + len); 446 447 List<Rectangle<BigRational>> refine = cr.complexRoots(a, len); 448 //System.out.println("refine = " + refine); 449 assertTrue("#roots == deg(a) ", refine.size() == a.degree(0)); 450 } 451 452 453 /** 454 * Test winding number with wrong precondition. 455 */ 456 @SuppressWarnings("unchecked") 457 public void testWindingNumberWrong() { 458 ComplexRootsSturm<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 459 //Complex<BigRational> I = cfac.getIMAG(); 460 461 a = dfac.univariate(0, 2L).sum(cfac.fromInteger(1)); // x^2 + 1 462 //a = dfac.random(kl, ll, el, q); 463 //a = dfac.univariate(0,2L).subtract(cfac.getONE()); // x^2 - 1 464 //a = dfac.univariate(0,2L).subtract(I); // x^2 - I 465 //a = dfac.univariate(0,1L); // x 466 //System.out.println("a = " + a); 467 468 Complex<BigRational> Mb = cfac.fromInteger(1); //.divide(cfac.fromInteger(2)); //cr.rootBound(a); 469 BigRational M = Mb.getRe(); 470 //System.out.println("M = " + M); 471 //BigRational eps = new BigRational(1, 1000); 472 //System.out.println("eps = " + eps); 473 BigRational zero = new BigRational(); 474 //BigRational one = new BigRational(1); 475 476 Complex<BigRational>[] corner = new Complex[4]; 477 478 corner[0] = new Complex<BigRational>(cfac, M.negate(), M); // nw 479 corner[1] = new Complex<BigRational>(cfac, M.negate(), zero); // sw 480 corner[2] = new Complex<BigRational>(cfac, M, zero); // se 481 corner[3] = new Complex<BigRational>(cfac, M, M); // ne 482 483 Rectangle<BigRational> rect = new Rectangle<BigRational>(corner); 484 //System.out.println("rect = " + rect); 485 486 try { 487 long v = cr.windingNumber(rect, a); 488 System.out.println("winding number = " + v); 489 fail("wind(rect,a) must throw an exception"); 490 } catch (InvalidBoundaryException e) { 491 } 492 } 493 494 495 /** 496 * Test complex root approximation. 497 */ 498 public void testComplexRootApproximation() { 499 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 500 501 //a = dfac.random(kl, ll, el-1, q); 502 //a = dfac.parse("( (x-1)*(x-2)*(x-3)*(x - { 0i1 })*(x-5) )*( x^4-2 )"); 503 //a = dfac.parse("( (x-1)*(x-2)*(x-3)*( x^4-2 ) )"); 504 //a = dfac.parse("( (x-2)*( x^4-2 ) )"); 505 a = dfac.parse("( ( x^4-2 ) )"); 506 b = dfac.parse("( (x-1)*(x-2)*(x-3) )"); 507 c = dfac.parse("( x^4-2 )"); 508 d = dfac.parse("( (x - { 0i1 })*(x-5) )"); 509 //a = c; // b; //.multiply(c); //.multiply(d); 510 //System.out.println("a = " + a); 511 //System.out.println("b = " + b); 512 //System.out.println("c = " + c); 513 //System.out.println("d = " + d); 514 //a = b.multiply(c).multiply(d); 515 //System.out.println("a = " + a); 516 Squarefree<Complex<BigRational>> engine = SquarefreeFactory 517 .<Complex<BigRational>> getImplementation(cfac); 518 a = engine.squarefreePart(a); 519 //System.out.println("a = " + a); 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<Rectangle<BigRational>> roots = cr.complexRoots(a); 529 //System.out.println("a = " + a); 530 //System.out.println("roots = " + roots); 531 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 532 533 for (Rectangle<BigRational> root : roots) { 534 try { 535 Complex<BigDecimal> cd = cr.approximateRoot(root, a, eps); 536 //System.out.println("cd = " + cd); 537 assertFalse("cd != 0", cd.isZERO()); 538 } catch (NoConvergenceException e) { 539 //fail("" + e); 540 } 541 } 542 } 543 544 545 /** 546 * Test complex root approximation full algorithm. 547 */ 548 public void testComplexRootApproximationFull() { 549 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 550 551 //a = dfac.random(kl, ll, el-1, q); 552 //a = dfac.parse("( (x-1)*(x-2)*(x-3)*(x - { 0i1 })*(x-5) )*( x^4-2 )"); 553 //a = dfac.parse("( (x-1)*(x-2)*(x-3)*( x^4-2 ) )"); 554 a = dfac.parse("( (x-2)*( x^4-2 ) )"); 555 //a = dfac.parse("( ( x^4-2 ) )"); 556 b = dfac.parse("( (x-1)*(x-2)*(x-3) )"); 557 c = dfac.parse("( x^4-2 )"); 558 d = dfac.parse("( (x - { 0i1 })*(x-5) )"); 559 //a = c; // b; //.multiply(c); //.multiply(d); 560 //System.out.println("a = " + a); 561 //System.out.println("b = " + b); 562 //System.out.println("c = " + c); 563 //System.out.println("d = " + d); 564 //a = b.multiply(c).multiply(d); 565 //System.out.println("a = " + a); 566 567 eps = eps.multiply(new BigRational(1000000)); 568 //System.out.println("eps = " + eps); 569 //BigDecimal eps1 = new BigDecimal(eps); 570 //BigDecimal eps2 = eps1.multiply(new BigDecimal("10")); 571 //System.out.println("eps1 = " + eps1); 572 //System.out.println("eps2 = " + eps2); 573 574 List<Complex<BigDecimal>> roots = cr.approximateRoots(a, eps); 575 //System.out.println("a = " + a); 576 //System.out.println("roots = " + roots); 577 //now always true: 578 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 579 } 580 581 582 /** 583 * Test complex root approximation full algorithm with Wilkinson 584 * polynomials. p = (x-i0)*(x-i1)*(x-i2)*(x-i3*...*(x-in) 585 */ 586 public void testComplexRootApproximationWilkinsonFull() { 587 final int N = 4; 588 d = dfac.getONE(); 589 e = dfac.univariate(0); 590 591 BigDecimal br = new BigDecimal(); 592 ComplexRing<BigDecimal> cf = new ComplexRing<BigDecimal>(br); 593 Complex<BigDecimal> I = cf.getIMAG(); 594 Complex<BigDecimal> cc = null; 595 Complex<BigRational> Ir = cfac.getIMAG(); 596 597 List<Complex<BigDecimal>> Rn = new ArrayList<Complex<BigDecimal>>(N); 598 a = d; 599 for (int i = 0; i < N; i++) { 600 cc = cf.fromInteger(i).multiply(I); 601 Rn.add(cc); 602 c = dfac.fromInteger(i).multiply(Ir); 603 b = e.subtract(c); 604 a = a.multiply(b); 605 } 606 //System.out.println("a = " + a); 607 Collections.reverse(Rn); 608 //System.out.println("Rn = " + Rn); 609 610 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 611 612 eps = eps.multiply(new BigRational(100000)); 613 //System.out.println("eps = " + eps); 614 BigDecimal eps1 = new BigDecimal(eps); 615 BigDecimal eps2 = eps1.multiply(new BigDecimal("10")); 616 //System.out.println("eps1 = " + eps1); 617 //System.out.println("eps2 = " + eps2); 618 619 List<Complex<BigDecimal>> roots = cr.approximateRoots(a, eps); 620 //System.out.println("a = " + a); 621 //System.out.println("roots = " + roots); 622 //now always true: 623 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 624 625 int i = 0; 626 for (Complex<BigDecimal> dd : roots) { 627 Complex<BigDecimal> di = Rn.get(i++); 628 //System.out.print("di = " + di + ", "); 629 //System.out.println("dd = " + dd); 630 assertTrue("|dd - di| < eps ", dd.subtract(di).norm().getRe().compareTo(eps2) <= 0); 631 } 632 } 633 634 635 /** 636 * Test complex root approximation full algorithm with Wilkinson 637 * polynomials, inverse roots. p = (x-1/i1)*(x-1/i2)*(x-1/i3*...*(x-1/in) 638 */ 639 public void testComplexRootApproximationWilkinsonInverseFull() { 640 final int N = 5; 641 d = dfac.getONE(); 642 e = dfac.univariate(0); 643 644 BigDecimal br = new BigDecimal(); 645 ComplexRing<BigDecimal> cf = new ComplexRing<BigDecimal>(br); 646 Complex<BigDecimal> I = cf.getIMAG(); 647 Complex<BigDecimal> cc = null; 648 Complex<BigRational> Ir = cfac.getIMAG(); 649 650 List<Complex<BigDecimal>> Rn = new ArrayList<Complex<BigDecimal>>(N); 651 a = d; 652 for (int i = 1; i < N; i++) { 653 cc = cf.fromInteger(i).multiply(I); 654 cc = cc.inverse(); 655 Rn.add(cc); 656 c = dfac.fromInteger(i).multiply(Ir); 657 c = d.divide(c); 658 b = e.subtract(c); 659 a = a.multiply(b); 660 } 661 //System.out.println("a = " + a); 662 //Collections.sort(Rn); 663 //System.out.println("Rn = " + Rn); 664 665 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 666 667 eps = eps.multiply(new BigRational(100000)); 668 //System.out.println("eps = " + eps); 669 BigDecimal eps1 = new BigDecimal(eps); 670 BigDecimal eps2 = eps1.multiply(new BigDecimal("10")); 671 //System.out.println("eps1 = " + eps1); 672 //System.out.println("eps2 = " + eps2); 673 674 List<Complex<BigDecimal>> roots = cr.approximateRoots(a, eps); 675 //System.out.println("a = " + a); 676 //System.out.println("roots = " + roots); 677 //now always true: 678 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 679 //Collections.sort(roots); 680 //System.out.println("roots = " + roots); 681 682 for (Complex<BigDecimal> dd : roots) { 683 //System.out.println("dd = " + dd); 684 boolean t = false; 685 for (Complex<BigDecimal> di : Rn) { 686 //System.out.println("di = " + di); 687 t = dd.subtract(di).norm().getRe().compareTo(eps2) <= 0; 688 if (t) { 689 break; 690 } 691 } 692 if (!t) { 693 //assertTrue("|dd - di| < eps ", dd.subtract(di).norm().getRe().compareTo(eps2) <= 0); 694 fail("|dd - di| < eps "); 695 } 696 } 697 } 698 699 700 /** 701 * Test complex root invariant rectangle. 702 */ 703 public void testComplexRootInvariant() { 704 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 705 706 a = dfac.random(kl, ll, el - 1, q); 707 b = dfac.random(kl, ll, 2, q); 708 //a = dfac.parse("( (x-1)^3 )"); 709 //a = dfac.parse("( x^4-2 )"); 710 if (a.degree() == 0) { 711 return; 712 } 713 Squarefree<Complex<BigRational>> engine = SquarefreeFactory 714 .<Complex<BigRational>> getImplementation(cfac); 715 a = engine.squarefreePart(a); 716 b = engine.squarefreePart(b); 717 //System.out.println("a = " + a); 718 //System.out.println("b = " + b); 719 720 List<Rectangle<BigRational>> roots = cr.complexRoots(a); 721 //System.out.println("roots = " + roots); 722 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 723 724 Rectangle<BigRational> rect = roots.get(0); 725 //System.out.println("rect = " + rect); 726 727 try { 728 Rectangle<BigRational> ref = cr.invariantRectangle(rect, a, b); 729 //System.out.println("rect = " + rect); 730 //System.out.println("ref = " + ref); 731 assertTrue("rect subseteq ref ", rect.contains(ref)); 732 } catch (InvalidBoundaryException e) { 733 e.printStackTrace(); 734 fail("bad boundary"); 735 } 736 } 737 738 739 /** 740 * Test complex root invariant magnitude rectangle. 741 */ 742 public void testComplexRootInvariantMagnitude() { 743 ComplexRootsAbstract<BigRational> cr = new ComplexRootsSturm<BigRational>(cfac); 744 745 a = dfac.random(kl, ll, el - 1, q); 746 b = dfac.random(kl, ll, 3, q); 747 //a = dfac.parse("( x^2 + 1 )"); 748 //b = dfac.parse("( x - 0i1 )"); 749 if (a.degree() == 0) { 750 return; 751 } 752 Squarefree<Complex<BigRational>> engine = SquarefreeFactory 753 .<Complex<BigRational>> getImplementation(cfac); 754 a = engine.squarefreePart(a); 755 b = engine.squarefreePart(b); 756 //System.out.println("a = " + a); 757 //System.out.println("b = " + b); 758 759 List<Rectangle<BigRational>> roots = cr.complexRoots(a); 760 //System.out.println("roots = " + roots); 761 assertTrue("#roots == deg(a) ", roots.size() == a.degree(0)); 762 763 Rectangle<BigRational> rect = roots.get(0); 764 //System.out.println("rect = " + rect); 765 766 try { 767 Rectangle<BigRational> ref = cr.invariantMagnitudeRectangle(rect, a, b, eps); 768 //System.out.println("ref = " + ref); 769 assertTrue("rect subseteq ref ", rect.contains(ref)); 770 Complex<BigRational> mag = cr.complexRectangleMagnitude(ref, a, b); 771 //System.out.println("mag = " + mag); 772 Complex<BigRational> cmag = cr.complexMagnitude(ref, a, b, eps); 773 //System.out.println("cmag = " + cmag); 774 assertEquals("mag == cmag: " + cmag, mag, cmag); 775 //BigRational rmag = cmag.getRe(); 776 //System.out.println("rmag = " + new BigDecimal(cmag.getRe()) + " i " + new BigDecimal(cmag.getIm())); 777 } catch (InvalidBoundaryException e) { 778 e.printStackTrace(); 779 fail("bad boundary"); 780 } 781 } 782 783}