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