Пример #1
0
  /**
   * Invariant interval for algebraic number magnitude.
   *
   * @param iv root isolating interval for f, with f(left) * f(right) < 0.
   * @param f univariate polynomial, non-zero.
   * @param g univariate polynomial, gcd(f,g) == 1.
   * @param eps length limit for interval length.
   * @return v with v a new interval contained in iv such that |g(a) - g(b)| < eps for a, b in v
   *     in iv.
   */
  public Interval<C> invariantMagnitudeInterval(
      Interval<C> iv, GenPolynomial<C> f, GenPolynomial<C> g, C eps) {
    Interval<C> v = iv;
    if (g == null || g.isZERO()) {
      return v;
    }
    if (g.isConstant()) {
      return v;
    }
    if (f == null || f.isZERO() || f.isConstant()) { // ?
      return v;
    }
    GenPolynomial<C> gp = PolyUtil.<C>baseDeriviative(g);
    // System.out.println("g  = " + g);
    // System.out.println("gp = " + gp);
    C B = magnitudeBound(iv, gp);
    // System.out.println("B = " + B);

    RingFactory<C> cfac = f.ring.coFac;
    C two = cfac.fromInteger(2);

    while (B.multiply(v.length()).compareTo(eps) >= 0) {
      C c = v.left.sum(v.right);
      c = c.divide(two);
      Interval<C> im = new Interval<C>(c, v.right);
      if (signChange(im, f)) {
        v = im;
      } else {
        v = new Interval<C>(v.left, c);
      }
      // System.out.println("v = " + v.toDecimal());
    }
    return v;
  }
Пример #2
0
 /**
  * Real algebraic number sign.
  *
  * @param iv root isolating interval for f, with f(left) * f(right) &lt; 0.
  * @param f univariate polynomial, non-zero.
  * @param g univariate polynomial, gcd(f,g) == 1.
  * @return sign(g(v)), with v a new interval contained in iv such that g(v) != 0.
  */
 public int realSign(Interval<C> iv, GenPolynomial<C> f, GenPolynomial<C> g) {
   if (g == null || g.isZERO()) {
     return 0;
   }
   if (f == null || f.isZERO() || f.isConstant()) {
     return g.signum();
   }
   if (g.isConstant()) {
     return g.signum();
   }
   Interval<C> v = invariantSignInterval(iv, f, g);
   return realIntervalSign(v, f, g);
 }
Пример #3
0
 /**
  * Test if x is an approximate real root.
  *
  * @param x approximate real root.
  * @param f univariate polynomial, non-zero.
  * @param fp univariate polynomial, non-zero, deriviative of f.
  * @param eps requested interval length.
  * @return true if x is a decimal approximation of a real v with f(v) = 0 with |d-v| &lt; eps,
  *     else false.
  */
 public boolean isApproximateRoot(
     BigDecimal x, GenPolynomial<BigDecimal> f, GenPolynomial<BigDecimal> fp, BigDecimal eps) {
   if (x == null) {
     throw new IllegalArgumentException("null root not allowed");
   }
   if (f == null || f.isZERO() || f.isConstant() || eps == null) {
     return true;
   }
   BigDecimal dc = BigDecimal.ONE; // only for clarity
   // f(x)
   BigDecimal fx = PolyUtil.<BigDecimal>evaluateMain(dc, f, x);
   // System.out.println("fx    = " + fx);
   if (fx.isZERO()) {
     return true;
   }
   // f'(x)
   BigDecimal fpx = PolyUtil.<BigDecimal>evaluateMain(dc, fp, x); // f'(d)
   // System.out.println("fpx   = " + fpx);
   if (fpx.isZERO()) {
     return false;
   }
   BigDecimal d = fx.divide(fpx);
   if (d.isZERO()) {
     return true;
   }
   if (d.abs().compareTo(eps) <= 0) {
     return true;
   }
   System.out.println("x     = " + x);
   System.out.println("d     = " + d);
   return false;
 }
