001/*
002 * $Id$
003 */
004
005package edu.jas.fd;
006
007
008import edu.jas.arith.BigInteger;
009import edu.jas.arith.BigRational;
010import edu.jas.kern.ComputerThreads;
011import edu.jas.poly.GenPolynomial;
012import edu.jas.poly.GenSolvablePolynomial;
013import edu.jas.poly.GenSolvablePolynomialRing;
014import edu.jas.poly.PolyUtil;
015import edu.jas.poly.RecSolvablePolynomial;
016import edu.jas.poly.RecSolvablePolynomialRing;
017import edu.jas.poly.RelationGenerator;
018import edu.jas.poly.TermOrder;
019import edu.jas.poly.WeylRelationsIterated;
020
021import junit.framework.Test;
022import junit.framework.TestCase;
023import junit.framework.TestSuite;
024
025
026/**
027 * FDUtil tests with JUnit.
028 * @author Heinz Kredel
029 */
030
031public class FDUtilTest extends TestCase {
032
033
034    /**
035     * main.
036     */
037    public static void main(String[] args) {
038        junit.textui.TestRunner.run(suite());
039        ComputerThreads.terminate();
040    }
041
042
043    /**
044     * Constructs a <CODE>FDUtilTest</CODE> object.
045     * @param name String.
046     */
047    public FDUtilTest(String name) {
048        super(name);
049    }
050
051
052    /**
053     */
054    public static Test suite() {
055        TestSuite suite = new TestSuite(FDUtilTest.class);
056        return suite;
057    }
058
059
060    TermOrder to = new TermOrder(TermOrder.INVLEX);
061
062
063    GenSolvablePolynomialRing<BigInteger> dfac;
064
065
066    GenSolvablePolynomialRing<BigRational> rdfac;
067
068
069    GenSolvablePolynomialRing<GenPolynomial<BigInteger>> rfac;
070
071
072    GenSolvablePolynomialRing<GenPolynomial<BigRational>> rrfac;
073
074
075    RecSolvablePolynomialRing<BigRational> rsfac;
076
077
078    GenSolvablePolynomial<BigInteger> a, b, c, d, e, f;
079
080
081    GenSolvablePolynomial<GenPolynomial<BigInteger>> ar, br, cr, dr, er, fr;
082
083
084    GenSolvablePolynomial<GenPolynomial<BigRational>> arr, brr, abrr, barr, crr, drr, err, frr, x1;
085
086
087    RecSolvablePolynomial<BigRational> as, bs, cs, ds, es, fs;
088
089
090    int rl = 4;
091
092
093    int kl = 2;
094
095
096    int ll = 4;
097
098
099    int el = 3;
100
101
102    float q = 0.35f;
103
104
105    @Override
106    protected void setUp() {
107        a = b = c = d = e = null;
108        ar = br = cr = dr = er = null;
109        String[] vars = new String[] { "a", "b", "c", "d" };
110        dfac = new GenSolvablePolynomialRing<BigInteger>(new BigInteger(1), rl, to, vars);
111        RelationGenerator<BigInteger> wl = new WeylRelationsIterated<BigInteger>();
112        dfac.addRelations(wl);
113        rfac = dfac.recursive(1);
114        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), rl, to, vars);
115        RelationGenerator<BigRational> wlr = new WeylRelationsIterated<BigRational>();
116        rdfac.addRelations(wlr);
117        rrfac = rdfac.recursive(1);
118    }
119
120
121    @Override
122    protected void tearDown() {
123        a = b = c = d = e = null;
124        ar = br = cr = dr = er = null;
125        dfac = null;
126        rfac = null;
127    }
128
129
130    /**
131     * Test base pseudo division.
132     */
133    public void testBasePseudoDivisionExact() {
134        //System.out.println("dfac  = " + dfac.toScript());
135        do {
136            a = dfac.random(kl, ll + 1, el, q);
137        } while (a.isZERO());
138        //a = dfac.parse(" 3 x^5 + 44 ");
139        //System.out.println("a = " + a);
140
141        do {
142            b = dfac.random(kl, ll + 1, el, q);
143        } while (b.isZERO());
144        //a = a.sum(b);
145        //b = dfac.parse(" 2 x^2 + 40 ");
146        //System.out.println("b = " + b);
147
148        // non commutative
149        c = b.multiply(a);
150        d = a.multiply(b);
151        //System.out.println("c = " + c);
152        //System.out.println("d = " + d);
153        assertTrue("c != 0: ", !c.isZERO());
154        assertTrue("d != 0: ", !d.isZERO());
155
156        assertTrue("a*b != b*a", !c.equals(d) || c.leadingExpVector().equals(d.leadingExpVector()));
157
158        // divide 
159        e = FDUtil.<BigInteger> leftBasePseudoQuotient(c, a);
160        //System.out.println("e = " + e);
161        assertEquals("b == b*a/a: ", b, e);
162
163        f = FDUtil.<BigInteger> rightBasePseudoQuotient(c, b);
164        //System.out.println("f = " + f);
165        assertEquals("a == b*a/b: ", a, f);
166
167        e = FDUtil.<BigInteger> rightBasePseudoQuotient(d, a);
168        //System.out.println("e = " + e);
169        assertEquals("b == a*b/a: ", b, e);
170
171        f = FDUtil.<BigInteger> leftBasePseudoQuotient(d, b);
172        //System.out.println("f = " + f);
173        assertEquals("a == a*b/b: ", a, f);
174    }
175
176
177    /**
178     * Test base pseudo division.
179     */
180    @SuppressWarnings({ "cast" })
181    public void testBasePseudoDivision() {
182        String[] names = new String[] { "x" };
183        dfac = new GenSolvablePolynomialRing<BigInteger>(new BigInteger(1), to, names);
184        GenSolvablePolynomialRing<BigRational> rdfac;
185        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), dfac);
186        //System.out.println("dfac  = " + dfac.toScript());
187
188        do {
189            a = dfac.random(kl, ll * 2, el + 1, q);
190        } while (a.isZERO());
191        //a = dfac.parse(" 3 x^5 + 44 ");
192        //System.out.println("a = " + a);
193
194        do {
195            b = dfac.random(kl, ll * 2, el + 1, q);
196        } while (b.isZERO());
197        //a = a.sum(b);
198        //b = dfac.parse(" 2 x^2 + 40 ");
199        //System.out.println("b = " + b);
200
201        GenPolynomial<BigInteger>[] QR = PolyUtil.<BigInteger> basePseudoQuotientRemainder(a, b);
202        c = (GenSolvablePolynomial<BigInteger>) QR[0];
203        d = (GenSolvablePolynomial<BigInteger>) QR[1];
204        //System.out.println("c   = " + c);
205        //System.out.println("d   = " + d);
206
207        boolean t = PolyUtil.<BigInteger> isBasePseudoQuotientRemainder(a, b, c, d);
208        assertTrue("lc^n c = e b + f: " + f, t);
209
210        GenSolvablePolynomial<BigInteger>[] QRs = FDUtil.<BigInteger> leftBasePseudoQuotientRemainder(a, b);
211        e = QRs[0];
212        f = QRs[1];
213        //System.out.println("e   = " + e);
214        //System.out.println("f   = " + f);
215
216        t = PolyUtil.<BigInteger> isBasePseudoQuotientRemainder(a, b, e, f);
217        assertTrue("ore(lc^n) c = e b + f: " + f, t);
218
219        // compare with field coefficients:
220        GenSolvablePolynomial<BigRational> ap, bp, cp, dp, ep, fp, qp, rp, rhs;
221        ap = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, a);
222        bp = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, b);
223        cp = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, c);
224        dp = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, d);
225        ep = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, e);
226        fp = (GenSolvablePolynomial<BigRational>) PolyUtil.<BigRational> fromIntegerCoefficients(rdfac, f);
227        //System.out.println("ap  = " + ap);
228        //System.out.println("bp  = " + bp);
229        //System.out.println("cp  = " + cp);
230        //System.out.println("dp  = " + dp);
231        //System.out.println("ep  = " + ep);
232        //System.out.println("fp  = " + fp);
233
234        qp = (GenSolvablePolynomial<BigRational>) ap.divide(bp);
235        rp = (GenSolvablePolynomial<BigRational>) ap.remainder(bp);
236        //System.out.println("qp  = " + qp);
237        //System.out.println("rp  = " + rp);
238        GenSolvablePolynomial<BigRational>[] QRr = ap.quotientRemainder(bp);
239        assertEquals("qp == QRr[0]: ", qp, QRr[0]);
240        assertEquals("rp == QRr[1]: ", rp, QRr[1]);
241
242        rhs = (GenSolvablePolynomial<BigRational>) qp.multiply(bp).sum(rp);
243        //System.out.println("qp bp + rp  = " + rhs);
244        assertEquals("ap == qp bp + rp: ", ap, rhs);
245
246        assertEquals("cp == qp: ", qp.monic(), cp.monic());
247        assertEquals("dp == rp: ", rp.monic(), dp.monic());
248        //System.out.println("dp = qp: " + qp.monic().equals(dp.monic()) );
249        assertEquals("ep == qp: ", ep.monic(), cp.monic());
250        assertEquals("fp == rp: ", fp.monic(), dp.monic());
251    }
252
253
254    /**
255     * Test recursive pseudo division.
256     * @see edu.jas.ufd.PolyUfdUtilTest#testRecursivePseudoDivisionSparse
257     */
258    public void testRecursivePseudoDivision() {
259        //String[] cnames = new String[] { "x" };
260        //String[] mnames = new String[] { "t" };
261        String[] names = new String[] { "t", "x", "y", "z" };
262        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), to, names);
263        RelationGenerator<BigRational> wl = new WeylRelationsIterated<BigRational>();
264        rdfac.addRelations(wl);
265        rsfac = (RecSolvablePolynomialRing<BigRational>) rdfac.recursive(1);
266
267        // q = q;
268        kl = 1;
269        ll = 3;
270
271        arr = rrfac.random(kl, ll, el, q);
272        //arr = rrfac.parse(" ( t + x + y ) z^2 + ( 2 x - 8 ) y^2 - ( 13 t^4 - 13 t^3 + t^2 + 2 t - 13 ) ");
273        brr = rrfac.random(kl, ll, el, q);
274        if (brr.isZERO()) {
275            brr = rrfac.parse(" ( x - 2 ) z - ( t - y^2 + y ) ");
276        }
277        //System.out.println("FDQR: arr  = " + arr);
278        //System.out.println("FDQR: brr  = " + brr);
279
280        drr = FDUtil.<BigRational> recursivePseudoQuotient(arr, brr);
281        crr = FDUtil.<BigRational> recursiveSparsePseudoRemainder(arr, brr);
282        //System.out.println("FDQR: qr  = " + drr);
283        //System.out.println("FDQR: rr  = " + crr);
284
285        GenSolvablePolynomial<GenPolynomial<BigRational>>[] QR;
286        QR = FDUtil.<BigRational> recursivePseudoQuotientRemainder(arr, brr);
287        assertEquals("drr == QR[0]: ", drr, QR[0]);
288        assertEquals("crr == QR[1]: ", crr, QR[1]);
289
290        boolean t = FDUtil.<BigRational> isRecursivePseudoQuotientRemainder(arr, brr, drr, crr);
291        //System.out.println("FDQR: ore(lc^n) a == q b + r: " + t);
292        assertTrue("ore(lc^n) a = q b + r: " + crr, t); // ?? 
293    }
294
295
296    /**
297     * Test recursive division coefficient polynomial.
298     */
299    public void testLeftAndRightRecursiveDivision() {
300        //String[] names = new String[] { "t", "x", "y", "z" };
301        String[] names = new String[] { "y", "z" };
302        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), to, names);
303        RelationGenerator<BigRational> wl = new WeylRelationsIterated<BigRational>();
304        rdfac.addRelations(wl);
305        rrfac = rdfac.recursive(1);
306        //System.out.println("\nrdfac  = " + rdfac.toScript());
307        //System.out.println("rrfac  = " + rrfac.toScript());
308        GenSolvablePolynomial<GenPolynomial<BigRational>>[] QR;
309        boolean t;
310
311        // q = q;
312        kl = 2;
313        ll = 4;
314        el = 5;
315
316        arr = rrfac.random(kl, ll, el + 1, q);
317        //arr = rrfac.parse("z^5 - ( 1260/551 y^2 - 143/35 y - 33/100  ) z - ( 1/3 y^2 + 419/299 y - 19/56  )");
318        // b * q + r:
319        //arr = rrfac.parse("z^5 + z^2 - 1");
320        //System.out.println("arr  = " + arr);
321
322        brr = rrfac.random(kl, ll, el, q);
323        //brr = rrfac.parse("z^3 - ( 377/140 y^2 + 211/232 y + 1213967/85560  )");
324        //brr = rrfac.parse("( y ) z^3 - ( 1 ) z + ( 2 )");
325        //System.out.println("brr  = " + brr);
326
327        abrr = arr.multiply(brr);
328        //System.out.println("abrr  = " + abrr);
329
330        // exact left division
331        drr = FDUtil.<BigRational> recursivePseudoQuotient(abrr, brr);
332        crr = FDUtil.<BigRational> recursiveSparsePseudoRemainder(abrr, brr);
333        //System.out.println("drr  = " + drr);
334        //System.out.println("crr  = " + crr);
335
336        QR = FDUtil.<BigRational> recursivePseudoQuotientRemainder(abrr, brr);
337        assertEquals("drr == QR[0]: ", drr, QR[0]);
338        assertEquals("crr == QR[1]: ", crr, QR[1]);
339
340        //t = PolyUtil.<BigRational> isRecursivePseudoQuotientRemainder(arr, brr, drr, crr);
341        t = FDUtil.<BigRational> isRecursivePseudoQuotientRemainder(abrr, brr, drr, crr);
342        //System.out.println("FDQR: ore(lc^n) a == q b + r: " + t);
343        assertTrue("ore(lc^n) a = q b + r: " + crr, t); // ?? 
344
345        barr = brr.multiply(arr);
346        //System.out.println("barr  = " + barr);
347
348        // exact right division
349        QR = FDUtil.<BigRational> recursiveRightPseudoQuotientRemainder(barr, brr);
350        drr = QR[0];
351        crr = QR[1];
352        //System.out.println("drr  = " + drr);
353        //System.out.println("crr  = " + crr);
354        //assertEquals("drr == QR[0]: ", drr, QR[0]);
355        //assertEquals("crr == QR[1]: ", crr, QR[1]);
356
357        t = FDUtil.<BigRational> isRecursiveRightPseudoQuotientRemainder(barr, brr, drr, crr);
358        //System.out.println("FDQR: a ore(lc^n) == q b + r: " + t);
359        assertTrue("a ore(lc^n) = q b + r: " + crr, t); // ?? 
360
361        // left division
362        QR = FDUtil.<BigRational> recursivePseudoQuotientRemainder(arr, brr);
363        drr = QR[0];
364        crr = QR[1];
365        t = FDUtil.<BigRational> isRecursivePseudoQuotientRemainder(arr, brr, drr, crr);
366        //System.out.println("drr  = " + drr);
367        //System.out.println("crr  = " + crr);
368        assertTrue("ore(lc^n) a = b q + r: " + crr, t); // ?? 
369
370        // right division
371        QR = FDUtil.<BigRational> recursiveRightPseudoQuotientRemainder(arr, brr);
372        drr = QR[0];
373        crr = QR[1];
374        t = FDUtil.<BigRational> isRecursiveRightPseudoQuotientRemainder(arr, brr, drr, crr);
375        //System.out.println("drr  = " + drr);
376        //System.out.println("crr  = " + crr);
377        assertTrue("ore(lc^n) a = q p + r: " + crr, t); // ?? 
378    }
379
380
381    /**
382     * Test recursive right coefficient polynomial.
383     */
384    @SuppressWarnings("unchecked")
385    public void testRightRecursivePolynomial() {
386        //String[] names = new String[] { "t", "x", "y", "z" };
387        String[] names = new String[] { "y", "z" };
388        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), to, names);
389        RelationGenerator<BigRational> wl = new WeylRelationsIterated<BigRational>();
390        rdfac.addRelations(wl);
391        rrfac = rdfac.recursive(1);
392        //System.out.println("\nrdfac  = " + rdfac.toScript());
393        //System.out.println("rrfac  = " + rrfac.toScript());
394        //GenSolvablePolynomialRing<BigRational> cfac = (GenSolvablePolynomialRing) rrfac.coFac;
395        //System.out.println("cfac  = " + cfac.toScript());
396
397        // q = q;
398        kl = 3;
399        ll = 4;
400        el = 5;
401
402        arr = rrfac.random(kl, ll, el, q);
403        //arr = rrfac.parse(" z { y } ");
404        //System.out.println("FDQR: arr  = " + arr);
405
406        brr = arr.rightRecursivePolynomial();
407        //System.out.println("FDQR: brr  = " + brr);
408
409        boolean t = arr.isRightRecursivePolynomial(brr);
410        assertTrue("arr == eval(brr): ", t);
411
412        GenSolvablePolynomial<BigRational> c = (GenSolvablePolynomial<BigRational>) rrfac
413                        .random(kl, ll, el, q).leadingBaseCoefficient();
414        //c = cfac.parse("y**2");
415        //System.out.println("FDQR: c  = " + c);
416
417        drr = arr.multiply(c); // arr * c = drr
418        //System.out.println("FDQR: drr  = " + drr);
419
420        err = FDUtil.<BigRational> recursiveLeftDivide(drr, c); // err * c = drr
421        //System.out.println("FDQR: err  = " + err);
422        assertEquals("arr == err: ", arr, err);
423
424
425        //System.out.println("\nFDQR: arr  = " + arr);
426        drr = arr.multiplyLeft(c); // c * arr = drr
427        //System.out.println("FDQR: drr  = " + drr);
428
429        err = FDUtil.<BigRational> recursiveRightDivide(drr, c); // c * err = drr
430        //System.out.println("FDQR: err  = " + err);
431        assertEquals("arr == err: ", arr, err);
432    }
433
434
435    /*
436     * Test exact division of recursive polynomials.
437     */
438    @SuppressWarnings({ "cast" })
439    public void testRecursiveDivide() {
440        rdfac = new GenSolvablePolynomialRing<BigRational>(new BigRational(1), dfac);
441        RelationGenerator<BigRational> wl = new WeylRelationsIterated<BigRational>();
442        rdfac.addRelations(wl);
443        //System.out.println("rdfac  = " + rdfac.toScript());
444        rsfac = (RecSolvablePolynomialRing<BigRational>) rdfac.recursive(1);
445        //System.out.println("rsfac  = " + rsfac.toScript());
446
447        assertFalse("isCommutative()", rsfac.isCommutative());
448        assertTrue("isAssociative()", rsfac.isAssociative());
449
450        do {
451            as = rsfac.random(kl, ll, el, q);
452        } while (as.isZERO());
453        //System.out.println("as = " + as);
454
455        do {
456            bs = rsfac.random(kl, ll, el, q);
457        } while (bs.isZERO());
458        //System.out.println("bs = " + bs);
459
460        // non commutative
461        cs = bs.multiply(as);
462        ds = as.multiply(bs);
463        //System.out.println("cs = " + cs);
464        //System.out.println("ds = " + ds);
465        assertTrue("cs != 0: ", !cs.isZERO());
466        assertTrue("ds != 0: ", !ds.isZERO());
467
468        //es = (RecSolvablePolynomial<BigRational>) ds.subtract(cs);
469        assertTrue("as*bs != bs*as", !cs.equals(ds) || cs.leadingExpVector().equals(ds.leadingExpVector()));
470
471        // divide 
472        es = (RecSolvablePolynomial<BigRational>) FDUtil.<BigRational> recursivePseudoQuotient(cs, as);
473        //System.out.println("es = " + es);
474        final int max = 4;
475        int i = 0;
476        do {
477            x1 = (RecSolvablePolynomial<BigRational>) bs.multiplyLeft(as.leadingBaseCoefficient().power(i));
478            //System.out.println("lc(a)^"+i+"*b = " + x1);
479            if (es.equals(x1)) {
480                assertEquals("b == b*a/a: ", es, x1);
481                break;
482            }
483            if (es.leadingBaseCoefficient().equals(x1.leadingBaseCoefficient())) {
484                // assertEquals("b == b*a/a: ", e, x1);
485                System.out.println("fail: b == b*a/a: lc(e)==lc(x1)");
486                if (es.abs().equals(bs.abs())) {
487                    System.out.println("success via pseudo: b == b*a/a: ");
488                }
489                break;
490            }
491        } while (i++ < max);
492
493        fs = (RecSolvablePolynomial<BigRational>) FDUtil.<BigRational> recursiveRightPseudoQuotient(cs, bs);
494        //System.out.println("fs = " + fs);
495        i = 0;
496        do {
497            x1 = (RecSolvablePolynomial<BigRational>) as.multiply(bs.leadingBaseCoefficient().power(i));
498            //System.out.println("a*lc(b)^"+i+" = " + x1);
499            if (fs.equals(x1)) {
500                assertEquals("a == b*a/b: ", fs, x1);
501                break;
502            }
503            if (fs.leadingBaseCoefficient().equals(x1.leadingBaseCoefficient())) {
504                System.out.println("fail: a == b*a/b: lc(f)==lc(x1)");
505                if (fs.abs().equals(as.abs())) {
506                    System.out.println("success via pseudo: a == b*a/b: ");
507                }
508                break;
509            }
510        } while (i++ < max);
511
512        es = (RecSolvablePolynomial<BigRational>) FDUtil.<BigRational> recursiveRightPseudoQuotient(ds, as);
513        //System.out.println("es = " + es);
514        i = 0;
515        do {
516            x1 = (RecSolvablePolynomial<BigRational>) bs.multiply(as.leadingBaseCoefficient().power(i));
517            //System.out.println("b*lc(a)^"+i+" = " + x1);
518            if (es.equals(x1)) {
519                assertEquals("b == a*b/a: ", es, x1);
520                break;
521            }
522            if (es.leadingBaseCoefficient().equals(x1.leadingBaseCoefficient())) {
523                System.out.println("fail: b == a*b/a: lc(e) == lc(x1)");
524                if (es.abs().equals(bs.abs())) {
525                    //System.out.println("success via pseudo: b == a*b/a: ");
526                }
527                break;
528            }
529        } while (i++ < max);
530
531        fs = (RecSolvablePolynomial<BigRational>) FDUtil.<BigRational> recursivePseudoQuotient(ds, bs);
532        //System.out.println("fs = " + fs);
533        i = 0;
534        do {
535            x1 = (RecSolvablePolynomial<BigRational>) as.multiplyLeft(bs.leadingBaseCoefficient().power(i));
536            //System.out.println("lc(b)^"+i+"*a = " + x1);
537            if (fs.equals(x1)) {
538                assertEquals("a == a*b/b: ", fs, x1);
539                break;
540            }
541            if (fs.leadingBaseCoefficient().equals(x1.leadingBaseCoefficient())) {
542                System.out.println("fail: a == a*b/b: lc(f)==lc(x1)");
543                if (fs.abs().equals(as.abs())) {
544                    System.out.println("success via pseudo: a == a*b/b: ");
545                }
546                break;
547            }
548        } while (i++ < max);
549    }
550
551}