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