Пример #4
0
 /**
  * Real algebraic number magnitude.
  *
  * @param iv root isolating interval for f, with f(left) * f(right) &lt; 0.
  * @param f univariate polynomial, non-zero.
  * @param g univariate polynomial, gcd(f,g) == 1.
  * @param eps length limit for interval length.
  * @return g(iv) .
  */
 public C realMagnitude(Interval<C> iv, GenPolynomial<C> f, GenPolynomial<C> g, C eps) {
   if (g.isZERO() || g.isConstant()) {
     return g.leadingBaseCoefficient();
   }
   Interval<C> v = invariantMagnitudeInterval(iv, f, g, eps);
   return realIntervalMagnitude(v, f, g, eps);
 }
Пример #5
0
 /**
  * Real root bound. With f(M) * f(-M) != 0.
  *
  * @param f univariate polynomial.
  * @return M such that -M &lt; root(f) &lt; M.
  */
 public C realRootBound(GenPolynomial<C> f) {
   if (f == null) {
     return null;
   }
   RingFactory<C> cfac = f.ring.coFac;
   C M = cfac.getONE();
   if (f.isZERO() || f.isConstant()) {
     return M;
   }
   C a = f.leadingBaseCoefficient().abs();
   for (C c : f.getMap().values()) {
     C d = c.abs().divide(a);
     if (M.compareTo(d) < 0) {
       M = d;
     }
   }
   // works also without this case, only for optimization
   // to use rational number interval end points
   // can fail if real root is in interval [r,r+1]
   // for too low precision or too big r, since r is approximation
   if ((Object) M instanceof RealAlgebraicNumber) {
     RealAlgebraicNumber Mr = (RealAlgebraicNumber) M;
     BigRational r = Mr.magnitude();
     M = cfac.fromInteger(r.numerator()).divide(cfac.fromInteger(r.denominator()));
   }
   M = M.sum(f.ring.coFac.getONE());
   // System.out.println("M = " + M);
   return M;
 }
Пример #6
0
 /**
  * GenPolynomial greatest squarefree divisor.
  *
  * @param P GenPolynomial.
  * @return squarefree(pp(P)).
  */
 @Override
 public GenPolynomial<C> squarefreePart(GenPolynomial<C> P) {
   if (P == null) {
     throw new IllegalArgumentException(this.getClass().getName() + " P != null");
   }
   if (P.isZERO()) {
     return P;
   }
   GenPolynomialRing<C> pfac = P.ring;
   if (pfac.nvar <= 1) {
     return baseSquarefreePart(P);
   }
   // just for the moment:
   GenPolynomial<C> s = pfac.getONE();
   SortedMap<GenPolynomial<C>, Long> factors = squarefreeFactors(P);
   if (logger.isInfoEnabled()) {
     logger.info("sqfPart,factors = " + factors);
   }
   for (GenPolynomial<C> sp : factors.keySet()) {
     if (sp.isConstant()) {
       continue;
     }
     s = s.multiply(sp);
   }
   return s.monic();
 }
Пример #7
0
 /**
  * Refine interval.
  *
  * @param iv root isolating interval with f(left) * f(right) &lt; 0.
  * @param f univariate polynomial, non-zero.
  * @param eps requested interval length.
  * @return a new interval v such that |v| &lt; eps.
  */
 public Interval<C> refineInterval(Interval<C> iv, GenPolynomial<C> f, C eps) {
   if (f == null || f.isZERO() || f.isConstant() || eps == null) {
     return iv;
   }
   if (iv.length().compareTo(eps) < 0) {
     return iv;
   }
   RingFactory<C> cfac = f.ring.coFac;
   C two = cfac.fromInteger(2);
   Interval<C> v = iv;
   while (v.length().compareTo(eps) >= 0) {
     C c = v.left.sum(v.right);
     c = c.divide(two);
     // System.out.println("c = " + c);
     // c = RootUtil.<C>bisectionPoint(v,f);
     if (PolyUtil.<C>evaluateMain(cfac, f, c).isZERO()) {
       v = new Interval<C>(c, c);
       break;
     }
     Interval<C> iv1 = new Interval<C>(v.left, c);
     if (signChange(iv1, f)) {
       v = iv1;
     } else {
       v = new Interval<C>(c, v.right);
     }
   }
   return v;
 }
