def _simplify(expr): u"""Simplifie une expression. Alias de simplify (sympy 0.6.4). Mais simplify n'est pas garanti d'être stable dans le temps. (Cf. simplify.__doc__).""" return together(expand(Poly.cancel(powsimp(expr))))
def ratint_ratpart(f, g, x): """Horowitz-Ostrogradsky algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime and deg(f) < deg(g), returns fractions A and B in K(x), such that f/g = A' + B and B has square-free denominator. """ f, g = Poly(f, x), Poly(g, x) u = poly_gcd(g, g.diff()) v = poly_div(g, u)[0] n = u.degree - 1 m = v.degree - 1 d = g.degree A_coeff = [ Symbol('a' + str(n-i), dummy=True) for i in xrange(0, n+1) ] B_coeff = [ Symbol('b' + str(m-i), dummy=True) for i in xrange(0, m+1) ] symbols = A_coeff + B_coeff A = Poly(zip(A_coeff, xrange(n, -1, -1)), x) B = Poly(zip(B_coeff, xrange(m, -1, -1)), x) H = f - A.diff()*v + A*poly_div(u.diff()*v, u)[0] - B*u result = solve(H.coeffs, symbols) A = A.subs(result) B = B.subs(result) rat_part = Poly.cancel((A, u), x) log_part = Poly.cancel((B, v), x) return rat_part, log_part
def test_poly_cancel(): assert Poly.cancel(x) == x assert Poly.cancel(x+1) == x+1 assert Poly.cancel((x+1)/(1-x)) == (x+1)/(1-x) assert Poly.cancel((x**2-1)/(x-1)) == x+1 assert Poly.cancel((x**2-y**2)/(x-y)) == x+y assert Poly.cancel((x**2-y)/(x-y)) == (x**2 - y)/(x - y) assert Poly.cancel((x**2-2)/(x+sqrt(2))) == x - sqrt(2) assert Poly.cancel((x**2-y**2)/(x-y), x) == x+y assert Poly.cancel((x, S.One), x) == x assert Poly.cancel((x+1, S.One), x) == x+1 assert Poly.cancel((x+1, x-1), x) == (x+1)/(x-1) assert Poly.cancel((x**2-1, x-1), x) == x+1 assert Poly.cancel((x**2-y**2, x-y), x, y) == x+y assert Poly.cancel((x**2-y, x-y), x, y) == (x**2 - y)/(x - y) assert Poly.cancel((x**2-2, x+sqrt(2)), x) == x - sqrt(2) assert Poly.cancel((x**2-y**2, x-y), x) == x+y assert Poly.cancel(((x**2-y**2).as_poly(x), (x-y).as_poly(x))) == x+y f = -1/(3 + 2*sqrt(2))*(1 + 1/(3 + 2*sqrt(2))*(7 + 5*sqrt(2))) assert Poly.cancel(f) == -2 + sqrt(2) raises(SymbolsError, "Poly.cancel((x**2-y**2, x-y))")
def test_poly_cancel(): assert Poly.cancel(x) == x assert Poly.cancel(x+1) == x+1 assert Poly.cancel((x+1)/(1-x)) == (x+1)/(1-x) assert Poly.cancel((x**2-1)/(x-1)) == x+1 assert Poly.cancel((x**2-y**2)/(x-y)) == x+y assert Poly.cancel((x**2-y)/(x-y)) == (x**2 - y)/(x - y) assert Poly.cancel((x**2-2)/(x+sqrt(2))) == x - sqrt(2) assert Poly.cancel((x**2-y**2)/(x-y), x) == x+y assert Poly.cancel((x, S.One), x) == x assert Poly.cancel((x+1, S.One), x) == x+1 assert Poly.cancel((x+1, x-1), x) == (x+1)/(x-1) assert Poly.cancel((x**2-1, x-1), x) == x+1 assert Poly.cancel((x**2-y**2, x-y), x, y) == x+y assert Poly.cancel((x**2-y, x-y), x, y) == (x**2 - y)/(x - y) assert Poly.cancel((x**2-2, x+sqrt(2)), x) == x - sqrt(2) assert Poly.cancel((x**2-y**2, x-y), x) == x+y assert Poly.cancel(((x**2-y**2).as_poly(x), (x-y).as_poly(x))) == x+y f = -1/(3 + 2*sqrt(2))*(1 + 1/(3 + 2*sqrt(2))*(7 + 5*sqrt(2))) assert Poly.cancel(f) == -2 + sqrt(2) a, b = x, 1/(1/y + 1/(x+y)) assert Poly.cancel(y/(x+y) * b/(a+b), x, y) == y**2/(x**2 + 3*x*y + y**2 ) raises(SymbolsError, "Poly.cancel((x**2-y**2, x-y))")