/** * 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; }
/** * GenPolynomial polynomial squarefree factorization. * * @param A 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> 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; }