001    /*
002     * $Id: SquarefreeAlgQuotModTest.java 3456 2010-12-27 22:21:57Z kredel $
003     */
004    
005    package edu.jas.ufd;
006    
007    
008    import java.util.SortedMap;
009    
010    import junit.framework.Test;
011    import junit.framework.TestCase;
012    import junit.framework.TestSuite;
013    
014    import org.apache.log4j.BasicConfigurator;
015    
016    import edu.jas.arith.ModInteger;
017    import edu.jas.arith.ModIntegerRing;
018    import edu.jas.kern.ComputerThreads;
019    import edu.jas.poly.ExpVector;
020    import edu.jas.poly.GenPolynomial;
021    import edu.jas.poly.GenPolynomialRing;
022    import edu.jas.poly.PolyUtil;
023    import edu.jas.poly.TermOrder;
024    import edu.jas.poly.AlgebraicNumber;
025    import edu.jas.poly.AlgebraicNumberRing;
026    import edu.jas.structure.Power;
027    
028    
029    /**
030     * Squarefree factorization tests with JUnit.
031     * @author Heinz Kredel.
032     */
033    
034    public 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    }