Пример #8
0
 /**
  * Bi-section point.
  *
  * @param iv interval with f(left) * f(right) != 0.
  * @param f univariate polynomial, non-zero.
  * @return a point c in the interval iv such that f(c) != 0.
  */
 public C bisectionPoint(Interval<C> iv, GenPolynomial<C> f) {
   if (f == null) {
     return null;
   }
   RingFactory<C> cfac = f.ring.coFac;
   C two = cfac.fromInteger(2);
   C c = iv.left.sum(iv.right);
   c = c.divide(two);
   if (f.isZERO() || f.isConstant()) {
     return c;
   }
   C m = PolyUtil.<C>evaluateMain(cfac, f, c);
   while (m.isZERO()) {
     C d = iv.left.sum(c);
     d = d.divide(two);
     if (d.equals(c)) {
       d = iv.right.sum(c);
       d = d.divide(two);
       if (d.equals(c)) {
         throw new RuntimeException("should not happen " + iv);
       }
     }
     c = d;
     m = PolyUtil.<C>evaluateMain(cfac, f, c);
     // System.out.println("c = " + c);
   }
   // System.out.println("c = " + c);
   return c;
 }
Пример #9
0
 /**
  * Real algebraic number sign.
  *
  * @param iv root isolating interval for f, with f(left) * f(right) &lt; 0, with iv such that
  *     g(iv) != 0.
  * @param f univariate polynomial, non-zero.
  * @param g univariate polynomial, gcd(f,g) == 1.
  * @return sign(g(iv)) .
  */
 public int realIntervalSign(Interval<C> iv, GenPolynomial<C> f, GenPolynomial<C> g) {
   if (g == null || g.isZERO()) {
     return 0;
   }
   if (f == null || f.isZERO() || f.isConstant()) {
     return g.signum();
   }
   if (g.isConstant()) {
     return g.signum();
   }
   RingFactory<C> cfac = f.ring.coFac;
   C c = iv.left.sum(iv.right);
   c = c.divide(cfac.fromInteger(2));
   C ev = PolyUtil.<C>evaluateMain(cfac, g, c);
   // System.out.println("ev = " + ev);
   return ev.signum();
 }
Пример #10
0
 /**
  * Real algebraic number magnitude.
  *
  * @param iv root isolating interval for f, with f(left) * f(right) &lt; 0, with iv such that
  *     |g(a) - g(b)| &lt; eps for a, b in iv.
  * @param f univariate polynomial, non-zero.
  * @param g univariate polynomial, gcd(f,g) == 1.
  * @param eps length limit for interval length.
  * @return g(iv) .
  */
 public C realIntervalMagnitude(Interval<C> iv, GenPolynomial<C> f, GenPolynomial<C> g, C eps) {
   if (g.isZERO() || g.isConstant()) {
     return g.leadingBaseCoefficient();
   }
   RingFactory<C> cfac = g.ring.coFac;
   C c = iv.left.sum(iv.right);
   c = c.divide(cfac.fromInteger(2));
   C ev = PolyUtil.<C>evaluateMain(cfac, g, c);
   // System.out.println("ev = " + ev);
   return ev;
 }
Пример #11
0
 /**
  * Refine intervals.
  *
  * @param V list of isolating intervals with f(left) * f(right) &lt; 0.
  * @param f univariate polynomial, non-zero.
  * @param eps requested intervals length.
  * @return a list of new intervals v such that |v| &lt; eps.
  */
 public List<Interval<C>> refineIntervals(List<Interval<C>> V, GenPolynomial<C> f, C eps) {
   if (f == null || f.isZERO() || f.isConstant() || eps == null) {
     return V;
   }
   List<Interval<C>> IV = new ArrayList<Interval<C>>();
   for (Interval<C> v : V) {
     Interval<C> iv = refineInterval(v, f, eps);
     IV.add(iv);
   }
   return IV;
 }
