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