/** Test extension and contraction. */
  public void testExtendContract() {
    // rational numbers
    BigRational cf = new BigRational(99);
    // System.out.println("cf = " + cf);

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(cf, rl);
    // System.out.println("pf = " + pf);

    GenPolynomial<BigRational> a = pf.random(kl, ll, el, q);
    // System.out.println("a = " + a);

    int k = rl;
    GenPolynomialRing<BigRational> pfe = pf.extend(k);
    GenPolynomialRing<BigRational> pfec = pfe.contract(k);
    assertEquals("pf == pfec", pf, pfec);

    GenPolynomial<BigRational> ae = a.extend(pfe, 0, 0);

    Map<ExpVector, GenPolynomial<BigRational>> m = ae.contract(pfec);
    List<GenPolynomial<BigRational>> ml = new ArrayList<GenPolynomial<BigRational>>(m.values());
    GenPolynomial<BigRational> aec = ml.get(0);
    assertEquals("a == aec", a, aec);
    // System.out.println("ae = " + ae);
    // System.out.println("aec = " + aec);
  }
  /** Test addition. */
  public void testAddition() {

    a = fac.random(ll);
    b = fac.random(ll);

    c = a.sum(b);
    d = c.subtract(b);
    assertEquals("a+b-b = a", a, d);

    c = fac.random(ll);

    ExpVector u = ExpVector.EVRAND(rl, el, q);
    BigQuaternion x = BigQuaternion.QRAND(kl);

    b = new GenPolynomial<BigQuaternion>(fac, x, u);
    c = a.sum(b);
    d = a.sum(x, u);
    assertEquals("a+p(x,u) = a+(x,u)", c, d);

    c = a.subtract(b);
    d = a.subtract(x, u);
    assertEquals("a-p(x,u) = a-(x,u)", c, d);

    a = new GenPolynomial<BigQuaternion>(fac);
    b = new GenPolynomial<BigQuaternion>(fac, x, u);
    c = b.sum(a);
    d = a.sum(x, u);
    assertEquals("a+p(x,u) = a+(x,u)", c, d);

    c = a.subtract(b);
    d = a.subtract(x, u);
    assertEquals("a-p(x,u) = a-(x,u)", c, d);
  }
 /** Test random polynomial. */
 public void testRandom() {
   for (int i = 0; i < 7; i++) {
     a = fac.random(ll);
     // fac.random(rl+i, kl*(i+1), ll+2*i, el+i, q );
     assertTrue("length( a" + i + " ) <> 0", a.length() >= 0);
     assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
     assertTrue(" not isONE( a" + i + " )", !a.isONE());
   }
 }
  /** Test coefficient map function. */
  public void testMap() {
    // integers
    BigInteger rf = new BigInteger();
    // System.out.println("rf = " + rf);

    // polynomials over integral numbers
    GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
    // System.out.println("pf = " + pf);

    // random polynomial
    GenPolynomial<BigInteger> p = pf.random(kl, 2 * ll, el, q);
    // System.out.println("p = " + p);

    // test times 1
    GenPolynomial<BigInteger> q;
    q = p.map(new Multiply<BigInteger>(rf.getONE()));
    assertEquals("p == q ", p, q);

    // test times 0
    q = p.map(new Multiply<BigInteger>(rf.getZERO()));
    assertTrue("q == 0 ", q.isZERO());

    // test times -1
    q = p.map(new Multiply<BigInteger>(rf.getONE().negate()));
    assertEquals("p == q ", p.negate(), q);
  }
  /** Test reversion. */
  public void testReverse() {
    // rational numbers
    BigRational cf = new BigRational(99);
    // System.out.println("cf = " + cf);

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(cf, rl);
    // System.out.println("pf = " + pf);

    GenPolynomial<BigRational> a = pf.random(kl, ll, el, q);
    // System.out.println("a = " + a);

    GenPolynomialRing<BigRational> pfr = pf.reverse();
    GenPolynomialRing<BigRational> pfrr = pfr.reverse();
    assertEquals("pf == pfrr", pf, pfrr);
    // System.out.println("pfr = " + pfr);

    GenPolynomial<BigRational> ar = a.reverse(pfr);
    GenPolynomial<BigRational> arr = ar.reverse(pfrr);
    assertEquals("a == arr", a, arr);
    // System.out.println("ar = " + ar);
    // System.out.println("arr = " + arr);
  }
  /** Test iterators. */
  public void testIterators() {
    // integers
    BigInteger rf = new BigInteger();
    // System.out.println("rf = " + rf);

    // polynomials over integral numbers
    GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
    // System.out.println("pf = " + pf);

    // random polynomial
    GenPolynomial<BigInteger> p = pf.random(kl, 2 * ll, el, q);
    // System.out.println("p = " + p);

    // test monomials
    for (Monomial<BigInteger> m : p) {
      // System.out.println("m = " + m);
      assertFalse("m.c == 0 ", m.coefficient().isZERO());
      assertFalse("m.e < (0) ", m.exponent().signum() < 0);
    }

    // test exponents
    Iterator<ExpVector> et = p.exponentIterator();
    while (et.hasNext()) {
      ExpVector e = et.next();
      // System.out.println("e = " + e);
      assertFalse("e < (0) ", e.signum() < 0);
    }

    // test coefficents
    Iterator<BigInteger> ct = p.coefficientIterator();
    while (ct.hasNext()) {
      BigInteger i = ct.next();
      // System.out.println("i = " + i);
      assertFalse("i == 0 ", i.isZERO());
    }
  }
  /** Test constructor and toString. */
  public void testConstruction() {
    c = fac.getONE();
    assertTrue("length( c ) = 1", c.length() == 1);
    assertTrue("isZERO( c )", !c.isZERO());
    assertTrue("isONE( c )", c.isONE());

    d = fac.getZERO();
    assertTrue("length( d ) = 0", d.length() == 0);
    assertTrue("isZERO( d )", d.isZERO());
    assertTrue("isONE( d )", !d.isONE());
  }
  /** Test object multiplication. */
  public void testMultiplication() {

    a = fac.random(ll);
    assertTrue("not isZERO( a )", !a.isZERO());

    b = fac.random(ll);
    assertTrue("not isZERO( b )", !b.isZERO());

    c = b.multiply(a);
    d = a.multiply(b);
    assertTrue("not isZERO( c )", !c.isZERO());
    assertTrue("not isZERO( d )", !d.isZERO());

    // System.out.println("a = " + a);
    // System.out.println("b = " + b);
    e = d.subtract(c);
    assertTrue("!isZERO( a*b-b*a ) " + e, !e.isZERO());

    assertTrue("a*b = b*a", !c.equals(d));
    // assertEquals("a*b = b*a",c,d);

    c = fac.random(ll);
    // System.out.println("c = " + c);
    d = a.multiply(b.multiply(c));
    e = (a.multiply(b)).multiply(c);

    // System.out.println("d = " + d);
    // System.out.println("e = " + e);

    // System.out.println("d-e = " + d.subtract(c) );

    assertEquals("a(bc) = (ab)c", d, e);
    assertTrue("a(bc) = (ab)c", d.equals(e));

    BigQuaternion x = a.leadingBaseCoefficient().inverse();
    c = a.monic();
    d = a.multiply(x);
    assertEquals("a.monic() = a(1/ldcf(a))", c, d);

    BigQuaternion y = b.leadingBaseCoefficient().inverse();
    c = b.monic();
    d = b.multiply(y);
    assertEquals("b.monic() = b(1/ldcf(b))", c, d);

    e = new GenPolynomial<BigQuaternion>(fac, y);
    d = b.multiply(e);
    assertEquals("b.monic() = b(1/ldcf(b))", c, d);

    // d = e.multiply(b);
    // assertEquals("b.monic() = (1/ldcf(b) (0))*b",c,d);
  }
  /** Test constructors and factory. */
  public void testConstructors() {
    // rational numbers
    BigRational rf = new BigRational();
    // System.out.println("rf = " + rf);

    // BigRational r = rf.fromInteger( 99 );
    // System.out.println("r = " + r);
    // r = rf.random( 9 ).sum(r);
    // System.out.println("r = " + r);
    // assertFalse("r.isZERO() = ", r.isZERO());

    // RingElem<BigRational> re = new BigRational( 3 );
    // System.out.println("re = " + re);
    // rf = (BigRational) re;

    // RingFactory<BigRational> ref = new BigRational( 3 );
    // System.out.println("re = " + re);
    // rf = (BigRational) ref;

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 2);
    // System.out.println("pf = " + pf);

    GenPolynomial<BigRational> p = pf.getONE();
    // System.out.println("p = " + p);
    p = pf.random(9);
    // System.out.println("p = " + p);
    p = pf.getZERO();
    // System.out.println("p = " + p);

    RingElem<GenPolynomial<BigRational>> pe = new GenPolynomial<BigRational>(pf);
    // System.out.println("pe = " + pe);
    // System.out.println("p.equals(pe) = " + p.equals(pe) );
    // System.out.println("p.equals(p) = " + p.equals(p) );
    assertTrue("p.equals(pe) = ", p.equals(pe));
    assertTrue("p.equals(p) = ", p.equals(p));

    pe = pe.sum(p); // why not p = p.add(pe) ?
    // System.out.println("pe = " + pe);
    assertTrue("pe.isZERO() = ", pe.isZERO());
    p = pf.random(9);
    p = p.subtract(p);
    // System.out.println("p = " + p);
    // System.out.println("p.isZERO() = " + p.isZERO());
    assertTrue("p.isZERO() = ", p.isZERO());

    // polynomials over (polynomials over rational numbers)
    GenPolynomialRing<GenPolynomial<BigRational>> ppf =
        new GenPolynomialRing<GenPolynomial<BigRational>>(pf, 3);
    // System.out.println("ppf = " + ppf);

    GenPolynomial<GenPolynomial<BigRational>> pp = ppf.getONE();
    // System.out.println("pp = " + pp);
    pp = ppf.random(2);
    // System.out.println("pp = " + pp);
    pp = ppf.getZERO();
    // System.out.println("pp = " + pp);

    RingElem<GenPolynomial<GenPolynomial<BigRational>>> ppe =
        new GenPolynomial<GenPolynomial<BigRational>>(ppf);
    // System.out.println("ppe = " + ppe);
    // System.out.println("pp.equals(ppe) = " + pp.equals(ppe) );
    // System.out.println("pp.equals(pp) = " + pp.equals(pp) );
    assertTrue("pp.equals(ppe) = ", pp.equals(ppe));
    assertTrue("pp.equals(pp) = ", pp.equals(pp));

    ppe = ppe.sum(pp); // why not pp = pp.add(ppe) ?
    // System.out.println("ppe = " + ppe);
    assertTrue("ppe.isZERO() = ", ppe.isZERO());
    pp = ppf.random(2);
    pp = pp.subtract(pp);
    // System.out.println("pp = " + pp);
    // System.out.println("pp.isZERO() = " + pp.isZERO());
    assertTrue("pp.isZERO() = ", pp.isZERO());

    // polynomials over (polynomials over (polynomials over rational numbers))
    GenPolynomialRing<GenPolynomial<GenPolynomial<BigRational>>> pppf =
        new GenPolynomialRing<GenPolynomial<GenPolynomial<BigRational>>>(ppf, 4);
    // System.out.println("pppf = " + pppf);

    GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>> ppp = pppf.getONE();
    // System.out.println("ppp = " + ppp);
    ppp = pppf.random(2);
    // System.out.println("ppp = " + ppp);
    ppp = pppf.getZERO();
    // System.out.println("ppp = " + ppp);

    RingElem<GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>>> pppe =
        new GenPolynomial<GenPolynomial<GenPolynomial<BigRational>>>(pppf);
    // System.out.println("pppe = " + pppe);
    // System.out.println("ppp.equals(pppe) = " + ppp.equals(pppe) );
    // System.out.println("ppp.equals(ppp) = " + ppp.equals(ppp) );
    assertTrue("ppp.equals(pppe) = ", ppp.equals(pppe));
    assertTrue("ppp.equals(ppp) = ", ppp.equals(ppp));

    pppe = pppe.sum(ppp); // why not ppp = ppp.add(pppe) ?
    // System.out.println("pppe = " + pppe);
    assertTrue("pppe.isZERO() = ", pppe.isZERO());
    ppp = pppf.random(2);
    ppp = ppp.subtract(ppp);
    // System.out.println("ppp = " + ppp);
    // System.out.println("ppp.isZERO() = " + ppp.isZERO());
    assertTrue("ppp.isZERO() = ", ppp.isZERO());

    // some tests
    // GenPolynomial<BigRational> pfx = new GenPolynomial<BigRational>();
    // System.out.println("pfx = " + pfx);
  }
  /** Test univariate. */
  public void testUnivariate() {
    BigInteger rf = new BigInteger();
    // System.out.println("rf = " + rf);

    // polynomials over integral numbers
    GenPolynomialRing<BigInteger> pf = new GenPolynomialRing<BigInteger>(rf, rl);
    // System.out.println("pf = " + pf);

    GenPolynomial<BigInteger> a, b, c, d;

    // x**1
    a = pf.univariate(pf.nvar - 1);
    // System.out.println("a = " + a);
    assertTrue("deg(a) = 1: ", a.degree() == 1);
    assertEquals("xi == xi: ", pf.vars[0], a.toString());

    b = pf.univariate(pf.vars[0]);
    // System.out.println("b = " + b);
    assertTrue("deg(b) = 1: ", b.degree() == 1);
    assertEquals("xi == xi: ", pf.vars[0], b.toString());

    c = pf.univariate(0);
    // System.out.println("c = " + c);
    assertTrue("deg(c) = 1: ", c.degree() == 1);
    assertEquals("xi == xi: ", pf.vars[pf.nvar - 1], c.toString());

    d = pf.univariate(pf.vars[pf.nvar - 1]);
    // System.out.println("d = " + d);
    assertTrue("deg(c) = 1: ", c.degree() == 1);
    assertEquals("xi == xi: ", pf.vars[pf.nvar - 1], d.toString());

    // x**7
    a = pf.univariate(pf.nvar - 1, 7);
    // System.out.println("a = " + a);
    assertTrue("deg(a) = 7: ", a.degree() == 7);
    assertEquals("xi == xi: ", pf.vars[0] + "^7", a.toString());

    b = pf.univariate(pf.vars[0], 7);
    // System.out.println("b = " + b);
    assertTrue("deg(b) = 7: ", b.degree() == 7);
    assertEquals("xi == xi: ", pf.vars[0] + "^7", b.toString());

    c = pf.univariate(0, 7);
    // System.out.println("c = " + c);
    assertTrue("deg(c) = 7: ", c.degree() == 7);
    assertEquals("xi == xi: ", pf.vars[pf.nvar - 1] + "^7", c.toString());

    d = pf.univariate(pf.vars[pf.nvar - 1], 7);
    // System.out.println("d = " + d);
    assertTrue("deg(c) = 7: ", c.degree() == 7);
    assertEquals("xi == xi: ", pf.vars[pf.nvar - 1] + "^7", d.toString());
  }
  /** Test weight homogeneous. */
  public void testWeightHomogeneous() {
    // rational numbers
    BigRational rf = new BigRational();
    // System.out.println("rf = " + rf);

    // weight term order
    long[] weight = new long[] {2, 3, 4, 5};
    TermOrder to = TermOrderByName.weightOrder(weight);
    // System.out.println("to = " + to);

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 4, to);
    // System.out.println("pf = " + pf.toScript());

    // test 1
    GenPolynomial<BigRational> p = pf.getONE();
    // System.out.println("p = " + p);
    assertTrue("1 is weight homogeneous " + p, p.isWeightHomogeneous());

    // test 0
    p = pf.getZERO();
    // System.out.println("p = " + p);
    assertTrue("0 is weight homogeneous " + p, p.isWeightHomogeneous());

    // test random
    p = pf.random(kl, 3 * ll, el, q);
    // System.out.println("p = " + p);
    assertFalse("rnd is weight homogeneous " + p, p.isWeightHomogeneous());

    GenPolynomial<BigRational> pl = p.leadingWeightPolynomial();
    // System.out.println("pl = " + pl);
    assertTrue("lw(rnd) is weight homogeneous " + pl, pl.isWeightHomogeneous());

    GenPolynomial<BigRational> r = pf.random(kl, 3 * ll, el, q);
    // System.out.println("r = " + r);
    assertFalse("rnd is weight homogeneous " + r, r.isWeightHomogeneous());

    GenPolynomial<BigRational> rl = r.leadingWeightPolynomial();
    // System.out.println("rl = " + rl);
    assertTrue("lw(rnd) is weight homogeneous " + rl, rl.isWeightHomogeneous());

    GenPolynomial<BigRational> t = pl.multiply(rl);
    // System.out.println("t = " + t);
    assertTrue("lw(rnd)*lw(rnd) is weight homogeneous " + t, t.isWeightHomogeneous());
  }
  /** Test homogeneous. */
  public void testHomogeneous() {
    // rational numbers
    BigRational rf = new BigRational();
    // System.out.println("rf = " + rf);

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, 2); // rl);
    // System.out.println("pf = " + pf);

    // test 1
    GenPolynomial<BigRational> p = pf.getONE();
    // System.out.println("p = " + p);
    assertTrue("1 is homogeneous " + p, p.isHomogeneous());

    // test 0
    p = pf.getZERO();
    // System.out.println("p = " + p);
    assertTrue("0 is homogeneous " + p, p.isHomogeneous());

    // test random
    p = pf.random(kl, 2 * ll, el, q);
    // p = pf.random(kl,ll,el,q);
    // System.out.println("p = " + p);
    assertFalse("rnd is homogeneous " + p, p.isHomogeneous());

    // make homogeneous
    GenPolynomialRing<BigRational> pfh = pf.extend(1);
    // System.out.println("pfh = " + pfh);
    // remove block order
    TermOrder to = new TermOrder(TermOrder.IGRLEX);
    pfh = new GenPolynomialRing<BigRational>(pfh, to);
    // System.out.println("pfh = " + pfh);

    GenPolynomial<BigRational> ph = p.homogenize(pfh);
    // System.out.println("ph = " + ph);
    assertTrue("ph is homogeneous " + ph, ph.isHomogeneous());
    GenPolynomial<BigRational> ps = ph.deHomogenize(pf);
    // System.out.println("ps = " + ps);
    assertEquals("phs == p ", ps, p); // findbugs
    // System.out.println("p is homogeneous = " + p.isHomogeneous());
    // System.out.println("ph is homogeneous = " + ph.isHomogeneous());

    GenPolynomial<BigRational> s = pf.random(kl, ll, el, q);
    // System.out.println("s = " + s);
    assertFalse("rnd is homogeneous " + s, s.isHomogeneous());

    GenPolynomial<BigRational> sh = s.homogenize(pfh);
    // System.out.println("sh = " + sh);
    assertTrue("sh is homogeneous " + sh, sh.isHomogeneous());
    GenPolynomial<BigRational> ss = sh.deHomogenize(pf);
    // System.out.println("ss = " + ss);
    assertEquals("ss = s ", ss, s);

    GenPolynomial<BigRational> th = ph.multiply(sh);
    // System.out.println("th = " + th);
    assertTrue("th is homogeneous " + th, th.isHomogeneous());

    GenPolynomial<BigRational> t = p.multiply(s);
    // System.out.println("t = " + t);

    GenPolynomial<BigRational> ts = th.deHomogenize(pf);
    // System.out.println("ts = " + ts);
    assertEquals("ts = t ", ts, t);
  }
  /** Test accessors. */
  public void testAccessors() {
    // rational numbers
    BigRational rf = new BigRational();
    // System.out.println("rf = " + rf);

    // polynomials over rational numbers
    GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(rf, rl);
    // System.out.println("pf = " + pf);

    // test 1
    GenPolynomial<BigRational> p = pf.getONE();
    // System.out.println("p = " + p);

    ExpVector e = p.leadingExpVector();
    BigRational c = p.leadingBaseCoefficient();

    GenPolynomial<BigRational> f = new GenPolynomial<BigRational>(pf, c, e);
    assertEquals("1 == 1 ", p, f);

    GenPolynomial<BigRational> r = p.reductum();
    assertTrue("red(1) == 0 ", r.isZERO());

    // test 0
    p = pf.getZERO();
    // System.out.println("p = " + p);
    e = p.leadingExpVector();
    c = p.leadingBaseCoefficient();

    f = new GenPolynomial<BigRational>(pf, c, e);
    assertEquals("0 == 0 ", p, f);

    r = p.reductum();
    assertTrue("red(0) == 0 ", r.isZERO());

    // test random
    p = pf.random(kl, 2 * ll, el, q);
    // System.out.println("p = " + p);
    e = p.leadingExpVector();
    c = p.leadingBaseCoefficient();
    r = p.reductum();

    f = new GenPolynomial<BigRational>(pf, c, e);
    f = r.sum(f);
    assertEquals("p == lm(f)+red(f) ", p, f);

    // test iteration over random
    GenPolynomial<BigRational> g;
    g = p;
    f = pf.getZERO();
    while (!g.isZERO()) {
      e = g.leadingExpVector();
      c = g.leadingBaseCoefficient();
      // System.out.println("c e = " + c + " " + e);
      r = g.reductum();
      f = f.sum(c, e);
      g = r;
    }
    assertEquals("p == lm(f)+lm(red(f))+... ", p, f);
  }