/**
  * ResidueSolvableWordPolynomial left and right multiplication. Product with ring element and
  * exponent vector.
  *
  * @param b coefficient polynomial.
  * @param e exponent.
  * @param c coefficient polynomial.
  * @param f exponent.
  * @return b x<sup>e</sup> * this * c x<sup>f</sup>, where * denotes solvable multiplication.
  */
 @Override
 public ResidueSolvableWordPolynomial<C> multiply(
     WordResidue<C> b, ExpVector e, WordResidue<C> c, ExpVector f) {
   if (b == null || b.isZERO()) {
     return ring.getZERO();
   }
   if (c == null || c.isZERO()) {
     return ring.getZERO();
   }
   ResidueSolvableWordPolynomial<C> Cp = ring.valueOf(b, e);
   ResidueSolvableWordPolynomial<C> Dp = ring.valueOf(c, f);
   return multiply(Cp, Dp);
 }
 /**
  * ResidueSolvableWordPolynomial left and right multiplication. Product with coefficient ring
  * element.
  *
  * @param b coefficient polynomial.
  * @param c coefficient polynomial.
  * @return b*this*c, where * is coefficient multiplication.
  */
 @Override
 public ResidueSolvableWordPolynomial<C> multiply(WordResidue<C> b, WordResidue<C> c) {
   ResidueSolvableWordPolynomial<C> Cp = ring.getZERO().copy();
   if (b == null || b.isZERO()) {
     return Cp;
   }
   if (c == null || c.isZERO()) {
     return Cp;
   }
   ResidueSolvableWordPolynomial<C> Cb = ring.valueOf(b);
   ResidueSolvableWordPolynomial<C> Cc = ring.valueOf(c);
   return Cb.multiply(this).multiply(Cc);
 }
 /**
  * Constructor for ResidueSolvableWordPolynomial.
  *
  * @param r solvable polynomial ring factory.
  * @param c coefficient word residue.
  * @param e exponent.
  */
 public ResidueSolvableWordPolynomial(
     ResidueSolvableWordPolynomialRing<C> r, WordResidue<C> c, ExpVector e) {
   this(r);
   if (c != null && !c.isZERO()) {
     val.put(e, c);
   }
 }
 /**
  * ResidueSolvableWordPolynomial multiplication. Left product with ring element and exponent
  * vector.
  *
  * @param b coefficient polynomial.
  * @param e exponent.
  * @return b x<sup>e</sup> * this, where * denotes solvable multiplication.
  */
 @Override
 public ResidueSolvableWordPolynomial<C> multiplyLeft(WordResidue<C> b, ExpVector e) {
   if (b == null || b.isZERO()) {
     return ring.getZERO();
   }
   ResidueSolvableWordPolynomial<C> Cp = ring.valueOf(b, e);
   return Cp.multiply(this);
 }
 /**
  * ResidueSolvableWordPolynomial multiplication. Left product with coefficient ring element.
  *
  * @param b coefficient polynomial.
  * @return b*this, where * is coefficient multiplication.
  */
 @Override
 public ResidueSolvableWordPolynomial<C> multiplyLeft(WordResidue<C> b) {
   ResidueSolvableWordPolynomial<C> Cp = ring.getZERO().copy();
   if (b == null || b.isZERO()) {
     return Cp;
   }
   Map<ExpVector, WordResidue<C>> Cm = Cp.val; // getMap();
   Map<ExpVector, WordResidue<C>> Am = val;
   WordResidue<C> c;
   for (Map.Entry<ExpVector, WordResidue<C>> y : Am.entrySet()) {
     ExpVector e = y.getKey();
     WordResidue<C> a = y.getValue();
     c = b.multiply(a);
     if (!c.isZERO()) {
       Cm.put(e, c);
     }
   }
   return Cp;
 }
 /**
  * ResidueSolvableWordPolynomial multiplication. Product with coefficient ring element.
  *
  * @param b coefficient polynomial.
  * @return this*b, where * is coefficient multiplication.
  */
 @Override
 // public GenSolvablePolynomial<WordResidue<C>> multiply(WordResidue<C> b) {
 public ResidueSolvableWordPolynomial<C> multiply(WordResidue<C> b) {
   ResidueSolvableWordPolynomial<C> Cp = ring.getZERO().copy();
   if (b == null || b.isZERO()) {
     return Cp;
   }
   Cp = ring.valueOf(b);
   return multiply(Cp);
 }
 /**
  * ResidueSolvableWordPolynomial multiplication. Commutative product with exponent vector.
  *
  * @param B solvable polynomial.
  * @param f exponent vector.
  * @return B*f, where * is commutative multiplication.
  */
 protected ResidueSolvableWordPolynomial<C> shift(
     ResidueSolvableWordPolynomial<C> B, ExpVector f) {
   ResidueSolvableWordPolynomial<C> C = ring.getZERO().copy();
   if (B == null || B.isZERO()) {
     return C;
   }
   if (f == null || f.isZERO()) {
     return B;
   }
   Map<ExpVector, WordResidue<C>> Cm = C.val;
   Map<ExpVector, WordResidue<C>> Bm = B.val;
   for (Map.Entry<ExpVector, WordResidue<C>> y : Bm.entrySet()) {
     ExpVector e = y.getKey();
     WordResidue<C> a = y.getValue();
     ExpVector d = e.sum(f);
     if (!a.isZERO()) {
       Cm.put(d, a);
     }
   }
   return C;
 }