001    /*
002     * $Id: ComplexRootTest.java 3696 2011-07-24 15:19:25Z kredel $
003     */
004    
005    package edu.jas.application;
006    
007    
008    import java.util.List;
009    
010    import junit.framework.Test;
011    import junit.framework.TestCase;
012    import junit.framework.TestSuite;
013    
014    import org.apache.log4j.BasicConfigurator;
015    
016    import edu.jas.arith.BigDecimal;
017    import edu.jas.arith.BigRational;
018    import edu.jas.kern.ComputerThreads;
019    import edu.jas.poly.Complex;
020    import edu.jas.poly.ComplexRing;
021    import edu.jas.poly.GenPolynomial;
022    import edu.jas.poly.GenPolynomialRing;
023    import edu.jas.poly.TermOrder;
024    import edu.jas.root.ComplexRoots;
025    import edu.jas.root.ComplexRootsSturm;
026    import edu.jas.root.Rectangle;
027    import edu.jas.structure.Power;
028    import edu.jas.ufd.Squarefree;
029    import edu.jas.ufd.SquarefreeFactory;
030    
031    
032    /**
033     * RootUtil tests with JUnit.
034     * @author Heinz Kredel.
035     */
036    
037    public class ComplexRootTest extends TestCase {
038    
039    
040        /**
041         * main.
042         */
043        public static void main(String[] args) {
044            BasicConfigurator.configure();
045            junit.textui.TestRunner.run(suite());
046            ComputerThreads.terminate();
047        }
048    
049    
050        /**
051         * Constructs a <CODE>ComplexRootTest</CODE> object.
052         * @param name String.
053         */
054        public ComplexRootTest(String name) {
055            super(name);
056        }
057    
058    
059        /**
060         */
061        public static Test suite() {
062            TestSuite suite = new TestSuite(ComplexRootTest.class);
063            return suite;
064        }
065    
066    
067        TermOrder to = new TermOrder(TermOrder.INVLEX);
068    
069    
070        GenPolynomialRing<Complex<BigRational>> dfac;
071    
072    
073        ComplexRing<BigRational> cfac;
074    
075    
076        BigRational eps;
077    
078    
079        Complex<BigRational> ceps;
080    
081    
082        GenPolynomial<Complex<BigRational>> a;
083    
084    
085        GenPolynomial<Complex<BigRational>> b;
086    
087    
088        GenPolynomial<Complex<BigRational>> c;
089    
090    
091        GenPolynomial<Complex<BigRational>> d;
092    
093    
094        GenPolynomial<Complex<BigRational>> e;
095    
096    
097        int rl = 1;
098    
099    
100        int kl = 3;
101    
102    
103        int ll = 3;
104    
105    
106        int el = 5;
107    
108    
109        float q = 0.7f;
110    
111    
112        @Override
113        protected void setUp() {
114            a = b = c = d = e = null;
115            cfac = new ComplexRing<BigRational>(new BigRational(1));
116            String[] vars = new String[] { "z" };
117            dfac = new GenPolynomialRing<Complex<BigRational>>(cfac, rl, to, vars);
118            eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION);
119            ceps = new Complex<BigRational>(cfac, eps);
120        }
121    
122    
123        @Override
124        protected void tearDown() {
125            a = b = c = d = e = null;
126            dfac = null;
127            cfac = null;
128            eps = null;
129        }
130    
131    
132        /**
133         * Test complex roots, imaginary.
134         */
135        public void testComplexRootsImag() {
136            //Complex<BigRational> I = cfac.getIMAG(); 
137            //a = dfac.parse("z^3 - i2"); 
138            //a = dfac.random(ll+1).monic();
139            //a = dfac.parse("z^7 - 2 z");
140            a = dfac.parse("z^6 - i3");
141            //System.out.println("a = " + a);
142    
143            List<Complex<RealAlgebraicNumber<BigRational>>> roots;
144            roots = RootFactory.<BigRational> complexAlgebraicNumbersComplex(a);
145            //System.out.println("a = " + a);
146            //System.out.println("roots = " + roots);
147            assertTrue("#roots == deg(a) ", roots.size() == a.degree(0));
148            for (Complex<RealAlgebraicNumber<BigRational>> root : roots) {
149                //System.out.println("root = " + root.getRe().decimalMagnitude() + " + " + root.getIm().decimalMagnitude() + " i");
150                assertTrue("f(r) == 0: " + root, RootFactory.<BigRational> isRoot(a,root));
151            }
152        }
153    
154    
155        /*
156         * Test complex roots, random polynomial.
157         */
158        public void testComplexRootsRand() {
159            //Complex<BigRational> I = cfac.getIMAG(); 
160            a = dfac.random(ll + 1).monic();
161            if (a.isZERO() || a.isONE()) {
162                a = dfac.parse("z^6 - i3");
163            }
164            Squarefree<Complex<BigRational>> sqf = SquarefreeFactory
165                            .<Complex<BigRational>> getImplementation(cfac);
166            a = sqf.squarefreePart(a);
167            //System.out.println("a = " + a);
168            List<Complex<RealAlgebraicNumber<BigRational>>> roots;
169            roots = RootFactory.<BigRational> complexAlgebraicNumbersComplex(a);
170            //System.out.println("a = " + a);
171            //System.out.println("roots = " + roots);
172            assertTrue("#roots == deg(a): " + (roots.size() - a.degree(0)) + ", a = " + a,
173                            roots.size() == a.degree(0));
174            for (Complex<RealAlgebraicNumber<BigRational>> root : roots) {
175                //System.out.println("root = " + root.getRe().decimalMagnitude() + " + " + root.getIm().decimalMagnitude() + " i");
176                assertTrue("f(r) == 0: " + root, RootFactory.<BigRational> isRoot(a,root));
177            }
178        }
179    
180    
181        /**
182         * Test polynomial with complex roots.
183         */
184        public void testPolynomialComplexRoots() {
185            a = dfac.parse("z^3 - 2");
186            //System.out.println("a = " + a);
187            List<Complex<RealAlgebraicNumber<BigRational>>> roots = RootFactory
188                            .<BigRational> complexAlgebraicNumbersComplex(a);
189            //System.out.println("a = " + a);
190            //System.out.println("roots = " + roots);
191            assertTrue("#roots == deg(a) ", roots.size() == a.degree(0));
192            for (Complex<RealAlgebraicNumber<BigRational>> car : roots) {
193                //System.out.println("car = " + car);
194                assertTrue("f(r) == 0: " + car, RootFactory.<BigRational> isRoot(a,car));
195            }
196            Complex<RealAlgebraicNumber<BigRational>> root = roots.get(2); // 0,1,2)
197            //System.out.println("a = " + a);
198            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
199            //                  + root.getIm().decimalMagnitude() + " i");
200            //System.out.println("root = " + root.getRe() + " + " + root.getIm() + " i");
201            String vre = root.getRe().toString().replace("{", "").replace("}", "").trim();
202            String vim = root.getIm().toString().replace("{", "").replace("}", "").trim();
203            //System.out.println("vre = " + vre);
204            //System.out.println("vim = " + vim);
205            String IM = root.ring.getIMAG().toString().replace("{", "").replace("}", "").replace(" ", "").trim();
206            //System.out.println("IM  = " + IM);
207    
208            GenPolynomialRing<Complex<RealAlgebraicNumber<BigRational>>> cring 
209                = new GenPolynomialRing<Complex<RealAlgebraicNumber<BigRational>>>(root.ring, to, new String[] { "t" });
210            List<GenPolynomial<Complex<RealAlgebraicNumber<BigRational>>>> gens = cring.generators();
211            //System.out.println("gens  = " + gens);
212    
213            GenPolynomial<Complex<RealAlgebraicNumber<BigRational>>> cpol;
214            //cpol = cring.random(1, 4, 4, q);
215    
216            //cpol = cring.univariate(0,3L).subtract(cring.fromInteger(2L));
217            //cpol = cring.univariate(0,3L).subtract(gens.get(2));
218            //cpol = cring.univariate(0,5L).subtract(cring.univariate(0,2L).multiply(root));
219            //cpol = cring.univariate(0,4L).subtract(root);
220            //cpol = cring.univariate(0,4L).subtract(root.multiply(root));
221            //cpol = cring.univariate(0,3L).subtract(cring.univariate(0,1L).multiply(root).sum(root.multiply(root)));
222            cpol = cring.univariate(0,2L).subtract(root.multiply(root)); // okay
223            //cpol = cring.univariate(0,3L).subtract(root.multiply(root)); // okay
224            //cpol = cring.univariate(0,3L).subtract(root.multiply(root).multiply(root)); // not much sense r^3 = 2
225            String vpol = vre + " + " + IM + " " + vim;
226            //String vpol = " 3 + " + IM + " * 3 ";
227            //String vpol = " 3i3 ";
228            //String vpol = IM + " " + vim;
229            //String vpol = " 2 ";// + vre; // + " " + IM;
230            //String vpol = vre; // + " " + IM;
231            //System.out.println("vpol = " + vpol);
232            //cpol = cring.univariate(0, 3L).subtract(cring.parse(vpol));
233            cpol = cpol.monic();
234            //System.out.println("cpol = " + cpol);
235            long d = cpol.degree(0);
236            Squarefree<Complex<RealAlgebraicNumber<BigRational>>> sen 
237                = SquarefreeFactory.<Complex<RealAlgebraicNumber<BigRational>>> getImplementation(root.ring);
238            cpol = sen.squarefreePart(cpol);
239            if ( cpol.degree(0) < d ) {
240                //System.out.println("cpol = " + cpol);
241            }
242            //System.out.println("cpol = " + cpol);
243    
244            // new version with recursion: with real factorization
245            long t1 = System.currentTimeMillis();
246            List<Complex<RealAlgebraicNumber<RealAlgebraicNumber<BigRational>>>> croots 
247                = RootFactory.<RealAlgebraicNumber<BigRational>> complexAlgebraicNumbersComplex(cpol);
248            t1 = System.currentTimeMillis() - t1;
249            //System.out.println("\na = " + a.toScript());
250            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
251            //                             + root.getIm().decimalMagnitude() + " i");
252            //System.out.println("a = " + a);
253            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
254            //                  + root.getIm().decimalMagnitude() + " i");
255            //System.out.println("root = " + root.getRe() + " + (" + root.getIm() + ") i");
256            //System.out.println("root.ring = " + root.ring);
257            //System.out.println("cpol      = " + cpol);
258            //System.out.println("cpol.ring = " + cpol.ring);
259            //System.out.println("croots = " + croots);
260            for (Complex<RealAlgebraicNumber<RealAlgebraicNumber<BigRational>>> croot : croots) {
261                //System.out.println("croot = " + croot);
262                //System.out.println("croot = " + croot.getRe() + " + ( " + croot.getIm() + ") i");
263                //System.out.println("croot.ring = " + croot.ring); //magnitude());
264                //System.out.println("croot = " + croot.getRe().decimalMagnitude() + " + "
265                //                              + croot.getIm().decimalMagnitude() + " i");
266                assertTrue("f(r) == 0: " + croot, RootFactory.<RealAlgebraicNumber<BigRational>> isRoot(cpol,croot));
267            }
268            assertTrue("#croots == deg(cpol) " + croots.size() + " != " + cpol.degree(0), croots.size() == cpol.degree(0));
269    
270    
271            // existing version with winding number and recursion: but only one step
272            long t2 = System.currentTimeMillis();
273            List<edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>>> coroots
274                = edu.jas.root.RootFactory.<RealAlgebraicNumber<BigRational>> complexAlgebraicNumbersComplex(cpol);
275            t2 = System.currentTimeMillis() - t2;
276            //System.out.println("\ncpol = " + cpol);
277            //System.out.println("root = " + root.getRe() + " + (" + root.getIm() + ") i");
278            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
279            //                             + root.getIm().decimalMagnitude() + " i");
280            for (edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>> cr2 : coroots) {
281                //System.out.println("r2.ring = " + cr2.ring); //magnitude());
282                assertTrue("f(r) == 0: " + cr2, edu.jas.root.RootFactory.<RealAlgebraicNumber<BigRational>> isRootComplex(cpol,cr2));
283            }
284    
285            // decimal for comparison
286            long t3 = System.currentTimeMillis();
287            for (Complex<RealAlgebraicNumber<RealAlgebraicNumber<BigRational>>> croot : croots) {
288                String crs =   croot.getRe().decimalMagnitude() + " + "
289                             + croot.getIm().decimalMagnitude() + " i";
290                //System.out.println("croot = " + crs);
291            }
292            t3 = System.currentTimeMillis() - t3;
293            long t4 = System.currentTimeMillis();
294            for (edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>> cr2 : coroots) {
295                String crs = cr2.decimalMagnitude().toString();
296                //System.out.println("r2.dec  = " + crs);
297            }
298            t4 = System.currentTimeMillis() - t4;
299            assertTrue("#coroots == deg(cpol) ", coroots.size() == cpol.degree(0));
300            //System.out.println("time, real ideal = " + t1 + "+" + t3 + ", complex winding = " + t2 + "+" + t4 + " milliseconds");
301        }
302    
303    }