
edu.jas.ufd.GreatestCommonDivisorHensel Maven / Gradle / Ivy
The newest version!
/*
* $Id: GreatestCommonDivisorHensel.java 4365 2013-02-03 14:07:02Z kredel $
*/
package edu.jas.ufd;
import java.util.ArrayList;
import java.util.Iterator;
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.arith.PrimeList;
import edu.jas.poly.ExpVector;
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;
import edu.jas.structure.NotInvertibleException;
//import edu.jas.application.Ideal;
/**
* Greatest common divisor algorithms with subresultant polynomial remainder
* sequence and univariate Hensel lifting.
* @author Heinz Kredel
*/
public class GreatestCommonDivisorHensel & Modular> extends
GreatestCommonDivisorAbstract {
private static final Logger logger = Logger.getLogger(GreatestCommonDivisorHensel.class);
private final boolean debug = logger.isDebugEnabled();
/**
* Flag for linear or quadratic Hensel lift.
*/
public final boolean quadratic;
/**
* Fall back gcd algorithm.
*/
public final GreatestCommonDivisorAbstract iufd;
/*
* Internal dispatcher.
*/
private final GreatestCommonDivisorAbstract ufd;
/**
* Constructor.
*/
public GreatestCommonDivisorHensel() {
this(true);
}
/**
* Constructor.
* @param quadratic use quadratic Hensel lift.
*/
public GreatestCommonDivisorHensel(boolean quadratic) {
this.quadratic = quadratic;
iufd = new GreatestCommonDivisorSubres();
ufd = this; //iufd;
}
/**
* Univariate GenPolynomial greatest comon divisor. Uses univariate Hensel
* lifting.
* @param P univariate GenPolynomial.
* @param S univariate GenPolynomial.
* @return gcd(P,S).
*/
@Override
public GenPolynomial baseGcd(GenPolynomial P, GenPolynomial S) {
if (S == null || S.isZERO()) {
return P;
}
if (P == null || P.isZERO()) {
return S;
}
if (P.ring.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
}
GenPolynomialRing fac = P.ring;
long e = P.degree(0);
long f = S.degree(0);
GenPolynomial q;
GenPolynomial r;
if (f > e) {
r = P;
q = S;
long g = f;
f = e;
e = g;
} else {
q = P;
r = S;
}
if (debug) {
logger.debug("degrees: e = " + e + ", f = " + f);
}
r = r.abs();
q = q.abs();
// compute contents and primitive parts
BigInteger a = baseContent(r);
BigInteger b = baseContent(q);
// gcd of coefficient contents
BigInteger c = gcd(a, b); // indirection
r = divide(r, a); // indirection
q = divide(q, b); // indirection
if (r.isONE()) {
return r.multiply(c);
}
if (q.isONE()) {
return q.multiply(c);
}
// compute normalization factor
BigInteger ac = r.leadingBaseCoefficient();
BigInteger bc = q.leadingBaseCoefficient();
BigInteger cc = gcd(ac, bc); // indirection
// compute degree vectors, only univeriate
ExpVector rdegv = r.degreeVector();
ExpVector qdegv = q.degreeVector();
//initialize prime list and degree vector
PrimeList primes = new PrimeList(PrimeList.Range.medium);
int pn = 50; //primes.size();
ModularRingFactory cofac;
GenPolynomial qm;
GenPolynomial qmf;
GenPolynomial rm;
GenPolynomial rmf;
GenPolynomial cmf;
GenPolynomialRing mfac;
GenPolynomial cm = null;
GenPolynomial[] ecm = null;
GenPolynomial sm = null;
GenPolynomial tm = null;
HenselApprox lift = null;
if (debug) {
logger.debug("c = " + c);
logger.debug("cc = " + cc);
logger.debug("primes = " + primes);
}
int i = 0;
for (java.math.BigInteger p : primes) {
//System.out.println("next run ++++++++++++++++++++++++++++++++++");
if (++i >= pn) {
logger.error("prime list exhausted, pn = " + pn);
//logger.info("primes = " + primes);
return iufd.baseGcd(P, S);
//throw new ArithmeticException("prime list exhausted");
}
// initialize coefficient factory and map normalization factor
//cofac = new ModIntegerRing(p, true);
if (ModLongRing.MAX_LONG.compareTo(p) > 0) {
cofac = (ModularRingFactory) new ModLongRing(p, true);
} else {
cofac = (ModularRingFactory) new ModIntegerRing(p, true);
}
MOD nf = cofac.fromInteger(cc.getVal());
if (nf.isZERO()) {
continue;
}
nf = cofac.fromInteger(q.leadingBaseCoefficient().getVal());
if (nf.isZERO()) {
continue;
}
nf = cofac.fromInteger(r.leadingBaseCoefficient().getVal());
if (nf.isZERO()) {
continue;
}
// initialize polynomial factory and map polynomials
mfac = new GenPolynomialRing(cofac, fac.nvar, fac.tord, fac.getVars());
qm = PolyUtil. fromIntegerCoefficients(mfac, q);
if (!qm.degreeVector().equals(qdegv)) {
continue;
}
rm = PolyUtil. fromIntegerCoefficients(mfac, r);
if (!rm.degreeVector().equals(rdegv)) {
continue;
}
if (debug) {
logger.info("cofac = " + cofac.getIntegerModul());
}
// compute univariate modular gcd
cm = qm.gcd(rm);
// test for constant g.c.d
if (cm.isConstant()) {
logger.debug("cm, constant = " + cm);
return fac.getONE().multiply(c);
}
// compute factors and gcd with factor
GenPolynomial crq;
rmf = rm.divide(cm); // rm = cm * rmf
ecm = cm.egcd(rmf);
if (ecm[0].isONE()) {
//logger.debug("gcd() first factor " + rmf);
crq = r;
cmf = rmf;
sm = ecm[1];
tm = ecm[2];
} else {
qmf = qm.divide(cm); // qm = cm * qmf
ecm = cm.egcd(qmf);
if (ecm[0].isONE()) {
//logger.debug("gcd() second factor " + qmf);
crq = q;
cmf = qmf;
sm = ecm[1];
tm = ecm[2];
} else {
logger.info("both gcd != 1: Hensel not applicable");
return iufd.baseGcd(P, S);
}
}
BigInteger cn = crq.maxNorm();
cn = cn.multiply(crq.leadingBaseCoefficient().abs());
cn = cn.multiply(cn.fromInteger(2));
if (debug) {
System.out.println("crq = " + crq);
System.out.println("cm = " + cm);
System.out.println("cmf = " + cmf);
System.out.println("sm = " + sm);
System.out.println("tm = " + tm);
System.out.println("cn = " + cn);
}
try {
if (quadratic) {
lift = HenselUtil.liftHenselQuadratic(crq, cn, cm, cmf, sm, tm);
} else {
lift = HenselUtil.liftHensel(crq, cn, cm, cmf, sm, tm);
}
} catch (NoLiftingException nle) {
logger.info("giving up on Hensel gcd reverting to Subres gcd " + nle);
return iufd.baseGcd(P, S);
}
q = lift.A;
if (debug) {
System.out.println("q = " + q);
System.out.println("qf = " + lift.B);
}
q = basePrimitivePart(q);
q = q.multiply(c).abs();
if (PolyUtil. baseSparsePseudoRemainder(P, q).isZERO()
&& PolyUtil. baseSparsePseudoRemainder(S, q).isZERO()) {
break;
}
logger.info("final devision not successfull");
//System.out.println("P rem q = " + PolyUtil.basePseudoRemainder(P,q));
//System.out.println("S rem q = " + PolyUtil.basePseudoRemainder(S,q));
//break;
}
return q;
}
/**
* Univariate GenPolynomial recursive greatest comon divisor. Uses
* multivariate Hensel list.
* @param P univariate recursive GenPolynomial.
* @param S univariate recursive GenPolynomial.
* @return gcd(P,S).
*/
@Override
public GenPolynomial> recursiveUnivariateGcd(
GenPolynomial> P, GenPolynomial> S) {
if (S == null || S.isZERO()) {
return P;
}
if (P == null || P.isZERO()) {
return S;
}
if (P.ring.nvar > 1) {
throw new IllegalArgumentException(this.getClass().getName() + " no univariate polynomial");
}
long e = P.degree(0);
long f = S.degree(0);
GenPolynomial> q, r, s;
if (f > e) {
r = P;
q = S;
long g = f;
f = e;
e = g;
} else {
q = P;
r = S;
}
if (debug) {
logger.debug("degrees: e = " + e + ", f = " + f);
}
r = r.abs();
q = q.abs();
//logger.info("r: " + r + ", q: " + q);
GenPolynomial a = ufd.recursiveContent(r);
GenPolynomial b = ufd.recursiveContent(q);
GenPolynomial c = ufd.gcd(a, b); // go to recursion
//System.out.println("rgcd c = " + c);
r = PolyUtil. recursiveDivide(r, a);
q = PolyUtil. recursiveDivide(q, b);
a = PolyUtil. basePseudoDivide(a, c);
b = PolyUtil. basePseudoDivide(b, c);
if (r.isONE()) {
return r.multiply(c);
}
if (q.isONE()) {
return q.multiply(c);
}
// check constant ldcf, TODO general case
GenPolynomial la, lb, lc, lh;
la = r.leadingBaseCoefficient();
lb = q.leadingBaseCoefficient();
lc = ufd.gcd(la,lb);
//logger.info("la = " + la + ", lb = " + lb + ", lc = " + lc);
if ( !lc.isConstant() ) {
//continue; // easy way out
GenPolynomial> T = iufd.recursiveUnivariateGcd(r, q);
T = T.abs().multiply(c);
logger.info("non monic ldcf (" + lc + ") not implemented: " + T + "= gcd(" + r + "," + q + ") * " + c);
return T;
}
// convert from Z[y1,...,yr][x] to Z[x][y1,...,yr] to Z[x,y1,...,yr]
GenPolynomial> qs = PolyUtil. switchVariables(q);
GenPolynomial> rs = PolyUtil. switchVariables(r);
GenPolynomialRing> rfac = qs.ring;
RingFactory> rrfac = rfac.coFac;
GenPolynomialRing cfac = (GenPolynomialRing) rrfac;
GenPolynomialRing dfac = cfac.extend(rfac.getVars());
//System.out.println("pfac = " + P.ring.toScript());
//System.out.println("rfac = " + rfac.toScript());
//System.out.println("dfac = " + dfac.toScript());
GenPolynomial qd = PolyUtil. distribute(dfac, qs);
GenPolynomial rd = PolyUtil. distribute(dfac, rs);
// compute normalization factor
BigInteger ac = rd.leadingBaseCoefficient();
BigInteger bc = qd.leadingBaseCoefficient();
BigInteger cc = gcd(ac, bc); // indirection
//initialize prime list
PrimeList primes = new PrimeList(PrimeList.Range.medium);
Iterator primeIter = primes.iterator();
int pn = 50; //primes.size();
// double check variables
// need qe,re,qd,rd,a,b
GenPolynomial qe0, re0, ce0 = null;
for (int i = 0; i < 11; i++) { // meta loop
//System.out.println("======== run " + dfac.nvar + ", " + i);
java.math.BigInteger p = null; //new java.math.BigInteger("19"); //primes.next();
// 5 small, 4 medium and 2 large size primes
if (i == 0) { // medium size
primes = new PrimeList(PrimeList.Range.medium);
primeIter = primes.iterator();
}
if (i == 4) { // small size
primes = new PrimeList(PrimeList.Range.small);
primeIter = primes.iterator();
p = primeIter.next(); // 2
p = primeIter.next(); // 3
p = primeIter.next(); // 5
p = primeIter.next(); // 7
}
if (i == 9) { // large size
primes = new PrimeList(PrimeList.Range.large);
primeIter = primes.iterator();
}
ModularRingFactory cofac = null;
int pi = 0;
while (pi < pn && primeIter.hasNext()) {
p = primeIter.next();
//p = new java.math.BigInteger("19");
logger.info("prime = " + p);
// initialize coefficient factory and map normalization factor and polynomials
ModularRingFactory cf = null;
if (ModLongRing.MAX_LONG.compareTo(p) > 0) {
cf = (ModularRingFactory) new ModLongRing(p, true);
} else {
cf = (ModularRingFactory) new ModIntegerRing(p, true);
}
MOD nf = cf.fromInteger(cc.getVal());
if (nf.isZERO()) {
continue;
}
nf = cf.fromInteger(q.leadingBaseCoefficient().leadingBaseCoefficient().getVal());
if (nf.isZERO()) {
continue;
}
nf = cf.fromInteger(r.leadingBaseCoefficient().leadingBaseCoefficient().getVal());
if (nf.isZERO()) {
continue;
}
cofac = cf;
break;
}
if (cofac == null) { // no lucky prime found
GenPolynomial> T = iufd.recursiveUnivariateGcd(q, r);
logger.info("no lucky prime, gave up on Hensel: " + T + "= gcd(" + r + "," + q + ")");
return T.abs().multiply(c); //.abs();
}
//System.out.println("cofac = " + cofac);
// search evaluation points and evaluate
List V = new ArrayList(P.ring.nvar);
GenPolynomialRing ckfac = dfac;
GenPolynomial qe = qd;
GenPolynomial re = rd;
GenPolynomial qei;
GenPolynomial rei;
for (int j = dfac.nvar; j > 1; j--) {
// evaluation to univariate case
long degq = qe.degree(ckfac.nvar - 2);
long degr = re.degree(ckfac.nvar - 2);
ckfac = ckfac.contract(1);
long vi = 1L; //(long)(dfac.nvar-j); // 1L; 0 not so good for small p
if (p.longValue() > 1000L) {
//vi = (long)j+1L;
vi = 0L;
}
// search small evaluation point
while (true) {
MOD vp = cofac.fromInteger(vi++);
//System.out.println("vp = " + vp);
if (vp.isZERO() && vi != 1L) { // all elements of Z_p exhausted
qe = null;
re = null;
break;
}
BigInteger vii = new BigInteger(vi-1);
qei = PolyUtil. evaluateMain(ckfac, qe, vii);
rei = PolyUtil. evaluateMain(ckfac, re, vii);
//System.out.println("qei = " + qei);
//System.out.println("rei = " + rei);
// check lucky evaluation point
if (degq != qei.degree(ckfac.nvar - 1)) {
//System.out.println("degv(qe) = " + qe.degreeVector());
//System.out.println("deg(qe) = " + degq + ", deg(qe) = " + qei.degree(ckfac.nvar-1));
continue;
}
if (degr != rei.degree(ckfac.nvar - 1)) {
//System.out.println("degv(re) = " + re.degreeVector());
//System.out.println("deg(re) = " + degr + ", deg(re) = " + rei.degree(ckfac.nvar-1));
continue;
}
V.add(vii);
qe = qei;
re = rei;
break;
}
if (qe == null && re == null) {
break;
}
}
if (qe == null && re == null) {
continue;
}
logger.info("evaluation points = " + V);
// recursion base:
GenPolynomial ce = ufd.baseGcd(qe, re);
if (ce.isConstant()) {
return P.ring.getONE().multiply(c);
}
logger.info("base gcd = " + ce);
// double check
// need qe,re,qd,rd,a,b
if (i == 0) {
qe0 = qe;
re0 = re;
ce0 = ce;
continue;
}
long d0 = ce0.degree(0);
long d1 = ce.degree(0);
//System.out.println("d0, d1 = " + d0 + ", " + d1);
if (d1 < d0) {
qe0 = qe;
re0 = re;
ce0 = ce;
continue;
} else if (d1 > d0) {
continue;
}
// d0 == d1 is ok
long dx = r.degree(0);
//System.out.println("d0, dx = " + d0 + ", " + dx);
if (d0 == dx) { // gcd == r ?
if (PolyUtil. recursivePseudoRemainder(q, r).isZERO()) {
r = r.abs().multiply(c); //.abs();
logger.info("exit with r | q : " + r);
return r;
}
continue;
}
// norm
BigInteger mn = null; //mn = mn.multiply(cc).multiply(mn.fromInteger(2));
// prepare lifting, chose factor polynomials
GenPolynomial re1 = PolyUtil. basePseudoDivide(re, ce);
GenPolynomial qe1 = PolyUtil. basePseudoDivide(qe, ce);
GenPolynomial ui, he, pe;
GenPolynomial g, gi, lui;
GenPolynomial gcr, gcq;
gcr = ufd.baseGcd(re1, ce);
gcq = ufd.baseGcd(qe1, ce);
if (gcr.isONE() && gcq.isONE() ) { // both gcds == 1: chose smaller ldcf
if ( la.totalDegree() > lb.totalDegree() ) {
ui = qd;
s = q;
he = qe1;
pe = qe;
BigInteger bn = qd.maxNorm();
mn = bn.multiply(cc).multiply(new BigInteger(2L));
g = lb;
logger.debug("select deg: ui = qd, g = b"); //, qe1 = " + qe1); // + ", qe = " + qe);
} else {
ui = rd;
s = r;
he = re1;
pe = re;
BigInteger an = rd.maxNorm();
mn = an.multiply(cc).multiply(new BigInteger(2L));
g = la;
logger.debug("select deg: ui = rd, g = a"); //, re1 = " + re1); // + ", re = " + re);
}
} else if (gcr.isONE()) {
ui = rd;
s = r;
he = re1;
pe = re;
BigInteger an = rd.maxNorm();
mn = an.multiply(cc).multiply(new BigInteger(2L));
g = la;
logger.debug("select: ui = rd, g = a"); //, re1 = " + re1); // + ", re = " + re);
} else if (gcq.isONE()) {
ui = qd;
s = q;
he = qe1;
pe = qe;
BigInteger bn = qd.maxNorm();
mn = bn.multiply(cc).multiply(new BigInteger(2L));
g = lb;
logger.debug("select: ui = qd, g = b"); //, qe1 = " + qe1); // + ", qe = " + qe);
} else { // both gcds != 1: method not applicable
logger.info("both gcds != 1: method not applicable");
break;
}
lui = lc; //s.leadingBaseCoefficient();
lh = PolyUtil. basePseudoDivide(g, lui);
BigInteger ge = PolyUtil. evaluateAll(g.ring.coFac, lui, V);
if ( ge.isZERO() ) {
continue;
}
BigInteger geh = PolyUtil. evaluateAll(g.ring.coFac, lh, V);
if ( geh.isZERO() ) {
continue;
}
BigInteger gg = PolyUtil. evaluateAll(g.ring.coFac, g, V);
if ( gg.isZERO() ) {
continue;
}
//System.out.println("ge = " + ge + ", geh = " + geh + ", gg = " + gg + ", pe = " + pe);
//
//ce = ce.multiply(geh); //ge);
//
he = he.multiply(ge); //gg); //ge); //geh);
//
gi = lui.extendLower(dfac,0,0L); //lui. // g.
//
ui = ui.multiply(gi); // gi !.multiply(gi)
//System.out.println("ui = " + ui + ", deg(ui) = " + ui.degreeVector());
//System.out.println("ce = " + ce + ", he = " + he + ", ge = " + ge);
logger.info("gcd(ldcf): " + lui + ", ldcf cofactor: " + lh + ", base cofactor: " + he);
long k = Power.logarithm(new BigInteger(p), mn);
//System.out.println("mn = " + mn);
//System.out.println("k = " + k);
BigInteger qp = Power.positivePower(cofac.getIntegerModul(), k); // == p
ModularRingFactory muqfac;
if (ModLongRing.MAX_LONG.compareTo(qp.getVal()) > 0) {
muqfac = (ModularRingFactory) new ModLongRing(qp.getVal(),true); // nearly a field
} else {
muqfac = (ModularRingFactory) new ModIntegerRing(qp.getVal(),true); // nearly a field
}
GenPolynomialRing mucpfac = new GenPolynomialRing(muqfac, ckfac);
//System.out.println("mucpfac = " + mucpfac.toScript());
if ( muqfac.fromInteger(ge.getVal()).isZERO() ) {
continue;
}
//GenPolynomial xxx = invertPoly(muqfac,lui,V);
//System.out.println("inv(lui) = " + xxx + ", muqfac = " + muqfac + ", lui = " + lui);
//ce = ce.multiply(xxx); //.leadingBaseCoefficient());
//xxx = invertPoly(muqfac,lh,V);
//System.out.println("inv(lh) = " + xxx + ", muqfac = " + muqfac + ", lh = " + lh);
//he = he.multiply(xxx); //.leadingBaseCoefficient());
GenPolynomial cm = PolyUtil. fromIntegerCoefficients(mucpfac, ce);
GenPolynomial hm = PolyUtil. fromIntegerCoefficients(mucpfac, he);
if ( cm.degree(0) != ce.degree(0) || hm.degree(0) != he.degree(0) ) {
continue;
}
if ( cm.isZERO() || hm.isZERO() ) {
continue;
}
logger.info("univariate modulo p^k: " + cm + ", " + hm);
// convert C from Z[...] to Z_q[...]
GenPolynomialRing qcfac = new GenPolynomialRing(muqfac, dfac);
GenPolynomial uq = PolyUtil. fromIntegerCoefficients(qcfac, ui);
if ( !ui.leadingExpVector().equals(uq.leadingExpVector()) ) {
logger.info("ev(ui) = " + ui.leadingExpVector() + ", ev(uq) = " + uq.leadingExpVector() );
continue;
}
logger.info("multivariate modulo p^k: " + uq);
List> F = new ArrayList>(2);
F.add(cm);
F.add(hm);
List> G = new ArrayList>(2);
G.add(lui.ring.getONE()); //lui: lui.ring.getONE()); // TODO
G.add(lui.ring.getONE()); //lh: lui);
List> lift;
try {
//lift = HenselMultUtil. liftHenselFull(ui, F, V, k, G);
lift = HenselMultUtil. liftHensel(ui, uq, F, V, k, G);
logger.info("lift = " + lift);
} catch (NoLiftingException nle) {
logger.info("NoLiftingException");
//System.out.println("exception : " + nle);
continue;
} catch (ArithmeticException ae) {
logger.info("ArithmeticException");
//System.out.println("exception : " + ae);
continue;
} catch (NotInvertibleException ni) {
logger.info("NotInvertibleException");
//System.out.println("exception : " + ni);
continue;
}
if ( false && ! HenselMultUtil. isHenselLift(ui, uq, F, k, lift) ) { // not meaningfull test
logger.info("isHenselLift: false");
//continue;
}
// convert Ci from Z_{p^k}[x,y1,...,yr] to Z[x,y1,...,yr] to Z[x][y1,...,yr] to Z[y1,...,yr][x]
GenPolynomial ci = PolyUtil.integerFromModularCoefficients(dfac, lift.get(0));
ci = basePrimitivePart(ci);
GenPolynomial> Cr = PolyUtil. recursive(rfac, ci);
GenPolynomial> Cs = PolyUtil. switchVariables(Cr);
if (!Cs.ring.equals(P.ring)) {
System.out.println("Cs.ring = " + Cs.ring + ", P.ring = " + P.ring);
}
GenPolynomial> Q = ufd.recursivePrimitivePart(Cs);
Q = ufd.baseRecursivePrimitivePart(Q);
Q = Q.abs().multiply(c); //.abs();
GenPolynomial> Pq, Sq;
Pq = PolyUtil. recursivePseudoRemainder(P, Q);
Sq = PolyUtil. recursivePseudoRemainder(S, Q);
if ( Pq.isZERO() && Sq.isZERO()) {
logger.info("gcd normal exit: " + Q);
return Q;
}
logger.info("bad Q = " + Q); // + ", Pq = " + Pq + ", Sq = " + Sq);
} // end for meta loop
// Hensel gcd failed
GenPolynomial> T = iufd.recursiveUnivariateGcd(r,q);
T = T.abs().multiply(c);
logger.info("no lucky prime or evaluation points, gave up on Hensel: " + T + "= gcd(" + r + "," + q + ")");
return T;
}
GenPolynomial invertPoly(ModularRingFactory mfac,
GenPolynomial li, List V) {
if ( li == null || li.isZERO() ) {
throw new RuntimeException("li not invertible: " + li);
}
if ( li.isONE() ) {
return li;
}
//System.out.println("mfac = " + mfac + ", V = " + V +", li = " + li);
GenPolynomialRing pfac = li.ring;
GenPolynomialRing mpfac = new GenPolynomialRing(mfac,pfac);
GenPolynomial lm = PolyUtil. fromIntegerCoefficients(mpfac, li);
//System.out.println("pfac = " + pfac + ", lm = " + lm);
List> lid = new ArrayList>(V.size());
int i = 0;
for ( BigInteger bi : V ) {
MOD m = mfac.fromInteger(bi.getVal());
GenPolynomial mp = mpfac.univariate(i);
mp = mp.subtract(m); // X_i - v_i
lid.add(mp);
i++;
}
//System.out.println("lid = " + lid);
//Ideal id = new Ideal(mpfac,lid,true); // is a GB
//System.out.println("id = " + id);
GenPolynomial mi = lm; //id.inverse(lm);
//System.out.println("mi = " + mi);
GenPolynomial inv = PolyUtil.integerFromModularCoefficients(pfac, mi);
return inv;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy