/** * GenPolynomial squarefree factorization. * * @param P GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<C>, Long> squarefreeFactors(GenPolynomial<C> P) { if (P == null) { throw new IllegalArgumentException(this.getClass().getName() + " P != null"); } GenPolynomialRing<C> pfac = P.ring; if (pfac.nvar <= 1) { return baseSquarefreeFactors(P); } SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); if (P.isZERO()) { return sfactors; } GenPolynomialRing<C> cfac = pfac.contract(1); GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cfac, 1); GenPolynomial<GenPolynomial<C>> Pr = PolyUtil.<C>recursive(rfac, P); SortedMap<GenPolynomial<GenPolynomial<C>>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr); for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> m : PP.entrySet()) { Long i = m.getValue(); GenPolynomial<GenPolynomial<C>> Dr = m.getKey(); GenPolynomial<C> D = PolyUtil.<C>distribute(pfac, Dr); sfactors.put(D, i); } return sfactors; }
/** * GenPolynomial greatest squarefree divisor. * * @param P GenPolynomial. * @return squarefree(pp(P)). */ @Override public GenPolynomial<C> squarefreePart(GenPolynomial<C> P) { if (P == null) { throw new IllegalArgumentException(this.getClass().getName() + " P != null"); } if (P.isZERO()) { return P; } GenPolynomialRing<C> pfac = P.ring; if (pfac.nvar <= 1) { return baseSquarefreePart(P); } // just for the moment: GenPolynomial<C> s = pfac.getONE(); SortedMap<GenPolynomial<C>, Long> factors = squarefreeFactors(P); if (logger.isInfoEnabled()) { logger.info("sqfPart,factors = " + factors); } for (GenPolynomial<C> sp : factors.keySet()) { if (sp.isConstant()) { continue; } s = s.multiply(sp); } return s.monic(); }
/** Test compare sequential with parallel GBase. */ public void testSequentialParallelGBase() { List<GenPolynomial<BigRational>> Gs, Gp; L = new ArrayList<GenPolynomial<BigRational>>(); a = fac.random(kl, ll, el, q); b = fac.random(kl, ll, el, q); c = fac.random(kl, ll, el, q); d = fac.random(kl, ll, el, q); e = d; // fac.random(kl, ll, el, q ); if (a.isZERO() || b.isZERO() || c.isZERO() || d.isZERO()) { return; } L.add(a); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(b); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(c); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(d); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(e); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); }
/** Test parallel GBase. */ public void testParallelGBase() { L = new ArrayList<GenPolynomial<BigRational>>(); a = fac.random(kl, ll, el, q); b = fac.random(kl, ll, el, q); c = fac.random(kl, ll, el, q); d = fac.random(kl, ll, el, q); e = d; // fac.random(kl, ll, el, q ); if (a.isZERO() || b.isZERO() || c.isZERO() || d.isZERO()) { return; } assertTrue("not isZERO( a )", !a.isZERO()); L.add(a); L = bbpar.GB(L); assertTrue("isGB( { a } )", bbpar.isGB(L)); assertTrue("not isZERO( b )", !b.isZERO()); L.add(b); // System.out.println("L = " + L.size() ); L = bbpar.GB(L); assertTrue("isGB( { a, b } )", bbpar.isGB(L)); assertTrue("not isZERO( c )", !c.isZERO()); L.add(c); L = bbpar.GB(L); assertTrue("isGB( { a, b, c } )", bbpar.isGB(L)); assertTrue("not isZERO( d )", !d.isZERO()); L.add(d); L = bbpar.GB(L); assertTrue("isGB( { a, b, c, d } )", bbpar.isGB(L)); assertTrue("not isZERO( e )", !e.isZERO()); L.add(e); L = bbpar.GB(L); assertTrue("isGB( { a, b, c, d, e } )", bbpar.isGB(L)); }
/** * GenPolynomial polynomial greatest squarefree divisor. * * @param P GenPolynomial. * @return squarefree(pp(P)). */ @Override public GenPolynomial<C> baseSquarefreePart(GenPolynomial<C> P) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing<C> pfac = P.ring; if (pfac.nvar > 1) { throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } // just for the moment: GenPolynomial<C> s = pfac.getONE(); SortedMap<GenPolynomial<C>, Long> factors = baseSquarefreeFactors(P); logger.info("sqfPart,factors = " + factors); for (GenPolynomial<C> sp : factors.keySet()) { s = s.multiply(sp); } return s.monic(); }
/** Test modular evaluation gcd. */ public void testModEvalGcd() { GreatestCommonDivisorAbstract<ModInteger> ufd_me = new GreatestCommonDivisorModEval(); for (int i = 0; i < 1; i++) { a = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); b = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); c = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); c = c.multiply(dfac.univariate(0)); // a = ufd.basePrimitivePart(a); // b = ufd.basePrimitivePart(b); if (a.isZERO() || b.isZERO() || c.isZERO()) { // skip for this turn continue; } assertTrue("length( c" + i + " ) <> 0", c.length() > 0); // assertTrue(" not isZERO( c"+i+" )", !c.isZERO() ); // assertTrue(" not isONE( c"+i+" )", !c.isONE() ); a = a.multiply(c); b = b.multiply(c); // System.out.println("a = " + a); // System.out.println("b = " + b); d = ufd_me.gcd(a, b); c = ufd.basePrimitivePart(c).abs(); e = PolyUtil.<ModInteger>basePseudoRemainder(d, c); // System.out.println("c = " + c); // System.out.println("d = " + d); assertTrue("c | gcd(ac,bc) " + e, e.isZERO()); e = PolyUtil.<ModInteger>basePseudoRemainder(a, d); // System.out.println("e = " + e); assertTrue("gcd(a,b) | a" + e, e.isZERO()); e = PolyUtil.<ModInteger>basePseudoRemainder(b, d); // System.out.println("e = " + e); assertTrue("gcd(a,b) | b" + e, e.isZERO()); } }
/** * 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); }
/** * Univariate GenPolynomial algebraic partial fraction decomposition, Rothstein-Trager algorithm. * * @param A univariate GenPolynomial, deg(A) < deg(P). * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1. * @return partial fraction container. */ @Deprecated public PartialFraction<C> baseAlgebraicPartialFractionIrreducible( GenPolynomial<C> A, GenPolynomial<C> P) { if (P == null || P.isZERO()) { throw new RuntimeException(" P == null or P == 0"); } // System.out.println("\nP_base_algeb_part = " + 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"); } List<C> cfactors = new ArrayList<C>(); List<GenPolynomial<C>> cdenom = new ArrayList<GenPolynomial<C>>(); List<AlgebraicNumber<C>> afactors = new ArrayList<AlgebraicNumber<C>>(); List<GenPolynomial<AlgebraicNumber<C>>> adenom = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); // P linear if (P.degree(0) <= 1) { cfactors.add(A.leadingBaseCoefficient()); cdenom.add(P); return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); } // deriviative GenPolynomial<C> Pp = PolyUtil.<C>baseDeriviative(P); // no: Pp = Pp.monic(); // System.out.println("\nP = " + P); // System.out.println("Pp = " + Pp); // Q[t] String[] vars = new String[] {"t"}; GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(pfac.coFac, 1, pfac.tord, vars); GenPolynomial<C> t = cfac.univariate(0); // System.out.println("t = " + t); // Q[x][t] GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(pfac, cfac); // sic // System.out.println("rfac = " + rfac.toScript()); // transform polynomials to bi-variate polynomial GenPolynomial<GenPolynomial<C>> Ac = PolyUfdUtil.<C>introduceLowerVariable(rfac, A); // System.out.println("Ac = " + Ac); GenPolynomial<GenPolynomial<C>> Pc = PolyUfdUtil.<C>introduceLowerVariable(rfac, P); // System.out.println("Pc = " + Pc); GenPolynomial<GenPolynomial<C>> Pcp = PolyUfdUtil.<C>introduceLowerVariable(rfac, Pp); // System.out.println("Pcp = " + Pcp); // Q[t][x] GenPolynomialRing<GenPolynomial<C>> rfac1 = Pc.ring; // System.out.println("rfac1 = " + rfac1.toScript()); // A - t P' GenPolynomial<GenPolynomial<C>> tc = rfac1.getONE().multiply(t); // System.out.println("tc = " + tc); GenPolynomial<GenPolynomial<C>> At = Ac.subtract(tc.multiply(Pcp)); // System.out.println("At = " + At); GreatestCommonDivisorSubres<C> engine = new GreatestCommonDivisorSubres<C>(); // = GCDFactory.<C>getImplementation( cfac.coFac ); GreatestCommonDivisorAbstract<AlgebraicNumber<C>> aengine = null; GenPolynomial<GenPolynomial<C>> Rc = engine.recursiveResultant(Pc, At); // System.out.println("Rc = " + Rc); GenPolynomial<C> res = Rc.leadingBaseCoefficient(); // no: res = res.monic(); // System.out.println("\nres = " + res); SortedMap<GenPolynomial<C>, Long> resfac = baseFactors(res); // System.out.println("resfac = " + resfac + "\n"); for (GenPolynomial<C> r : resfac.keySet()) { // System.out.println("\nr(t) = " + r); if (r.isConstant()) { continue; } // if ( r.degree(0) <= 1L ) { // System.out.println("warning linear factor in resultant ignored"); // continue; // //throw new RuntimeException("input not irreducible"); // } // vars = new String[] { "z_" + Math.abs(r.hashCode() % 1000) }; vars = pfac.newVars("z_"); pfac = pfac.clone(); vars = pfac.setVars(vars); r = pfac.copy(r); // hack to exchange the variables // System.out.println("r(z_) = " + r); AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(r, true); // since irreducible logger.debug("afac = " + afac.toScript()); AlgebraicNumber<C> a = afac.getGenerator(); // no: a = a.negate(); // System.out.println("a = " + a); // K(alpha)[x] GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, Pc.ring); // System.out.println("pafac = " + pafac.toScript()); // convert to K(alpha)[x] GenPolynomial<AlgebraicNumber<C>> Pa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, P); // System.out.println("Pa = " + Pa); GenPolynomial<AlgebraicNumber<C>> Pap = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, Pp); // System.out.println("Pap = " + Pap); GenPolynomial<AlgebraicNumber<C>> Aa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, A); // System.out.println("Aa = " + Aa); // A - a P' GenPolynomial<AlgebraicNumber<C>> Ap = Aa.subtract(Pap.multiply(a)); // System.out.println("Ap = " + Ap); if (aengine == null) { aengine = GCDFactory.<AlgebraicNumber<C>>getImplementation(afac); // System.out.println("aengine = " + aengine); } GenPolynomial<AlgebraicNumber<C>> Ga = aengine.baseGcd(Pa, Ap); // System.out.println("Ga = " + Ga); if (Ga.isConstant()) { // System.out.println("warning constant gcd ignored"); continue; } afactors.add(a); adenom.add(Ga); // quadratic case if (P.degree(0) == 2 && Ga.degree(0) == 1) { GenPolynomial<AlgebraicNumber<C>>[] qra = PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga); GenPolynomial<AlgebraicNumber<C>> Qa = qra[0]; if (!qra[1].isZERO()) { throw new RuntimeException("remainder not zero"); } // System.out.println("Qa = " + Qa); afactors.add(a.negate()); adenom.add(Qa); } if (false && P.degree(0) == 3 && Ga.degree(0) == 1) { GenPolynomial<AlgebraicNumber<C>>[] qra = PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga); GenPolynomial<AlgebraicNumber<C>> Qa = qra[0]; if (!qra[1].isZERO()) { throw new RuntimeException("remainder not zero"); } System.out.println("Qa3 = " + Qa); // afactors.add( a.negate() ); // adenom.add( Qa ); } } return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); }
/** * 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); }
/** Test scalar multiplication. */ public void testPolynomialMultiplication() { BigRational cfac = new BigRational(1); GenPolynomialRing<BigRational> pfac = new GenPolynomialRing<BigRational>(cfac, rl); GenVectorModul<GenPolynomial<BigRational>> mfac = new GenVectorModul<GenPolynomial<BigRational>>(pfac, ll); GenPolynomial<BigRational> r, s, t; GenVector<GenPolynomial<BigRational>> a, b, c, d, e; r = pfac.random(kl); // System.out.println("r = " + r); s = r.negate(); // System.out.println("s = " + s); a = mfac.random(kl, q); // System.out.println("a = " + a); c = a.scalarMultiply(r); d = a.scalarMultiply(s); e = c.sum(d); // System.out.println("c = " + c); // System.out.println("d = " + d); // System.out.println("e = " + e); assertEquals("a*b + a*(-b) = 0", e, mfac.getZERO()); b = mfac.random(kl, q); // System.out.println("b = " + b); t = pfac.getONE(); // System.out.println("t = " + t); c = a.linearCombination(b, t); d = b.linearCombination(a, t); // System.out.println("c = " + c); // System.out.println("d = " + d); assertEquals("a+1*b = b+1*a", c, d); c = a.linearCombination(b, t); d = a.sum(b); // System.out.println("c = " + c); // System.out.println("d = " + d); assertEquals("a+1*b = b+1*a", c, d); s = t.negate(); // System.out.println("s = " + s); c = a.linearCombination(b, t); d = c.linearCombination(b, s); // System.out.println("c = " + c); // System.out.println("d = " + d); assertEquals("a+1*b+(-1)*b = a", a, d); c = a.linearCombination(t, b, t); d = c.linearCombination(t, b, s); // System.out.println("c = " + c); // System.out.println("d = " + d); assertEquals("a+1*b+(-1)*b = a", a, d); t = pfac.getZERO(); // System.out.println("t = " + t); c = a.linearCombination(b, t); // System.out.println("c = " + c); assertEquals("a+0*b = a", a, c); d = a.linearCombination(t, b, t); // System.out.println("d = " + d); assertEquals("0*a+0*b = 0", mfac.getZERO(), d); r = a.scalarProduct(b); s = b.scalarProduct(a); // System.out.println("r = " + r); // System.out.println("s = " + s); assertEquals("a.b = b.a", r, s); }
/** * GenPolynomial recursive univariate polynomial squarefree factorization. * * @param P recursive univariate GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<GenPolynomial<C>>, Long> recursiveUnivariateSquarefreeFactors( GenPolynomial<GenPolynomial<C>> P) { SortedMap<GenPolynomial<GenPolynomial<C>>, Long> sfactors = new TreeMap<GenPolynomial<GenPolynomial<C>>, Long>(); if (P == null || P.isZERO()) { return sfactors; } GenPolynomialRing<GenPolynomial<C>> pfac = P.ring; if (pfac.nvar > 1) { // recursiveContent not possible by return type throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } // if base coefficient ring is a field, make monic GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac; C ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); if (!ldbcf.isONE()) { GenPolynomial<C> lc = cfac.getONE().multiply(ldbcf); GenPolynomial<GenPolynomial<C>> pl = pfac.getONE().multiply(lc); sfactors.put(pl, 1L); C li = ldbcf.inverse(); // System.out.println("li = " + li); P = P.multiply(cfac.getONE().multiply(li)); // System.out.println("P,monic = " + P); ldbcf = P.leadingBaseCoefficient().leadingBaseCoefficient(); if (debug) { logger.debug("new ldbcf: " + ldbcf); } } // factors of content GenPolynomial<C> Pc = engine.recursiveContent(P); if (logger.isInfoEnabled()) { logger.info("Pc = " + Pc); } Pc = Pc.monic(); if (!Pc.isONE()) { P = PolyUtil.<C>coefficientPseudoDivide(P, Pc); } SortedMap<GenPolynomial<C>, Long> rsf = squarefreeFactors(Pc); if (logger.isInfoEnabled()) { logger.info("rsf = " + rsf); } // add factors of content for (Map.Entry<GenPolynomial<C>, Long> me : rsf.entrySet()) { GenPolynomial<C> c = me.getKey(); if (!c.isONE()) { GenPolynomial<GenPolynomial<C>> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rsf.get(c); sfactors.put(cr, rk); } } // factors of recursive polynomial GenPolynomial<GenPolynomial<C>> T0 = P; long e = 1L; GenPolynomial<GenPolynomial<C>> Tp; GenPolynomial<GenPolynomial<C>> T = null; GenPolynomial<GenPolynomial<C>> V = null; long k = 0L; long mp = 0L; boolean init = true; while (true) { if (init) { if (T0.isConstant() || T0.isZERO()) { break; } Tp = PolyUtil.<C>recursiveDeriviative(T0); T = engine.recursiveUnivariateGcd(T0, Tp); T = PolyUtil.<C>monic(T); V = PolyUtil.<C>recursivePseudoDivide(T0, T); // System.out.println("iT0 = " + T0); // System.out.println("iTp = " + Tp); // System.out.println("iT = " + T); // System.out.println("iV = " + V); k = 0L; mp = 0L; init = false; } if (V.isConstant()) { mp = pfac.characteristic().longValue(); // assert != 0 // T0 = PolyUtil.<C> recursiveModRoot(T,mp); T0 = recursiveUnivariateRootCharacteristic(T); logger.info("char root: T0r = " + T0 + ", Tr = " + T); if (T0 == null) { // break; T0 = pfac.getZERO(); } e = e * mp; init = true; // continue; } k++; if (mp != 0L && k % mp == 0L) { T = PolyUtil.<C>recursivePseudoDivide(T, V); System.out.println("k = " + k); // System.out.println("T = " + T); k++; } GenPolynomial<GenPolynomial<C>> W = engine.recursiveUnivariateGcd(T, V); W = PolyUtil.<C>monic(W); GenPolynomial<GenPolynomial<C>> z = PolyUtil.<C>recursivePseudoDivide(V, W); // System.out.println("W = " + W); // System.out.println("z = " + z); V = W; T = PolyUtil.<C>recursivePseudoDivide(T, V); // System.out.println("V = " + V); // System.out.println("T = " + T); // was: if ( z.degree(0) > 0 ) { if (!z.isONE() && !z.isZERO()) { z = PolyUtil.<C>monic(z); logger.info("z,put = " + z); sfactors.put(z, (e * k)); } } logger.info("exit char root: T0 = " + T0 + ", T = " + T); if (sfactors.size() == 0) { sfactors.put(pfac.getONE(), 1L); } return sfactors; }
/** * GenPolynomial polynomial squarefree factorization. * * @param A GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A) { SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); if (A == null || A.isZERO()) { return sfactors; } GenPolynomialRing<C> pfac = A.ring; if (A.isConstant()) { C coeff = A.leadingBaseCoefficient(); // System.out.println("coeff = " + coeff + " @ " + coeff.factory()); SortedMap<C, Long> rfactors = squarefreeFactors(coeff); // System.out.println("rfactors,const = " + rfactors); if (rfactors != null && rfactors.size() > 0) { for (Map.Entry<C, Long> me : rfactors.entrySet()) { C c = me.getKey(); if (!c.isONE()) { GenPolynomial<C> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rfactors.get(c); sfactors.put(cr, rk); } } } else { sfactors.put(A, 1L); } return sfactors; } if (pfac.nvar > 1) { throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } C ldbcf = A.leadingBaseCoefficient(); if (!ldbcf.isONE()) { A = A.divide(ldbcf); SortedMap<C, Long> rfactors = squarefreeFactors(ldbcf); // System.out.println("rfactors,ldbcf = " + rfactors); if (rfactors != null && rfactors.size() > 0) { for (Map.Entry<C, Long> me : rfactors.entrySet()) { C c = me.getKey(); if (!c.isONE()) { GenPolynomial<C> cr = pfac.getONE().multiply(c); Long rk = me.getValue(); // rfactors.get(c); sfactors.put(cr, rk); } } } else { GenPolynomial<C> f1 = pfac.getONE().multiply(ldbcf); // System.out.println("gcda sqf f1 = " + f1); sfactors.put(f1, 1L); } ldbcf = pfac.coFac.getONE(); } GenPolynomial<C> T0 = A; long e = 1L; GenPolynomial<C> Tp; GenPolynomial<C> T = null; GenPolynomial<C> V = null; long k = 0L; long mp = 0L; boolean init = true; while (true) { // System.out.println("T0 = " + T0); if (init) { if (T0.isConstant() || T0.isZERO()) { break; } Tp = PolyUtil.<C>baseDeriviative(T0); T = engine.baseGcd(T0, Tp); T = T.monic(); V = PolyUtil.<C>basePseudoDivide(T0, T); // System.out.println("iT0 = " + T0); // System.out.println("iTp = " + Tp); // System.out.println("iT = " + T); // System.out.println("iV = " + V); // System.out.println("const(iV) = " + V.isConstant()); k = 0L; mp = 0L; init = false; } if (V.isConstant()) { mp = pfac.characteristic().longValue(); // assert != 0 // T0 = PolyUtil.<C> baseModRoot(T,mp); T0 = baseRootCharacteristic(T); logger.info("char root: T0 = " + T0 + ", T = " + T); if (T0 == null) { // break; T0 = pfac.getZERO(); } e = e * mp; init = true; continue; } k++; if (mp != 0L && k % mp == 0L) { T = PolyUtil.<C>basePseudoDivide(T, V); System.out.println("k = " + k); // System.out.println("T = " + T); k++; } GenPolynomial<C> W = engine.baseGcd(T, V); W = W.monic(); GenPolynomial<C> z = PolyUtil.<C>basePseudoDivide(V, W); // System.out.println("W = " + W); // System.out.println("z = " + z); V = W; T = PolyUtil.<C>basePseudoDivide(T, V); // System.out.println("V = " + V); // System.out.println("T = " + T); if (z.degree(0) > 0) { if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) { z = z.monic(); logger.info("z,monic = " + z); } sfactors.put(z, (e * k)); } } // look, a stupid error: // if ( !ldbcf.isONE() ) { // GenPolynomial<C> f1 = sfactors.firstKey(); // long e1 = sfactors.remove(f1); // System.out.println("gcda sqf c = " + c); // f1 = f1.multiply(c); // //System.out.println("gcda sqf f1e = " + f1); // sfactors.put(f1,e1); // } logger.info("exit char root: T0 = " + T0 + ", T = " + T); return sfactors; }