def ratint_logpart(f, g, x, t=None): """Lazard-Rioboo-Trager algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime, deg(f) < deg(g) and g is square-free, returns a list of tuples (s_i, q_i) of polynomials, for i = 1..n, such that s_i in K[t, x] and q_i in K[t], and: ___ ___ d f d \ ` \ ` -- - = -- ) ) a log(s_i(a, x)) dx g dx /__, /__, i=1..n a | q_i(a) = 0 """ f, g = Poly(f, x), Poly(g, x) t = t or Dummy('t') a, b = g, f - g.diff()*Poly(t, x) R = subresultants(a, b) res = Poly(resultant(a, b), t) R_map, H = {}, [] for r in R: R_map[r.degree()] = r def _include_sign(c, sqf): if c < 0: h, k = sqf[0] sqf[0] = h*c, k C, res_sqf = res.sqf_list() _include_sign(C, res_sqf) for q, i in res_sqf: _, q = q.primitive() if g.degree() == i: H.append((g, q)) else: h = R_map[i] h_lc = Poly(h.LC(), t, field=True) c, h_lc_sqf = h_lc.sqf_list(all=True) _include_sign(c, h_lc_sqf) for a, j in h_lc_sqf: h = h.exquo(Poly(a.gcd(q)**j, x)) inv, coeffs = h_lc.invert(q), [S(1)] for coeff in h.coeffs()[1:]: T = (inv*coeff).rem(q) coeffs.append(T.as_basic()) h = Poly(dict(zip(h.monoms(), coeffs)), x) H.append((h, q)) return H
def ratint_logpart(f, g, x, t=None): """ Lazard-Rioboo-Trager algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime, deg(f) < deg(g) and g is square-free, returns a list of tuples (s_i, q_i) of polynomials, for i = 1..n, such that s_i in K[t, x] and q_i in K[t], and: ___ ___ d f d \ ` \ ` -- - = -- ) ) a log(s_i(a, x)) dx g dx /__, /__, i=1..n a | q_i(a) = 0 Examples ======== >>> from sympy.integrals.rationaltools import ratint_logpart >>> from sympy.abc import x >>> from sympy import Poly >>> ratint_logpart(Poly(1, x, domain='ZZ'), ... Poly(x**2 + x + 1, x, domain='ZZ'), x) [(Poly(x + 3*_t/2 + 1/2, x, domain='QQ[_t]'), ...Poly(3*_t**2 + 1, _t, domain='ZZ'))] >>> ratint_logpart(Poly(12, x, domain='ZZ'), ... Poly(x**2 - x - 2, x, domain='ZZ'), x) [(Poly(x - 3*_t/8 - 1/2, x, domain='QQ[_t]'), ...Poly(-_t**2 + 16, _t, domain='ZZ'))] """ f, g = Poly(f, x), Poly(g, x) t = t or Dummy('t') a, b = g, f - g.diff()*Poly(t, x) R = subresultants(a, b) res = Poly(resultant(a, b), t, composite=False) R_map, H = {}, [] for r in R: R_map[r.degree()] = r def _include_sign(c, sqf): if c < 0: h, k = sqf[0] sqf[0] = h*c, k C, res_sqf = res.sqf_list() _include_sign(C, res_sqf) for q, i in res_sqf: _, q = q.primitive() if g.degree() == i: H.append((g, q)) else: h = R_map[i] h_lc = Poly(h.LC(), t, field=True) c, h_lc_sqf = h_lc.sqf_list(all=True) _include_sign(c, h_lc_sqf) for a, j in h_lc_sqf: h = h.quo(Poly(a.gcd(q)**j, x)) inv, coeffs = h_lc.invert(q), [S(1)] for coeff in h.coeffs()[1:]: T = (inv*coeff).rem(q) coeffs.append(T.as_expr()) h = Poly(dict(zip(h.monoms(), coeffs)), x) H.append((h, q)) return H
def ratint_logpart(f, g, x, t=None): """Lazard-Rioboo-Trager algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime, deg(f) < deg(g) and g is square-free, returns a list of tuples (s_i, q_i) of polynomials, for i = 1..n, such that s_i in K[t, x] and q_i in K[t], and: ___ ___ d f d \ ` \ ` -- - = -- ) ) a log(s_i(a, x)) dx g dx /__, /__, i=1..n a | q_i(a) = 0 """ f, g = Poly(f, x), Poly(g, x) t = t or Dummy('t') a, b = g, f - g.diff() * Poly(t, x) R = subresultants(a, b) res = Poly(resultant(a, b), t) R_map, H = {}, [] for r in R: R_map[r.degree()] = r def _include_sign(c, sqf): if c < 0: h, k = sqf[0] sqf[0] = h * c, k C, res_sqf = res.sqf_list() _include_sign(C, res_sqf) for q, i in res_sqf: _, q = q.primitive() if g.degree() == i: H.append((g, q)) else: h = R_map[i] h_lc = Poly(h.LC(), t, field=True) c, h_lc_sqf = h_lc.sqf_list(all=True) _include_sign(c, h_lc_sqf) for a, j in h_lc_sqf: h = h.exquo(Poly(a.gcd(q)**j, x)) inv, coeffs = h_lc.invert(q), [S(1)] for coeff in h.coeffs()[1:]: T = (inv * coeff).rem(q) coeffs.append(T.as_basic()) h = Poly(dict(zip(h.monoms(), coeffs)), x) H.append((h, q)) return H
def ratint_logpart(f, g, x, t=None): """ Lazard-Rioboo-Trager algorithm. Given a field K and polynomials f and g in K[x], such that f and g are coprime, deg(f) < deg(g) and g is square-free, returns a list of tuples (s_i, q_i) of polynomials, for i = 1..n, such that s_i in K[t, x] and q_i in K[t], and: ___ ___ d f d \ ` \ ` -- - = -- ) ) a log(s_i(a, x)) dx g dx /__, /__, i=1..n a | q_i(a) = 0 Examples ======== >>> from sympy.integrals.rationaltools import ratint_logpart >>> from sympy.abc import x >>> from sympy import Poly >>> ratint_logpart(Poly(1, x, domain='ZZ'), ... Poly(x**2 + x + 1, x, domain='ZZ'), x) [(Poly(x + 3*_t/2 + 1/2, x, domain='QQ[_t]'), ...Poly(3*_t**2 + 1, _t, domain='ZZ'))] >>> ratint_logpart(Poly(12, x, domain='ZZ'), ... Poly(x**2 - x - 2, x, domain='ZZ'), x) [(Poly(x - 3*_t/8 - 1/2, x, domain='QQ[_t]'), ...Poly(-_t**2 + 16, _t, domain='ZZ'))] """ f, g = Poly(f, x), Poly(g, x) t = t or Dummy('t') a, b = g, f - g.diff() * Poly(t, x) R = subresultants(a, b) res = Poly(resultant(a, b), t, composite=False) R_map, H = {}, [] for r in R: R_map[r.degree()] = r def _include_sign(c, sqf): if c < 0: h, k = sqf[0] sqf[0] = h * c, k C, res_sqf = res.sqf_list() _include_sign(C, res_sqf) for q, i in res_sqf: _, q = q.primitive() if g.degree() == i: H.append((g, q)) else: h = R_map[i] h_lc = Poly(h.LC(), t, field=True) c, h_lc_sqf = h_lc.sqf_list(all=True) _include_sign(c, h_lc_sqf) for a, j in h_lc_sqf: h = h.quo(Poly(a.gcd(q)**j, x)) inv, coeffs = h_lc.invert(q), [S(1)] for coeff in h.coeffs()[1:]: T = (inv * coeff).rem(q) coeffs.append(T.as_expr()) h = Poly(dict(zip(h.monoms(), coeffs)), x) H.append((h, q)) return H