001/*
002 * $Id: ComplexRootTest.java 4122 2012-08-19 15:54:52Z kredel $
003 */
004
005package edu.jas.application;
006
007
008import java.util.List;
009
010import junit.framework.Test;
011import junit.framework.TestCase;
012import junit.framework.TestSuite;
013
014import org.apache.log4j.BasicConfigurator;
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.TermOrder;
024import edu.jas.structure.Power;
025import edu.jas.ufd.Squarefree;
026import edu.jas.ufd.SquarefreeFactory;
027
028
029/**
030 * RootUtil tests with JUnit.
031 * @author Heinz Kredel.
032 */
033
034public class ComplexRootTest extends TestCase {
035
036
037    /**
038     * main.
039     */
040    public static void main(String[] args) {
041        BasicConfigurator.configure();
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[] { "z" };
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 complex roots, imaginary.
131     */
132    public void testComplexRootsImag() {
133        //Complex<BigRational> I = cfac.getIMAG(); 
134        //a = dfac.parse("z^3 - i2"); 
135        //a = dfac.random(ll+1).monic();
136        //a = dfac.parse("z^7 - 2 z");
137        a = dfac.parse("z^6 - i3");
138        //System.out.println("a = " + a);
139
140        List<Complex<RealAlgebraicNumber<BigRational>>> roots;
141        roots = RootFactory.<BigRational> complexAlgebraicNumbersComplex(a);
142        //System.out.println("a = " + a);
143        //System.out.println("roots = " + roots);
144        assertTrue("#roots == deg(a) ", roots.size() == a.degree(0));
145        for (Complex<RealAlgebraicNumber<BigRational>> root : roots) {
146            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + " + root.getIm().decimalMagnitude() + " i");
147            assertTrue("f(r) == 0: " + root, RootFactory.<BigRational> isRoot(a, root));
148        }
149    }
150
151
152    /*
153     * Test complex roots, random polynomial.
154     */
155    public void testComplexRootsRand() {
156        //Complex<BigRational> I = cfac.getIMAG(); 
157        a = dfac.random(ll + 1).monic();
158        if (a.isZERO() || a.isONE()) {
159            a = dfac.parse("z^6 - i3");
160        }
161        Squarefree<Complex<BigRational>> sqf = SquarefreeFactory
162                        .<Complex<BigRational>> getImplementation(cfac);
163        a = sqf.squarefreePart(a);
164        //System.out.println("a = " + a);
165        List<Complex<RealAlgebraicNumber<BigRational>>> roots;
166        roots = RootFactory.<BigRational> complexAlgebraicNumbersComplex(a);
167        //System.out.println("a = " + a);
168        //System.out.println("roots = " + roots);
169        assertTrue("#roots == deg(a): " + (roots.size() - a.degree(0)) + ", a = " + a,
170                        roots.size() == a.degree(0));
171        for (Complex<RealAlgebraicNumber<BigRational>> root : roots) {
172            //System.out.println("root = " + root.getRe().decimalMagnitude() + " + " + root.getIm().decimalMagnitude() + " i");
173            assertTrue("f(r) == 0: " + root, RootFactory.<BigRational> isRoot(a, root));
174        }
175    }
176
177
178    /**
179     * Test polynomial with complex roots.
180     */
181    public void testPolynomialComplexRoots() {
182        a = dfac.parse("z^3 - 2");
183        //System.out.println("a = " + a);
184        List<Complex<RealAlgebraicNumber<BigRational>>> roots = RootFactory
185                        .<BigRational> complexAlgebraicNumbersComplex(a);
186        //System.out.println("a = " + a);
187        //System.out.println("roots = " + roots);
188        assertTrue("#roots == deg(a) ", roots.size() == a.degree(0));
189        for (Complex<RealAlgebraicNumber<BigRational>> car : roots) {
190            //System.out.println("car = " + car);
191            RealAlgebraicRing<BigRational> rfac = car.getRe().ring;
192            rfac.setField(true); // ?? to check
193            assertTrue("isField(rfac) ", rfac.isField());
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 = new GenPolynomialRing<Complex<RealAlgebraicNumber<BigRational>>>(
209                        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 dd = cpol.degree(0);
236        Squarefree<Complex<RealAlgebraicNumber<BigRational>>> sen = SquarefreeFactory
237                        .<Complex<RealAlgebraicNumber<BigRational>>> getImplementation(root.ring);
238        cpol = sen.squarefreePart(cpol);
239        //if (cpol.degree(0) < dd) {
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 = RootFactory
247                        .<RealAlgebraicNumber<BigRational>> complexAlgebraicNumbersComplex(cpol);
248        t1 = System.currentTimeMillis() - t1;
249        assertTrue("nonsense " + t1, t1 >= 0L);
250        //System.out.println("\na = " + a.toScript());
251        //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
252        //                             + root.getIm().decimalMagnitude() + " i");
253        //System.out.println("a = " + a);
254        //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
255        //                  + root.getIm().decimalMagnitude() + " i");
256        //System.out.println("root = " + root.getRe() + " + (" + root.getIm() + ") i");
257        //System.out.println("root.ring = " + root.ring);
258        //System.out.println("cpol      = " + cpol);
259        //System.out.println("cpol.ring = " + cpol.ring);
260        //System.out.println("croots = " + croots);
261        for (Complex<RealAlgebraicNumber<RealAlgebraicNumber<BigRational>>> croot : croots) {
262            //System.out.println("croot = " + croot);
263            //System.out.println("croot = " + croot.getRe() + " + ( " + croot.getIm() + ") i");
264            //System.out.println("croot.ring = " + croot.ring); //magnitude());
265            //System.out.println("croot = " + croot.getRe().decimalMagnitude() + " + "
266            //                              + croot.getIm().decimalMagnitude() + " i");
267            assertTrue("f(r) == 0: " + croot,
268                            RootFactory.<RealAlgebraicNumber<BigRational>> isRoot(cpol, croot));
269        }
270        assertTrue("#croots == deg(cpol) " + croots.size() + " != " + cpol.degree(0),
271                        croots.size() == cpol.degree(0));
272
273
274        // existing version with winding number and recursion: but only one step
275        long t2 = System.currentTimeMillis();
276        List<edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>>> coroots = edu.jas.root.RootFactory
277                        .<RealAlgebraicNumber<BigRational>> complexAlgebraicNumbersComplex(cpol);
278        t2 = System.currentTimeMillis() - t2;
279        assertTrue("nonsense " + t2, t2 >= 0L);
280        //System.out.println("\ncpol = " + cpol);
281        //System.out.println("root = " + root.getRe() + " + (" + root.getIm() + ") i");
282        //System.out.println("root = " + root.getRe().decimalMagnitude() + " + "
283        //                             + root.getIm().decimalMagnitude() + " i");
284        for (edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>> cr2 : coroots) {
285            //System.out.println("r2.ring = " + cr2.ring); //magnitude());
286            assertTrue("f(r) == 0: " + cr2,
287                            edu.jas.root.RootFactory.<RealAlgebraicNumber<BigRational>> isRootComplex(cpol,
288                                            cr2));
289        }
290
291        // decimal for comparison
292        long t3 = System.currentTimeMillis();
293        for (Complex<RealAlgebraicNumber<RealAlgebraicNumber<BigRational>>> croot : croots) {
294            String crs = croot.getRe().decimalMagnitude() + " + " + croot.getIm().decimalMagnitude() + " i";
295            //System.out.println("croot = " + crs);
296            assertFalse("crs not empty", crs.length() == 0); // java-5
297        }
298        t3 = System.currentTimeMillis() - t3;
299        assertTrue("nonsense " + t3, t3 >= 0L);
300        long t4 = System.currentTimeMillis();
301        for (edu.jas.root.ComplexAlgebraicNumber<RealAlgebraicNumber<BigRational>> cr2 : coroots) {
302            String crs = cr2.decimalMagnitude().toString();
303            //System.out.println("r2.dec  = " + crs);
304            assertFalse("crs not empty", crs.length() == 0); // java-5
305        }
306        t4 = System.currentTimeMillis() - t4;
307        assertTrue("nonsense " + t4, t4 >= 0L);
308        assertTrue("#coroots == deg(cpol) ", coroots.size() == cpol.degree(0));
309        //System.out.println("time, real ideal = " + t1 + "+" + t3 + ", complex winding = " + t2 + "+" + t4 + " milliseconds");
310    }
311
312}