Пример #12
0
 /**
  * Test if x is an approximate real root.
  *
  * @param x approximate real root.
  * @param f univariate polynomial, non-zero.
  * @param eps requested interval length.
  * @return true if x is a decimal approximation of a real v with f(v) = 0 with |d-v| &lt; eps,
  *     else false.
  */
 public boolean isApproximateRoot(BigDecimal x, GenPolynomial<C> f, C eps) {
   if (x == null) {
     throw new IllegalArgumentException("null root not allowed");
   }
   if (f == null || f.isZERO() || f.isConstant() || eps == null) {
     return true;
   }
   BigDecimal e = new BigDecimal(eps.getRational());
   e = e.multiply(new BigDecimal("1000")); // relax
   BigDecimal dc = BigDecimal.ONE;
   // polynomials with decimal coefficients
   GenPolynomialRing<BigDecimal> dfac = new GenPolynomialRing<BigDecimal>(dc, f.ring);
   GenPolynomial<BigDecimal> df = PolyUtil.<C>decimalFromRational(dfac, f);
   GenPolynomial<C> fp = PolyUtil.<C>baseDeriviative(f);
   GenPolynomial<BigDecimal> dfp = PolyUtil.<C>decimalFromRational(dfac, fp);
   //
   return isApproximateRoot(x, df, dfp, e);
 }
Пример #13
0
  /**
   * Magnitude bound.
   *
   * @param iv interval.
   * @param f univariate polynomial.
   * @return B such that |f(c)| &lt; B for c in iv.
   */
  public C magnitudeBound(Interval<C> iv, GenPolynomial<C> f) {
    if (f == null) {
      return null;
    }
    if (f.isZERO()) {
      return f.ring.coFac.getONE();
    }
    if (f.isConstant()) {
      return f.leadingBaseCoefficient().abs();
    }
    GenPolynomial<C> fa =
        f.map(
            new UnaryFunctor<C, C>() {

              public C eval(C a) {
                return a.abs();
              }
            });
    // System.out.println("fa = " + fa);
    C M = iv.left.abs();
    if (M.compareTo(iv.right.abs()) < 0) {
      M = iv.right.abs();
    }
    // System.out.println("M = " + M);
    RingFactory<C> cfac = f.ring.coFac;
    C B = PolyUtil.<C>evaluateMain(cfac, fa, M);
    // works also without this case, only for optimization
    // to use rational number interval end points
    // can fail if real root is in interval [r,r+1]
    // for too low precision or too big r, since r is approximation
    if ((Object) B instanceof RealAlgebraicNumber) {
      RealAlgebraicNumber Br = (RealAlgebraicNumber) B;
      BigRational r = Br.magnitude();
      B = cfac.fromInteger(r.numerator()).divide(cfac.fromInteger(r.denominator()));
    }
    // System.out.println("B = " + B);
    return B;
  }
Пример #14
0
 /**
  * Polynomial is char-th root.
  *
  * @param P polynomial.
  * @param F = [p_1 -&gt; e_1, ..., p_k -&gt; e_k].
  * @return true if P = prod_{i=1,...,k} p_i**(e_i*p), else false.
  */
 public boolean isCharRoot(GenPolynomial<C> P, SortedMap<GenPolynomial<C>, Long> F) {
   if (P == null || F == null) {
     throw new IllegalArgumentException("P and F may not be null");
   }
   if (P.isZERO() && F.size() == 0) {
     return true;
   }
   GenPolynomial<C> t = P.ring.getONE();
   long p = P.ring.characteristic().longValue();
   for (Map.Entry<GenPolynomial<C>, Long> me : F.entrySet()) {
     GenPolynomial<C> f = me.getKey();
     Long E = me.getValue(); // F.get(f);
     long e = E.longValue();
     GenPolynomial<C> g = Power.<GenPolynomial<C>>positivePower(f, e);
     if (!f.isConstant()) {
       g = Power.<GenPolynomial<C>>positivePower(g, p);
     }
     t = t.multiply(g);
   }
   boolean f = P.equals(t) || P.equals(t.negate());
   if (!f) {
     System.out.println("\nfactorization(map): " + f);
     System.out.println("P = " + P);
     System.out.println("t = " + t);
     P = P.monic();
     t = t.monic();
     f = P.equals(t) || P.equals(t.negate());
     if (f) {
       return f;
     }
     System.out.println("\nfactorization(map): " + f);
     System.out.println("P = " + P);
     System.out.println("t = " + t);
   }
   return f;
 }
