001/*
002 * $Id: SquarefreeAlgQuotModTest.java 5863 2018-07-20 11:13:34Z kredel $
003 */
004
005package edu.jas.ufd;
006
007
008import java.util.SortedMap;
009
010import junit.framework.Test;
011import junit.framework.TestCase;
012import junit.framework.TestSuite;
013
014
015import edu.jas.arith.ModInteger;
016import edu.jas.arith.ModIntegerRing;
017import edu.jas.kern.ComputerThreads;
018import edu.jas.poly.ExpVector;
019import edu.jas.poly.GenPolynomial;
020import edu.jas.poly.GenPolynomialRing;
021import edu.jas.poly.PolyUtil;
022import edu.jas.poly.TermOrder;
023import edu.jas.poly.AlgebraicNumber;
024import edu.jas.poly.AlgebraicNumberRing;
025import edu.jas.structure.Power;
026
027
028/**
029 * Squarefree factorization tests with JUnit.
030 * @author Heinz Kredel
031 */
032
033public class SquarefreeAlgQuotModTest extends TestCase {
034
035
036    /**
037     * main.
038     */
039    public static void main(String[] args) {
040        junit.textui.TestRunner.run(suite());
041        ComputerThreads.terminate();
042    }
043
044
045    /**
046     * Constructs a <CODE>SquarefreeAlgQuotModTest</CODE> object.
047     * @param name String.
048     */
049    public SquarefreeAlgQuotModTest(String name) {
050        super(name);
051    }
052
053
054    /**
055     */
056    public static Test suite() {
057        TestSuite suite = new TestSuite(SquarefreeAlgQuotModTest.class);
058        return suite;
059    }
060
061
062    TermOrder to = new TermOrder(TermOrder.INVLEX);
063
064
065    int rl = 3;
066
067
068    int kl = 1;
069
070
071    int ll = 3;
072
073
074    int el = 3;
075
076
077    float q = 0.25f;
078
079
080    String[] vars;
081
082
083    String[] cvars;
084
085
086    String[] c1vars;
087
088
089    String[] rvars;
090
091
092    ModIntegerRing mfac;
093
094
095    String[] alpha;
096
097
098    String[] beta;
099
100
101    GenPolynomialRing<ModInteger> mpfac;
102
103
104    GenPolynomial<ModInteger> agen;
105
106
107    QuotientRing<ModInteger> fac;
108
109
110    AlgebraicNumberRing<Quotient<ModInteger>> afac;
111
112
113    SquarefreeInfiniteFieldCharP<ModInteger> sqf;
114
115
116    SquarefreeInfiniteAlgebraicFieldCharP<Quotient<ModInteger>> asqf;
117
118
119    GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>> dfac;
120
121
122    GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>> a;
123
124
125    GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>> b;
126
127
128    GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>> c;
129
130
131    GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>> d;
132
133
134    GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>> e;
135
136
137    GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>> cfac;
138
139
140    GenPolynomialRing<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> rfac;
141
142
143    GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> ar;
144
145
146    GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> br;
147
148
149    GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> cr;
150
151
152    GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> dr;
153
154
155    GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> er;
156
157
158    @Override
159    protected void setUp() {
160        vars = ExpVector.STDVARS(rl);
161        cvars = ExpVector.STDVARS(rl - 1);
162        c1vars = new String[] { cvars[0] };
163        rvars = new String[] { vars[rl - 1] };
164
165        mfac = new ModIntegerRing(7);
166        alpha = new String[] { "u" };
167        beta = new String[] { "b" };
168        mpfac = new GenPolynomialRing<ModInteger>(mfac, 1, to, alpha);
169        fac = new QuotientRing<ModInteger>(mpfac);
170
171        GenPolynomialRing<Quotient<ModInteger>> qpfac 
172           = new GenPolynomialRing<Quotient<ModInteger>>(fac, 1, to, beta);
173
174        // beta^2 - 3
175        GenPolynomial<Quotient<ModInteger>> an = qpfac.univariate(0,2L);
176        an = an.subtract(qpfac.fromInteger(3));
177
178        afac = new AlgebraicNumberRing<Quotient<ModInteger>>(an,true);
179
180
181        sqf = new SquarefreeInfiniteFieldCharP<ModInteger>(fac);
182        asqf = new SquarefreeInfiniteAlgebraicFieldCharP<Quotient<ModInteger>>(afac);
183
184        SquarefreeAbstract<AlgebraicNumber<Quotient<ModInteger>>> sqff = SquarefreeFactory.getImplementation(afac);
185        //System.out.println("sqf  = " + sqf);
186        //System.out.println("sqff = " + sqff);
187        assertEquals("asqf == sqff ", asqf.getClass(), sqff.getClass());
188
189        a = b = c = d = e = null;
190        ar = br = cr = dr = er = null;
191    }
192
193
194    @Override
195    protected void tearDown() {
196        a = b = c = d = e = null;
197        ar = br = cr = dr = er = null;
198        //ComputerThreads.terminate();
199    }
200
201
202    /**
203     * Test base squarefree.
204     * 
205     */
206    public void testBaseSquarefree() {
207        //System.out.println("\nbase:");
208
209        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 1, to, rvars);
210
211        a = dfac.random(kl + 0, ll - 1, el + 0, q);
212        b = dfac.random(kl + 0, ll, el + 1, q);
213        c = dfac.random(kl, ll, el, q);
214        //System.out.println("a  = " + a);
215        //System.out.println("b  = " + b);
216        //System.out.println("c  = " + c);
217
218        if (a.isZERO() || b.isZERO() || c.isZERO()) {
219            // skip for this turn
220            return;
221        }
222
223        // a a b b b c
224        d = a.multiply(a).multiply(b).multiply(b).multiply(b).multiply(c);
225        c = a.multiply(b).multiply(c);
226        //System.out.println("d  = " + d);
227        //System.out.println("c  = " + c);
228
229        c = asqf.baseSquarefreePart(c);
230        d = asqf.baseSquarefreePart(d);
231        //System.out.println("d  = " + d);
232        //System.out.println("c  = " + c);
233        assertTrue("isSquarefree(c) " + c, asqf.isSquarefree(c));
234        assertTrue("isSquarefree(d) " + d, asqf.isSquarefree(d));
235
236        e = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> basePseudoRemainder(d, c);
237        //System.out.println("e  = " + e);
238        assertTrue("squarefree(abc) | squarefree(aabbbc) " + e, e.isZERO());
239    }
240
241
242    /**
243     * Test base squarefree factors.
244     * 
245     */
246    public void testBaseSquarefreeFactors() {
247
248        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 1, to, rvars);
249
250        a = dfac.random(kl + 0, ll - 1, el + 0, q);
251        b = dfac.random(kl + 0, ll, el + 1, q);
252        c = dfac.random(kl, ll, el + 0, q);
253        //System.out.println("a  = " + a);
254        //System.out.println("b  = " + b);
255        //System.out.println("c  = " + c);
256
257        if (a.isZERO() || b.isZERO() || c.isZERO()) {
258            // skip for this turn
259            return;
260        }
261        int num = 0;
262        if (! a.isConstant()) {
263            num++;
264        }
265        if (! b.isConstant()) {
266            num++;
267        }
268        if (! c.isConstant()) {
269            num++;
270        }
271
272        // a a b b b c
273        d = a.multiply(a).multiply(b).multiply(b).multiply(b).multiply(c);
274        //System.out.println("d  = " + d);
275
276        SortedMap<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>, Long> sfactors;
277        sfactors = asqf.baseSquarefreeFactors(d);
278        //System.out.println("sfactors = " + sfactors);
279
280        assertTrue("isFactorization(d,sfactors) ", asqf.isFactorization(d, sfactors));
281        assertTrue("#factors " + asqf.factorCount(sfactors) + " >= " + num + ": " + d + " = " + sfactors, asqf.factorCount(sfactors) >= num );
282    }
283
284
285    /**
286     * Test recursive squarefree.
287     * 
288     */
289    public void testRecursiveSquarefree() {
290        //System.out.println("\nrecursive:");
291
292        cfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 2 - 1, to, c1vars);
293        rfac = new GenPolynomialRing<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>(cfac, 1, to, rvars);
294
295        ar = rfac.random(kl, 3, 2+1, q);
296        br = rfac.random(kl, 3-0, 2, q);
297        cr = rfac.random(kl, ll, el, q);
298        //System.out.println("ar = " + ar);
299        //System.out.println("br = " + br);
300        //System.out.println("cr = " + cr);
301
302        if (ar.isZERO() || br.isZERO() || cr.isZERO()) {
303            // skip for this turn
304            return;
305        }
306
307        dr = ar.multiply(ar).multiply(br).multiply(br);
308        cr = ar.multiply(br);
309        //System.out.println("dr  = " + dr);
310        //System.out.println("cr  = " + cr);
311
312        cr = asqf.recursiveUnivariateSquarefreePart(cr);
313        dr = asqf.recursiveUnivariateSquarefreePart(dr);
314        //System.out.println("dr  = " + dr);
315        //System.out.println("cr  = " + cr);
316        assertTrue("isSquarefree(cr) " + cr, asqf.isRecursiveSquarefree(cr));
317        assertTrue("isSquarefree(dr) " + dr, asqf.isRecursiveSquarefree(dr));
318
319        er = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> recursivePseudoRemainder(dr, cr);
320        //System.out.println("er  = " + er);
321        assertTrue("squarefree(abc) | squarefree(aabbc) " + er, er.isZERO());
322    }
323
324
325    /**
326     * Test recursive squarefree factors.
327     * 
328     */
329    public void testRecursiveSquarefreeFactors() {
330
331        cfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 2 - 1, to, c1vars);
332        rfac = new GenPolynomialRing<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>(cfac, 1, to, rvars);
333
334        ar = rfac.random(kl, 3, 2+1, q);
335        br = rfac.random(kl, 3-1, 2, q);
336        cr = rfac.random(kl, 3, 2, q);
337        //System.out.println("ar = " + ar);
338        //System.out.println("br = " + br);
339        //System.out.println("cr = " + cr);
340
341        //if (ar.isZERO() || br.isZERO() || cr.isZERO()) {
342        if (ar.isZERO() || br.isZERO()) {
343            // skip for this turn
344            return;
345        }
346        int num = 0;
347        if (! ar.isConstant()) {
348            num++;
349        }
350        if (! br.isConstant()) {
351            num++;
352        }
353        //if (! cr.isConstant()) {
354        //    num++;
355        //}
356
357        //dr = ar.multiply(cr).multiply(br).multiply(br);
358        dr = ar.multiply(br).multiply(br);
359        //System.out.println("dr  = " + dr);
360
361        SortedMap<GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>, Long> sfactors;
362        sfactors = asqf.recursiveUnivariateSquarefreeFactors(dr);
363        //System.out.println("sfactors = " + sfactors);
364
365        // better use factorCount
366        assertTrue("isFactorization(d,sfactors) ", asqf.isRecursiveFactorization(dr, sfactors));
367        assertTrue("#factors " + sfactors.size() + " >= " + num + ": " + d + " = " + sfactors, sfactors.size() >= num );
368    }
369
370
371    /**
372     * Test squarefree.
373     * 
374     */
375    public void testSquarefree() {
376        //System.out.println("\nfull:");
377
378        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, rl, to, vars);
379
380        a = dfac.random(kl, ll, 2, q);
381        b = dfac.random(kl, ll - 1, 2, q);
382        c = dfac.random(kl, ll, 2, q);
383        //System.out.println("a  = " + a);
384        //System.out.println("b  = " + b);
385        //System.out.println("c  = " + c);
386
387        if (a.isZERO() || b.isZERO() || c.isZERO()) {
388            // skip for this turn
389            return;
390        }
391
392        d = a.multiply(a).multiply(b).multiply(b).multiply(c);
393        c = a.multiply(b).multiply(c);
394        //System.out.println("d  = " + d);
395        //System.out.println("c  = " + c);
396
397        c = asqf.squarefreePart(c);
398        d = asqf.squarefreePart(d);
399        //System.out.println("c  = " + c);
400        //System.out.println("d  = " + d);
401        assertTrue("isSquarefree(d) " + d, asqf.isSquarefree(d));
402        assertTrue("isSquarefree(c) " + c, asqf.isSquarefree(c));
403
404        e = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> basePseudoRemainder(d, c);
405        //System.out.println("e  = " + e);
406
407        assertTrue("squarefree(abc) | squarefree(aabbc) " + e, e.isZERO());
408    }
409
410
411    /**
412     * Test squarefree factors.
413     * 
414     */
415    public void testSquarefreeFactors() {
416
417        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, rl, to, vars);
418
419        a = dfac.random(kl, 3, 2+1, q);
420        b = dfac.random(kl, 2, 2, q);
421        c = dfac.random(kl, 3, 2, q);
422        //System.out.println("a  = " + a);
423        //System.out.println("b  = " + b);
424        //System.out.println("c  = " + c);
425
426        if (a.isZERO() || b.isZERO() || c.isZERO()) {
427            // skip for this turn
428            return;
429        }
430        int num = 0;
431        if (! a.isConstant()) {
432            num++;
433        }
434        if (! b.isConstant()) {
435            num++;
436        }
437        if (! c.isConstant()) {
438            num++;
439        }
440
441        // a a b b b c
442        d = a.multiply(a).multiply(b).multiply(b).multiply(b).multiply(c);
443        //System.out.println("d  = " + d);
444
445        SortedMap<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>, Long> sfactors;
446        sfactors = asqf.squarefreeFactors(d);
447        //System.out.println("sfactors = " + sfactors);
448
449        assertTrue("isFactorization(d,sfactors) ", asqf.isFactorization(d, sfactors));
450        assertTrue("#factors " + asqf.factorCount(sfactors) + " >= " + num + ": " + d + " = " + sfactors, asqf.factorCount(sfactors) >= num );
451    }
452
453
454    /* ------------char-th root ------------------------- */
455
456
457    /**
458     * Test base squarefree with char-th root.
459     * 
460     */
461    public void testBaseSquarefreeCharRoot() {
462        //System.out.println("\nbase CharRoot:");
463
464        long p = fac.characteristic().longValue();
465
466        //dfac = new GenPolynomialRing<ModInteger>(fac,1,to,rvars);
467        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 1, to, rvars);
468
469        a = dfac.random(kl + 0, ll + 0, el + 1, q).monic();
470        b = dfac.random(kl, ll + 1, el + 1, q).monic();
471        c = dfac.random(kl + 0, ll, el, q).monic();
472
473        if (a.isZERO() || b.isZERO() || c.isZERO() || a.isConstant() || b.isConstant()) {
474            // skip for this turn
475            return;
476        }
477        //System.out.println("a  = " + a);
478        //System.out.println("b  = " + b);
479        //System.out.println("c  = " + c);
480
481        // a a b^p c
482        d = a.multiply(a).multiply(
483              Power.<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> positivePower(b, p)
484              ).multiply(c);
485        c = a.multiply(b).multiply(c);
486        //System.out.println("c  = " + c);
487        //System.out.println("d  = " + d);
488
489        c = asqf.baseSquarefreePart(c);
490        d = asqf.baseSquarefreePart(d);
491        //System.out.println("c  = " + c);
492        //System.out.println("d  = " + d);
493        assertTrue("isSquarefree(c) " + c, asqf.isSquarefree(c));
494        assertTrue("isSquarefree(d) " + d, asqf.isSquarefree(d));
495
496        e = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> basePseudoRemainder(d, c);
497        //System.out.println("e  = " + e);
498        assertTrue("squarefree(abc) | squarefree(aab^pc) " + e, e.isZERO());
499    }
500
501
502    /**
503     * Test base squarefree factors with char-th root.
504     * 
505     */
506    public void testBaseSquarefreeFactorsCharRoot() {
507
508        long p = fac.characteristic().longValue();
509
510        //dfac = new GenPolynomialRing<ModInteger>(fac,1,to,rvars);
511        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 1, to, rvars);
512
513        a = dfac.random(kl, ll + 1, el + 1, q).monic();
514        b = dfac.random(kl, ll + 1, el + 2, q).monic();
515        c = dfac.random(kl, ll, el + 2, q).monic();
516
517        if (a.isZERO() || b.isZERO() || c.isZERO() || a.isConstant() || b.isConstant()) {
518            // skip for this turn
519            return;
520        }
521        //System.out.println("a  = " + a);
522        //System.out.println("b  = " + b);
523        //System.out.println("c  = " + c);
524
525        // a a b^p c
526        d = a.multiply(a).multiply(
527              Power.<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> positivePower(b, p)
528              ).multiply(c);
529        //d = d.monic();
530        //System.out.println("d  = " + d);
531
532        SortedMap<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>, Long> sfactors;
533        sfactors = asqf.baseSquarefreeFactors(d);
534        //System.out.println("sfactors = " + sfactors);
535
536        assertTrue("isFactorization(d,sfactors) ", asqf.isFactorization(d, sfactors));
537    }
538
539
540    /**
541     * Test recursive squarefree with char-th root.
542     * 
543     */
544    public void testRecursiveSquarefreeCharRoot() {
545        //System.out.println("\nrecursive CharRoot:");
546
547        long p = fac.characteristic().longValue();
548
549        cfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 2 - 1, to, c1vars);
550        rfac = new GenPolynomialRing<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>(cfac, 1, to, rvars);
551
552        ar = rfac.random(kl, 3, 2 + 1, q);
553        br = rfac.random(kl, 3, 2, q);
554        cr = rfac.random(kl, ll, el, q);
555
556        if (ar.isZERO() || br.isZERO() || cr.isZERO()) {
557            // skip for this turn
558            return;
559        }
560        ar = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(ar);
561        br = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(br);
562        cr = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(cr);
563        //System.out.println("ar = " + ar);
564        //System.out.println("br = " + br);
565        //System.out.println("cr = " + cr);
566
567        // a b^p c
568        dr = ar.multiply(
569                Power.<GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>> positivePower(br, p)
570                ).multiply(cr);
571        cr = ar.multiply(br).multiply(cr);
572        //System.out.println("cr  = " + cr);
573        //System.out.println("dr  = " + dr);
574
575        cr = asqf.recursiveUnivariateSquarefreePart(cr);
576        dr = asqf.recursiveUnivariateSquarefreePart(dr);
577        //System.out.println("cr  = " + cr);
578        //System.out.println("dr  = " + dr);
579        assertTrue("isSquarefree(cr) " + cr, asqf.isRecursiveSquarefree(cr));
580        assertTrue("isSquarefree(dr) " + dr, asqf.isRecursiveSquarefree(dr));
581
582        er = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> recursivePseudoRemainder(dr, cr);
583        //System.out.println("er  = " + er);
584        assertTrue("squarefree(abc) | squarefree(aabbc) " + er, er.isZERO());
585    }
586
587
588    /**
589     * Test recursive squarefree factors with char-th root.
590     * 
591     */
592    public void testRecursiveSquarefreeFactorsCharRoot() {
593
594        long p = fac.characteristic().longValue();
595
596        cfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, 2 - 1, to, c1vars);
597        rfac = new GenPolynomialRing<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>(cfac, 1, to, rvars);
598
599        ar = rfac.random(kl, 3, 2 + 1, q);
600        br = rfac.random(kl, 3, 2, q);
601        cr = rfac.random(kl, 3, 2, q);
602
603        if (ar.isZERO() || br.isZERO() || cr.isZERO()) {
604            // skip for this turn
605            return;
606        }
607        ar = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(ar);
608        br = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(br);
609        cr = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> monic(cr);
610        //System.out.println("ar = " + ar);
611        //System.out.println("br = " + br);
612        //System.out.println("cr = " + cr);
613
614        // a b^p c
615        dr = ar.multiply(
616                Power.<GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>> positivePower(br, p)
617                ).multiply(cr);
618        //System.out.println("dr  = " + dr);
619
620        SortedMap<GenPolynomial<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>>, Long> sfactors;
621        sfactors = asqf.recursiveUnivariateSquarefreeFactors(dr);
622        //System.out.println("sfactors = " + sfactors);
623
624        assertTrue("isFactorization(d,sfactors) ", asqf.isRecursiveFactorization(dr, sfactors));
625    }
626
627
628    /**
629     * Test squarefree with char-th root.
630     * 
631     */
632    public void testSquarefreeCharRoot() {
633        //System.out.println("\nfull CharRoot:");
634
635        long p = fac.characteristic().longValue();
636
637        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, rl, to, vars);
638
639        a = dfac.random(kl, ll, 3-1, q);
640        b = dfac.random(kl, 3, 2, q);
641        c = dfac.random(kl, ll, 3, q);
642
643        if (a.isZERO() || b.isZERO() || c.isZERO() || b.isConstant()) {
644            // skip for this turn
645            return;
646        }
647        //System.out.println("a  = " + a);
648        //System.out.println("b  = " + b);
649        //System.out.println("c  = " + c);
650
651        // a a b^p c
652        d = a.multiply(a).multiply(
653              Power.<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> positivePower(b, p)
654              ).multiply(c);
655        c = a.multiply(b).multiply(c);
656        //System.out.println("c  = " + c);
657        //System.out.println("d  = " + d);
658
659        c = asqf.squarefreePart(c);
660        d = asqf.squarefreePart(d);
661        //System.out.println("c  = " + c);
662        //System.out.println("d  = " + d);
663        assertTrue("isSquarefree(d) " + d, asqf.isSquarefree(d));
664        assertTrue("isSquarefree(c) " + c, asqf.isSquarefree(c));
665
666        e = PolyUtil.<AlgebraicNumber<Quotient<ModInteger>>> basePseudoRemainder(d, c);
667        //System.out.println("e  = " + e);
668        assertTrue("squarefree(abc) | squarefree(aab^pc) " + e, e.isZERO());
669    }
670
671
672    /**
673     * Test squarefree factors with char-th root.
674     * 
675     */
676    public void testSquarefreeFactorsCharRoot() {
677
678        long p = fac.characteristic().longValue();
679
680        dfac = new GenPolynomialRing<AlgebraicNumber<Quotient<ModInteger>>>(afac, rl, to, vars);
681
682        a = dfac.random(kl, ll, 3-1, q);
683        b = dfac.random(kl, 3, 2, q);
684        c = dfac.random(kl, ll, 3, q);
685
686        if (a.isZERO() || b.isZERO() || c.isZERO() || b.isConstant()) {
687            // skip for this turn
688            return;
689        }
690        //System.out.println("a  = " + a);
691        //System.out.println("b  = " + b);
692        //System.out.println("c  = " + c);
693
694        // a a b^p c
695        d = a.multiply(a).multiply(
696              Power.<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>> positivePower(b, p)
697              ).multiply(c);
698        //System.out.println("d  = " + d);
699
700        SortedMap<GenPolynomial<AlgebraicNumber<Quotient<ModInteger>>>, Long> sfactors;
701        sfactors = asqf.squarefreeFactors(d);
702        //System.out.println("sfactors = " + sfactors);
703
704        assertTrue("isFactorization(d,sfactors) ", asqf.isFactorization(d, sfactors));
705    }
706
707}