001    /*
002     * $Id: RealAlgebraicTest.java 3625 2011-05-08 09:35:21Z kredel $
003     */
004    
005    package edu.jas.application;
006    
007    
008    import java.util.ArrayList;
009    import java.util.List;
010    
011    import junit.framework.Test;
012    import junit.framework.TestCase;
013    import junit.framework.TestSuite;
014    
015    import org.apache.log4j.BasicConfigurator;
016    
017    import edu.jas.arith.BigDecimal;
018    import edu.jas.arith.BigRational;
019    import edu.jas.kern.ComputerThreads;
020    import edu.jas.poly.Complex;
021    import edu.jas.poly.ComplexRing;
022    import edu.jas.poly.GenPolynomial;
023    import edu.jas.poly.GenPolynomialRing;
024    import edu.jas.poly.TermOrder;
025    import edu.jas.root.RealRootTuple;
026    import edu.jas.structure.NotInvertibleException;
027    import edu.jas.structure.Power;
028    
029    
030    /**
031     * RealAlgebraicNumber Test using JUnit.
032     * @author Heinz Kredel.
033     */
034    
035    public class RealAlgebraicTest extends TestCase {
036    
037    
038        /**
039         * main.
040         */
041        public static void main(String[] args) {
042            BasicConfigurator.configure();
043            junit.textui.TestRunner.run(suite());
044        }
045    
046    
047        /**
048         * Constructs a <CODE>RealAlgebraicTest</CODE> object.
049         * @param name String.
050         */
051        public RealAlgebraicTest(String name) {
052            super(name);
053        }
054    
055    
056        /**
057         * suite.
058         */
059        public static Test suite() {
060            TestSuite suite = new TestSuite(RealAlgebraicTest.class);
061            return suite;
062        }
063    
064    
065        //private final static int bitlen = 100;
066    
067        RealAlgebraicRing<BigRational> fac;
068    
069    
070        GenPolynomialRing<BigRational> mfac;
071    
072    
073        RealAlgebraicNumber<BigRational> a;
074    
075    
076        RealAlgebraicNumber<BigRational> b;
077    
078    
079        RealAlgebraicNumber<BigRational> c;
080    
081    
082        RealAlgebraicNumber<BigRational> d;
083    
084    
085        RealAlgebraicNumber<BigRational> e;
086    
087    
088        int rl = 1;
089    
090    
091        int kl = 10;
092    
093    
094        int ll = 10;
095    
096    
097        int el = ll;
098    
099    
100        float q = 0.5f;
101    
102    
103        @Override
104        protected void setUp() {
105            a = b = c = d = e = null;
106            BigRational rfac = new BigRational();
107            String[] vars = new String[] { "x", "y" };
108            TermOrder tord = new TermOrder(TermOrder.INVLEX);
109            mfac = new GenPolynomialRing<BigRational>(rfac, tord, vars);
110            //System.out.println("mfac = " + mfac);
111            // z^3 - 2 i: z    |--> x + i y
112            GenPolynomial<BigRational> fr = mfac.parse("y**3 - 3 * x**2 * y  - 2");
113            GenPolynomial<BigRational> fi = mfac.parse("-3 * x * y**2 + x**3");
114            List<GenPolynomial<BigRational>> li = new ArrayList<GenPolynomial<BigRational>>(2);
115            li.add(fr);
116            li.add(fi);
117            Ideal<BigRational> id = new Ideal<BigRational>(mfac, li);
118            //System.out.println("id = " + id);
119    
120            List<IdealWithUniv<BigRational>> idul = id.zeroDimRootDecomposition();
121            IdealWithUniv<BigRational> idu = idul.get(0);
122            if (idul.size() > 1) {
123                //System.out.println("idul = " + idul);
124                //idu = idul.get(1);
125            }
126            //System.out.println("idu = " + idu);
127            GenPolynomial<BigRational> x = idu.ideal.list.list.remove(1);
128            //System.out.println("x = " + x);
129            x = x.multiply(x).subtract(mfac.fromInteger(3));
130            //System.out.println("x = " + x);
131            idu.ideal.list.list.add(x);
132            //System.out.println("idu = " + idu);
133    
134            IdealWithRealAlgebraicRoots<BigRational, BigRational> idr = PolyUtilApp
135                            .<BigRational, BigRational> realAlgebraicRoots(idu.ideal).get(0);
136            //System.out.println("idr = " + idr);
137            //idr.doDecimalApproximation();
138            //for ( List<BigDecimal> d : idr.decimalApproximation() ) {
139            //    System.out.println("d = " + d);
140            //}
141            List<List<edu.jas.root.RealAlgebraicNumber<BigRational>>> ran = idr.ran;
142            RealRootTuple<BigRational> root = new RealRootTuple<BigRational>(ran.get(0));
143            if (ran.size() > 1) {
144                //System.out.println("ran = " + ran);
145                root = new RealRootTuple<BigRational>(ran.get(1));
146            }
147            //System.out.println("root = " + root);
148            fac = new RealAlgebraicRing<BigRational>(idu, root); //,not true);
149            //System.out.println("fac = " + fac);
150        }
151    
152    
153        @Override
154        protected void tearDown() {
155            ComputerThreads.terminate();
156            a = b = c = d = e = null;
157            fac = null;
158        }
159    
160    
161        /**
162         * Test constructor and toString.
163         */
164        public void testConstruction() {
165            c = fac.getONE();
166            //System.out.println("c = " + c);
167            //System.out.println("c.getVal() = " + c.getVal());
168            //assertTrue("length( c ) = 1", c.number.getVal().length() == 1);
169            assertTrue("isZERO( c )", !c.isZERO());
170            assertTrue("isONE( c )", c.isONE());
171    
172            d = fac.getZERO();
173            //System.out.println("d = " + d);
174            //System.out.println("d.getVal() = " + d.getVal());
175            //assertTrue("length( d ) = 0", d.number.getVal().length() == 0);
176            assertTrue("isZERO( d )", d.isZERO());
177            assertTrue("isONE( d )", !d.isONE());
178        }
179    
180    
181        /**
182         * Test random polynomial.
183         */
184        public void testRandom() {
185            for (int i = 0; i < 7; i++) {
186                a = fac.random(el);
187                //System.out.println("a = " + a);
188                if (a.isZERO() || a.isONE()) {
189                    continue;
190                }
191                // fac.random(rl+i, kl*(i+1), ll+2*i, el+i, q );
192                //assertTrue("length( a" + i + " ) <> 0", a.number.getVal().length() >= 0);
193                assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
194                assertTrue(" not isONE( a" + i + " )", !a.isONE());
195            }
196        }
197    
198    
199        /**
200         * Test real and imaginary.
201         */
202        public void testReIm() {
203            //System.out.println("fac = " + fac.toScript());
204            a = fac.random(ll);
205            b = fac.random(ll);
206            //a = fac.getZERO();
207            //a = fac.getONE();
208            //a = fac.parse("x");
209            //a = fac.parse("y^3 + 2");
210            //a = fac.parse("3 y^2");
211            //b = fac.parse("y");
212            //System.out.println("a = " + a);
213            //System.out.println("b = " + b);
214    
215            ComplexRing<RealAlgebraicNumber<BigRational>> crr;
216            crr = new ComplexRing<RealAlgebraicNumber<BigRational>>(fac);
217    
218            Complex<RealAlgebraicNumber<BigRational>> ac, bc, cc, dc, ec;
219            cc = new Complex<RealAlgebraicNumber<BigRational>>(crr, a, b);
220            //System.out.println("cc = " + cc);
221            assertEquals("a == re(c)", a, cc.getRe());
222            assertEquals("b == im(c)", b, cc.getIm());
223    
224            dc = cc.conjugate();
225            ec = dc.conjugate();
226            //System.out.println("dc = " + dc);
227            //System.out.println("ec = " + ec);
228            assertEquals("con(con(c)) = c", cc, ec);
229    
230            ac = cc.multiply(dc);
231            ec = cc.norm();
232            //System.out.println("ac = " + ac);
233            //System.out.println("ec = " + ec);
234    
235            c = ac.getRe();
236            e = ec.getRe();
237            //System.out.println("c = " + c);
238            //System.out.println("e = " + e);
239            assertEquals("c*con(c) = norm(c)", c, e);
240    
241            c = ac.getIm();
242            e = ec.getIm();
243            //System.out.println("c = " + c);
244            //System.out.println("e = " + e);
245            assertEquals("c*con(c) = norm(c)", c, e);
246        }
247    
248    
249        /**
250         * Test addition.
251         */
252        public void testAddition() {
253            a = fac.random(ll);
254            b = fac.random(ll);
255    
256            c = a.sum(b);
257            d = c.subtract(b);
258            assertEquals("a+b-b = a", a, d);
259    
260            c = a.sum(b);
261            d = b.sum(a);
262            assertEquals("a+b = b+a", c, d);
263    
264            c = fac.random(ll);
265            d = c.sum(a.sum(b));
266            e = c.sum(a).sum(b);
267            assertEquals("c+(a+b) = (c+a)+b", d, e);
268    
269            c = a.sum(fac.getZERO());
270            d = a.subtract(fac.getZERO());
271            assertEquals("a+0 = a-0", c, d);
272    
273            c = fac.getZERO().sum(a);
274            d = fac.getZERO().subtract(a.negate());
275            assertEquals("0+a = 0+(-a)", c, d);
276        }
277    
278    
279        /**
280         * Test object multiplication.
281         */
282        public void testMultiplication() {
283            a = fac.random(ll);
284            assertTrue("not isZERO( a )", !a.isZERO());
285    
286            b = fac.random(ll);
287            assertTrue("not isZERO( b )", !b.isZERO());
288    
289            c = b.multiply(a);
290            d = a.multiply(b);
291            assertTrue("not isZERO( c )", !c.isZERO());
292            assertTrue("not isZERO( d )", !d.isZERO());
293    
294            //System.out.println("a = " + a);
295            //System.out.println("b = " + b);
296            e = d.subtract(c);
297            assertTrue("isZERO( a*b-b*a ) " + e, e.isZERO());
298    
299            assertTrue("a*b = b*a", c.equals(d));
300            assertEquals("a*b = b*a", c, d);
301    
302            c = fac.random(ll);
303            //System.out.println("c = " + c);
304            d = a.multiply(b.multiply(c));
305            e = (a.multiply(b)).multiply(c);
306    
307            //System.out.println("d = " + d);
308            //System.out.println("e = " + e);
309    
310            //System.out.println("d-e = " + d.subtract(c) );
311    
312            assertEquals("a(bc) = (ab)c", d, e);
313            assertTrue("a(bc) = (ab)c", d.equals(e));
314    
315            c = a.multiply(fac.getONE());
316            d = fac.getONE().multiply(a);
317            assertEquals("a*1 = 1*a", c, d);
318    
319    
320            c = a.inverse();
321            d = c.multiply(a);
322            //System.out.println("a = " + a);
323            //System.out.println("c = " + c);
324            //System.out.println("d = " + d);
325            assertEquals("a*1/a = 1", fac.getONE(), d);
326    
327            try {
328                a = fac.getZERO().inverse();
329                fail("0 invertible");
330            } catch (NotInvertibleException expected) {
331                //pass, return;
332            }
333        }
334    
335    
336        /**
337         * Test distributive law.
338         */
339        public void testDistributive() {
340            a = fac.random(ll);
341            b = fac.random(ll);
342            c = fac.random(ll);
343    
344            d = a.multiply(b.sum(c));
345            e = a.multiply(b).sum(a.multiply(c));
346    
347            assertEquals("a(b+c) = ab+ac", d, e);
348        }
349    
350    
351        /**
352         * Test signum and magnitude.
353         */
354        public void testSignum() {
355            a = fac.random(ll);
356            //a = fac.getONE();
357            //System.out.println("a = " + a);
358    
359            int s = a.signum();
360            //System.out.println("sign(a) = " + s);
361            assertTrue("isZERO( c )", (a.isZERO() && s == 0) || (!a.isZERO() && s != 0));
362    
363            BigDecimal r = a.decimalMagnitude();
364            //System.out.println("magnitude(a)              = " + r);
365    
366            b = a.multiply(a);
367            BigDecimal rb = b.decimalMagnitude();
368            //System.out.println("magnitude(a*a)            = " + rb);
369            BigDecimal rr = r.multiply(r);
370            //System.out.println("magnitude(a)*magnitude(a) = " + rr);
371            BigDecimal eps = Power.positivePower(new BigDecimal(0.1), 9); //BigDecimal.DEFAULT_PRECISION);
372            //System.out.println("eps                       = " + eps);
373            BigDecimal err = rr.subtract(rb).divide(rr).abs();
374            //System.out.println("err                       = " + err);
375            assertTrue("magnitude(a)*magnitude(a) == magnitude(a*a): " + err + " <= " + eps,
376                            err.compareTo(eps) <= 0);
377        }
378    
379    
380        /**
381         * Test compareTo of complex algebraic numbers.
382         */
383        public void testCompare() {
384            a = fac.random(ll).abs();
385            b = a.sum(fac.getONE());
386            c = b.sum(fac.getONE());
387    
388            int ab = a.compareTo(b);
389            int bc = b.compareTo(c);
390            int ac = a.compareTo(c);
391    
392            assertTrue("a < a+1 ", ab < 0);
393            assertTrue("a+1 < a+2 ", bc < 0);
394            assertTrue("a < a+2 ", ac < 0);
395    
396            a = a.negate();
397            b = a.sum(fac.getONE());
398            c = b.sum(fac.getONE());
399    
400            ab = a.compareTo(b);
401            bc = b.compareTo(c);
402            ac = a.compareTo(c);
403    
404            assertTrue("a < a+1 ", ab < 0);
405            assertTrue("a+1 < a+2 ", bc < 0);
406            assertTrue("a < a+2 ", ac < 0);
407        }
408    
409    }