001/*
002 * $Id: GenPolynomialTest.java 5863 2018-07-20 11:13:34Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.util.ArrayList;
009import java.util.Iterator;
010import java.util.List;
011import java.util.Map;
012
013import junit.framework.Test;
014import junit.framework.TestCase;
015import junit.framework.TestSuite;
016
017
018import edu.jas.arith.BigInteger;
019import edu.jas.arith.BigRational;
020import edu.jas.structure.RingElem;
021import edu.jas.structure.UnaryFunctor;
022
023
024/**
025 * GenPolynomial tests with JUnit.
026 * @author Heinz Kredel
027 */
028
029public class GenPolynomialTest extends TestCase {
030
031
032    /**
033     * main
034     */
035    public static void main(String[] args) {
036        junit.textui.TestRunner.run(suite());
037    }
038
039
040    /**
041     * Constructs a <CODE>GenPolynomialTest</CODE> object.
042     * @param name String.
043     */
044    public GenPolynomialTest(String name) {
045        super(name);
046    }
047
048
049    /**
050     * suite.
051     */
052    public static Test suite() {
053        TestSuite suite = new TestSuite(GenPolynomialTest.class);
054        return suite;
055    }
056
057
058    int rl = 6;
059
060
061    int kl = 5;
062
063
064    int ll = 7;
065
066
067    int el = 4;
068
069
070    float q = 0.5f;
071
072
073    @Override
074    protected void setUp() {
075    }
076
077
078    @Override
079    protected void tearDown() {
080    }
081
082
083    /**
084     * Test constructors and factory.
085     */
086    public void testConstructors() {
087        // rational numbers
088        BigRational rf = new BigRational();
089        // System.out.println("rf = " + rf);
090
091        //BigRational r = rf.fromInteger( 99 );
092        // System.out.println("r = " + r);
093        //r = rf.random( 9 ).sum(r);
094        // System.out.println("r = " + r);
095        //assertFalse("r.isZERO() = ", r.isZERO());
096
097        //RingElem<BigRational> re = new BigRational( 3 );
098        // System.out.println("re = " + re);
099        //rf = (BigRational) re;
100
101        //RingFactory<BigRational> ref = new BigRational( 3 );
102        // System.out.println("re = " + re);
103        //rf = (BigRational) ref;
104
105        // polynomials over rational numbers
106        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 2);
107        // System.out.println("pf = " + pf);
108
109        GenPolynomial<BigRational> p = pf.getONE();
110        // System.out.println("p = " + p);
111        p = pf.random(9);
112        // System.out.println("p = " + p);
113        p = pf.getZERO();
114        // System.out.println("p = " + p);
115
116        RingElem<GenPolynomial<BigRational>> pe = new GenPolynomial<BigRational>(pf);
117        //System.out.println("pe = " + pe);
118        //System.out.println("p.equals(pe) = " + p.equals(pe) );
119        //System.out.println("p.equals(p) = " + p.equals(p) );
120        assertTrue("p.equals(pe) = ", p.equals(pe));
121        assertTrue("p.equals(p) = ", p.equals(p));
122
123        pe = pe.sum(p); // why not p = p.add(pe) ?
124        //System.out.println("pe = " + pe);
125        assertTrue("pe.isZERO() = ", pe.isZERO());
126        p = pf.random(9);
127        p = p.subtract(p);
128        //System.out.println("p = " + p);
129        //System.out.println("p.isZERO() = " + p.isZERO());
130        assertTrue("p.isZERO() = ", p.isZERO());
131
132        // polynomials over (polynomials over rational numbers)
133        GenPolynomialRing<GenPolynomial<BigRational>> ppf = new GenPolynomialRing<GenPolynomial<BigRational>>(
134                        pf, 3);
135        // System.out.println("ppf = " + ppf);
136
137        GenPolynomial<GenPolynomial<BigRational>> pp = ppf.getONE();
138        // System.out.println("pp = " + pp);
139        pp = ppf.random(2);
140        // System.out.println("pp = " + pp);
141        pp = ppf.getZERO();
142        // System.out.println("pp = " + pp);
143
144        RingElem<GenPolynomial<GenPolynomial<BigRational>>> ppe = new GenPolynomial<GenPolynomial<BigRational>>(
145                        ppf);
146        // System.out.println("ppe = " + ppe);
147        // System.out.println("pp.equals(ppe) = " + pp.equals(ppe) );
148        // System.out.println("pp.equals(pp) = " + pp.equals(pp) );
149        assertTrue("pp.equals(ppe) = ", pp.equals(ppe));
150        assertTrue("pp.equals(pp) = ", pp.equals(pp));
151
152        ppe = ppe.sum(pp); // why not pp = pp.add(ppe) ?
153        //System.out.println("ppe = " + ppe);
154        assertTrue("ppe.isZERO() = ", ppe.isZERO());
155        pp = ppf.random(2);
156        pp = pp.subtract(pp);
157        //System.out.println("pp = " + pp);
158        //System.out.println("pp.isZERO() = " + pp.isZERO());
159        assertTrue("pp.isZERO() = ", pp.isZERO());
160
161        // polynomials over (polynomials over (polynomials over rational numbers))
162        GenPolynomialRing<GenPolynomial<GenPolynomial<BigRational>>> pppf = new GenPolynomialRing<GenPolynomial<GenPolynomial<BigRational>>>(
163                        ppf, 4);
164        // System.out.println("pppf = " + pppf);
165
166        GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>> ppp = pppf.getONE();
167        //System.out.println("ppp = " + ppp);
168        ppp = pppf.random(2);
169        // System.out.println("ppp = " + ppp);
170        ppp = pppf.getZERO();
171        // System.out.println("ppp = " + ppp);
172
173        RingElem<GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>>> pppe = new GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>>(
174                        pppf);
175        // System.out.println("pppe = " + pppe);
176        // System.out.println("ppp.equals(pppe) = " + ppp.equals(pppe) );
177        // System.out.println("ppp.equals(ppp) = " + ppp.equals(ppp) );
178        assertTrue("ppp.equals(pppe) = ", ppp.equals(pppe));
179        assertTrue("ppp.equals(ppp) = ", ppp.equals(ppp));
180
181        pppe = pppe.sum(ppp); // why not ppp = ppp.add(pppe) ?
182        // System.out.println("pppe = " + pppe);
183        assertTrue("pppe.isZERO() = ", pppe.isZERO());
184        ppp = pppf.random(2);
185        ppp = ppp.subtract(ppp);
186        // System.out.println("ppp = " + ppp);
187        // System.out.println("ppp.isZERO() = " + ppp.isZERO());
188        assertTrue("ppp.isZERO() = ", ppp.isZERO());
189
190        // some tests
191        //GenPolynomial<BigRational> pfx = new GenPolynomial<BigRational>();
192        //System.out.println("pfx = " + pfx);
193    }
194
195
196    /**
197     * Test extension and contraction.
198     */
199    public void testExtendContract() {
200        // rational numbers
201        BigRational cf = new BigRational(99);
202        // System.out.println("cf = " + cf);
203
204        // polynomials over rational numbers
205        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(cf, rl);
206        // System.out.println("pf = " + pf);
207
208        GenPolynomial<BigRational> a = pf.random(kl, ll, el, q);
209        //System.out.println("a = " + a);
210
211        int k = rl;
212        GenPolynomialRing<BigRational> pfe = pf.extend(k);
213        GenPolynomialRing<BigRational> pfec = pfe.contract(k);
214        assertEquals("pf == pfec", pf, pfec);
215
216        GenPolynomial<BigRational> ae = a.extend(pfe, 0, 0);
217
218        Map<ExpVector, GenPolynomial<BigRational>> m = ae.contract(pfec);
219        List<GenPolynomial<BigRational>> ml = new ArrayList<GenPolynomial<BigRational>>(m.values());
220        GenPolynomial<BigRational> aec = ml.get(0);
221        assertEquals("a == aec", a, aec);
222        //System.out.println("ae = " + ae);
223        //System.out.println("aec = " + aec);
224    }
225
226
227    /**
228     * Test reversion.
229     */
230    public void testReverse() {
231        // rational numbers
232        BigRational cf = new BigRational(99);
233        // System.out.println("cf = " + cf);
234
235        // polynomials over rational numbers
236        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(cf, rl);
237        //System.out.println("pf = " + pf);
238
239        GenPolynomial<BigRational> a = pf.random(kl, ll, el, q);
240        //System.out.println("a = " + a);
241
242        GenPolynomialRing<BigRational> pfr = pf.reverse();
243        GenPolynomialRing<BigRational> pfrr = pfr.reverse();
244        assertEquals("pf == pfrr", pf, pfrr);
245        //System.out.println("pfr = " + pfr);
246
247        GenPolynomial<BigRational> ar = a.reverse(pfr);
248        GenPolynomial<BigRational> arr = ar.reverse(pfrr);
249        assertEquals("a == arr", a, arr);
250        //System.out.println("ar = " + ar);
251        //System.out.println("arr = " + arr);
252    }
253
254
255    /**
256     * Test accessors.
257     */
258    public void testAccessors() {
259        // rational numbers
260        BigRational rf = new BigRational();
261        // System.out.println("rf = " + rf);
262
263        // polynomials over rational numbers
264        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, rl);
265        // System.out.println("pf = " + pf);
266
267        // test 1
268        GenPolynomial<BigRational> p = pf.getONE();
269        // System.out.println("p = " + p);
270
271        ExpVector e = p.leadingExpVector();
272        BigRational c = p.leadingBaseCoefficient();
273
274        GenPolynomial<BigRational> f = new GenPolynomial<BigRational>(pf, c, e);
275        assertEquals("1 == 1 ", p, f);
276
277        GenPolynomial<BigRational> r = p.reductum();
278        assertTrue("red(1) == 0 ", r.isZERO());
279
280        // test 0
281        p = pf.getZERO();
282        // System.out.println("p = " + p);
283        e = p.leadingExpVector();
284        c = p.leadingBaseCoefficient();
285
286        f = new GenPolynomial<BigRational>(pf, c, e);
287        assertEquals("0 == 0 ", p, f);
288
289        r = p.reductum();
290        assertTrue("red(0) == 0 ", r.isZERO());
291
292        // test random
293        p = pf.random(kl, 2 * ll, el, q);
294        // System.out.println("p = " + p);
295        e = p.leadingExpVector();
296        c = p.leadingBaseCoefficient();
297        r = p.reductum();
298
299        f = new GenPolynomial<BigRational>(pf, c, e);
300        f = r.sum(f);
301        assertEquals("p == lm(f)+red(f) ", p, f);
302
303        // test iteration over random
304        GenPolynomial<BigRational> g;
305        g = p;
306        f = pf.getZERO();
307        while (!g.isZERO()) {
308            e = g.leadingExpVector();
309            c = g.leadingBaseCoefficient();
310            //System.out.println("c e = " + c + " " + e);
311            r = g.reductum();
312            f = f.sum(c, e);
313            g = r;
314        }
315        assertEquals("p == lm(f)+lm(red(f))+... ", p, f);
316    }
317
318
319    /**
320     * Test homogeneous.
321     */
322    public void testHomogeneous() {
323        // rational numbers
324        BigRational rf = new BigRational();
325        // System.out.println("rf = " + rf);
326
327        // polynomials over rational numbers
328        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 2); //rl);
329        // System.out.println("pf = " + pf);
330
331        // test 1
332        GenPolynomial<BigRational> p = pf.getONE();
333        // System.out.println("p = " + p);
334        assertTrue("1 is homogeneous " + p, p.isHomogeneous());
335
336        // test 0
337        p = pf.getZERO();
338        // System.out.println("p = " + p);
339        assertTrue("0 is homogeneous " + p, p.isHomogeneous());
340
341        // test random
342        p = pf.random(kl, 2 * ll, el, q);
343        //p = pf.random(kl,ll,el,q);
344        //System.out.println("p = " + p);
345        assertFalse("rnd is homogeneous " + p, p.isHomogeneous());
346
347        // make homogeneous
348        GenPolynomialRing<BigRational> pfh = pf.extend(1);
349        //System.out.println("pfh = " + pfh);
350        // remove block order
351        TermOrder to = new TermOrder(TermOrder.IGRLEX);
352        pfh = new GenPolynomialRing<BigRational>(pfh, to);
353        //System.out.println("pfh = " + pfh);
354
355        GenPolynomial<BigRational> ph = p.homogenize(pfh);
356        //System.out.println("ph = " + ph);
357        assertTrue("ph is homogeneous " + ph, ph.isHomogeneous());
358        GenPolynomial<BigRational> ps = ph.deHomogenize(pf);
359        //System.out.println("ps = " + ps);
360        assertEquals("phs == p ", ps, p); // findbugs
361        //System.out.println("p is homogeneous = " + p.isHomogeneous());
362        //System.out.println("ph is homogeneous = " + ph.isHomogeneous());
363
364        GenPolynomial<BigRational> s = pf.random(kl, ll, el, q);
365        //System.out.println("s = " + s);
366        assertFalse("rnd is homogeneous " + s, s.isHomogeneous() && !s.isConstant());
367
368        GenPolynomial<BigRational> sh = s.homogenize(pfh);
369        //System.out.println("sh = " + sh);
370        assertTrue("sh is homogeneous " + sh, sh.isHomogeneous());
371        GenPolynomial<BigRational> ss = sh.deHomogenize(pf);
372        //System.out.println("ss = " + ss);
373        assertEquals("ss = s ", ss, s);
374
375        GenPolynomial<BigRational> th = ph.multiply(sh);
376        //System.out.println("th = " + th);
377        assertTrue("th is homogeneous " + th, th.isHomogeneous());
378
379        GenPolynomial<BigRational> t = p.multiply(s);
380        //System.out.println("t = " + t);
381
382        GenPolynomial<BigRational> ts = th.deHomogenize(pf);
383        //System.out.println("ts = " + ts);
384        assertEquals("ts = t ", ts, t);
385    }
386
387
388    /**
389     * Test weight homogeneous.
390     */
391    public void testWeightHomogeneous() {
392        // rational numbers
393        BigRational rf = new BigRational();
394        // System.out.println("rf = " + rf);
395
396        // weight term order
397        long[] weight = new long[] { 2, 3, 4, 5 };
398        TermOrder to = TermOrderByName.weightOrder(weight);
399        // System.out.println("to = " + to);
400
401        // polynomials over rational numbers
402        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 4, to);
403        // System.out.println("pf = " + pf.toScript());
404
405        // test 1
406        GenPolynomial<BigRational> p = pf.getONE();
407        // System.out.println("p = " + p);
408        assertTrue("1 is weight homogeneous " + p, p.isWeightHomogeneous());
409
410        // test 0
411        p = pf.getZERO();
412        // System.out.println("p = " + p);
413        assertTrue("0 is weight homogeneous " + p, p.isWeightHomogeneous());
414
415        // test random
416        p = pf.random(kl, 3 * ll, el, q);
417        // System.out.println("p = " + p);
418        assertFalse("rnd is weight homogeneous " + p, p.isWeightHomogeneous());
419
420        GenPolynomial<BigRational> pl = p.leadingWeightPolynomial();
421        // System.out.println("pl = " + pl);
422        assertTrue("lw(rnd) is weight homogeneous " + pl, pl.isWeightHomogeneous());
423
424        GenPolynomial<BigRational> r = pf.random(kl, 3 * ll, el, q);
425        // System.out.println("r = " + r);
426        assertFalse("rnd is weight homogeneous " + r, r.isWeightHomogeneous());
427
428        GenPolynomial<BigRational> rl = r.leadingWeightPolynomial();
429        // System.out.println("rl = " + rl);
430        assertTrue("lw(rnd) is weight homogeneous " + rl, rl.isWeightHomogeneous());
431
432        GenPolynomial<BigRational> t = pl.multiply(rl);
433        // System.out.println("t = " + t);
434        assertTrue("lw(rnd)*lw(rnd) is weight homogeneous " + t, t.isWeightHomogeneous());
435    }
436
437
438    /**
439     * Test univariate.
440     */
441    public void testUnivariate() {
442        BigInteger rf = new BigInteger();
443        // System.out.println("rf = " + rf);
444
445        // polynomials over integral numbers
446        GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
447        //System.out.println("pf = " + pf);
448
449        GenPolynomial<BigInteger> a, b, c, d;
450
451        // x**1
452        a = pf.univariate(pf.nvar - 1);
453        //System.out.println("a = " + a);
454        assertTrue("deg(a) = 1: ", a.degree() == 1);
455        assertEquals("xi == xi: ", pf.vars[0], a.toString());
456
457        b = pf.univariate(pf.vars[0]);
458        //System.out.println("b = " + b);
459        assertTrue("deg(b) = 1: ", b.degree() == 1);
460        assertEquals("xi == xi: ", pf.vars[0], b.toString());
461
462        c = pf.univariate(0);
463        //System.out.println("c = " + c);
464        assertTrue("deg(c) = 1: ", c.degree() == 1);
465        assertEquals("xi == xi: ", pf.vars[pf.nvar - 1], c.toString());
466
467        d = pf.univariate(pf.vars[pf.nvar - 1]);
468        //System.out.println("d = " + d);
469        assertTrue("deg(c) = 1: ", c.degree() == 1);
470        assertEquals("xi == xi: ", pf.vars[pf.nvar - 1], d.toString());
471
472        // x**7
473        a = pf.univariate(pf.nvar - 1, 7);
474        //System.out.println("a = " + a);
475        assertTrue("deg(a) = 7: ", a.degree() == 7);
476        assertEquals("xi == xi: ", pf.vars[0] + "^7", a.toString());
477
478        b = pf.univariate(pf.vars[0], 7);
479        //System.out.println("b = " + b);
480        assertTrue("deg(b) = 7: ", b.degree() == 7);
481        assertEquals("xi == xi: ", pf.vars[0] + "^7", b.toString());
482
483        c = pf.univariate(0, 7);
484        //System.out.println("c = " + c);
485        assertTrue("deg(c) = 7: ", c.degree() == 7);
486        assertEquals("xi == xi: ", pf.vars[pf.nvar - 1] + "^7", c.toString());
487
488        d = pf.univariate(pf.vars[pf.nvar - 1], 7);
489        //System.out.println("d = " + d);
490        assertTrue("deg(c) = 7: ", c.degree() == 7);
491        assertEquals("xi == xi: ", pf.vars[pf.nvar - 1] + "^7", d.toString());
492    }
493
494
495    /**
496     * Test iterators.
497     */
498    public void testIterators() {
499        // integers
500        BigInteger rf = new BigInteger();
501        // System.out.println("rf = " + rf);
502
503        // polynomials over integral numbers
504        GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
505        // System.out.println("pf = " + pf);
506
507        // random polynomial
508        GenPolynomial<BigInteger> p = pf.random(kl, 2 * ll, el, q);
509        //System.out.println("p = " + p);
510
511        // test monomials
512        for (Monomial<BigInteger> m : p) {
513            //System.out.println("m = " + m);
514            assertFalse("m.c == 0 ", m.coefficient().isZERO());
515            assertFalse("m.e < (0) ", m.exponent().signum() < 0);
516        }
517
518        // test exponents
519        Iterator<ExpVector> et = p.exponentIterator();
520        while (et.hasNext()) {
521            ExpVector e = et.next();
522            //System.out.println("e = " + e);
523            assertFalse("e < (0) ", e.signum() < 0);
524        }
525
526        // test coefficents
527        Iterator<BigInteger> ct = p.coefficientIterator();
528        while (ct.hasNext()) {
529            BigInteger i = ct.next();
530            //System.out.println("i = " + i);
531            assertFalse("i == 0 ", i.isZERO());
532        }
533    }
534
535
536    /**
537     * Test coefficient map function.
538     */
539    public void testMap() {
540        // integers
541        BigInteger rf = new BigInteger();
542        // System.out.println("rf = " + rf);
543
544        // polynomials over integral numbers
545        GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
546        // System.out.println("pf = " + pf);
547
548        // random polynomial
549        GenPolynomial<BigInteger> p = pf.random(kl, 2 * ll, el, q);
550        //System.out.println("p = " + p);
551
552        // test times 1
553        GenPolynomial<BigInteger> q;
554        q = p.map(new Multiply<BigInteger>(rf.getONE()));
555        assertEquals("p == q ", p, q);
556
557        // test times 0
558        q = p.map(new Multiply<BigInteger>(rf.getZERO()));
559        assertTrue("q == 0 ", q.isZERO());
560
561        // test times -1
562        q = p.map(new Multiply<BigInteger>(rf.getONE().negate()));
563        assertEquals("p == q ", p.negate(), q);
564    }
565
566
567    /**
568     * Test bitLength.
569     */
570    public void testBitLength() {
571        // integers
572        BigInteger rf = new BigInteger();
573        // System.out.println("rf = " + rf);
574
575        // polynomials over integral numbers
576        GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, 5);
577        // System.out.println("pf = " + pf);
578
579        GenPolynomial<BigInteger> a, b, c;
580        a = pf.getZERO();
581        assertEquals("blen(0) = 0", 0, a.bitLength());
582
583        a = pf.getONE();
584        assertEquals("blen(1) = 7", 7, a.bitLength());
585
586        // random polynomials
587        a = pf.random(kl, 2 * ll, el, q);
588        //System.out.println("a = " + a);
589        //System.out.println("blen(a) = " + a.bitLength());
590        assertTrue("blen(random) >= 0", 0 <= a.bitLength());
591
592        b = pf.random(kl, 2 * ll, el, q);
593        //System.out.println("b = " + b);
594        //System.out.println("blen(b) = " + b.bitLength());
595        assertTrue("blen(random) >= 0", 0 <= b.bitLength());
596
597        //c = a.multiply(b);
598        c = a.sum(b);
599        //System.out.println("c = " + c);
600        //System.out.println("blen(a)+blen(b) = " + (a.bitLength()+b.bitLength()));
601        //System.out.println("blen(c) = " + c.bitLength());
602        assertTrue("blen(random) >= 0", 0 <= c.bitLength());
603        assertTrue("blen(random)+blen(random) >= blen(random+random)",
604                        a.bitLength() + b.bitLength() >= c.bitLength());
605    }
606
607}
608
609
610/**
611 * Internal scalar multiplication functor.
612 */
613class Multiply<C extends RingElem<C>> implements UnaryFunctor<C, C> {
614
615
616    C x;
617
618
619    public Multiply(C x) {
620        this.x = x;
621    }
622
623
624    public C eval(C c) {
625        return c.multiply(x);
626    }
627}