Пример #15
0
  /**
   * Approximate real root.
   *
   * @param iv real root isolating interval with f(left) * f(right) &lt; 0.
   * @param f univariate polynomial, non-zero.
   * @param eps requested interval length.
   * @return a decimal approximation d such that |d-v| &lt; eps, for f(v) = 0, v real.
   */
  public BigDecimal approximateRoot(Interval<C> iv, GenPolynomial<C> f, C eps)
      throws NoConvergenceException {
    if (iv == null) {
      throw new IllegalArgumentException("null interval not allowed");
    }
    BigDecimal d = iv.toDecimal();
    if (f == null || f.isZERO() || f.isConstant() || eps == null) {
      return d;
    }
    if (iv.length().compareTo(eps) < 0) {
      return d;
    }
    BigDecimal left = new BigDecimal(iv.left.getRational());
    BigDecimal right = new BigDecimal(iv.right.getRational());
    BigDecimal e = new BigDecimal(eps.getRational());
    BigDecimal q = new BigDecimal("0.25");
    // System.out.println("left  = " + left);
    // System.out.println("right = " + right);
    e = e.multiply(d); // relative error
    // System.out.println("e     = " + e);
    BigDecimal dc = BigDecimal.ONE;
    // polynomials with decimal coefficients
    GenPolynomialRing<BigDecimal> dfac = new GenPolynomialRing<BigDecimal>(dc, f.ring);
    GenPolynomial<BigDecimal> df = PolyUtil.<C>decimalFromRational(dfac, f);
    GenPolynomial<C> fp = PolyUtil.<C>baseDeriviative(f);
    GenPolynomial<BigDecimal> dfp = PolyUtil.<C>decimalFromRational(dfac, fp);

    // Newton Raphson iteration: x_{n+1} = x_n - f(x_n)/f'(x_n)
    int i = 0;
    final int MITER = 50;
    int dir = 0;
    while (i++ < MITER) {
      BigDecimal fx = PolyUtil.<BigDecimal>evaluateMain(dc, df, d); // f(d)
      if (fx.isZERO()) {
        return d;
      }
      BigDecimal fpx = PolyUtil.<BigDecimal>evaluateMain(dc, dfp, d); // f'(d)
      if (fpx.isZERO()) {
        throw new NoConvergenceException("zero deriviative should not happen");
      }
      BigDecimal x = fx.divide(fpx);
      BigDecimal dx = d.subtract(x);
      // System.out.println("dx = " + dx);
      if (d.subtract(dx).abs().compareTo(e) <= 0) {
        return dx;
      }
      while (dx.compareTo(left) < 0 || dx.compareTo(right) > 0) { // dx < left: dx - left < 0
        // dx > right: dx - right > 0
        // System.out.println("trying to leave interval");
        if (i++ > MITER) { // dx > right: dx - right > 0
          throw new NoConvergenceException("no convergence after " + i + " steps");
        }
        if (i > MITER / 2 && dir == 0) {
          BigDecimal sd = new BigDecimal(iv.randomPoint().getRational());
          d = sd;
          x = sd.getZERO();
          logger.info("trying new random starting point " + d);
          i = 0;
          dir = 1;
        }
        if (i > MITER / 2 && dir == 1) {
          BigDecimal sd = new BigDecimal(iv.randomPoint().getRational());
          d = sd;
          x = sd.getZERO();
          logger.info("trying new random starting point " + d);
          // i = 0;
          dir = 2; // end
        }
        x = x.multiply(q); // x * 1/4
        dx = d.subtract(x);
        // System.out.println(" x = " + x);
        // System.out.println("dx = " + dx);
      }
      d = dx;
    }
    throw new NoConvergenceException("no convergence after " + i + " steps");
  }
