001/*
002 * $Id: FactorMoreTest.java 5781 2017-12-03 21:38:59Z kredel $
003 */
004
005package edu.jas.ufd;
006
007
008import java.util.List;
009import java.util.SortedMap;
010
011import org.apache.log4j.BasicConfigurator;
012
013import edu.jas.arith.BigInteger;
014import edu.jas.arith.BigRational;
015import edu.jas.arith.ModInteger;
016import edu.jas.arith.ModIntegerRing;
017import edu.jas.kern.ComputerThreads;
018import edu.jas.poly.GenPolynomial;
019import edu.jas.poly.GenPolynomialRing;
020import edu.jas.poly.TermOrder;
021
022import junit.framework.Test;
023import junit.framework.TestCase;
024import junit.framework.TestSuite;
025
026
027/**
028 * Factor tests with JUnit.
029 * @author Heinz Kredel
030 */
031
032public class FactorMoreTest extends TestCase {
033
034
035    /**
036     * main.
037     */
038    public static void main(String[] args) {
039        BasicConfigurator.configure();
040        junit.textui.TestRunner.run(suite());
041    }
042
043
044    /**
045     * Constructs a <CODE>FactorTest</CODE> object.
046     * @param name String.
047     */
048    public FactorMoreTest(String name) {
049        super(name);
050    }
051
052
053    /**
054     */
055    public static Test suite() {
056        TestSuite suite = new TestSuite(FactorMoreTest.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 integral function factorization.
097     */
098    public void testIntegralFunctionFactorization() {
099
100        TermOrder to = new TermOrder(TermOrder.INVLEX);
101        BigRational cfac = new BigRational(1);
102        String[] qvars = new String[] { "t" };
103        GenPolynomialRing<BigRational> pfac = new GenPolynomialRing<BigRational>(cfac, 1, to, qvars);
104        GenPolynomial<BigRational> t = pfac.univariate(0);
105
106        FactorAbstract<BigRational> fac = new FactorRational();
107
108        String[] vars = new String[] { "x" };
109        GenPolynomialRing<GenPolynomial<BigRational>> pqfac = new GenPolynomialRing<GenPolynomial<BigRational>>(
110                        pfac, 1, to, vars);
111        GenPolynomial<GenPolynomial<BigRational>> x = pqfac.univariate(0);
112        GenPolynomial<GenPolynomial<BigRational>> x2 = pqfac.univariate(0, 2);
113
114        for (int i = 1; i < 3; i++) {
115            int facs = 0;
116            GenPolynomial<GenPolynomial<BigRational>> a;
117            GenPolynomial<GenPolynomial<BigRational>> b = pqfac.random(2, 3, el, q);
118            //b = b.monic();
119            //b = b.multiply(b);
120            GenPolynomial<GenPolynomial<BigRational>> c = pqfac.random(2, 3, el, q);
121            //c = c.monic();
122            if (c.degree() < 1) {
123                c = x2.subtract(pqfac.getONE().multiply(t));
124            }
125            if (b.degree() < 1) {
126                b = x.sum(pqfac.getONE());
127            }
128
129            if (c.degree() > 0) {
130                facs++;
131            }
132            if (b.degree() > 0) {
133                facs++;
134            }
135            a = c.multiply(b);
136            //System.out.println("\na = " + a);
137            //System.out.println("b = " + b);
138            //System.out.println("c = " + c);
139
140            SortedMap<GenPolynomial<GenPolynomial<BigRational>>, Long> sm = fac.recursiveFactors(a);
141            //System.out.println("\na   = " + a);
142            //System.out.println("sm = " + sm);
143
144            if (sm.size() >= facs) {
145                assertTrue("#facs < " + facs, sm.size() >= facs);
146            } else {
147                long sf = 0;
148                for (Long e : sm.values()) {
149                    sf += e;
150                }
151                assertTrue("#facs < " + facs + ", sm = " + sm + ", c*b: " + c + " * " + b, sf >= facs);
152            }
153
154            boolean tt = fac.isRecursiveFactorization(a, sm);
155            //System.out.println("t        = " + tt);
156            assertTrue("prod(factor(a)) = a", tt);
157        }
158        ComputerThreads.terminate();
159    }
160
161
162    /**
163     * Test integer integral function factorization.
164     */
165    public void testIntegerIntegralFunctionFactorization() {
166
167        TermOrder to = new TermOrder(TermOrder.INVLEX);
168        BigInteger cfac = new BigInteger(1);
169        String[] qvars = new String[] { "t" };
170        GenPolynomialRing<BigInteger> pfac = new GenPolynomialRing<BigInteger>(cfac, 1, to, qvars);
171        GenPolynomial<BigInteger> t = pfac.univariate(0);
172
173        FactorAbstract<BigInteger> fac = new FactorInteger<ModInteger>();
174
175        String[] vars = new String[] { "x" };
176        GenPolynomialRing<GenPolynomial<BigInteger>> pqfac = new GenPolynomialRing<GenPolynomial<BigInteger>>(
177                        pfac, 1, to, vars);
178        GenPolynomial<GenPolynomial<BigInteger>> x = pqfac.univariate(0);
179        GenPolynomial<GenPolynomial<BigInteger>> x2 = pqfac.univariate(0, 2);
180
181        for (int i = 1; i < 3; i++) {
182            int facs = 0;
183            GenPolynomial<GenPolynomial<BigInteger>> a;
184            GenPolynomial<GenPolynomial<BigInteger>> b = pqfac.random(2, 3, el, q);
185            //b = b.monic();
186            //b = b.multiply(b);
187            GenPolynomial<GenPolynomial<BigInteger>> c = pqfac.random(2, 3, el, q);
188            //c = c.monic();
189            if (c.degree() < 1) {
190                c = x2.subtract(pqfac.getONE().multiply(t));
191            }
192            if (b.degree() < 1) {
193                b = x.sum(pqfac.getONE());
194            }
195
196            if (c.degree() > 0) {
197                facs++;
198            }
199            if (b.degree() > 0) {
200                facs++;
201            }
202            a = c.multiply(b);
203            //a = pqfac.parse("( ( -26 t - 91  ) x^3 - ( 13 t + 26  ) x^2 + ( 6 t^2 + 21 t ) x + ( 3 t^2 + 6 t ) )");
204            //a = pqfac.parse("( -3  x^3 + ( t - 1 ) x^2 + ( 3 t ) x - ( t^2 - t ) )");
205            //System.out.println("\na = " + a);
206            //System.out.println("b = " + b);
207            //System.out.println("c = " + c);
208
209            SortedMap<GenPolynomial<GenPolynomial<BigInteger>>, Long> sm = fac.recursiveFactors(a);
210            //System.out.println("\na   = " + a);
211            //System.out.println("sm = " + sm);
212
213            if (sm.size() >= facs) {
214                assertTrue("#facs < " + facs, sm.size() >= facs);
215            } else {
216                long sf = 0;
217                for (Long e : sm.values()) {
218                    sf += e;
219                }
220                assertTrue("#facs < " + facs + ", sm = " + sm + ", c*b: " + c + " * " + b, sf >= facs);
221            }
222
223            boolean tt = fac.isRecursiveFactorization(a, sm);
224            //System.out.println("t        = " + tt);
225            assertTrue("prod(factor(a)) = a", tt);
226        }
227        ComputerThreads.terminate();
228    }
229
230
231    /**
232     * Test rational function factorization.
233     */
234    public void testRationalFunctionFactorization() {
235
236        TermOrder to = new TermOrder(TermOrder.INVLEX);
237        BigRational cfac = new BigRational(1);
238        String[] qvars = new String[] { "t" };
239        GenPolynomialRing<BigRational> pfac = new GenPolynomialRing<BigRational>(cfac, 1, to, qvars);
240        QuotientRing<BigRational> qfac = new QuotientRing<BigRational>(pfac);
241        Quotient<BigRational> t = qfac.generators().get(1);
242
243        FactorQuotient<BigRational> fac = new FactorQuotient<BigRational>(qfac);
244
245        String[] vars = new String[] { "x" };
246        GenPolynomialRing<Quotient<BigRational>> pqfac = new GenPolynomialRing<Quotient<BigRational>>(qfac, 1,
247                        to, vars);
248        GenPolynomial<Quotient<BigRational>> x = pqfac.univariate(0);
249        GenPolynomial<Quotient<BigRational>> x2 = pqfac.univariate(0, 2);
250
251        for (int i = 1; i < 3; i++) {
252            int facs = 0;
253            GenPolynomial<Quotient<BigRational>> a;
254            GenPolynomial<Quotient<BigRational>> b = pqfac.random(2, 3, el, q);
255            //b = b.monic();
256            //b = b.multiply(b);
257            GenPolynomial<Quotient<BigRational>> c = pqfac.random(2, 3, el, q);
258            //c = c.monic();
259            if (c.degree() < 1) {
260                c = x2.subtract(pqfac.getONE().multiply(t));
261            }
262            if (b.degree() < 1) {
263                b = x.sum(pqfac.getONE());
264            }
265
266            if (c.degree() > 0) {
267                facs++;
268            }
269            if (b.degree() > 0) {
270                facs++;
271            }
272            a = c.multiply(b);
273            //System.out.println("\na = " + a);
274            //System.out.println("b = " + b);
275            //System.out.println("c = " + c);
276
277            SortedMap<GenPolynomial<Quotient<BigRational>>, Long> sm = fac.factors(a);
278            //System.out.println("\na   = " + a);
279            //System.out.println("sm = " + sm);
280
281            if (sm.size() >= facs) {
282                assertTrue("#facs < " + facs, sm.size() >= facs);
283            } else {
284                long sf = 0;
285                for (Long e : sm.values()) {
286                    sf += e;
287                }
288                assertTrue("#facs < " + facs + ", sm = " + sm + ", c*b: " + c + " * " + b, sf >= facs);
289            }
290
291            boolean tt = fac.isFactorization(a, sm);
292            //System.out.println("t        = " + tt);
293            assertTrue("prod(factor(a)) = a", tt);
294        }
295        ComputerThreads.terminate();
296    }
297
298
299    /**
300     * Test modular rational function factorization.
301     */
302    public void testModularRationalFunctionFactorization() {
303
304        TermOrder to = new TermOrder(TermOrder.INVLEX);
305        ModIntegerRing cfac = new ModIntegerRing(19, true);
306        String[] qvars = new String[] { "t" };
307        GenPolynomialRing<ModInteger> pfac = new GenPolynomialRing<ModInteger>(cfac, 1, to, qvars);
308        QuotientRing<ModInteger> qfac = new QuotientRing<ModInteger>(pfac);
309        Quotient<ModInteger> t = qfac.generators().get(1);
310
311        FactorQuotient<ModInteger> fac = new FactorQuotient<ModInteger>(qfac);
312
313        String[] vars = new String[] { "x" };
314        GenPolynomialRing<Quotient<ModInteger>> pqfac = new GenPolynomialRing<Quotient<ModInteger>>(qfac, 1,
315                        to, vars);
316        GenPolynomial<Quotient<ModInteger>> x = pqfac.univariate(0);
317        GenPolynomial<Quotient<ModInteger>> x2 = pqfac.univariate(0, 2);
318
319        for (int i = 1; i < 3; i++) {
320            int facs = 0;
321            GenPolynomial<Quotient<ModInteger>> a;
322            GenPolynomial<Quotient<ModInteger>> b = pqfac.random(2, 3, el, q);
323            //b = b.monic();
324            //b = b.multiply(b);
325            GenPolynomial<Quotient<ModInteger>> c = pqfac.random(2, 3, el, q);
326            //c = c.monic();
327            if (c.degree() < 1) {
328                c = x2.subtract(pqfac.getONE().multiply(t));
329            }
330            if (b.degree() < 1) {
331                b = x.sum(pqfac.getONE());
332            }
333
334            if (c.degree() > 0) {
335                facs++;
336            }
337            if (b.degree() > 0) {
338                facs++;
339            }
340            a = c.multiply(b);
341            //System.out.println("\na = " + a);
342            //System.out.println("b = " + b);
343            //System.out.println("c = " + c);
344
345            SortedMap<GenPolynomial<Quotient<ModInteger>>, Long> sm = fac.factors(a);
346            //System.out.println("\na   = " + a);
347            //System.out.println("sm = " + sm);
348
349            if (sm.size() >= facs) {
350                assertTrue("#facs < " + facs, sm.size() >= facs);
351            } else {
352                long sf = 0;
353                for (Long e : sm.values()) {
354                    sf += e;
355                }
356                assertTrue("#facs < " + facs + ", sm = " + sm + ", c*b: " + c + " * " + b, sf >= facs);
357            }
358
359            boolean tt = fac.isFactorization(a, sm);
360            //System.out.println("t        = " + tt);
361            assertTrue("prod(factor(a)) = a", tt);
362        }
363        ComputerThreads.terminate();
364    }
365
366
367    /**
368     * Test cyclotomic polynomial factorization.
369     */
370    public void testCyclotomicPolynomialFactorization() {
371        TermOrder to = new TermOrder(TermOrder.INVLEX);
372        BigInteger cfac = new BigInteger(1);
373        String[] qvars = new String[] { "x" };
374        GenPolynomialRing<BigInteger> pfac = new GenPolynomialRing<BigInteger>(cfac, 1, to, qvars);
375        //System.out.println("pfac = " + pfac.toScript());
376
377        GenPolynomial<BigInteger> r = pfac.univariate(0, 2).subtract(pfac.getONE());
378        //System.out.println("r = " + r);
379
380        GenPolynomial<BigInteger> q = r.inflate(3);
381        //System.out.println("q = " + q);
382        assertTrue("q != 0: ", !q.isZERO());
383
384        GenPolynomial<BigInteger> h;
385        h = CycloUtil.cyclotomicPolynomial(pfac, 100L);
386        //System.out.println("h = " + h);
387        assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
388
389        h = CycloUtil.cyclotomicPolynomial(pfac, 258L);
390        //System.out.println("h = " + h);
391        assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
392
393        List<GenPolynomial<BigInteger>> H;
394        H = CycloUtil.cyclotomicDecompose(pfac, 100L);
395        //System.out.println("H = " + H);
396        for (GenPolynomial<BigInteger> hp : H) {
397            assertTrue("isCyclotomicPolynomial: " + hp, CycloUtil.isCyclotomicPolynomial(hp));
398        }
399
400        H = CycloUtil.cyclotomicDecompose(pfac, 258L);
401        //System.out.println("H = " + H);
402        //System.out.println("");
403        for (GenPolynomial<BigInteger> hp : H) {
404            assertTrue("isCyclotomicPolynomial: " + hp, CycloUtil.isCyclotomicPolynomial(hp));
405        }
406
407        //FactorAbstract<BigInteger> fac = new FactorInteger();
408        //Map<GenPolynomial<BigInteger>, Long> F;
409
410        h = pfac.univariate(0, 20).subtract(pfac.getONE());
411        //System.out.println("hc = " + h);
412        assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
413
414        H = CycloUtil.cyclotomicFactors(h);
415        //System.out.println("H = " + H);
416        //System.out.println("factors = " + fac.factors(h));
417        //System.out.println("H = " + H);
418        //System.out.println("");
419
420        h = pfac.univariate(0, 20).sum(pfac.getONE());
421        //System.out.println("hc = " + h);
422        assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
423
424        H = CycloUtil.cyclotomicFactors(h);
425        //System.out.println("H = " + H);
426        //System.out.println("factors = " + fac.factors(h));
427        //System.out.println("H = " + H);
428
429        for (long n = 1L; n < 1L; n++) {
430            h = CycloUtil.cyclotomicPolynomial(pfac, n);
431            //F = fac.factors(h);
432            //System.out.println("factors = " + F.size());
433            //System.out.println("h(" + n + ") = " + h);
434            assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
435        }
436
437        h = pfac.univariate(0, 258).subtract(pfac.getONE());
438        //h = pfac.univariate(0, 2).sum(pfac.getONE());
439        //h = pfac.parse("x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1"); // yes
440        //h = pfac.parse("x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1");  // no
441        //System.out.println("hc = " + h);
442        assertTrue("isCyclotomicPolynomial: " + h, CycloUtil.isCyclotomicPolynomial(h));
443    }
444
445}