001/*
002 * $Id$
003 */
004
005package edu.jas.ufd;
006
007
008import java.util.List;
009import java.util.SortedMap;
010
011import edu.jas.arith.ModInt;
012import edu.jas.arith.ModIntRing;
013import edu.jas.arith.ModInteger;
014import edu.jas.arith.ModIntegerRing;
015import edu.jas.arith.PrimeList;
016import edu.jas.kern.ComputerThreads;
017import edu.jas.poly.AlgebraicNumber;
018import edu.jas.poly.AlgebraicNumberRing;
019import edu.jas.poly.GenPolynomial;
020import edu.jas.poly.GenPolynomialRing;
021import edu.jas.poly.TermOrder;
022
023import junit.framework.Test;
024import junit.framework.TestCase;
025import junit.framework.TestSuite;
026
027
028/**
029 * Factor modular tests with JUnit.
030 * @author Heinz Kredel
031 */
032
033public class FactorModularTest extends TestCase {
034
035
036    /**
037     * main.
038     */
039    public static void main(String[] args) {
040        junit.textui.TestRunner.run(suite());
041    }
042
043
044    /**
045     * Constructs a <CODE>FactorModularTest</CODE> object.
046     * @param name String.
047     */
048    public FactorModularTest(String name) {
049        super(name);
050    }
051
052
053    /**
054     */
055    public static Test suite() {
056        TestSuite suite = new TestSuite(FactorModularTest.class);
057        return suite;
058    }
059
060
061    int rl = 3;
062
063
064    int kl = 5;
065
066
067    int ll = 5;
068
069
070    int el = 3;
071
072
073    float q = 0.3f;
074
075
076    @Override
077    protected void setUp() {
078    }
079
080
081    @Override
082    protected void tearDown() {
083        ComputerThreads.terminate();
084    }
085
086
087    /**
088     * Test dummy for Junit.
089     * 
090     */
091    public void testDummy() {
092    }
093
094
095    /**
096     * Test modular factorization.
097     */
098    public void testModularFactorization() {
099        PrimeList pl = new PrimeList(PrimeList.Range.medium);
100        TermOrder to = new TermOrder(TermOrder.INVLEX);
101        ModIntegerRing cfac = new ModIntegerRing(pl.get(3));
102        //System.out.println("cfac = " + cfac);
103        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, 1, to);
104        FactorModular<ModInteger> fac = new FactorModular<ModInteger>(cfac);
105        for (int i = 1; i < 4; i++) {
106            int facs = 0;
107            GenPolynomial<ModInteger> a = null; //pfac.random(kl,ll*(i+1),el*(i+1),q);
108            GenPolynomial<ModInteger> b = pfac.random(kl, ll * (i + 1), el * (i + 1), q);
109            GenPolynomial<ModInteger> c = pfac.random(kl, ll * (i + 1), el * (i + 1), q);
110            if (b.isZERO() || c.isZERO()) {
111                continue;
112            }
113            if (c.degree() > 0) {
114                facs++;
115            }
116            if (b.degree() > 0) {
117                facs++;
118            }
119            a = c.multiply(b);
120            if (a.isConstant()) {
121                continue;
122            }
123            a = a.monic();
124            //System.out.println("\na = " + a);
125            //System.out.println("b = " + b);
126            //System.out.println("c = " + c);
127
128            SortedMap<GenPolynomial<ModInteger>, Long> sm = fac.baseFactors(a);
129            //System.out.println("sm = " + sm);
130
131            if (sm.size() >= facs) {
132                assertTrue("#facs < " + facs, sm.size() >= facs);
133            } else {
134                long sf = 0;
135                for (Long e : sm.values()) {
136                    sf += e;
137                }
138                assertTrue("#facs < " + facs, sf >= facs);
139            }
140
141            boolean t = fac.isFactorization(a, sm);
142            //System.out.println("t        = " + t);
143            assertTrue("prod(factor(a)) = a", t);
144        }
145    }
146
147
148    /**
149     * Test modular factorization example.
150     */
151    public void testModularFactorizationExam() {
152        TermOrder to = new TermOrder(TermOrder.INVLEX);
153        ModIntegerRing cfac = new ModIntegerRing(7);
154        //System.out.println("cfac = " + cfac);
155        String[] vars = new String[] { "x" };
156        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, 1, to, vars);
157        FactorModular<ModInteger> fac = new FactorModular<ModInteger>(cfac);
158
159        int facs = 3;
160        GenPolynomial<ModInteger> a = pfac.parse("(x^12+5)");
161        a = a.monic();
162        //System.out.println("\na = " + a);
163
164        SortedMap<GenPolynomial<ModInteger>, Long> sm = fac.baseFactors(a);
165        //System.out.println("sm = " + sm);
166
167        if (sm.size() >= facs) {
168            assertTrue("#facs < " + facs, sm.size() >= facs);
169        } else {
170            long sf = 0;
171            for (Long e : sm.values()) {
172                sf += e;
173            }
174            assertTrue("#facs < " + facs, sf >= facs);
175        }
176
177        boolean t = fac.isFactorization(a, sm);
178        //System.out.println("t        = " + t);
179        assertTrue("prod(factor(a)) = a", t);
180    }
181
182
183    /**
184     * Test modular factorization, case p = 2.
185     */
186    public void testModular2Factorization() {
187        TermOrder to = new TermOrder(TermOrder.INVLEX);
188        ModIntegerRing cfac = new ModIntegerRing(2L);
189        //System.out.println("cfac = " + cfac);
190        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, new String[]{"x"}, to);
191        FactorModular<ModInteger> fac = new FactorModular<ModInteger>(cfac);
192        for (int i = 1; i < 4; i++) {
193            int facs = 0;
194            GenPolynomial<ModInteger> a = null; //pfac.random(kl,ll*(i+1),el*(i+1),q);
195            GenPolynomial<ModInteger> b = pfac.random(kl, ll * (i + 1), el * (i + 1), q);
196            GenPolynomial<ModInteger> c = pfac.random(kl, ll * (i + 1), el * (i + 1), q);
197            if (b.isZERO() || c.isZERO()) {
198                continue;
199            }
200            if (c.degree() > 0) {
201                facs++;
202            }
203            if (b.degree() > 0) {
204                facs++;
205            }
206            a = c.multiply(b);
207            if (a.isConstant()) {
208                continue;
209            }
210            //a = pfac.parse(" x**13 + x**11 + x**7 + x**3 + x ");
211            a = a.monic();
212            //System.out.println("\na = " + a);
213            //System.out.println("b = " + b);
214            //System.out.println("c = " + c);
215
216            SortedMap<GenPolynomial<ModInteger>, Long> sm = fac.baseFactors(a);
217            //System.out.println("sm = " + sm);
218
219            if (sm.size() >= facs) {
220                assertTrue("#facs < " + facs, sm.size() >= facs);
221            } else {
222                long sf = 0;
223                for (Long e : sm.values()) {
224                    sf += e;
225                }
226                assertTrue("#facs < " + facs, sf >= facs);
227            }
228
229            boolean t = fac.isFactorization(a, sm);
230            //System.out.println("t        = " + t);
231            assertTrue("prod(factor(a)) = a", t);
232        }
233    }
234
235
236    /**
237     * Test multivariate modular factorization.
238     */
239    public void testMultivariateModularFactorization() {
240        //PrimeList pl = new PrimeList(PrimeList.Range.small);
241        TermOrder to = new TermOrder(TermOrder.INVLEX);
242        ModIntegerRing cfac = new ModIntegerRing(13); // pl.get(3), 7, 11, 13
243        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, rl, to);
244        FactorModular<ModInteger> fac = new FactorModular<ModInteger>(cfac);
245        for (int i = 1; i < 2; i++) {
246            int facs = 0;
247            GenPolynomial<ModInteger> a = null; //pfac.random(kl,ll*(i+1),el,q);
248            GenPolynomial<ModInteger> b = pfac.random(kl, 2, el, q);
249            GenPolynomial<ModInteger> c = pfac.random(kl, 2, el, q);
250            if (b.isZERO() || c.isZERO()) {
251                continue;
252            }
253            if (c.degree() > 0) {
254                facs++;
255            }
256            if (b.degree() > 0) {
257                facs++;
258            }
259            a = c.multiply(b);
260            if (a.isConstant()) {
261                continue;
262            }
263            //a = a.monic();
264            //System.out.println("\na = " + a);
265            //System.out.println("b = " + b);
266            //System.out.println("c = " + c);
267
268            SortedMap<GenPolynomial<ModInteger>, Long> sm = fac.factors(a);
269            //System.out.println("sm = " + sm);
270
271            if (sm.size() >= facs) {
272                assertTrue("#facs < " + facs, sm.size() >= facs);
273            } else {
274                long sf = 0;
275                for (Long e : sm.values()) {
276                    sf += e;
277                }
278                assertTrue("#facs < " + facs, sf >= facs);
279            }
280
281            boolean t = fac.isFactorization(a, sm);
282            //System.out.println("t        = " + t);
283            assertTrue("prod(factor(a)) = a", t);
284        }
285    }
286
287
288    /**
289     * Test modular absolute factorization.
290     */
291    public void testBaseModularAbsoluteFactorization() {
292        TermOrder to = new TermOrder(TermOrder.INVLEX);
293        ModIntegerRing cfac = new ModIntegerRing(17);
294        String[] alpha = new String[] { "alpha" };
295        //String[] vars = new String[] { "z" };
296        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, 1, to, alpha);
297        GenPolynomial<ModInteger> agen = pfac.univariate(0, 4);
298        agen = agen.sum(pfac.fromInteger(1)); // x^4 + 1
299
300        FactorModular<ModInteger> engine = new FactorModular<ModInteger>(cfac);
301
302        FactorsMap<ModInteger> F
303        //= engine.baseFactorsAbsoluteSquarefree(agen);
304        //= engine.baseFactorsAbsoluteIrreducible(agen);
305                        = engine.baseFactorsAbsolute(agen);
306        //System.out.println("agen        = " + agen);
307        //System.out.println("F           = " + F);
308
309        boolean t = engine.isAbsoluteFactorization(F);
310        //System.out.println("t        = " + t);
311        assertTrue("prod(factor(a)) = a", t);
312    }
313
314
315    /**
316     * Berlekamp small odd prime factorization test.
317     */
318    public void testFactorBerlekampSmallOdd() {
319        int q = 11; //32003; //11;
320        ModIntRing mi = new ModIntRing(q);
321        //System.out.println("mi = " + mi.toScript());
322        GenPolynomialRing<ModInt> pfac = new GenPolynomialRing<ModInt>(mi, new String[] { "x" });
323        //System.out.println("SmallOdd pfac = " + pfac.toScript());
324        GenPolynomial<ModInt> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
325        //System.out.println("A = " + A.toScript());
326
327        FactorAbstract<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
328        List<GenPolynomial<ModInt>> factors = bf.baseFactorsSquarefree(A);
329        //System.out.println("factors = " + factors + "\n");
330        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
331        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
332
333        GenPolynomial<ModInt> B = pfac.random(5).monic();
334        GenPolynomial<ModInt> C = pfac.random(5).monic();
335        A = B.multiply(C);
336        //System.out.println("A = " + A.toScript());
337        //System.out.println("B = " + B.toScript());
338        //System.out.println("C = " + C.toScript());
339
340        factors = bf.baseFactorsSquarefree(A);
341        //System.out.println("factors = " + factors + "\n");
342        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
343        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
344    }
345
346
347    /**
348     * Berlekamp big odd prime factorization test.
349     */
350    public void testFactorBerlekampBigOdd() {
351        int q = 32003; //11;
352        ModIntRing mi = new ModIntRing(q);
353        //System.out.println("mi = " + mi.toScript());
354        GenPolynomialRing<ModInt> pfac = new GenPolynomialRing<ModInt>(mi, new String[] { "x" });
355        //System.out.println("BigOdd pfac = " + pfac.toScript());
356        GenPolynomial<ModInt> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
357        //System.out.println("A = " + A.toScript());
358
359        //FactorAbstract<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
360        FactorModularBerlekamp<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
361        List<GenPolynomial<ModInt>> factors = bf.baseFactorsSquarefreeBigPrime(A);
362        //System.out.println("factors = " + factors + "\n");
363        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
364        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
365
366        GenPolynomial<ModInt> B = pfac.random(5).monic();
367        GenPolynomial<ModInt> C = pfac.random(5).monic();
368        A = B.multiply(C);
369        //System.out.println("A = " + A.toScript());
370        //System.out.println("B = " + B.toScript());
371        //System.out.println("C = " + C.toScript());
372
373        factors = bf.baseFactorsSquarefreeBigPrime(A);
374        //System.out.println("factors = " + factors + "\n");
375        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
376        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
377    }
378
379
380    /**
381     * Berlekamp big even prime factorization test.
382     */
383    public void testFactorBerlekampBigEven() {
384        int q = 2;
385        ModIntRing mi = new ModIntRing(q);
386        //System.out.println("mi = " + mi.toScript());
387        GenPolynomialRing<ModInt> pfac = new GenPolynomialRing<ModInt>(mi, new String[] { "x" });
388        //System.out.println("BigEven pfac = " + pfac.toScript());
389        GenPolynomial<ModInt> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
390        //GenPolynomial<ModInt> A = pfac.parse(" x**13 + x**11 + x**7 + x**3 + x "); //sm = {x=1, x^2 + x + 1 =6}
391
392        //System.out.println("A = " + A.toScript());
393
394        //FactorAbstract<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
395        FactorModularBerlekamp<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
396        List<GenPolynomial<ModInt>> factors = bf.baseFactorsSquarefreeBigPrime(A);
397        //System.out.println("factors = " + factors + "\n");
398        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
399        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
400
401        GenPolynomial<ModInt> B = pfac.random(10).monic();
402        GenPolynomial<ModInt> C = pfac.random(10).monic();
403        A = B.multiply(C);
404        //System.out.println("A = " + A.toScript());
405        //System.out.println("B = " + B.toScript());
406        //System.out.println("C = " + C.toScript());
407
408        factors = bf.baseFactorsSquarefreeBigPrime(A);
409        //System.out.println("factors = " + factors + "\n");
410        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
411        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
412    }
413
414
415    /**
416     * Berlekamp small even prime factorization test.
417     */
418    public void testFactorBerlekampSmallEven() {
419        int q = 2;
420        ModIntRing mi = new ModIntRing(q);
421        //System.out.println("mi = " + mi.toScript());
422        GenPolynomialRing<ModInt> pfac = new GenPolynomialRing<ModInt>(mi, new String[] { "x" });
423        //System.out.println("SmallEven pfac = " + pfac.toScript());
424        GenPolynomial<ModInt> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
425        //GenPolynomial<ModInt> A = pfac.parse(" x**13 + x**11 + x**7 + x**3 + x "); //sm = {x=1, x^2 + x + 1 =6}
426        //System.out.println("A = " + A.toScript());
427
428        //FactorAbstract<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
429        FactorModularBerlekamp<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
430        List<GenPolynomial<ModInt>> factors = bf.baseFactorsSquarefreeSmallPrime(A);
431        //System.out.println("factors = " + factors + "\n");
432        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
433        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
434
435        GenPolynomial<ModInt> B = pfac.random(10).monic();
436        GenPolynomial<ModInt> C = pfac.random(10).monic();
437        A = B.multiply(C);
438        //System.out.println("A = " + A.toScript());
439        //System.out.println("B = " + B.toScript());
440        //System.out.println("C = " + C.toScript());
441
442        factors = bf.baseFactorsSquarefreeSmallPrime(A);
443        //System.out.println("factors = " + factors + "\n");
444        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
445        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
446    }
447
448
449    /**
450     * Berlekamp big even prime power factorization test.
451     */
452    public void testFactorBerlekampBigEvenPower() {
453        int q = 2;
454        //int qp = 4;
455        ModIntRing mi = new ModIntRing(q);
456        //System.out.println("mi = " + mi.toScript());
457        GenPolynomialRing<ModInt> mfac = new GenPolynomialRing<ModInt>(mi, new String[] { "a" });
458        GenPolynomial<ModInt> amod = mfac.parse("a^4 + a + 1");
459        //AlgebraicNumberRing<ModInt> gf = PolyUfdUtil.algebraicNumberField(mi, qp);
460        AlgebraicNumberRing<ModInt> gf = new AlgebraicNumberRing<ModInt>(amod, true);
461        //System.out.println("gf(2^4) = " + gf.toScript());
462        GenPolynomialRing<AlgebraicNumber<ModInt>> pfac = new GenPolynomialRing<AlgebraicNumber<ModInt>>(gf,
463                        new String[] { "x" });
464        //System.out.println("BigEvenPower pfac = " + pfac.toScript());
465        //GenPolynomial<AlgebraicNumber<ModInt>> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
466        GenPolynomial<AlgebraicNumber<ModInt>> A = pfac
467                        .parse("x^5 + (a^3 + a + 1) x^4 + (a^3 + a^2 + 1) x^3 + ( a ) x + (a^3 + a + 1)");
468        //System.out.println("A = " + A.toScript());
469
470        //FactorAbstract<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(pfac.coFac);
471        FactorModularBerlekamp<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(
472                        pfac.coFac);
473        List<GenPolynomial<AlgebraicNumber<ModInt>>> factors = bf.baseFactorsSquarefreeBigPrime(A);
474        //System.out.println("factors = " + factors + "\n");
475        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
476        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
477
478        GenPolynomial<AlgebraicNumber<ModInt>> B = pfac.random(5).monic();
479        GenPolynomial<AlgebraicNumber<ModInt>> C = pfac.random(7).monic();
480        A = B.multiply(C);
481        //System.out.println("A = " + A.toScript());
482        //System.out.println("B = " + B.toScript());
483        //System.out.println("C = " + C.toScript());
484
485        factors = bf.baseFactorsSquarefreeBigPrime(A);
486        //System.out.println("factors = " + factors + "\n");
487        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
488        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
489    }
490
491
492    /**
493     * Berlekamp small even prime power factorization test.
494     */
495    public void testFactorBerlekampSmallEvenPower() {
496        int q = 2;
497        //int qp = 4;
498        ModIntRing mi = new ModIntRing(q);
499        //System.out.println("mi = " + mi.toScript());
500        GenPolynomialRing<ModInt> mfac = new GenPolynomialRing<ModInt>(mi, new String[] { "a" });
501        GenPolynomial<ModInt> amod = mfac.parse("a^4 + a + 1");
502        //AlgebraicNumberRing<ModInt> gf = PolyUfdUtil.algebraicNumberField(mi, qp);
503        AlgebraicNumberRing<ModInt> gf = new AlgebraicNumberRing<ModInt>(amod, true);
504        //System.out.println("gf(2^4) = " + gf.toScript());
505        GenPolynomialRing<AlgebraicNumber<ModInt>> pfac = new GenPolynomialRing<AlgebraicNumber<ModInt>>(gf,
506                        new String[] { "x" });
507        //System.out.println("SmallEvenPower pfac = " + pfac.toScript());
508        //GenPolynomial<AlgebraicNumber<ModInt>> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
509        GenPolynomial<AlgebraicNumber<ModInt>> A = pfac
510                        .parse("x^5 + (a^3 + a + 1) x^4 + (a^3 + a^2 + 1) x^3 + ( a ) x + (a^3 + a + 1)");
511        //System.out.println("A = " + A.toScript());
512
513        //FactorAbstract<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(pfac.coFac);
514        FactorModularBerlekamp<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(
515                        pfac.coFac);
516        List<GenPolynomial<AlgebraicNumber<ModInt>>> factors = bf.baseFactorsSquarefreeSmallPrime(A);
517        //System.out.println("factors = " + factors + "\n");
518        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
519        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
520
521        GenPolynomial<AlgebraicNumber<ModInt>> B = pfac.random(5).monic();
522        GenPolynomial<AlgebraicNumber<ModInt>> C = pfac.random(7).monic();
523        A = B.multiply(C);
524        //System.out.println("A = " + A.toScript());
525        //System.out.println("B = " + B.toScript());
526        //System.out.println("C = " + C.toScript());
527
528        factors = bf.baseFactorsSquarefreeSmallPrime(A);
529        //System.out.println("factors = " + factors + "\n");
530        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
531        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
532    }
533
534
535    /**
536     * Berlekamp small odd prime power factorization test.
537     */
538    public void testFactorBerlekampSmallOddPower() {
539        int q = 3;
540        int qp = 4;
541        ModIntRing mi = new ModIntRing(q);
542        //System.out.println("mi = " + mi.toScript());
543        GenPolynomialRing<ModInt> mfac = new GenPolynomialRing<ModInt>(mi, new String[] { "a" });
544        //GenPolynomial<ModInt> amod = mfac.parse("a^4 + a + 1");
545        //AlgebraicNumberRing<ModInt> gf = new AlgebraicNumberRing<ModInt>(amod, true);
546        AlgebraicNumberRing<ModInt> gf = PolyUfdUtil.algebraicNumberField(mfac, qp);
547        //System.out.println("gf(2^4) = " + gf.toScript());
548        GenPolynomialRing<AlgebraicNumber<ModInt>> pfac = new GenPolynomialRing<AlgebraicNumber<ModInt>>(gf,
549                        new String[] { "x" });
550        //System.out.println("SmallOddPower pfac = " + pfac.toScript());
551        //GenPolynomial<AlgebraicNumber<ModInt>> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
552        GenPolynomial<AlgebraicNumber<ModInt>> A = pfac
553                        .parse("x^5 + (a^3 + a + 1) x^4 + (a^3 + a^2 + 1) x^3 + ( a ) x + (a^3 + a + 1)");
554        //System.out.println("A = " + A.toScript());
555
556        //FactorAbstract<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(pfac.coFac);
557        FactorModularBerlekamp<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(
558                        pfac.coFac);
559        List<GenPolynomial<AlgebraicNumber<ModInt>>> factors = bf.baseFactorsSquarefreeSmallPrime(A);
560        //System.out.println("factors = " + factors + "\n");
561        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
562        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
563
564        GenPolynomial<AlgebraicNumber<ModInt>> B = pfac.random(5).monic();
565        GenPolynomial<AlgebraicNumber<ModInt>> C = pfac.random(7).monic();
566        A = B.multiply(C);
567        //System.out.println("A = " + A.toScript());
568        //System.out.println("B = " + B.toScript());
569        //System.out.println("C = " + C.toScript());
570
571        factors = bf.baseFactorsSquarefreeSmallPrime(A);
572        //System.out.println("factors = " + factors + "\n");
573        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
574        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
575    }
576
577
578    /**
579     * Berlekamp big odd prime power factorization test.
580     */
581    public void testFactorBerlekampBigOddPower() {
582        int q = 3;
583        int qp = 4;
584        ModIntRing mi = new ModIntRing(q);
585        //System.out.println("mi = " + mi.toScript());
586        GenPolynomialRing<ModInt> mfac = new GenPolynomialRing<ModInt>(mi, new String[] { "a" });
587        //GenPolynomial<ModInt> amod = mfac.parse("a^4 + a + 1");
588        //AlgebraicNumberRing<ModInt> gf = new AlgebraicNumberRing<ModInt>(amod, true);
589        AlgebraicNumberRing<ModInt> gf = PolyUfdUtil.algebraicNumberField(mfac, qp);
590        //System.out.println("gf(2^4) = " + gf.toScript());
591        GenPolynomialRing<AlgebraicNumber<ModInt>> pfac = new GenPolynomialRing<AlgebraicNumber<ModInt>>(gf,
592                        new String[] { "x" });
593        //System.out.println("BigOddPower pfac = " + pfac.toScript());
594        //GenPolynomial<AlgebraicNumber<ModInt>> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
595        GenPolynomial<AlgebraicNumber<ModInt>> A = pfac
596                        .parse("x^5 + (a^3 + a + 1) x^4 + (a^3 + a^2 + 1) x^3 + ( a ) x + (a^3 + a + 1)");
597        //System.out.println("A = " + A.toScript());
598
599        //FactorAbstract<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(pfac.coFac);
600        FactorModularBerlekamp<AlgebraicNumber<ModInt>> bf = new FactorModularBerlekamp<AlgebraicNumber<ModInt>>(
601                        pfac.coFac);
602        List<GenPolynomial<AlgebraicNumber<ModInt>>> factors = bf.baseFactorsSquarefreeBigPrime(A);
603        //System.out.println("factors = " + factors + "\n");
604        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
605        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
606
607        GenPolynomial<AlgebraicNumber<ModInt>> B = pfac.random(5).monic();
608        GenPolynomial<AlgebraicNumber<ModInt>> C = pfac.random(7).monic();
609        A = B.multiply(C);
610        //System.out.println("A = " + A.toScript());
611        //System.out.println("B = " + B.toScript());
612        //System.out.println("C = " + C.toScript());
613
614        factors = bf.baseFactorsSquarefreeBigPrime(A);
615        //System.out.println("factors = " + factors + "\n");
616        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
617        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
618    }
619
620
621    /**
622     * Compare Berlekamp with other factorization test.
623     */
624    public void testCompareFactorBerlekamp() {
625        int q = 32003; //11; 29; 
626        ModIntRing mi = new ModIntRing(q);
627        //System.out.println("mi = " + mi.toScript());
628        GenPolynomialRing<ModInt> pfac = new GenPolynomialRing<ModInt>(mi, new String[] { "x" });
629        //System.out.println("time pfac = " + pfac.toScript());
630        GenPolynomial<ModInt> A = pfac.parse("x^6 - 3 x^5 + x^4 - 3 x^3 - x^2 -3 x + 1");
631        //System.out.println("A = " + A.toScript());
632
633        FactorAbstract<ModInt> df = new FactorModular<ModInt>(pfac.coFac);
634        FactorModularBerlekamp<ModInt> bf = new FactorModularBerlekamp<ModInt>(pfac.coFac);
635        SortedMap<GenPolynomial<ModInt>, Long> factors, f2;
636
637        GenPolynomial<ModInt> B = pfac.random(kl,ll*ll+20,el*el+10,q+q).monic();
638        GenPolynomial<ModInt> C = pfac.random(kl,ll*ll+20,el*el+10,q+q).monic();
639        A = B.multiply(C);
640        //System.out.println("A = " + A.toScript());
641        //System.out.println("B = " + B.toScript());
642        //System.out.println("C = " + C.toScript());
643
644        long tb = System.currentTimeMillis();
645        factors = bf.baseFactors(A);
646        tb = System.currentTimeMillis() - tb;
647        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
648        //System.out.println("factors = " + factors + "\n");
649
650        long td = System.currentTimeMillis();
651        f2 = df.baseFactors(A);
652        td = System.currentTimeMillis() - td;
653        //System.out.println("tberle = " + tb + ", tdd = " + td + "\n");
654        assertEquals("factors == f2: ", factors, f2);
655        //System.out.println("isFactorization = " + bf.isFactorization(A,factors));
656        assertTrue("A == prod(factors): " + factors, bf.isFactorization(A, factors));
657        assertTrue("t >= 0: " + tb + ", " + td, tb >= 0 && td >= 0);
658    }
659
660}