Пример #16
0
  /**
   * Univariate GenPolynomial algebraic partial fraction decomposition, Rothstein-Trager algorithm.
   *
   * @param A univariate GenPolynomial, deg(A) < deg(P).
   * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1.
   * @return partial fraction container.
   */
  @Deprecated
  public PartialFraction<C> baseAlgebraicPartialFractionIrreducible(
      GenPolynomial<C> A, GenPolynomial<C> P) {
    if (P == null || P.isZERO()) {
      throw new RuntimeException(" P == null or P == 0");
    }
    // System.out.println("\nP_base_algeb_part = " + P);
    GenPolynomialRing<C> pfac = P.ring; // K[x]
    if (pfac.nvar > 1) {
      // System.out.println("facs_base_irred: univ");
      throw new RuntimeException("only for univariate polynomials");
    }
    if (!pfac.coFac.isField()) {
      // System.out.println("facs_base_irred: field");
      throw new RuntimeException("only for field coefficients");
    }
    List<C> cfactors = new ArrayList<C>();
    List<GenPolynomial<C>> cdenom = new ArrayList<GenPolynomial<C>>();
    List<AlgebraicNumber<C>> afactors = new ArrayList<AlgebraicNumber<C>>();
    List<GenPolynomial<AlgebraicNumber<C>>> adenom =
        new ArrayList<GenPolynomial<AlgebraicNumber<C>>>();

    // P linear
    if (P.degree(0) <= 1) {
      cfactors.add(A.leadingBaseCoefficient());
      cdenom.add(P);
      return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom);
    }

    // deriviative
    GenPolynomial<C> Pp = PolyUtil.<C>baseDeriviative(P);
    // no: Pp = Pp.monic();
    // System.out.println("\nP  = " + P);
    // System.out.println("Pp = " + Pp);

    // Q[t]
    String[] vars = new String[] {"t"};
    GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(pfac.coFac, 1, pfac.tord, vars);
    GenPolynomial<C> t = cfac.univariate(0);
    // System.out.println("t = " + t);

    // Q[x][t]
    GenPolynomialRing<GenPolynomial<C>> rfac =
        new GenPolynomialRing<GenPolynomial<C>>(pfac, cfac); // sic
    // System.out.println("rfac = " + rfac.toScript());

    // transform polynomials to bi-variate polynomial
    GenPolynomial<GenPolynomial<C>> Ac = PolyUfdUtil.<C>introduceLowerVariable(rfac, A);
    // System.out.println("Ac = " + Ac);
    GenPolynomial<GenPolynomial<C>> Pc = PolyUfdUtil.<C>introduceLowerVariable(rfac, P);
    // System.out.println("Pc = " + Pc);
    GenPolynomial<GenPolynomial<C>> Pcp = PolyUfdUtil.<C>introduceLowerVariable(rfac, Pp);
    // System.out.println("Pcp = " + Pcp);

    // Q[t][x]
    GenPolynomialRing<GenPolynomial<C>> rfac1 = Pc.ring;
    // System.out.println("rfac1 = " + rfac1.toScript());

    // A - t P'
    GenPolynomial<GenPolynomial<C>> tc = rfac1.getONE().multiply(t);
    // System.out.println("tc = " + tc);
    GenPolynomial<GenPolynomial<C>> At = Ac.subtract(tc.multiply(Pcp));
    // System.out.println("At = " + At);

    GreatestCommonDivisorSubres<C> engine = new GreatestCommonDivisorSubres<C>();
    // = GCDFactory.<C>getImplementation( cfac.coFac );
    GreatestCommonDivisorAbstract<AlgebraicNumber<C>> aengine = null;

    GenPolynomial<GenPolynomial<C>> Rc = engine.recursiveResultant(Pc, At);
    // System.out.println("Rc = " + Rc);
    GenPolynomial<C> res = Rc.leadingBaseCoefficient();
    // no: res = res.monic();
    // System.out.println("\nres = " + res);

    SortedMap<GenPolynomial<C>, Long> resfac = baseFactors(res);
    // System.out.println("resfac = " + resfac + "\n");

    for (GenPolynomial<C> r : resfac.keySet()) {
      // System.out.println("\nr(t) = " + r);
      if (r.isConstant()) {
        continue;
      }
      //             if ( r.degree(0) <= 1L ) {
      //                 System.out.println("warning linear factor in resultant ignored");
      //                 continue;
      //                 //throw new RuntimeException("input not irreducible");
      //             }
      // vars = new String[] { "z_" + Math.abs(r.hashCode() % 1000) };
      vars = pfac.newVars("z_");
      pfac = pfac.clone();
      vars = pfac.setVars(vars);
      r = pfac.copy(r); // hack to exchange the variables
      // System.out.println("r(z_) = " + r);
      AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(r, true); // since irreducible
      logger.debug("afac = " + afac.toScript());
      AlgebraicNumber<C> a = afac.getGenerator();
      // no: a = a.negate();
      // System.out.println("a = " + a);

      // K(alpha)[x]
      GenPolynomialRing<AlgebraicNumber<C>> pafac =
          new GenPolynomialRing<AlgebraicNumber<C>>(afac, Pc.ring);
      // System.out.println("pafac = " + pafac.toScript());

      // convert to K(alpha)[x]
      GenPolynomial<AlgebraicNumber<C>> Pa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, P);
      // System.out.println("Pa = " + Pa);
      GenPolynomial<AlgebraicNumber<C>> Pap = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, Pp);
      // System.out.println("Pap = " + Pap);
      GenPolynomial<AlgebraicNumber<C>> Aa = PolyUtil.<C>convertToAlgebraicCoefficients(pafac, A);
      // System.out.println("Aa = " + Aa);

      // A - a P'
      GenPolynomial<AlgebraicNumber<C>> Ap = Aa.subtract(Pap.multiply(a));
      // System.out.println("Ap = " + Ap);

      if (aengine == null) {
        aengine = GCDFactory.<AlgebraicNumber<C>>getImplementation(afac);
        // System.out.println("aengine = " + aengine);
      }
      GenPolynomial<AlgebraicNumber<C>> Ga = aengine.baseGcd(Pa, Ap);
      // System.out.println("Ga = " + Ga);
      if (Ga.isConstant()) {
        // System.out.println("warning constant gcd ignored");
        continue;
      }
      afactors.add(a);
      adenom.add(Ga);
      // quadratic case
      if (P.degree(0) == 2 && Ga.degree(0) == 1) {
        GenPolynomial<AlgebraicNumber<C>>[] qra =
            PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga);
        GenPolynomial<AlgebraicNumber<C>> Qa = qra[0];
        if (!qra[1].isZERO()) {
          throw new RuntimeException("remainder not zero");
        }
        // System.out.println("Qa = " + Qa);
        afactors.add(a.negate());
        adenom.add(Qa);
      }
      if (false && P.degree(0) == 3 && Ga.degree(0) == 1) {
        GenPolynomial<AlgebraicNumber<C>>[] qra =
            PolyUtil.<AlgebraicNumber<C>>basePseudoQuotientRemainder(Pa, Ga);
        GenPolynomial<AlgebraicNumber<C>> Qa = qra[0];
        if (!qra[1].isZERO()) {
          throw new RuntimeException("remainder not zero");
        }
        System.out.println("Qa3 = " + Qa);
        // afactors.add( a.negate() );
        // adenom.add( Qa );
      }
    }
    return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom);
  }
