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