/*
 * $Id$
 */

package edu.jas.ufd;


import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.log4j.Logger;

import edu.jas.arith.BigInteger;
import edu.jas.arith.ModLongRing;
import edu.jas.arith.Modular;
import edu.jas.arith.ModularRingFactory;
import edu.jas.poly.GenPolynomial;
import edu.jas.poly.GenPolynomialRing;
import edu.jas.poly.PolyUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.Power;
import edu.jas.structure.RingFactory;


/**
 * Modular coefficients factorization algorithms. This class implements
 * factorization methods for polynomials over (prime) modular integers.
 * @author Heinz Kredel
 */

public class FactorModular & Modular> extends FactorAbsolute {


    private static final Logger logger = Logger.getLogger(FactorModular.class);


    private final boolean debug = logger.isDebugEnabled();


    /**
     * No argument constructor, do not use.
     */
    @SuppressWarnings("unused")
    private FactorModular() {
        this((RingFactory) (Object) new ModLongRing(13, true)); // hack, 13 unimportant
    }


    /**
     * Constructor.
     * @param cfac coefficient ring factory.
     */
    public FactorModular(RingFactory cfac) {
        super(cfac);
    }


    /**
     * GenPolynomial base distinct degree factorization.
     * @param P squarefree and monic GenPolynomial.
     * @return [e_1 -> p_1, ..., e_k -> p_k] with P = prod_{i=1,...,k} p_i
     *         and p_i has only irreducible factors of degree e_i.
     */
    public SortedMap> baseDistinctDegreeFactors(GenPolynomial P) {
        if (P == null) {
            throw new IllegalArgumentException(this.getClass().getName() + " P != null");
        }
        SortedMap> facs = new TreeMap>();
        if (P.isZERO()) {
            return facs;
        }
        GenPolynomialRing pfac = P.ring;
        if (pfac.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
        }
        ModularRingFactory mr = (ModularRingFactory) pfac.coFac;
        java.math.BigInteger m = mr.getIntegerModul().getVal();
        //if (m.longValue() == 2L) {
        //    logger.warn(this.getClass().getName() + " case p = 2 not implemented");
        //}
        GenPolynomial x = pfac.univariate(0);
        GenPolynomial h = x;
        GenPolynomial f = P;
        GenPolynomial g;
        Power> pow = new Power>(pfac);
        long d = 0;
        while (d + 1 <= f.degree(0) / 2) {
            d++;
            h = pow.modPower(h, m, f);
            g = engine.gcd(h.subtract(x), f);
            if (!g.isONE()) {
                facs.put(d, g);
                f = f.divide(g);
            }
        }
        if (!f.isONE()) {
            d = f.degree(0);
            facs.put(d, f);
        }
        return facs;
    }


    /**
     * GenPolynomial base equal degree factorization.
     * @param P squarefree and monic GenPolynomial.
     * @param deg such that P has only irreducible factors of degree deg.
     * @return [p_1,...,p_k] with P = prod_{i=1,...,r} p_i.
     */
    public List> baseEqualDegreeFactors(GenPolynomial P, long deg) {
        if (P == null) {
            throw new IllegalArgumentException(this.getClass().getName() + " P != null");
        }
        List> facs = new ArrayList>();
        if (P.isZERO()) {
            return facs;
        }
        GenPolynomialRing pfac = P.ring;
        if (pfac.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
        }
        if (P.degree(0) == deg) {
            facs.add(P);
            return facs;
        }
        ModularRingFactory mr = (ModularRingFactory) pfac.coFac;
        java.math.BigInteger m = mr.getIntegerModul().getVal();
        //System.out.println("m = " + m);
        boolean p2 = false;
        if (m.equals(java.math.BigInteger.valueOf(2L))) {
            p2 = true;
            //throw new RuntimeException(this.getClass().getName() + " case p = 2 not implemented");
        }
        GenPolynomial one = pfac.getONE();
        GenPolynomial t = pfac.univariate(0, 1L);
        GenPolynomial r;
        GenPolynomial h;
        GenPolynomial f = P;
        //GreatestCommonDivisor engine = GCDFactory. getImplementation(pfac.coFac);
        Power> pow = new Power>(pfac);
        GenPolynomial g = null;
        int degi = (int) deg; //f.degree(0);
        //System.out.println("deg = " + deg);
        BigInteger di = Power. positivePower(new BigInteger(m), deg);
        //System.out.println("di = " + di);
        java.math.BigInteger d = di.getVal(); //.longValue()-1;
        //System.out.println("d = " + d);
        d = d.shiftRight(1); // divide by 2
        do {
            if (p2) {
                h = t;
                for (int i = 1; i < degi; i++) {
                    h = t.sum(h.multiply(h));
                    h = h.remainder(f);
                }
                t = t.multiply(pfac.univariate(0, 2L));
                //System.out.println("h = " + h);
            } else {
                r = pfac.random(17, degi, 2 * degi, 1.0f);
                if (r.degree(0) >= f.degree(0)) {
                    r = r.remainder(f);
                }
                r = r.monic();
                //System.out.println("r = " + r);
                h = pow.modPower(r, d, f).subtract(one);
                degi++;
            }
            g = engine.gcd(h, f);
            //System.out.println("g = " + g);
        } while (g.degree(0) == 0 || g.degree(0) == f.degree(0));
        f = f.divide(g);
        facs.addAll(baseEqualDegreeFactors(f, deg));
        facs.addAll(baseEqualDegreeFactors(g, deg));
        return facs;
    }


    /**
     * GenPolynomial base factorization of a squarefree polynomial.
     * @param P squarefree and monic! GenPolynomial.
     * @return [p_1,...,p_k] with P = prod_{i=1,...,r} p_i.
     */
    @Override
    public List> baseFactorsSquarefree(GenPolynomial P) {
        if (P == null) {
            throw new IllegalArgumentException(this.getClass().getName() + " P == null");
        }
        List> factors = new ArrayList>();
        if (P.isZERO()) {
            return factors;
        }
        if (P.isONE()) {
            factors.add(P);
            return factors;
        }
        GenPolynomialRing pfac = P.ring;
        if (pfac.nvar > 1) {
            throw new IllegalArgumentException(this.getClass().getName() + " only for univariate polynomials");
        }
        if (!P.leadingBaseCoefficient().isONE()) {
            throw new IllegalArgumentException("ldcf(P) != 1: " + P);
        }
        SortedMap> dfacs = baseDistinctDegreeFactors(P);
        if (debug) {
            logger.info("dfacs    = " + dfacs);
            //System.out.println("dfacs    = " + dfacs);
        }
        for (Map.Entry> me : dfacs.entrySet()) {
            Long e = me.getKey();
            GenPolynomial f = me.getValue(); // dfacs.get(e);
            List> efacs = baseEqualDegreeFactors(f, e);
            if (debug) {
                logger.info("efacs " + e + "   = " + efacs);
                //System.out.println("efacs " + e + "   = " + efacs);
            }
            factors.addAll(efacs);
        }
        //System.out.println("factors  = " + factors);
        factors = PolyUtil. monic(factors);
        SortedSet> ss = new TreeSet>(factors);
        //System.out.println("sorted   = " + ss);
        factors.clear();
        factors.addAll(ss);
        return factors;
    }

}

 

Ads help maintain this website.