001/*
002 * $Id$
003 */
004
005package edu.jas.root;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import edu.jas.arith.BigDecimal;
012import edu.jas.arith.BigRational;
013import edu.jas.kern.ComputerThreads;
014import edu.jas.poly.Complex;
015import edu.jas.poly.ComplexRing;
016import edu.jas.poly.GenPolynomial;
017import edu.jas.poly.GenPolynomialRing;
018import edu.jas.poly.PolyUtil;
019import edu.jas.poly.TermOrder;
020import edu.jas.structure.Power;
021
022//import edu.jas.commons.math.Roots;
023
024import junit.framework.Test;
025import junit.framework.TestCase;
026import junit.framework.TestSuite;
027
028
029/**
030 * RootUtil tests with JUnit.
031 * @author Heinz Kredel
032 */
033
034public class RootUtilTest extends TestCase {
035
036
037    /**
038     * main.
039     */
040    public static void main(String[] args) {
041        junit.textui.TestRunner.run(suite());
042    }
043
044
045    /**
046     * Constructs a <CODE>RootUtilTest</CODE> object.
047     * @param name String.
048     */
049    public RootUtilTest(String name) {
050        super(name);
051    }
052
053
054    /**
055     */
056    public static Test suite() {
057        TestSuite suite = new TestSuite(RootUtilTest.class);
058        return suite;
059    }
060
061
062    TermOrder to = new TermOrder(TermOrder.INVLEX);
063
064
065    GenPolynomialRing<BigRational> dfac;
066
067
068    BigRational ai, bi, ci, di, ei, eps;
069
070
071    GenPolynomial<BigRational> a, b, c, d, e;
072
073
074    int rl = 1;
075
076
077    int kl = 3;
078
079
080    int ll = 5;
081
082
083    int el = 7;
084
085
086    float q = 0.7f;
087
088
089    @Override
090    protected void setUp() {
091        a = b = c = d = e = null;
092        ai = bi = ci = di = ei = null;
093        String[] vars = new String[] { "x" };
094        dfac = new GenPolynomialRing<BigRational>(new BigRational(1), rl, to, vars);
095        // eps = new BigRational(1L,1000000L*1000000L*1000000L);
096        eps = Power.positivePower(new BigRational(1L, 10L), BigDecimal.DEFAULT_PRECISION);
097    }
098
099
100    @Override
101    protected void tearDown() {
102        a = b = c = d = e = null;
103        ai = bi = ci = di = ei = null;
104        dfac = null;
105        eps = null;
106        ComputerThreads.terminate();
107    }
108
109
110    /**
111     * Test sign variations.
112     */
113    public void testSignVar() {
114        int[] li = new int[] { 1, 0, 0, -1, 2, 3, 0, 1, 0, 0, 0, -1 };
115
116        List<BigRational> Li = new ArrayList<BigRational>();
117
118        ai = new BigRational();
119
120        for (int i = 0; i < li.length; i++) {
121            bi = ai.fromInteger(li[i]);
122            Li.add(bi);
123        }
124        //System.out.println("Li = " + Li);
125
126        long v = RootUtil.<BigRational> signVar(Li);
127        //System.out.println("v = " + v);
128
129        assertEquals("varSign(Li)", v, 3);
130
131        List<BigRational> Mi = new ArrayList<BigRational>();
132        for (int i = 0; i < 7; i++) {
133            bi = ai.random(kl);
134            Mi.add(bi);
135        }
136        //System.out.println("Mi = " + Mi);
137
138        v = RootUtil.<BigRational> signVar(Mi);
139        //System.out.println("v = " + v);
140        long vv = v;
141
142        assertTrue("varSign(Mi)>=0", v >= 0);
143
144        List<BigRational> Ni = new ArrayList<BigRational>(Mi);
145        Ni.addAll(Li);
146        //System.out.println("Ni = " + Ni);
147
148        v = RootUtil.<BigRational> signVar(Ni);
149        //System.out.println("v = " + v);
150
151        assertTrue("varSign(Mi)>=3", v >= 3 + vv);
152
153        Ni = new ArrayList<BigRational>(Ni);
154        Ni.addAll(Mi);
155        //System.out.println("Ni = " + Ni);
156
157        v = RootUtil.<BigRational> signVar(Ni);
158        //System.out.println("v = " + v);
159
160        assertTrue("varSign(Mi)>=3", v >= 3 + vv);
161    }
162
163
164    /**
165     * Test intervals.
166     */
167    public void testIntervals() {
168        a = dfac.random(kl, ll * 2, el * 2, q);
169        b = dfac.random(kl, ll * 2, el * 2, q);
170        b = b.multiply(b);
171        //System.out.println("a = " + a);
172        //System.out.println("b = " + b);
173
174        RealRootsAbstract<BigRational> rr = new RealRootsSturm<BigRational>();
175
176        ai = rr.realRootBound(a);
177        bi = rr.realRootBound(b);
178        //System.out.println("ai = " + ai);
179        //System.out.println("bi = " + bi);
180
181        Interval<BigRational> v1 = new Interval<BigRational>(ai.negate(), ai);
182        Interval<BigRational> v2 = new Interval<BigRational>(bi.negate(), bi.sum(BigRational.ONE));
183        //System.out.println("v1 = " + v1);
184        //System.out.println("v2 = " + v2);
185
186        Interval<BigRational> v3 = v1.sum(v2);
187        Interval<BigRational> v4 = v1.subtract(v2);
188        Interval<BigRational> v5 = v1.multiply(v2);
189        //System.out.println("v3 = " + v3);
190        //System.out.println("v4 = " + v4);
191        //System.out.println("v5 = " + v5);
192        assertTrue("v1 in v3" , v3.contains(v1));
193        assertTrue("v2 in v3" , v3.contains(v2));
194
195        assertTrue("v1 in v4" , v4.contains(v1));
196        assertTrue("v2 in v4" , v4.contains(v2));
197
198        assertTrue("v3 in v5" , v5.contains(v3));
199        assertTrue("v4 in v5" , v5.contains(v4));
200    }
201
202
203    /**
204     * Test real algebraic factory.
205     */
206    public void testRealAlgebraicFactory() {
207        a = dfac.random(kl, ll * 2, el * 2, q);
208        //a = a.multiply( dfac.univariate(0) );
209        //System.out.println("a = " + a);
210
211        List<RealAlgebraicNumber<BigRational>> lrn = RootFactory.<BigRational> realAlgebraicNumbers(a);
212        //System.out.println("lrn = " + lrn);
213        //assertTrue("#roots >= 0 ", lrn.size() >= 0);
214        assertTrue("#roots >= 0 ", lrn != null);
215        for (RealAlgebraicNumber<BigRational> ra : lrn) {
216            //System.out.println("ra = " + ra.toScript() + " in " + ra.toScriptFactory());
217            assertTrue("f(r) == 0: " + ra, RootFactory.<BigRational> isRoot(a, ra));
218        }
219
220        lrn = RootFactory.<BigRational> realAlgebraicNumbersField(a);
221        //System.out.println("lrn = " + lrn);
222        assertTrue("#roots >= 0 ", lrn != null);
223        for (RealAlgebraicNumber<BigRational> ra : lrn) {
224            //System.out.println("ra = " + ra.toScript() + " in " + ra.toScriptFactory());
225            assertTrue("f(r) == 0: " + ra, RootFactory.<BigRational> isRoot(a, ra));
226        }
227    }
228
229
230    /**
231     * Test complex algebraic factory.
232     */
233    public void testComplexAlgebraicFactory() {
234        a = dfac.random(kl, ll, el, q);
235        //a = a.multiply( dfac.univariate(0) );
236        //System.out.println("a = " + a);
237        ComplexRing<BigRational> cf = new ComplexRing<BigRational>(new BigRational());
238        GenPolynomialRing<Complex<BigRational>> cfac = new GenPolynomialRing<Complex<BigRational>>(cf, dfac);
239
240        GenPolynomial<Complex<BigRational>> ca = PolyUtil.<BigRational> toComplex(cfac, a);
241        //System.out.println("ca = " + ca);
242        List<ComplexAlgebraicNumber<BigRational>> lcn = RootFactory
243            .<BigRational> complexAlgebraicNumbersComplex(ca);
244        //System.out.println("lcn = " + lcn);
245        assertTrue("#roots == deg(a): " + a, lcn.size() == a.degree(0));
246
247        for (ComplexAlgebraicNumber<BigRational> car : lcn) {
248            //System.out.println("car = " + car.toScript() + " in " + car.toScriptFactory());
249            //System.out.println("car = " + car.ring.root);
250            //System.out.println("car = " + car.ring.root.centerApprox() + ", "
251            //        + (Roots.sqrt(new BigDecimal(car.ring.root.rationalLength()))) + ", " + car.ring.root);
252            assertTrue("f(r) == 0: " + car, RootFactory.<BigRational> isRoot(a, car));
253        }
254    }
255
256
257    /**
258     * Test complex rational factory.
259     */
260    public void testComplexRationalFactory() {
261        a = dfac.random(kl, ll, el, q);
262        //a = a.multiply( dfac.univariate(0) );
263        //a = dfac.parse(" 1/8 x^6 - 5/3 x^5 + 3/20 x^4 - 2 x^3 ");
264        //System.out.println("a = " + a);
265
266        List<ComplexAlgebraicNumber<BigRational>> lcn = RootFactory.<BigRational> complexAlgebraicNumbers(a);
267        //System.out.println("lcn = " + lcn);
268        assertTrue("#roots == deg(a): " + a, lcn.size() == a.degree(0));
269
270        for (ComplexAlgebraicNumber<BigRational> car : lcn) {
271            //System.out.println("car = " + car.toScript() + " in " + car.toScriptFactory());
272            //System.out.println("car = " + car.ring.root);
273            //System.out.println("car = " + car.ring.root.centerApprox() + ", "
274            //        + (Roots.sqrt(new BigDecimal(car.ring.root.rationalLength()))) + ", " + car.ring.root);
275            assertTrue("f(r) == 0: " + car, RootFactory.<BigRational> isRoot(a, car));
276        }
277    }
278
279
280    /**
281     * Test algebraic roots, i.e. real and complex algebraic roots.
282     */
283    public void testAlgebraicRoots() {
284        a = dfac.random(kl, ll, el, q);
285        //a = a.multiply( dfac.univariate(0) );
286        //System.out.println("a = " + a);
287
288        AlgebraicRoots<BigRational> lcn = RootFactory.<BigRational> algebraicRoots(a);
289        //System.out.println("lcn = " + lcn.toScript());
290        //System.out.println("lcn = " + lcn.toDecimalScript());
291
292        long r = lcn.real.size() + lcn.complex.size();
293        ////Roots<BigRational> linalg = new Roots<BigRational>();
294        ////List<Complex<BigDecimal>> cd = linalg.complexRoots(a);
295        ////System.out.println("cd = " + cd);
296
297        // some real roots not detected under complex roots // todo
298        assertTrue("#roots == degree(f): " + r, r >= a.degree());
299    }
300
301}