Пример #17
0
 /**
  * GenPolynomial polynomial squarefree factorization.
  *
  * @param A GenPolynomial.
  * @return [p_1 -&gt; e_1, ..., p_k -&gt; e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i
  *     squarefree.
  */
 @Override
 public SortedMap<GenPolynomial<C>, Long> baseSquarefreeFactors(GenPolynomial<C> A) {
   SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>();
   if (A == null || A.isZERO()) {
     return sfactors;
   }
   GenPolynomialRing<C> pfac = A.ring;
   if (A.isConstant()) {
     C coeff = A.leadingBaseCoefficient();
     // System.out.println("coeff = " + coeff + " @ " + coeff.factory());
     SortedMap<C, Long> rfactors = squarefreeFactors(coeff);
     // System.out.println("rfactors,const = " + rfactors);
     if (rfactors != null && rfactors.size() > 0) {
       for (Map.Entry<C, Long> me : rfactors.entrySet()) {
         C c = me.getKey();
         if (!c.isONE()) {
           GenPolynomial<C> cr = pfac.getONE().multiply(c);
           Long rk = me.getValue(); // rfactors.get(c);
           sfactors.put(cr, rk);
         }
       }
     } else {
       sfactors.put(A, 1L);
     }
     return sfactors;
   }
   if (pfac.nvar > 1) {
     throw new IllegalArgumentException(
         this.getClass().getName() + " only for univariate polynomials");
   }
   C ldbcf = A.leadingBaseCoefficient();
   if (!ldbcf.isONE()) {
     A = A.divide(ldbcf);
     SortedMap<C, Long> rfactors = squarefreeFactors(ldbcf);
     // System.out.println("rfactors,ldbcf = " + rfactors);
     if (rfactors != null && rfactors.size() > 0) {
       for (Map.Entry<C, Long> me : rfactors.entrySet()) {
         C c = me.getKey();
         if (!c.isONE()) {
           GenPolynomial<C> cr = pfac.getONE().multiply(c);
           Long rk = me.getValue(); // rfactors.get(c);
           sfactors.put(cr, rk);
         }
       }
     } else {
       GenPolynomial<C> f1 = pfac.getONE().multiply(ldbcf);
       // System.out.println("gcda sqf f1 = " + f1);
       sfactors.put(f1, 1L);
     }
     ldbcf = pfac.coFac.getONE();
   }
   GenPolynomial<C> T0 = A;
   long e = 1L;
   GenPolynomial<C> Tp;
   GenPolynomial<C> T = null;
   GenPolynomial<C> V = null;
   long k = 0L;
   long mp = 0L;
   boolean init = true;
   while (true) {
     // System.out.println("T0 = " + T0);
     if (init) {
       if (T0.isConstant() || T0.isZERO()) {
         break;
       }
       Tp = PolyUtil.<C>baseDeriviative(T0);
       T = engine.baseGcd(T0, Tp);
       T = T.monic();
       V = PolyUtil.<C>basePseudoDivide(T0, T);
       // System.out.println("iT0 = " + T0);
       // System.out.println("iTp = " + Tp);
       // System.out.println("iT  = " + T);
       // System.out.println("iV  = " + V);
       // System.out.println("const(iV)  = " + V.isConstant());
       k = 0L;
       mp = 0L;
       init = false;
     }
     if (V.isConstant()) {
       mp = pfac.characteristic().longValue(); // assert != 0
       // T0 = PolyUtil.<C> baseModRoot(T,mp);
       T0 = baseRootCharacteristic(T);
       logger.info("char root: T0 = " + T0 + ", T = " + T);
       if (T0 == null) {
         // break;
         T0 = pfac.getZERO();
       }
       e = e * mp;
       init = true;
       continue;
     }
     k++;
     if (mp != 0L && k % mp == 0L) {
       T = PolyUtil.<C>basePseudoDivide(T, V);
       System.out.println("k = " + k);
       // System.out.println("T = " + T);
       k++;
     }
     GenPolynomial<C> W = engine.baseGcd(T, V);
     W = W.monic();
     GenPolynomial<C> z = PolyUtil.<C>basePseudoDivide(V, W);
     // System.out.println("W = " + W);
     // System.out.println("z = " + z);
     V = W;
     T = PolyUtil.<C>basePseudoDivide(T, V);
     // System.out.println("V = " + V);
     // System.out.println("T = " + T);
     if (z.degree(0) > 0) {
       if (ldbcf.isONE() && !z.leadingBaseCoefficient().isONE()) {
         z = z.monic();
         logger.info("z,monic = " + z);
       }
       sfactors.put(z, (e * k));
     }
   }
   //      look, a stupid error:
   //         if ( !ldbcf.isONE() ) {
   //             GenPolynomial<C> f1 = sfactors.firstKey();
   //             long e1 = sfactors.remove(f1);
   //             System.out.println("gcda sqf c = " + c);
   //             f1 = f1.multiply(c);
   //             //System.out.println("gcda sqf f1e = " + f1);
   //             sfactors.put(f1,e1);
   //         }
   logger.info("exit char root: T0 = " + T0 + ", T = " + T);
   return sfactors;
 }