// cannot @Override, @NoOverride public ResidueSolvableWordPolynomial<C> multiply(ResidueSolvableWordPolynomial<C> Bp) { if (Bp == null || Bp.isZERO()) { return ring.getZERO(); } if (this.isZERO()) { return this; } assert (ring.nvar == Bp.ring.nvar); if (debug) { logger.debug("ring = " + ring); } ExpVector Z = ring.evzero; ResidueSolvableWordPolynomial<C> Dp = ring.getZERO().copy(); ResidueSolvableWordPolynomial<C> zero = ring.getZERO().copy(); WordResidue<C> one = ring.getONECoefficient(); Map<ExpVector, WordResidue<C>> A = val; Map<ExpVector, WordResidue<C>> B = Bp.val; Set<Map.Entry<ExpVector, WordResidue<C>>> Bk = B.entrySet(); for (Map.Entry<ExpVector, WordResidue<C>> y : A.entrySet()) { WordResidue<C> a = y.getValue(); ExpVector e = y.getKey(); if (debug) logger.info("e = " + e + ", a = " + a); for (Map.Entry<ExpVector, WordResidue<C>> x : Bk) { WordResidue<C> b = x.getValue(); ExpVector f = x.getKey(); if (debug) logger.info("f = " + f + ", b = " + b); int[] fp = f.dependencyOnVariables(); int fl1 = 0; if (fp.length > 0) { fl1 = fp[fp.length - 1]; } int fl1s = ring.nvar + 1 - fl1; // polynomial/residue coefficient multiplication ResidueSolvableWordPolynomial<C> Cps = ring.getZERO().copy(); if (ring.polCoeff.coeffTable.isEmpty() || b.isConstant() || e.isZERO()) { // symmetric Cps = new ResidueSolvableWordPolynomial<C>(ring, b, e); if (debug) logger.info("symmetric coeff: b = " + b + ", e = " + e); } else { // unsymmetric if (debug) logger.info("unsymmetric coeff: b = " + b + ", e = " + e); // recursive polynomial coefficient multiplication : e * b.val RecSolvableWordPolynomial<C> rsp1 = new RecSolvableWordPolynomial<C>(ring.polCoeff, e); RecSolvableWordPolynomial<C> rsp2 = new RecSolvableWordPolynomial<C>(ring.polCoeff, b.val); RecSolvableWordPolynomial<C> rsp3 = rsp1.multiply(rsp2); Cps = ring.fromPolyCoefficients(rsp3); } if (debug) { logger.info("coeff-poly: Cps = " + Cps); } // polynomial multiplication ResidueSolvableWordPolynomial<C> Dps = ring.getZERO().copy(); ResidueSolvableWordPolynomial<C> Ds = null; ResidueSolvableWordPolynomial<C> D1, D2; if (ring.table.isEmpty() || Cps.isConstant() || f.isZERO()) { // symmetric if (debug) logger.info("symmetric poly: b = " + b + ", e = " + e); ExpVector g = e.sum(f); if (Cps.isConstant()) { Ds = new ResidueSolvableWordPolynomial<C>( ring, Cps.leadingBaseCoefficient(), g); // symmetric! } else { Ds = shift(Cps, f); // symmetric } } else { // eventually unsymmetric if (debug) logger.info("unsymmetric poly: Cps = " + Cps + ", f = " + f); for (Map.Entry<ExpVector, WordResidue<C>> z : Cps.val.entrySet()) { // split g = g1 * g2, f = f1 * f2 WordResidue<C> c = z.getValue(); ExpVector g = z.getKey(); if (debug) logger.info("g = " + g + ", c = " + c); int[] gp = g.dependencyOnVariables(); int gl1 = ring.nvar + 1; if (gp.length > 0) { gl1 = gp[0]; } int gl1s = ring.nvar + 1 - gl1; if (gl1s <= fl1s) { // symmetric ExpVector h = g.sum(f); if (debug) logger.info("disjoint poly: g = " + g + ", f = " + f + ", h = " + h); Ds = (ResidueSolvableWordPolynomial<C>) zero.sum(one, h); // symmetric! } else { ExpVector g1 = g.subst(gl1, 0); ExpVector g2 = Z.subst(gl1, g.getVal(gl1)); // bug el1, gl1 ExpVector g4; ExpVector f1 = f.subst(fl1, 0); ExpVector f2 = Z.subst(fl1, f.getVal(fl1)); if (debug) logger.info("poly, g1 = " + g1 + ", f1 = " + f1 + ", Dps = " + Dps); if (debug) logger.info("poly, g2 = " + g2 + ", f2 = " + f2); TableRelation<WordResidue<C>> rel = ring.table.lookup(g2, f2); if (debug) logger.info("poly, g = " + g + ", f = " + f + ", rel = " + rel); Ds = new ResidueSolvableWordPolynomial<C>(ring, rel.p); // ring.copy(rel.p); if (rel.f != null) { D2 = new ResidueSolvableWordPolynomial<C>(ring, one, rel.f); Ds = Ds.multiply(D2); if (rel.e == null) { g4 = g2; } else { g4 = g2.subtract(rel.e); } ring.table.update(g4, f2, Ds); } if (rel.e != null) { D1 = new ResidueSolvableWordPolynomial<C>(ring, one, rel.e); Ds = D1.multiply(Ds); ring.table.update(g2, f2, Ds); } if (!f1.isZERO()) { D2 = new ResidueSolvableWordPolynomial<C>(ring, one, f1); Ds = Ds.multiply(D2); // ring.table.update(?,f1,Ds) } if (!g1.isZERO()) { D1 = new ResidueSolvableWordPolynomial<C>(ring, one, g1); Ds = D1.multiply(Ds); // ring.table.update(e1,?,Ds) } } Ds = Ds.multiplyLeft(c); // assume c commutes with Cs Dps = (ResidueSolvableWordPolynomial<C>) Dps.sum(Ds); } // end Dps loop Ds = Dps; } Ds = Ds.multiplyLeft(a); // multiply(a,b); // non-symmetric if (debug) logger.debug("Ds = " + Ds); Dp = (ResidueSolvableWordPolynomial<C>) Dp.sum(Ds); } // end B loop } // end A loop return Dp; }
/** * ExpVector dependency on variables. * * @param U * @return array of indices where U has positive exponents. */ public static int[] EVDOV(ExpVector U) { return U.dependencyOnVariables(); }