/** * 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; }
/** * 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| < 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; }
/** * Real 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 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); }
/** * Refine interval. * * @param iv root isolating interval with f(left) * f(right) < 0. * @param f univariate polynomial, non-zero. * @param eps requested interval length. * @return a new interval v such that |v| < 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; }
/** * GenPolynomial is absolute factorization. * * @param facs factors list container. * @return true if P = prod_{i=1,...,r} p_i, else false. */ public boolean isAbsoluteFactorization(FactorsList<C> facs) { if (facs == null) { throw new IllegalArgumentException("facs may not be null"); } GenPolynomial<C> P = facs.poly; GenPolynomial<C> t = P.ring.getONE(); for (GenPolynomial<C> f : facs.factors) { t = t.multiply(f); } if (P.equals(t) || P.equals(t.negate())) { return true; } if (facs.afactors == null) { return false; } for (Factors<C> fs : facs.afactors) { if (!isAbsoluteFactorization(fs)) { return false; } t = t.multiply(facs.poly); } // return P.equals(t) || P.equals(t.negate()); boolean b = P.equals(t) || P.equals(t.negate()); if (!b) { System.out.println("\nFactorsList: " + facs); System.out.println("P = " + P); System.out.println("t = " + t); } return b; }
/** * 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; }
/** 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); BigComplex x = BigComplex.CRAND(kl); b = new GenPolynomial<BigComplex>(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<BigComplex>(fac); b = new GenPolynomial<BigComplex>(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); }
/** * GenPolynomial is absolute factorization. * * @param facs factors map container. * @return true if P = prod_{i=1,...,k} p_i**e_i , else false. */ public boolean isAbsoluteFactorization(FactorsMap<C> facs) { if (facs == null) { throw new IllegalArgumentException("facs may not be null"); } GenPolynomial<C> P = facs.poly; GenPolynomial<C> t = P.ring.getONE(); for (GenPolynomial<C> f : facs.factors.keySet()) { long e = facs.factors.get(f); GenPolynomial<C> g = Power.<GenPolynomial<C>>positivePower(f, e); t = t.multiply(g); } if (P.equals(t) || P.equals(t.negate())) { return true; } if (facs.afactors == null) { return false; } for (Factors<C> fs : facs.afactors.keySet()) { if (!isAbsoluteFactorization(fs)) { return false; } long e = facs.afactors.get(fs); GenPolynomial<C> g = Power.<GenPolynomial<C>>positivePower(fs.poly, e); t = t.multiply(g); } boolean b = P.equals(t) || P.equals(t.negate()); if (!b) { System.out.println("\nFactorsMap: " + facs); System.out.println("P = " + P); System.out.println("t = " + t); } return b; }
/** * Real root bound. With f(M) * f(-M) != 0. * * @param f univariate polynomial. * @return M such that -M < root(f) < 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; }
/** * Univariate GenPolynomial algebraic partial fraction decomposition, Absolute factorization or * Rothstein-Trager algorithm. * * @param A univariate GenPolynomial, deg(A) < deg(P). * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1. * @return partial fraction container. */ public PartialFraction<C> baseAlgebraicPartialFraction(GenPolynomial<C> A, GenPolynomial<C> P) { if (P == null || P.isZERO()) { throw new RuntimeException(" P == null or P == 0"); } if (A == null || A.isZERO()) { throw new RuntimeException(" A == null or A == 0"); // PartialFraction(A,P,al,pl,empty,empty) } // 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); } List<GenPolynomial<C>> Pfac = baseFactorsSquarefree(P); // System.out.println("\nPfac = " + Pfac); List<GenPolynomial<C>> Afac = engine.basePartialFraction(A, Pfac); GenPolynomial<C> A0 = Afac.remove(0); if (!A0.isZERO()) { throw new RuntimeException(" A0 != 0: deg(A)>= deg(P)"); } // algebraic and linear factors int i = 0; for (GenPolynomial<C> pi : Pfac) { GenPolynomial<C> ai = Afac.get(i++); if (pi.degree(0) <= 1) { cfactors.add(ai.leadingBaseCoefficient()); cdenom.add(pi); continue; } PartialFraction<C> pf = baseAlgebraicPartialFractionIrreducibleAbsolute(ai, pi); // PartialFraction<C> pf = baseAlgebraicPartialFractionIrreducible(ai,pi); cfactors.addAll(pf.cfactors); cdenom.addAll(pf.cdenom); afactors.addAll(pf.afactors); adenom.addAll(pf.adenom); } return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); }
/** 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 compare sequential with parallel GBase. */ public void testSequentialParallelGBase() { List<GenPolynomial<BigRational>> Gs, Gp; L = new ArrayList<GenPolynomial<BigRational>>(); a = fac.random(kl, ll, el, q); b = fac.random(kl, ll, el, q); c = fac.random(kl, ll, el, q); d = fac.random(kl, ll, el, q); e = d; // fac.random(kl, ll, el, q ); if (a.isZERO() || b.isZERO() || c.isZERO() || d.isZERO()) { return; } L.add(a); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(b); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(c); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(d); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); L = Gs; L.add(e); Gs = bbseq.GB(L); Gp = bbpar.GB(L); assertTrue("Gs.containsAll(Gp)", Gs.containsAll(Gp)); assertTrue("Gp.containsAll(Gs)", Gp.containsAll(Gs)); }
/** * Refine intervals. * * @param V list of isolating intervals with f(left) * f(right) < 0. * @param f univariate polynomial, non-zero. * @param eps requested intervals length. * @return a list of new intervals v such that |v| < 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; }
/** * Real algebraic number magnitude. * * @param iv root isolating interval for f, with f(left) * f(right) < 0, with iv such that * |g(a) - g(b)| < 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; }
/** Main run method. */ public void run() { if (logger.isDebugEnabled()) { logger.debug("ht(H) = " + H.leadingExpVector()); } H = red.normalform(G, H); // mod done.release(); // done.V(); if (logger.isDebugEnabled()) { logger.debug("ht(H) = " + H.leadingExpVector()); } // H = H.monic(); }
// @Override public FactorsList<C> baseFactorsAbsoluteSquarefree(GenPolynomial<C> P) { if (P == null) { throw new RuntimeException(this.getClass().getName() + " P == null"); } List<GenPolynomial<C>> factors = new ArrayList<GenPolynomial<C>>(); if (P.isZERO()) { return new FactorsList<C>(P, factors); } // System.out.println("\nP_base_sqf = " + P); GenPolynomialRing<C> pfac = P.ring; // K[x] if (pfac.nvar > 1) { // System.out.println("facs_base_sqf: univ"); throw new RuntimeException("only for univariate polynomials"); } if (!pfac.coFac.isField()) { // System.out.println("facs_base_sqf: field"); throw new RuntimeException("only for field coefficients"); } if (P.degree(0) <= 1) { factors.add(P); return new FactorsList<C>(P, factors); } // factor over K (=C) List<GenPolynomial<C>> facs = baseFactorsSquarefree(P); // System.out.println("facs_base_irred = " + facs); if (debug && !isFactorization(P, facs)) { throw new RuntimeException("isFactorization = false"); } if (logger.isInfoEnabled()) { logger.info("all K factors = " + facs); // Q[X] // System.out.println("\nall K factors = " + facs); // Q[X] } // factor over K(alpha) List<Factors<C>> afactors = new ArrayList<Factors<C>>(); for (GenPolynomial<C> p : facs) { // System.out.println("facs_base_sqf_p = " + p); if (p.degree(0) <= 1) { factors.add(p); } else { Factors<C> afacs = baseFactorsAbsoluteIrreducible(p); // System.out.println("afacs_base_sqf = " + afacs); if (logger.isInfoEnabled()) { logger.info("K(alpha) factors = " + afacs); // K(alpha)[X] } afactors.add(afacs); } } // System.out.println("K(alpha) factors = " + factors); return new FactorsList<C>(P, factors, afactors); }
/** * GenPolynomial squarefree factorization. * * @param P GenPolynomial. * @return [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} p_i^{e_i} and p_i * squarefree. */ @Override public SortedMap<GenPolynomial<C>, Long> squarefreeFactors(GenPolynomial<C> P) { if (P == null) { throw new IllegalArgumentException(this.getClass().getName() + " P != null"); } GenPolynomialRing<C> pfac = P.ring; if (pfac.nvar <= 1) { return baseSquarefreeFactors(P); } SortedMap<GenPolynomial<C>, Long> sfactors = new TreeMap<GenPolynomial<C>, Long>(); if (P.isZERO()) { return sfactors; } GenPolynomialRing<C> cfac = pfac.contract(1); GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(cfac, 1); GenPolynomial<GenPolynomial<C>> Pr = PolyUtil.<C>recursive(rfac, P); SortedMap<GenPolynomial<GenPolynomial<C>>, Long> PP = recursiveUnivariateSquarefreeFactors(Pr); for (Map.Entry<GenPolynomial<GenPolynomial<C>>, Long> m : PP.entrySet()) { Long i = m.getValue(); GenPolynomial<GenPolynomial<C>> Dr = m.getKey(); GenPolynomial<C> D = PolyUtil.<C>distribute(pfac, Dr); sfactors.put(D, i); } return sfactors; }
/** * GenPolynomial absolute factorization of a polynomial. * * @param P GenPolynomial. * @return factors map container: [p_1 -> e_1, ..., p_k -> e_k] with P = prod_{i=1,...,k} * p_i**e_i. <b>Note:</b> K(alpha) not yet minimal. */ public FactorsMap<C> factorsAbsolute(GenPolynomial<C> P) { if (P == null) { throw new RuntimeException(this.getClass().getName() + " P == null"); } SortedMap<GenPolynomial<C>, Long> factors = new TreeMap<GenPolynomial<C>, Long>(); if (P.isZERO()) { return new FactorsMap<C>(P, factors); } // System.out.println("\nP_mult = " + P); GenPolynomialRing<C> pfac = P.ring; // K[x] if (pfac.nvar <= 1) { return baseFactorsAbsolute(P); } if (!pfac.coFac.isField()) { throw new RuntimeException("only for field coefficients"); } if (P.degree() <= 1) { factors.put(P, 1L); return new FactorsMap<C>(P, factors); } // factor over K (=C) SortedMap<GenPolynomial<C>, Long> facs = factors(P); if (debug && !isFactorization(P, facs)) { throw new RuntimeException("isFactorization = false"); } if (logger.isInfoEnabled()) { logger.info("all K factors = " + facs); // Q[X] // System.out.println("\nall K factors = " + facs); // Q[X] } SortedMap<Factors<C>, Long> afactors = new TreeMap<Factors<C>, Long>(); // factor over K(alpha) for (GenPolynomial<C> p : facs.keySet()) { Long e = facs.get(p); if (p.degree() <= 1) { factors.put(p, e); } else { Factors<C> afacs = factorsAbsoluteIrreducible(p); if (afacs.afac == null) { // absolute irreducible factors.put(p, e); } else { afactors.put(afacs, e); } } } // System.out.println("K(alpha) factors multi = " + factors); return new FactorsMap<C>(P, factors, afactors); }
/** * Calculate the result array <code> * [ poly1.divide(gcd(poly1, poly2)), poly2.divide(gcd(poly1, poly2)) ]</code> if the given * expressions <code>poly1</code> and <code>poly2</code> are univariate polynomials with equal * variable name. * * @param poly1 univariate polynomial * @param poly2 univariate polynomial * @return <code>null</code> if the expressions couldn't be converted to JAS polynomials */ public static IExpr[] cancelGCD(IExpr poly1, IExpr poly2) throws JASConversionException { try { ExprVariables eVar = new ExprVariables(poly1); eVar.addVarList(poly2); if (!eVar.isSize(1)) { // gcd only possible for univariate polynomials return null; } ASTRange r = new ASTRange(eVar.getVarList(), 1); JASConvert<BigRational> jas = new JASConvert<BigRational>(r.toList(), BigRational.ZERO); GenPolynomial<BigRational> p1 = jas.expr2JAS(poly1); GenPolynomial<BigRational> p2 = jas.expr2JAS(poly2); GenPolynomial<BigRational> gcd = p1.gcd(p2); IExpr[] result = new IExpr[2]; if (gcd.isONE()) { result[0] = jas.rationalPoly2Expr(p1); result[1] = jas.rationalPoly2Expr(p2); } else { result[0] = jas.rationalPoly2Expr(p1.divide(gcd)); result[1] = jas.rationalPoly2Expr(p2.divide(gcd)); } return result; } catch (Exception e) { if (Config.SHOW_STACKTRACE) { e.printStackTrace(); } } return null; }
/** * 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| < 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); }
/** * GenPolynomial polynomial greatest squarefree divisor. * * @param P GenPolynomial. * @return squarefree(pp(P)). */ @Override public GenPolynomial<C> baseSquarefreePart(GenPolynomial<C> P) { if (P == null || P.isZERO()) { return P; } GenPolynomialRing<C> pfac = P.ring; if (pfac.nvar > 1) { throw new IllegalArgumentException( this.getClass().getName() + " only for univariate polynomials"); } // just for the moment: GenPolynomial<C> s = pfac.getONE(); SortedMap<GenPolynomial<C>, Long> factors = baseSquarefreeFactors(P); logger.info("sqfPart,factors = " + factors); for (GenPolynomial<C> sp : factors.keySet()) { s = s.multiply(sp); } return s.monic(); }
/** Test modular evaluation gcd. */ public void testModEvalGcd() { GreatestCommonDivisorAbstract<ModInteger> ufd_me = new GreatestCommonDivisorModEval(); for (int i = 0; i < 1; i++) { a = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); b = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); c = dfac.random(kl * (i + 2), ll + 2 * i, el + 0 * i, q); c = c.multiply(dfac.univariate(0)); // a = ufd.basePrimitivePart(a); // b = ufd.basePrimitivePart(b); if (a.isZERO() || b.isZERO() || c.isZERO()) { // skip for this turn continue; } assertTrue("length( c" + i + " ) <> 0", c.length() > 0); // assertTrue(" not isZERO( c"+i+" )", !c.isZERO() ); // assertTrue(" not isONE( c"+i+" )", !c.isONE() ); a = a.multiply(c); b = b.multiply(c); // System.out.println("a = " + a); // System.out.println("b = " + b); d = ufd_me.gcd(a, b); c = ufd.basePrimitivePart(c).abs(); e = PolyUtil.<ModInteger>basePseudoRemainder(d, c); // System.out.println("c = " + c); // System.out.println("d = " + d); assertTrue("c | gcd(ac,bc) " + e, e.isZERO()); e = PolyUtil.<ModInteger>basePseudoRemainder(a, d); // System.out.println("e = " + e); assertTrue("gcd(a,b) | a" + e, e.isZERO()); e = PolyUtil.<ModInteger>basePseudoRemainder(b, d); // System.out.println("e = " + e); assertTrue("gcd(a,b) | b" + e, e.isZERO()); } }
/** Test parallel GBase. */ public void testParallelGBase() { L = new ArrayList<GenPolynomial<BigRational>>(); a = fac.random(kl, ll, el, q); b = fac.random(kl, ll, el, q); c = fac.random(kl, ll, el, q); d = fac.random(kl, ll, el, q); e = d; // fac.random(kl, ll, el, q ); if (a.isZERO() || b.isZERO() || c.isZERO() || d.isZERO()) { return; } assertTrue("not isZERO( a )", !a.isZERO()); L.add(a); L = bbpar.GB(L); assertTrue("isGB( { a } )", bbpar.isGB(L)); assertTrue("not isZERO( b )", !b.isZERO()); L.add(b); // System.out.println("L = " + L.size() ); L = bbpar.GB(L); assertTrue("isGB( { a, b } )", bbpar.isGB(L)); assertTrue("not isZERO( c )", !c.isZERO()); L.add(c); L = bbpar.GB(L); assertTrue("isGB( { a, b, c } )", bbpar.isGB(L)); assertTrue("not isZERO( d )", !d.isZERO()); L.add(d); L = bbpar.GB(L); assertTrue("isGB( { a, b, c, d } )", bbpar.isGB(L)); assertTrue("not isZERO( e )", !e.isZERO()); L.add(e); L = bbpar.GB(L); assertTrue("isGB( { a, b, c, d, e } )", bbpar.isGB(L)); }
/** * 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(); }
/** * Magnitude bound. * * @param iv interval. * @param f univariate polynomial. * @return B such that |f(c)| < 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; }
/** 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()); }
/** * Real algebraic number sign. * * @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. * @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); }
/** * Real algebraic number sign. * * @param iv root isolating interval for f, with f(left) * f(right) < 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(); }
/** * GenPolynomial absolute factorization of a irreducible polynomial. * * @param P irreducible! GenPolynomial. * @return factors container: [p_1,...,p_k] with P = prod_{i=1, ..., k} p_i in K(alpha)[x] for * suitable alpha and p_i irreducible over L[x], where K \subset K(alpha) \subset L is an * algebraically closed field over K. <b>Note:</b> K(alpha) not yet minimal. */ public Factors<C> factorsAbsoluteIrreducible(GenPolynomial<C> P) { if (P == null) { throw new RuntimeException(this.getClass().getName() + " P == null"); } if (P.isZERO()) { return new Factors<C>(P); } GenPolynomialRing<C> pfac = P.ring; // K[x] if (pfac.nvar <= 1) { return baseFactorsAbsoluteIrreducible(P); } if (!pfac.coFac.isField()) { throw new RuntimeException("only for field coefficients"); } List<GenPolynomial<C>> factors = new ArrayList<GenPolynomial<C>>(); if (P.degree() <= 1) { return new Factors<C>(P); } // find field extension K(alpha) GenPolynomial<C> up = P; RingFactory<C> cf = pfac.coFac; long cr = cf.characteristic().longValue(); // char might be larger if (cr == 0L) { cr = Long.MAX_VALUE; } long rp = 0L; for (int i = 0; i < (pfac.nvar - 1); i++) { rp = 0L; GenPolynomialRing<C> nfac = pfac.contract(1); String[] vn = new String[] {pfac.getVars()[pfac.nvar - 1]}; GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(nfac, 1, pfac.tord, vn); GenPolynomial<GenPolynomial<C>> upr = PolyUtil.<C>recursive(rfac, up); // System.out.println("upr = " + upr); GenPolynomial<C> ep; do { if (rp >= cr) { throw new RuntimeException("elements of prime field exhausted: " + cr); } C r = cf.fromInteger(rp); // cf.random(rp); // System.out.println("r = " + r); ep = PolyUtil.<C>evaluateMain(nfac, upr, r); // System.out.println("ep = " + ep); rp++; } while (!isSquarefree(ep) /*todo: || ep.degree() <= 1*/); // max deg up = ep; pfac = nfac; } up = up.monic(); if (debug) { logger.info("P(" + rp + ") = " + up); // System.out.println("up = " + up); } if (debug && !isSquarefree(up)) { throw new RuntimeException("not irreducible up = " + up); } if (up.degree(0) <= 1) { return new Factors<C>(P); } // find irreducible factor of up List<GenPolynomial<C>> UF = baseFactorsSquarefree(up); // System.out.println("UF = " + UF); FactorsList<C> aUF = baseFactorsAbsoluteSquarefree(up); // System.out.println("aUF = " + aUF); AlgebraicNumberRing<C> arfac = aUF.findExtensionField(); // System.out.println("arfac = " + arfac); long e = up.degree(0); // search factor polynomial with smallest degree for (int i = 0; i < UF.size(); i++) { GenPolynomial<C> upi = UF.get(i); long d = upi.degree(0); if (1 <= d && d <= e) { up = upi; e = up.degree(0); } } if (up.degree(0) <= 1) { return new Factors<C>(P); } if (debug) { logger.info("field extension by " + up); } List<GenPolynomial<AlgebraicNumber<C>>> afactors = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); // setup field extension K(alpha) // String[] vars = new String[] { "z_" + Math.abs(up.hashCode() % 1000) }; String[] vars = pfac.newVars("z_"); pfac = pfac.clone(); String[] ovars = pfac.setVars(vars); // side effects! GenPolynomial<C> aup = pfac.copy(up); // hack to exchange the variables // AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(aup,true); // since irreducible AlgebraicNumberRing<C> afac = arfac; int depth = afac.depth(); // System.out.println("afac = " + afac); GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, P.ring.nvar, P.ring.tord, P.ring.getVars()); // System.out.println("pafac = " + pafac); // convert to K(alpha) GenPolynomial<AlgebraicNumber<C>> Pa = PolyUtil.<C>convertToRecAlgebraicCoefficients(depth, pafac, P); // System.out.println("Pa = " + Pa); // factor over K(alpha) FactorAbstract<AlgebraicNumber<C>> engine = FactorFactory.<C>getImplementation(afac); afactors = engine.factorsSquarefree(Pa); if (debug) { logger.info("K(alpha) factors multi = " + afactors); // System.out.println("K(alpha) factors = " + afactors); } if (afactors.size() <= 1) { return new Factors<C>(P); } // normalize first factor to monic GenPolynomial<AlgebraicNumber<C>> p1 = afactors.get(0); AlgebraicNumber<C> p1c = p1.leadingBaseCoefficient(); if (!p1c.isONE()) { GenPolynomial<AlgebraicNumber<C>> p2 = afactors.get(1); afactors.remove(p1); afactors.remove(p2); p1 = p1.divide(p1c); p2 = p2.multiply(p1c); afactors.add(p1); afactors.add(p2); } // recursion for splitting field // find minimal field extension K(beta) \subset K(alpha) return new Factors<C>(P, afac, Pa, afactors); }
/** * Univariate GenPolynomial algebraic partial fraction decomposition, via absolute factorization * to linear factors. * * @param A univariate GenPolynomial, deg(A) < deg(P). * @param P univariate squarefree GenPolynomial, gcd(A,P) == 1. * @return partial fraction container. */ public PartialFraction<C> baseAlgebraicPartialFractionIrreducibleAbsolute( 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); } // non linear case Factors<C> afacs = factorsAbsoluteIrreducible(P); // System.out.println("linear algebraic factors = " + afacs); // System.out.println("afactors = " + afacs.afactors); // System.out.println("arfactors = " + afacs.arfactors); // System.out.println("arfactors pol = " + afacs.arfactors.get(0).poly); // System.out.println("arfactors2 = " + afacs.arfactors.get(0).afactors); List<GenPolynomial<AlgebraicNumber<C>>> fact = afacs.getFactors(); // System.out.println("factors = " + fact); GenPolynomial<AlgebraicNumber<C>> Pa = afacs.apoly; GenPolynomial<AlgebraicNumber<C>> Aa = PolyUtil.<C>convertToRecAlgebraicCoefficients(1, Pa.ring, A); GreatestCommonDivisorAbstract<AlgebraicNumber<C>> aengine = GCDFactory.getProxy(afacs.afac); // System.out.println("denom = " + Pa); // System.out.println("numer = " + Aa); List<GenPolynomial<AlgebraicNumber<C>>> numers = aengine.basePartialFraction(Aa, fact); // System.out.println("part frac = " + numers); GenPolynomial<AlgebraicNumber<C>> A0 = numers.remove(0); if (!A0.isZERO()) { throw new RuntimeException(" A0 != 0: deg(A)>= deg(P)"); } int i = 0; for (GenPolynomial<AlgebraicNumber<C>> fa : fact) { GenPolynomial<AlgebraicNumber<C>> an = numers.get(i++); if (fa.degree(0) <= 1) { afactors.add(an.leadingBaseCoefficient()); adenom.add(fa); continue; } System.out.println("fa = " + fa); Factors<AlgebraicNumber<C>> faf = afacs.getFactor(fa); System.out.println("faf = " + faf); List<GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>>> fafact = faf.getFactors(); GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> Aaa = PolyUtil.<AlgebraicNumber<C>>convertToRecAlgebraicCoefficients(1, faf.apoly.ring, an); GreatestCommonDivisorAbstract<AlgebraicNumber<AlgebraicNumber<C>>> aaengine = GCDFactory.getImplementation(faf.afac); List<GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>>> anumers = aaengine.basePartialFraction(Aaa, fafact); System.out.println("algeb part frac = " + anumers); GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> A0a = anumers.remove(0); if (!A0a.isZERO()) { throw new RuntimeException(" A0 != 0: deg(A)>= deg(P)"); } int k = 0; for (GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> faa : fafact) { GenPolynomial<AlgebraicNumber<AlgebraicNumber<C>>> ana = anumers.get(k++); System.out.println("faa = " + faa); System.out.println("ana = " + ana); if (faa.degree(0) > 1) { throw new RuntimeException(" faa not linear"); } GenPolynomial<AlgebraicNumber<C>> ana1 = (GenPolynomial<AlgebraicNumber<C>>) (GenPolynomial) ana; GenPolynomial<AlgebraicNumber<C>> faa1 = (GenPolynomial<AlgebraicNumber<C>>) (GenPolynomial) faa; afactors.add(ana1.leadingBaseCoefficient()); adenom.add(faa1); } } return new PartialFraction<C>(A, P, cfactors, cdenom, afactors, adenom); }