[Home] DMelt member access. Java source code: edu.jas.ufd.HenselMultUtil
/*
* $Id$
*/
package edu.jas.ufd;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import edu.jas.arith.BigInteger;
import edu.jas.arith.ModIntegerRing;
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.ps.PolynomialTaylorFunction;
import edu.jas.ps.TaylorFunction;
import edu.jas.ps.UnivPowerSeries;
import edu.jas.ps.UnivPowerSeriesRing;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.Power;
import edu.jas.structure.RingFactory;
/**
* Hensel multivariate lifting utilities.
* @author Heinz Kredel
*/
public class HenselMultUtil {
private static final Logger logger = Logger.getLogger(HenselMultUtil.class);
private static final boolean debug = logger.isInfoEnabled();
/**
* Modular diophantine equation solution and lifting algorithm. Let p =
* A_i.ring.coFac.modul() and assume ggt(A,B) == 1 mod p.
* @param A modular GenPolynomial, mod p^k
* @param B modular GenPolynomial, mod p^k
* @param C modular GenPolynomial, mod p^k
* @param V list of substitution values, mod p^k
* @param d desired approximation exponent (x_i-v_i)^d.
* @param k desired approximation exponent p^k.
* @return [s, t] with s A' + t B' = C mod p^k, with A' = B, B' = A.
*/
public static & Modular> List> liftDiophant(
GenPolynomial A, GenPolynomial B, GenPolynomial C, List V, long d,
long k) throws NoLiftingException {
GenPolynomialRing pkfac = C.ring;
if (pkfac.nvar == 1) { // V, d ignored
return HenselUtil. liftDiophant(A, B, C, k);
}
if (!pkfac.equals(A.ring)) {
throw new IllegalArgumentException("A.ring != pkfac: " + A.ring + " != " + pkfac);
}
// evaluate at v_n:
List Vp = new ArrayList(V);
MOD v = Vp.remove(Vp.size() - 1);
//GenPolynomial zero = pkfac.getZERO();
// (x_n - v)
GenPolynomial mon = pkfac.getONE();
GenPolynomial xv = pkfac.univariate(0, 1);
xv = xv.subtract(pkfac.fromInteger(v.getSymmetricInteger().getVal()));
//System.out.println("xv = " + xv);
// A(v), B(v), C(v)
ModularRingFactory cf = (ModularRingFactory) pkfac.coFac;
MOD vp = cf.fromInteger(v.getSymmetricInteger().getVal());
//System.out.println("v = " + v + ", vp = " + vp);
GenPolynomialRing ckfac = pkfac.contract(1);
GenPolynomial Ap = PolyUtil. evaluateMain(ckfac, A, vp);
GenPolynomial Bp = PolyUtil. evaluateMain(ckfac, B, vp);
GenPolynomial Cp = PolyUtil. evaluateMain(ckfac, C, vp);
//System.out.println("Ap = " + Ap);
//System.out.println("Bp = " + Bp);
//System.out.println("Cp = " + Cp);
// recursion:
List> su = HenselMultUtil. liftDiophant(Ap, Bp, Cp, Vp, d, k);
//System.out.println("su@p^" + k + " = " + su);
//System.out.println("coFac = " + su.get(0).ring.coFac.toScript());
if (pkfac.nvar == 2 && !HenselUtil. isDiophantLift(Bp, Ap, su.get(0), su.get(1), Cp)) {
//System.out.println("isDiophantLift: false");
throw new NoLiftingException("isDiophantLift: false");
}
if (!ckfac.equals(su.get(0).ring)) {
throw new IllegalArgumentException("qfac != ckfac: " + su.get(0).ring + " != " + ckfac);
}
GenPolynomialRing ifac = new GenPolynomialRing(new BigInteger(), pkfac);
//GenPolynomialRing cifac = new GenPolynomialRing(new BigInteger(), ckfac);
//System.out.println("ifac = " + ifac.toScript());
String[] mn = new String[] { pkfac.getVars()[pkfac.nvar - 1] };
GenPolynomialRing> qrfac = new GenPolynomialRing>(ckfac, 1, mn);
//System.out.println("qrfac = " + qrfac);
List> sup = new ArrayList>(su.size());
List> supi = new ArrayList>(su.size());
for (GenPolynomial s : su) {
GenPolynomial sp = s.extend(pkfac, 0, 0L);
sup.add(sp);
GenPolynomial spi = PolyUtil.integerFromModularCoefficients(ifac, sp);
supi.add(spi);
}
//System.out.println("sup = " + sup);
//System.out.println("supi = " + supi);
GenPolynomial Ai = PolyUtil.integerFromModularCoefficients(ifac, A);
GenPolynomial Bi = PolyUtil.integerFromModularCoefficients(ifac, B);
GenPolynomial Ci = PolyUtil.integerFromModularCoefficients(ifac, C);
//System.out.println("Ai = " + Ai);
//System.out.println("Bi = " + Bi);
//System.out.println("Ci = " + Ci);
//GenPolynomial aq = PolyUtil. fromIntegerCoefficients(pkfac, Ai);
//GenPolynomial bq = PolyUtil. fromIntegerCoefficients(pkfac, Bi);
//System.out.println("aq = " + aq);
//System.out.println("bq = " + bq);
// compute error:
GenPolynomial E = Ci; // - sum_i s_i b_i
E = E.subtract(Bi.multiply(supi.get(0)));
E = E.subtract(Ai.multiply(supi.get(1)));
//System.out.println("E = " + E);
if (E.isZERO()) {
logger.info("liftDiophant leaving on zero E");
return sup;
}
GenPolynomial Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(0," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(0," + pkfac.nvar + ") = " + Ep);
if (Ep.isZERO()) {
logger.info("liftDiophant leaving on zero Ep mod p^k");
return sup;
}
for (int e = 1; e <= d; e++) {
//System.out.println("\ne = " + e + " -------------------------------------- " + pkfac.nvar);
GenPolynomial> Epr = PolyUtil. recursive(qrfac, Ep);
//System.out.println("Epr = " + Epr);
UnivPowerSeriesRing> psfac = new UnivPowerSeriesRing>(qrfac);
//System.out.println("psfac = " + psfac);
TaylorFunction> F = new PolynomialTaylorFunction>(Epr);
//System.out.println("F = " + F);
List> Vs = new ArrayList>(1);
GenPolynomial vq = ckfac.fromInteger(v.getSymmetricInteger().getVal());
Vs.add(vq);
//System.out.println("Vs = " + Vs);
UnivPowerSeries> Epst = psfac.seriesOfTaylor(F, vq);
//System.out.println("Epst = " + Epst);
GenPolynomial cm = Epst.coefficient(e);
//System.out.println("cm = " + cm + ", cm.ring = " + cm.ring.toScript());
// recursion:
List> S = HenselMultUtil. liftDiophant(Ap, Bp, cm, Vp, d, k);
//System.out.println("S = " + S);
if (!ckfac.coFac.equals(S.get(0).ring.coFac)) {
throw new IllegalArgumentException("ckfac != pkfac: " + ckfac.coFac + " != "
+ S.get(0).ring.coFac);
}
if (pkfac.nvar == 2 && !HenselUtil. isDiophantLift(Ap, Bp, S.get(1), S.get(0), cm)) {
//System.out.println("isDiophantLift: false");
throw new NoLiftingException("isDiophantLift: false");
}
mon = mon.multiply(xv); // Power.> power(pkfac,xv,e);
//System.out.println("mon = " + mon);
List> Sp = new ArrayList>(S.size());
int i = 0;
supi = new ArrayList>(su.size());
for (GenPolynomial dd : S) {
//System.out.println("dd = " + dd);
GenPolynomial de = dd.extend(pkfac, 0, 0L);
GenPolynomial dm = de.multiply(mon);
Sp.add(dm);
de = sup.get(i).sum(dm);
//System.out.println("dd = " + dd);
sup.set(i++, de);
GenPolynomial spi = PolyUtil.integerFromModularCoefficients(ifac, dm);
supi.add(spi);
}
//System.out.println("Sp = " + Sp);
//System.out.println("sup = " + sup);
//System.out.println("supi = " + supi);
// compute new error
//E = E; // - sum_i s_i b_i
E = E.subtract(Bi.multiply(supi.get(0)));
E = E.subtract(Ai.multiply(supi.get(1)));
//System.out.println("E = " + E);
if (E.isZERO()) {
logger.info("liftDiophant leaving on zero E");
return sup;
}
Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(" + e + "," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(" + e + "," + pkfac.nvar + ") = " + Ep);
if (Ep.isZERO()) {
logger.info("liftDiophant leaving on zero Ep mod p^k");
return sup;
}
}
//System.out.println("*** done: " + pkfac.nvar);
return sup;
}
/**
* Modular diophantine equation solution and lifting algorithm. Let p =
* A_i.ring.coFac.modul() and assume ggt(a,b) == 1 mod p, for a, b in A.
* @param A list of modular GenPolynomials, mod p^k
* @param C modular GenPolynomial, mod p^k
* @param V list of substitution values, mod p^k
* @param d desired approximation exponent (x_i-v_i)^d.
* @param k desired approximation exponent p^k.
* @return [s_1,..., s_n] with sum_i s_i A_i' = C mod p^k, with Ai' =
* prod_{j!=i} A_j.
*/
public static & Modular> List> liftDiophant(
List> A, GenPolynomial C, List V, long d, long k)
throws NoLiftingException {
GenPolynomialRing pkfac = C.ring;
if (pkfac.nvar == 1) { // V, d ignored
return HenselUtil. liftDiophant(A, C, k);
}
if (!pkfac.equals(A.get(0).ring)) {
throw new IllegalArgumentException("A.ring != pkfac: " + A.get(0).ring + " != " + pkfac);
}
// co-products
GenPolynomial As = pkfac.getONE();
for (GenPolynomial a : A) {
As = As.multiply(a);
}
List> Bp = new ArrayList>(A.size());
for (GenPolynomial a : A) {
GenPolynomial b = PolyUtil. basePseudoDivide(As, a);
Bp.add(b);
}
// evaluate at v_n:
List Vp = new ArrayList(V);
MOD v = Vp.remove(Vp.size() - 1);
// (x_n - v)
GenPolynomial mon = pkfac.getONE();
GenPolynomial xv = pkfac.univariate(0, 1);
xv = xv.subtract(pkfac.fromInteger(v.getSymmetricInteger().getVal()));
//System.out.println("xv = " + xv);
// A(v), B(v), C(v)
ModularRingFactory cf = (ModularRingFactory) pkfac.coFac;
MOD vp = cf.fromInteger(v.getSymmetricInteger().getVal());
//System.out.println("v = " + v + ", vp = " + vp);
GenPolynomialRing ckfac = pkfac.contract(1);
List> Ap = new ArrayList>(A.size());
for (GenPolynomial a : A) {
GenPolynomial ap = PolyUtil. evaluateMain(ckfac, a, vp);
Ap.add(ap);
}
GenPolynomial Cp = PolyUtil. evaluateMain(ckfac, C, vp);
//System.out.println("Ap = " + Ap);
//System.out.println("Cp = " + Cp);
// recursion:
List> su = HenselMultUtil. liftDiophant(Ap, Cp, Vp, d, k);
//System.out.println("su@p^" + k + " = " + su);
//System.out.println("coFac = " + su.get(0).ring.coFac.toScript());
if (pkfac.nvar == 2 && !HenselUtil. isDiophantLift(Ap, su, Cp)) {
//System.out.println("isDiophantLift: false");
throw new NoLiftingException("isDiophantLift: false");
}
if (!ckfac.equals(su.get(0).ring)) {
throw new IllegalArgumentException("qfac != ckfac: " + su.get(0).ring + " != " + ckfac);
}
GenPolynomialRing ifac = new GenPolynomialRing(new BigInteger(), pkfac);
//GenPolynomialRing cifac = new GenPolynomialRing(new BigInteger(), ckfac);
//System.out.println("ifac = " + ifac.toScript());
String[] mn = new String[] { pkfac.getVars()[pkfac.nvar - 1] };
GenPolynomialRing> qrfac = new GenPolynomialRing>(ckfac, 1, mn);
//System.out.println("qrfac = " + qrfac);
List> sup = new ArrayList>(su.size());
List> supi = new ArrayList>(su.size());
for (GenPolynomial s : su) {
GenPolynomial sp = s.extend(pkfac, 0, 0L);
sup.add(sp);
GenPolynomial spi = PolyUtil.integerFromModularCoefficients(ifac, sp);
supi.add(spi);
}
//System.out.println("sup = " + sup);
//System.out.println("supi = " + supi);
List> Ai = new ArrayList>(A.size());
for (GenPolynomial a : A) {
GenPolynomial ai = PolyUtil.integerFromModularCoefficients(ifac, a);
Ai.add(ai);
}
List> Bi = new ArrayList>(A.size());
for (GenPolynomial b : Bp) {
GenPolynomial bi = PolyUtil.integerFromModularCoefficients(ifac, b);
Bi.add(bi);
}
GenPolynomial Ci = PolyUtil.integerFromModularCoefficients(ifac, C);
//System.out.println("Ai = " + Ai);
//System.out.println("Ci = " + Ci);
List> Aq = new ArrayList>(A.size());
for (GenPolynomial ai : Ai) {
GenPolynomial aq = PolyUtil. fromIntegerCoefficients(pkfac, ai);
Aq.add(aq);
}
//System.out.println("Aq = " + Aq);
// compute error:
GenPolynomial E = Ci; // - sum_i s_i b_i
int i = 0;
for (GenPolynomial bi : Bi) {
E = E.subtract(bi.multiply(supi.get(i++)));
}
//System.out.println("E = " + E);
if (E.isZERO()) {
logger.info("liftDiophant leaving on zero E");
return sup;
}
GenPolynomial Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(0," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(0," + pkfac.nvar + ") = " + Ep);
if (Ep.isZERO()) {
logger.info("liftDiophant leaving on zero Ep mod p^k");
return sup;
}
for (int e = 1; e <= d; e++) {
//System.out.println("\ne = " + e + " -------------------------------------- " + pkfac.nvar);
GenPolynomial> Epr = PolyUtil. recursive(qrfac, Ep);
//System.out.println("Epr = " + Epr);
UnivPowerSeriesRing> psfac = new UnivPowerSeriesRing>(qrfac);
//System.out.println("psfac = " + psfac);
TaylorFunction> F = new PolynomialTaylorFunction>(Epr);
//System.out.println("F = " + F);
List> Vs = new ArrayList>(1);
GenPolynomial vq = ckfac.fromInteger(v.getSymmetricInteger().getVal());
Vs.add(vq);
//System.out.println("Vs = " + Vs);
UnivPowerSeries> Epst = psfac.seriesOfTaylor(F, vq);
//System.out.println("Epst = " + Epst);
GenPolynomial cm = Epst.coefficient(e);
//System.out.println("cm = " + cm + ", cm.ring = " + cm.ring.toScript());
if (cm.isZERO()) {
continue;
}
// recursion:
List> S = HenselMultUtil. liftDiophant(Ap, cm, Vp, d, k);
//System.out.println("S = " + S);
if (!ckfac.coFac.equals(S.get(0).ring.coFac)) {
throw new IllegalArgumentException("ckfac != pkfac: " + ckfac.coFac + " != "
+ S.get(0).ring.coFac);
}
if (pkfac.nvar == 2 && !HenselUtil. isDiophantLift(Ap, S, cm)) {
//System.out.println("isDiophantLift: false");
throw new NoLiftingException("isDiophantLift: false");
}
mon = mon.multiply(xv); // Power.> power(pkfac,xv,e);
//System.out.println("mon = " + mon);
List> Sp = new ArrayList>(S.size());
i = 0;
supi = new ArrayList>(su.size());
for (GenPolynomial dd : S) {
//System.out.println("dd = " + dd);
GenPolynomial de = dd.extend(pkfac, 0, 0L);
GenPolynomial dm = de.multiply(mon);
Sp.add(dm);
de = sup.get(i).sum(dm);
//System.out.println("dd = " + dd);
sup.set(i++, de);
GenPolynomial spi = PolyUtil.integerFromModularCoefficients(ifac, dm);
supi.add(spi);
}
//System.out.println("Sp = " + Sp);
//System.out.println("sup = " + sup);
//System.out.println("supi = " + supi);
// compute new error
//E = E; // - sum_i s_i b_i
i = 0;
for (GenPolynomial bi : Bi) {
E = E.subtract(bi.multiply(supi.get(i++)));
}
//System.out.println("E = " + E);
if (E.isZERO()) {
logger.info("liftDiophant leaving on zero E");
return sup;
}
Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(" + e + "," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(" + e + "," + pkfac.nvar + ") = " + Ep);
if (Ep.isZERO()) {
logger.info("liftDiophant leaving on zero Ep mod p^k");
return sup;
}
}
//System.out.println("*** done: " + pkfac.nvar);
return sup;
}
/**
* Modular Hensel lifting algorithm on coefficients test. Let p =
* f_i.ring.coFac.modul() and assume C == prod_{0,...,n-1} f_i mod p with
* gcd(f_i,f_j) == 1 mod p for i != j
* @param C integer polynomial
* @param Cp GenPolynomial mod p^k
* @param F = [f_0,...,f_{n-1}] list of monic modular polynomials.
* @param k approximation exponent.
* @param L = [g_0,...,g_{n-1}] list of lifted modular polynomials.
* @return true if C = prod_{0,...,n-1} g_i mod p^k, else false.
* @deprecated use isHenselLift() without parameter k
*/
@Deprecated
public static & Modular> boolean isHenselLift(GenPolynomial C,
GenPolynomial Cp, List> F, long k, List> L) {
return isHenselLift(C,Cp,F,L);
}
/**
* Modular Hensel lifting algorithm on coefficients test. Let p =
* f_i.ring.coFac.modul() and assume C == prod_{0,...,n-1} f_i mod p with
* gcd(f_i,f_j) == 1 mod p for i != j
* @param C integer polynomial
* @param Cp GenPolynomial mod p^k
* @param F = [f_0,...,f_{n-1}] list of monic modular polynomials.
* @param L = [g_0,...,g_{n-1}] list of lifted modular polynomials.
* @return true if C = prod_{0,...,n-1} g_i mod p^k, else false.
*/
public static & Modular> boolean isHenselLift(GenPolynomial C,
GenPolynomial Cp, List> F, List> L) {
boolean t = true;
GenPolynomialRing qfac = L.get(0).ring;
GenPolynomial q = qfac.getONE();
for (GenPolynomial fi : L) {
q = q.multiply(fi);
}
t = Cp.equals(q);
if (!t) {
System.out.println("Cp = " + Cp);
System.out.println("q = " + q);
System.out.println("Cp != q: " + Cp.subtract(q));
return t;
}
GenPolynomialRing dfac = C.ring;
GenPolynomial Ci = PolyUtil.integerFromModularCoefficients(dfac, q);
t = C.equals(Ci);
if (!t) {
System.out.println("C = " + C);
System.out.println("Ci = " + Ci);
System.out.println("C != Ci: " + C.subtract(Ci));
return t;
}
// test L mod id(V) == F
return t;
}
/**
* Modular Hensel lifting algorithm, monic case. Let p =
* A_i.ring.coFac.modul() and assume ggt(a,b) == 1 mod p, for a, b in A.
* @param C monic GenPolynomial with integer coefficients
* @param Cp GenPolynomial mod p^k
* @param F list of modular GenPolynomials, mod (I_v, p^k )
* @param V list of integer substitution values
* @param k desired approximation exponent p^k.
* @return [g'_1,..., g'_n] with prod_i g'_i = Cp mod p^k.
*/
public static & Modular> List> liftHenselMonic(
GenPolynomial C, GenPolynomial Cp, List> F,
List V, long k) throws NoLiftingException {
GenPolynomialRing pkfac = Cp.ring;
//if (pkfac.nvar == 1) { // V ignored
// return HenselUtil. liftHenselMonic(C,F,k);
//}
long d = C.degree();
//System.out.println("d = " + d);
// prepare stack of polynomial rings and polynomials
List> Pfac = new ArrayList>();
List> Ap = new ArrayList>();
List Vb = new ArrayList();
MOD v = pkfac.coFac.fromInteger( V.get(0).getVal() );
Pfac.add(pkfac);
Ap.add(Cp);
Vb.add(v);
GenPolynomialRing pf = pkfac;
GenPolynomial ap = Cp;
for (int j = pkfac.nvar; j > 2; j--) {
pf = pf.contract(1);
Pfac.add(0, pf);
//MOD vp = pkfac.coFac.fromInteger(V.get(j - 2).getSymmetricInteger().getVal());
MOD vp = pkfac.coFac.fromInteger(V.get(j - 2).getVal());
//System.out.println("vp = " + vp);
Vb.add(1, vp);
ap = PolyUtil. evaluateMain(pf, ap, vp);
Ap.add(0, ap);
}
//System.out.println("Pfac = " + Pfac);
if (debug) {
logger.debug("Pfac = " + Pfac);
}
//System.out.println("Ap = " + Ap);
//System.out.println("V = " + V);
//System.out.println("Vb = " + Vb);
// setup bi-variate base case
GenPolynomialRing pk1fac = F.get(0).ring;
if (!pkfac.coFac.equals(pk1fac.coFac)) {
throw new IllegalArgumentException("F.ring != pkfac: " + pk1fac + " != " + pkfac);
}
// TODO: adjust leading coefficients
pkfac = Pfac.get(0);
//Cp = Ap.get(0);
//System.out.println("pkfac = " + pkfac.toScript());
//System.out.println("pk1fac = " + pk1fac.toScript());
GenPolynomialRing i1fac = new GenPolynomialRing(new BigInteger(), pk1fac);
//System.out.println("i1fac = " + i1fac.toScript());
List> Bi = new ArrayList>(F.size());
for (GenPolynomial b : F) {
GenPolynomial bi = PolyUtil.integerFromModularCoefficients(i1fac, b);
Bi.add(bi);
}
//System.out.println("Bi = " + Bi);
// evaluate Cp at v_n:
//ModularRingFactory cf = (ModularRingFactory) pkfac.coFac;
//MOD vp = cf.fromInteger(v.getSymmetricInteger().getVal());
//System.out.println("v = " + v + ", vp = " + vp);
GenPolynomialRing ckfac; // = pkfac.contract(1);
//GenPolynomial Cs = PolyUtil. evaluateMain(ckfac, Cp, vp);
//System.out.println("Cp = " + Cp);
//System.out.println("Cs = " + Cs);
List> U = new ArrayList>(F.size());
for (GenPolynomial b : F) {
GenPolynomial bi = b.extend(pkfac, 0, 0L);
U.add(bi);
}
//System.out.println("U = " + U);
List> U1 = F;
//System.out.println("U1 = " + U1);
GenPolynomial E = C.ring.getZERO();
List Vh = new ArrayList();
while (Pfac.size() > 0) { // loop through stack of polynomial rings
pkfac = Pfac.remove(0);
Cp = Ap.remove(0);
v = Vb.remove(0);
//Vh.add(0,v);
//System.out.println("\npkfac = " + pkfac.toScript() + " ================================== " + Vh);
// (x_n - v)
GenPolynomial mon = pkfac.getONE();
GenPolynomial xv = pkfac.univariate(0, 1);
xv = xv.subtract(pkfac.fromInteger(v.getSymmetricInteger().getVal()));
//System.out.println("xv = " + xv);
long deg = Cp.degree(pkfac.nvar - 1);
//System.out.println("deg = " + deg);
GenPolynomialRing ifac = new GenPolynomialRing(new BigInteger(), pkfac);
//System.out.println("ifac = " + ifac.toScript());
List> Bip = new ArrayList>(F.size());
for (GenPolynomial b : Bi) {
GenPolynomial bi = b.extend(ifac, 0, 0L);
Bip.add(bi);
}
Bi = Bip;
//System.out.println("Bi = " + Bi);
GenPolynomial Ci = PolyUtil.integerFromModularCoefficients(ifac, Cp);
//System.out.println("Ci = " + Ci);
// compute error:
E = ifac.getONE();
for (GenPolynomial bi : Bi) {
E = E.multiply(bi);
}
E = Ci.subtract(E);
//System.out.println("E = " + E);
GenPolynomial Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(0," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(0," + deg + "," + pkfac.nvar + ") = " + Ep);
String[] mn = new String[] { pkfac.getVars()[pkfac.nvar - 1] };
ckfac = pkfac.contract(1);
GenPolynomialRing> pkrfac = new GenPolynomialRing>(ckfac,
1, mn);
//System.out.println("pkrfac = " + pkrfac.toScript());
for (int e = 1; e <= deg && !Ep.isZERO(); e++) {
//System.out.println("\ne = " + e + " -------------------------------------- " + pkfac.nvar);
GenPolynomial> Epr = PolyUtil. recursive(pkrfac, Ep);
//System.out.println("Epr = " + Epr);
UnivPowerSeriesRing> psfac = new UnivPowerSeriesRing>(
pkrfac);
//System.out.println("psfac = " + psfac);
TaylorFunction> T = new PolynomialTaylorFunction>(Epr);
//System.out.println("T = " + T);
List> Vs = new ArrayList>(1);
GenPolynomial vq = ckfac.fromInteger(v.getSymmetricInteger().getVal());
Vs.add(vq);
//System.out.println("Vs = " + Vs + ", Vh = " + Vh);
UnivPowerSeries> Epst = psfac.seriesOfTaylor(T, vq);
//System.out.println("Epst = " + Epst);
logger.info("Epst(" + e + "," + deg + ", " + pkfac.nvar + ") = " + Epst);
GenPolynomial cm = Epst.coefficient(e);
//System.out.println("cm = " + cm);
if (cm.isZERO()) {
continue;
}
List> Ud = HenselMultUtil. liftDiophant(U1, cm, Vh, d, k);
//System.out.println("Ud = " + Ud);
mon = mon.multiply(xv); // Power.> power(pkfac,xv,e);
//System.out.println("mon = " + mon);
List> Sd = new ArrayList>(Ud.size());
int i = 0;
List> Si = new ArrayList>(Ud.size());
for (GenPolynomial dd : Ud) {
//System.out.println("dd = " + dd);
GenPolynomial de = dd.extend(pkfac, 0, 0L);
GenPolynomial dm = de.multiply(mon);
Sd.add(dm);
de = U.get(i).sum(dm);
//System.out.println("de = " + de);
U.set(i++, de);
GenPolynomial si = PolyUtil.integerFromModularCoefficients(ifac, de);
Si.add(si);
}
//System.out.println("Sd = " + Sd);
//System.out.println("U = " + U);
//System.out.println("Si = " + Si);
// compute new error:
E = ifac.getONE();
for (GenPolynomial bi : Si) {
E = E.multiply(bi);
}
E = Ci.subtract(E);
//System.out.println("E = " + E);
Ep = PolyUtil. fromIntegerCoefficients(pkfac, E);
//System.out.println("Ep(0," + pkfac.nvar + ") = " + Ep);
logger.info("Ep(" + e + "," + deg + "," + pkfac.nvar + ") = " + Ep);
}
Vh.add(v);
U1 = U;
if (Pfac.size() > 0) {
List> U2 = new ArrayList>(U.size());
pkfac = Pfac.get(0);
for (GenPolynomial b : U) {
GenPolynomial bi = b.extend(pkfac, 0, 0L);
U2.add(bi);
}
U = U2;
//System.out.println("U = " + U);
}
}
if (E.isZERO()) {
logger.info("liftHensel leaving with zero E");
}
return U;
}
/**
* Modular Hensel lifting algorithm. Let p = A_i.ring.coFac.modul() and
* assume ggt(a,b) == 1 mod p, for a, b in A.
* @param C GenPolynomial with integer coefficients
* @param Cp GenPolynomial C mod p^k
* @param F list of modular GenPolynomials, mod (I_v, p^k )
* @param V list of integral substitution values
* @param k desired approximation exponent p^k.
* @param G list of leading coefficients of the factors of C.
* @return [g'_1,..., g'_n] with prod_i g'_i = Cp mod p^k.
*/
public static & Modular> List