001/*
002 * $Id: PolyUfdUtilTest.java 5844 2018-05-27 20:32:32Z kredel $
003 */
004
005package edu.jas.ufd;
006
007
008import edu.jas.arith.BigInteger;
009import edu.jas.arith.BigRational;
010import edu.jas.arith.ModLong;
011import edu.jas.arith.ModLongRing;
012import edu.jas.arith.ModInteger;
013import edu.jas.arith.ModIntegerRing;
014import edu.jas.kern.ComputerThreads;
015import edu.jas.poly.AlgebraicNumberRing;
016import edu.jas.poly.GenPolynomial;
017import edu.jas.poly.GenPolynomialRing;
018import edu.jas.poly.PolyUtil;
019import edu.jas.poly.TermOrder;
020import edu.jas.poly.TermOrderByName;
021
022import junit.framework.Test;
023import junit.framework.TestCase;
024import junit.framework.TestSuite;
025
026
027/**
028 * PolyUfdUtil tests with JUnit.
029 * @author Heinz Kredel
030 */
031
032public class PolyUfdUtilTest extends TestCase {
033
034
035    /**
036     * main.
037     */
038    public static void main(String[] args) {
039        //BasicConfigurator.configure();
040        junit.textui.TestRunner.run(suite());
041        ComputerThreads.terminate();
042    }
043
044
045    /**
046     * Constructs a <CODE>PolyUtilTest</CODE> object.
047     * @param name String.
048     */
049    public PolyUfdUtilTest(String name) {
050        super(name);
051    }
052
053
054    /**
055     */
056    public static Test suite() {
057        TestSuite suite = new TestSuite(PolyUfdUtilTest.class);
058        return suite;
059    }
060
061
062    TermOrder to = TermOrderByName.INVLEX;
063
064
065    GenPolynomialRing<BigInteger> dfac;
066
067
068    GenPolynomialRing<BigInteger> cfac;
069
070
071    GenPolynomialRing<GenPolynomial<BigInteger>> rfac;
072
073
074    BigInteger ai, bi, ci, di, ei;
075
076
077    GenPolynomial<BigInteger> a, b, c, d, e;
078
079
080    GenPolynomial<GenPolynomial<BigInteger>> ar, br, cr, dr, er;
081
082
083    GenPolynomialRing<BigRational> crfac;
084
085
086    GenPolynomialRing<GenPolynomial<BigRational>> rrfac;
087
088 
089    GenPolynomial<GenPolynomial<BigRational>> arr, brr, crr, drr, err, frr;
090
091
092    int rl = 5;
093
094
095    int kl = 5;
096
097
098    int ll = 5;
099
100
101    int el = 3;
102
103
104    float q = 0.3f;
105
106
107    @Override
108    protected void setUp() {
109        a = b = c = d = e = null;
110        ai = bi = ci = di = ei = null;
111        dfac = new GenPolynomialRing<BigInteger>(new BigInteger(1), rl, to);
112        cfac = new GenPolynomialRing<BigInteger>(new BigInteger(1), rl - 1, to);
113        rfac = new GenPolynomialRing<GenPolynomial<BigInteger>>(cfac, 1, to);
114    }
115
116
117    @Override
118    protected void tearDown() {
119        a = b = c = d = e = null;
120        ai = bi = ci = di = ei = null;
121        dfac = null;
122        cfac = null;
123        rfac = null;
124        ComputerThreads.terminate();
125    }
126
127
128    protected static java.math.BigInteger getPrime1() {
129        long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390)
130        for (int i = 1; i < 60; i++) {
131            prime *= 2;
132        }
133        prime -= 93;
134        //prime = 37;
135        //System.out.println("p1 = " + prime);
136        return new java.math.BigInteger("" + prime);
137    }
138
139
140    protected static java.math.BigInteger getPrime2() {
141        long prime = 2; //2^60-93; // 2^30-35; //19; knuth (2,390)
142        for (int i = 1; i < 30; i++) {
143            prime *= 2;
144        }
145        prime -= 35;
146        //prime = 19;
147        //System.out.println("p1 = " + prime);
148        return new java.math.BigInteger("" + prime);
149    }
150
151
152    /**
153     * Test Kronecker substitution.
154     */
155    public void testKroneckerSubstitution() {
156        for (int i = 0; i < 10; i++) {
157            a = dfac.random(kl, ll * 2, el * 5, q);
158            long d = a.degree() + 1L;
159            //System.out.println("\na        = " + a);
160            //System.out.println("deg(a)+1 = " + d);
161
162            b = PolyUfdUtil.<BigInteger> substituteKronecker(a, d);
163            //System.out.println("b        = " + b);
164
165            c = PolyUfdUtil.<BigInteger> backSubstituteKronecker(dfac, b, d);
166            //System.out.println("c        = " + c);
167            e = a.subtract(c);
168            //System.out.println("e        = " + e);
169            assertTrue("back(subst(a)) = a", e.isZERO());
170        }
171    }
172
173
174    /**
175     * Test algebraic number field.
176     */
177    public void testAlgebraicNumberField() {
178        int deg = 11;
179        // characteristic non zero, small
180        ModLongRing gfp = new ModLongRing(32003);
181        //System.out.println("gfp = " + gfp.toScript());
182        AlgebraicNumberRing<ModLong> gfpq = PolyUfdUtil.<ModLong> algebriacNumberField(gfp, deg);
183        //System.out.println("gfpq = " + gfpq.toScript());
184        assertTrue("gfpq.isField: ", gfpq.isField());
185
186        // characteristic non zero, large
187        ModIntegerRing gfP = new ModIntegerRing(getPrime1());
188        //System.out.println("gfP = " + gfP.toScript());
189        AlgebraicNumberRing<ModInteger> gfPq = PolyUfdUtil.<ModInteger> algebriacNumberField(gfP, deg);
190        //System.out.println("gfPq = " + gfPq.toScript());
191        assertTrue("gfPq.isField: ", gfPq.isField());
192
193        // characteristic zero
194        BigRational q = BigRational.ONE;
195        //System.out.println("q = " + q.toScriptFactory());
196        AlgebraicNumberRing<BigRational> gfqq = PolyUfdUtil.<BigRational> algebriacNumberField(q, deg);
197        //System.out.println("gfqq = " + gfqq.toScript());
198        assertTrue("gfqq.isField: ", gfqq.isField());
199
200        //PolyUfdUtil.<BigRational> ensureFieldProperty(gfqq);
201        //System.out.println("gfqq = " + gfqq);
202        //assertTrue("gfqq.isField: ", gfqq.isField());
203    }
204
205
206    /**
207     * Test recursive dense pseudo division.
208     */
209    public void testRecursivePseudoDivisionDense() {
210        String[] cnames = new String[] { "x" };
211        String[] mnames = new String[] { "t" };
212        dfac = new GenPolynomialRing<BigInteger>(new BigInteger(1), to, cnames);
213        //GenPolynomialRing<BigRational> rdfac = new GenPolynomialRing<BigRational>(new BigRational(1),dfac);
214        rfac = new GenPolynomialRing<GenPolynomial<BigInteger>>(dfac, to, mnames);
215        QuotientRing<BigInteger> qfac = new QuotientRing<BigInteger>(dfac);
216        GenPolynomialRing<Quotient<BigInteger>> rqfac = new GenPolynomialRing<Quotient<BigInteger>>(qfac,
217                        rfac);
218        //System.out.println("\ndfac  = " + dfac);
219        //System.out.println("rdfac = " + rdfac);
220        //System.out.println("rfac  = " + rfac);
221        //System.out.println("qfac  = " + qfac);
222        //System.out.println("rqfac = " + rqfac);
223
224        ar = rfac.random(kl, 2 * ll, el + 4, q);
225        //ar = rfac.parse(" ( -2 x^4 + 8 x^3 - 5 x^2 - x + 6  ) t^3 + ( 2 x - 8  ) t^2 - ( 13 x^4 - 13 x^3 + x^2 + 2 x - 13  ) ");
226        br = rfac.random(kl, 2 * ll, el + 2, q);
227        //ar = ar.multiply(br);
228        //br = rfac.parse(" ( 13 ) t^3 + ( 3 x^2 - 6  ) t - ( 13 x^4 - 8 x^3 + 10 x^2 + 22 x + 21  ) ");
229        //System.out.println("ar   = " + ar);
230        //System.out.println("br   = " + br);
231
232        dr = PolyUtil.<BigInteger> recursivePseudoDivide(ar, br);
233        //System.out.println("qr   = " + dr);
234        cr = PolyUtil.<BigInteger> recursiveDensePseudoRemainder(ar, br);
235        //System.out.println("rr   = " + cr);
236
237        //boolean t = PolyUtil.<BigInteger> isRecursivePseudoQuotientRemainder(ar, br, dr, cr);
238        //System.out.println("assertTrue lc^n a = q b + r: " + t);
239        //assertTrue("lc^n a = q b + r: " + cr, t); // ?? not always true
240
241        GenPolynomial<Quotient<BigInteger>> ap = PolyUfdUtil
242                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, ar);
243        GenPolynomial<Quotient<BigInteger>> bp = PolyUfdUtil
244                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, br);
245        GenPolynomial<Quotient<BigInteger>> cp = PolyUfdUtil
246                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, cr);
247        GenPolynomial<Quotient<BigInteger>> dp = PolyUfdUtil
248                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, dr);
249        //System.out.println("ap  = " + ap);
250        //System.out.println("bp  = " + bp);
251        //System.out.println("cp  = " + cp);
252        ////System.out.println("dp  = " + dp);
253        //System.out.println("dp  = " + dp.monic());
254
255        GenPolynomial<Quotient<BigInteger>> qp = ap.divide(bp);
256        GenPolynomial<Quotient<BigInteger>> rp = ap.remainder(bp);
257        ////System.out.println("qp  = " + qp);
258        //System.out.println("qp  = " + qp.monic());
259        //System.out.println("rp  = " + rp);
260        GenPolynomial<Quotient<BigInteger>> rhs = qp.multiply(bp).sum(rp);
261        //System.out.println("qp bp + rp  = " + rhs);
262
263        assertEquals("ap = qp bp + rp: ", ap, rhs);
264
265        assertEquals("cp = rp: ", rp.monic(), cp.monic());
266        //System.out.println("dp = qp: " + qp.monic().equals(dp.monic()) );
267        assertEquals("dp = qp: ", qp.monic(), dp.monic()); // ??
268    }
269
270
271    /**
272     * Test recursive sparse pseudo division.
273     */
274    public void testRecursivePseudoDivisionSparse() {
275        String[] cnames = new String[] { "x" };
276        String[] mnames = new String[] { "t" };
277        dfac = new GenPolynomialRing<BigInteger>(new BigInteger(1), to, cnames);
278        //GenPolynomialRing<BigRational> rdfac = new GenPolynomialRing<BigRational>(new BigRational(1),dfac);
279        rfac = new GenPolynomialRing<GenPolynomial<BigInteger>>(dfac, to, mnames);
280        QuotientRing<BigInteger> qfac = new QuotientRing<BigInteger>(dfac);
281        GenPolynomialRing<Quotient<BigInteger>> rqfac = new GenPolynomialRing<Quotient<BigInteger>>(qfac,
282                        rfac);
283        //System.out.println("\ndfac  = " + dfac);
284        //System.out.println("rdfac = " + rdfac);
285        //System.out.println("rfac  = " + rfac);
286        //System.out.println("qfac  = " + qfac);
287        //System.out.println("rqfac = " + rqfac);
288
289        ar = rfac.random(kl, 2 * ll, el + 4, q);
290        //ar = rfac.parse(" ( -2 x^4 + 8 x^3 - 5 x^2 - x + 6  ) t^3 + ( 2 x - 8  ) t^2 - ( 13 x^4 - 13 x^3 + x^2 + 2 x - 13  ) ");
291        br = rfac.random(kl, 2 * ll, el + 2, q);
292        //ar = ar.multiply(br);
293        //br = rfac.parse(" ( 13 ) t^3 + ( 3 x^2 - 6  ) t - ( 13 x^4 - 8 x^3 + 10 x^2 + 22 x + 21  ) ");
294        //System.out.println("ar   = " + ar);
295        //System.out.println("br   = " + br);
296
297        dr = PolyUtil.<BigInteger> recursivePseudoDivide(ar, br);
298        //System.out.println("qr   = " + dr);
299        cr = PolyUtil.<BigInteger> recursiveSparsePseudoRemainder(ar, br);
300        //System.out.println("rr   = " + cr);
301
302        //boolean t = PolyUtil.<BigInteger> isRecursivePseudoQuotientRemainder(ar, br, dr, cr);
303        //System.out.println("assertTrue lc^n a = q b + r: " + t);
304        //assertTrue("lc^n a = q b + r: " + cr, t); // ?? not always true
305
306        GenPolynomial<Quotient<BigInteger>> ap = PolyUfdUtil
307                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, ar);
308        GenPolynomial<Quotient<BigInteger>> bp = PolyUfdUtil
309                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, br);
310        GenPolynomial<Quotient<BigInteger>> cp = PolyUfdUtil
311                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, cr);
312        GenPolynomial<Quotient<BigInteger>> dp = PolyUfdUtil
313                        .<BigInteger> quotientFromIntegralCoefficients(rqfac, dr);
314        //System.out.println("ap  = " + ap);
315        //System.out.println("bp  = " + bp);
316        //System.out.println("cp  = " + cp);
317        ////System.out.println("dp  = " + dp);
318        //System.out.println("dp  = " + dp.monic());
319
320        GenPolynomial<Quotient<BigInteger>> qp = ap.divide(bp);
321        GenPolynomial<Quotient<BigInteger>> rp = ap.remainder(bp);
322        ////System.out.println("qp  = " + qp);
323        //System.out.println("qp  = " + qp.monic());
324        //System.out.println("rp  = " + rp);
325        GenPolynomial<Quotient<BigInteger>> rhs = qp.multiply(bp).sum(rp);
326        //System.out.println("qp bp + rp  = " + rhs);
327
328        assertEquals("ap = qp bp + rp: ", ap, rhs);
329
330        assertEquals("cp = rp: ", rp.monic(), cp.monic());
331        //System.out.println("dp = qp: " + qp.monic().equals(dp.monic()) );
332        assertEquals("dp = qp: ", qp.monic(), dp.monic()); // ??
333    }
334
335
336    /**
337     * Test integer from rational coefficients, recursive.
338     */
339    public void testRecursiveIntegerFromRationalCoefficients() {
340        crfac = new GenPolynomialRing<BigRational>(new BigRational(1), cfac);
341        rrfac = new GenPolynomialRing<GenPolynomial<BigRational>>(crfac, rfac);
342        //System.out.println("\ncfac  = " + cfac);
343        //System.out.println("crfac = " + crfac);
344        //System.out.println("rfac  = " + rfac);
345        //System.out.println("rrfac  = " + rrfac);
346
347        // BigRational
348        arr = rrfac.random(kl*kl, 2 * ll, el + 4, q);
349        arr = arr.sum(arr).multiply(arr); //rrfac.fromInteger(11));
350        //System.out.println("arr   = " + arr);
351
352        // BigInteger
353        ar = PolyUfdUtil.integerFromRationalCoefficients(rfac, arr);
354        //System.out.println("ar   = " + ar);
355
356        crr = PolyUtil.<BigRational> monic(arr);
357        //System.out.println("crr   = " + crr);
358
359        // BigRational
360        err = PolyUfdUtil.<BigRational> fromIntegerCoefficients(rrfac, ar);
361        //System.out.println("err   = " + err);
362        err = PolyUtil.<BigRational> monic(err);
363        //System.out.println("err   = " + err);
364
365        assertEquals("crr != err: ", crr, err);
366    }
367
368}