Example #1
0
  /**
   * GenPolynomial absolute factorization of a irreducible polynomial.
   *
   * @param P irreducible! GenPolynomial.
   * @return factors container: [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i in K(alpha)[x] for
   *     suitable alpha and p_i irreducible over L[x], where K \subset K(alpha) \subset L is an
   *     algebraically closed field over K. <b>Note:</b> K(alpha) not yet minimal.
   */
  public Factors<C> factorsAbsoluteIrreducible(GenPolynomial<C> P) {
    if (P == null) {
      throw new RuntimeException(this.getClass().getName() + " P == null");
    }
    if (P.isZERO()) {
      return new Factors<C>(P);
    }
    GenPolynomialRing<C> pfac = P.ring; // K[x]
    if (pfac.nvar <= 1) {
      return baseFactorsAbsoluteIrreducible(P);
    }
    if (!pfac.coFac.isField()) {
      throw new RuntimeException("only for field coefficients");
    }
    List<GenPolynomial<C>> factors = new ArrayList<GenPolynomial<C>>();
    if (P.degree() <= 1) {
      return new Factors<C>(P);
    }
    // find field extension K(alpha)
    GenPolynomial<C> up = P;
    RingFactory<C> cf = pfac.coFac;
    long cr = cf.characteristic().longValue(); // char might be larger
    if (cr == 0L) {
      cr = Long.MAX_VALUE;
    }
    long rp = 0L;
    for (int i = 0; i < (pfac.nvar - 1); i++) {
      rp = 0L;
      GenPolynomialRing<C> nfac = pfac.contract(1);
      String[] vn = new String[] {pfac.getVars()[pfac.nvar - 1]};
      GenPolynomialRing<GenPolynomial<C>> rfac =
          new GenPolynomialRing<GenPolynomial<C>>(nfac, 1, pfac.tord, vn);
      GenPolynomial<GenPolynomial<C>> upr = PolyUtil.<C>recursive(rfac, up);
      // System.out.println("upr = " + upr);
      GenPolynomial<C> ep;
      do {
        if (rp >= cr) {
          throw new RuntimeException("elements of prime field exhausted: " + cr);
        }
        C r = cf.fromInteger(rp); // cf.random(rp);
        // System.out.println("r   = " + r);
        ep = PolyUtil.<C>evaluateMain(nfac, upr, r);
        // System.out.println("ep  = " + ep);
        rp++;
      } while (!isSquarefree(ep) /*todo: || ep.degree() <= 1*/); // max deg
      up = ep;
      pfac = nfac;
    }
    up = up.monic();
    if (debug) {
      logger.info("P(" + rp + ") = " + up);
      // System.out.println("up  = " + up);
    }
    if (debug && !isSquarefree(up)) {
      throw new RuntimeException("not irreducible up = " + up);
    }
    if (up.degree(0) <= 1) {
      return new Factors<C>(P);
    }
    // find irreducible factor of up
    List<GenPolynomial<C>> UF = baseFactorsSquarefree(up);
    // System.out.println("UF  = " + UF);
    FactorsList<C> aUF = baseFactorsAbsoluteSquarefree(up);
    // System.out.println("aUF  = " + aUF);
    AlgebraicNumberRing<C> arfac = aUF.findExtensionField();
    // System.out.println("arfac  = " + arfac);

    long e = up.degree(0);
    // search factor polynomial with smallest degree
    for (int i = 0; i < UF.size(); i++) {
      GenPolynomial<C> upi = UF.get(i);
      long d = upi.degree(0);
      if (1 <= d && d <= e) {
        up = upi;
        e = up.degree(0);
      }
    }
    if (up.degree(0) <= 1) {
      return new Factors<C>(P);
    }
    if (debug) {
      logger.info("field extension by " + up);
    }

    List<GenPolynomial<AlgebraicNumber<C>>> afactors =
        new ArrayList<GenPolynomial<AlgebraicNumber<C>>>();

    // setup field extension K(alpha)
    // String[] vars = new String[] { "z_" + Math.abs(up.hashCode() % 1000) };
    String[] vars = pfac.newVars("z_");
    pfac = pfac.clone();
    String[] ovars = pfac.setVars(vars); // side effects!
    GenPolynomial<C> aup = pfac.copy(up); // hack to exchange the variables

    // AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(aup,true); // since irreducible
    AlgebraicNumberRing<C> afac = arfac;
    int depth = afac.depth();
    // System.out.println("afac = " + afac);
    GenPolynomialRing<AlgebraicNumber<C>> pafac =
        new GenPolynomialRing<AlgebraicNumber<C>>(afac, P.ring.nvar, P.ring.tord, P.ring.getVars());
    // System.out.println("pafac = " + pafac);
    // convert to K(alpha)
    GenPolynomial<AlgebraicNumber<C>> Pa =
        PolyUtil.<C>convertToRecAlgebraicCoefficients(depth, pafac, P);
    // System.out.println("Pa = " + Pa);
    // factor over K(alpha)
    FactorAbstract<AlgebraicNumber<C>> engine = FactorFactory.<C>getImplementation(afac);
    afactors = engine.factorsSquarefree(Pa);
    if (debug) {
      logger.info("K(alpha) factors multi = " + afactors);
      // System.out.println("K(alpha) factors = " + afactors);
    }
    if (afactors.size() <= 1) {
      return new Factors<C>(P);
    }
    // normalize first factor to monic
    GenPolynomial<AlgebraicNumber<C>> p1 = afactors.get(0);
    AlgebraicNumber<C> p1c = p1.leadingBaseCoefficient();
    if (!p1c.isONE()) {
      GenPolynomial<AlgebraicNumber<C>> p2 = afactors.get(1);
      afactors.remove(p1);
      afactors.remove(p2);
      p1 = p1.divide(p1c);
      p2 = p2.multiply(p1c);
      afactors.add(p1);
      afactors.add(p2);
    }
    // recursion for splitting field
    // find minimal field extension K(beta) \subset K(alpha)
    return new Factors<C>(P, afac, Pa, afactors);
  }
Example #2
0
 /**
  * GenPolynomial base absolute factorization of a irreducible polynomial.
  *
  * @param P irreducible! univariate GenPolynomial.
  * @return factors container: [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i in K(alpha)[x] for
  *     suitable alpha and p_i irreducible over L[x], where K \subset K(alpha) \subset L is an
  *     algebraically closed field over K. <b>Note:</b> K(alpha) not yet minimal.
  */
 public Factors<C> baseFactorsAbsoluteIrreducible(GenPolynomial<C> P) {
   if (P == null) {
     throw new RuntimeException(this.getClass().getName() + " P == null");
   }
   if (P.isZERO()) {
     return new Factors<C>(P);
   }
   // System.out.println("\nP_base_irred = " + P);
   GenPolynomialRing<C> pfac = P.ring; // K[x]
   if (pfac.nvar > 1) {
     // System.out.println("facs_base_irred: univ");
     throw new RuntimeException("only for univariate polynomials");
   }
   if (!pfac.coFac.isField()) {
     // System.out.println("facs_base_irred: field");
     throw new RuntimeException("only for field coefficients");
   }
   if (P.degree(0) <= 1) {
     return new Factors<C>(P);
   }
   // setup field extension K(alpha) where alpha = z_xx
   // String[] vars = new String[] { "z_" + Math.abs(P.hashCode() % 1000) };
   String[] vars = pfac.newVars("z_");
   pfac = pfac.clone();
   vars = pfac.setVars(vars);
   GenPolynomial<C> aP = pfac.copy(P); // hack to exchange the variables
   AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(aP, true); // since irreducible
   if (logger.isInfoEnabled()) {
     logger.info("K(alpha) = " + afac);
     logger.info("K(alpha) = " + afac.toScript());
     // System.out.println("K(alpha) = " + afac);
   }
   GenPolynomialRing<AlgebraicNumber<C>> pafac =
       new GenPolynomialRing<AlgebraicNumber<C>>(afac, aP.ring.nvar, aP.ring.tord, /*old*/ vars);
   // convert to K(alpha)
   GenPolynomial<AlgebraicNumber<C>> Pa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, P);
   if (logger.isInfoEnabled()) {
     logger.info("P over K(alpha) = " + Pa);
     // logger.info("P over K(alpha) = " + Pa.toScript());
     // System.out.println("P in K(alpha) = " + Pa);
   }
   // factor over K(alpha)
   FactorAbstract<AlgebraicNumber<C>> engine = FactorFactory.<C>getImplementation(afac);
   // System.out.println("K(alpha) engine = " + engine);
   List<GenPolynomial<AlgebraicNumber<C>>> factors = engine.baseFactorsSquarefree(Pa);
   // System.out.println("factors = " + factors);
   if (logger.isInfoEnabled()) {
     logger.info("factors over K(alpha) = " + factors);
     // System.out.println("factors over K(alpha) = " + factors);
   }
   List<GenPolynomial<AlgebraicNumber<C>>> faca =
       new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(factors.size());
   ;
   List<Factors<AlgebraicNumber<C>>> facar = new ArrayList<Factors<AlgebraicNumber<C>>>();
   for (GenPolynomial<AlgebraicNumber<C>> fi : factors) {
     if (fi.degree(0) <= 1) {
       faca.add(fi);
     } else {
       // System.out.println("fi.deg > 1 = " + fi);
       FactorAbsolute<AlgebraicNumber<C>> aengine =
           (FactorAbsolute<AlgebraicNumber<C>>) FactorFactory.<C>getImplementation(afac);
       Factors<AlgebraicNumber<C>> fif = aengine.baseFactorsAbsoluteIrreducible(fi);
       // System.out.println("fif = " + fif);
       facar.add(fif);
     }
   }
   if (facar.size() == 0) {
     facar = null;
   }
   // find minimal field extension K(beta) \subset K(alpha)
   return new Factors<C>(P, afac, Pa, faca, facar);
 }