def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs(n, i) == c assert catalan(n).rewrite(Product).subs(n, i).doit() == c assert catalan(x) == catalan(x) assert catalan(2*x).rewrite(binomial) == binomial(4*x, 2*x)/(2*x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8/(3*pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3*x).rewrite(gamma) == 4**( 3*x)*gamma(3*x + Rational(1, 2))/(sqrt(pi)*gamma(3*x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2,), 1) assert catalan(n).rewrite(factorial) == factorial(2*n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma( 0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4))*catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(S.Half).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert str((re(c), im(c))) == '(0.398, -0.0209)'
def test_euler(): assert euler(0) == 1 assert euler(1) == 0 assert euler(2) == -1 assert euler(3) == 0 assert euler(4) == 5 assert euler(6) == -61 assert euler(8) == 1385 assert euler(20, evaluate=False) != 370371188237525 n = Symbol('n', integer=True) assert euler(n) != -1 assert euler(n).subs(n, 2) == -1 raises(ValueError, lambda: euler(-2)) raises(ValueError, lambda: euler(-3)) raises(ValueError, lambda: euler(2.3)) assert euler(20).evalf() == 370371188237525.0 assert euler(20, evaluate=False).evalf() == 370371188237525.0 assert euler(n).rewrite(Sum) == euler(n) n = Symbol('n', integer=True, nonnegative=True) assert euler(2 * n + 1).rewrite(Sum) == 0 _j = Dummy('j') _k = Dummy('k') assert euler(2 * n).rewrite(Sum).dummy_eq(I * Sum( (-1)**_j * 2**(-_k) * I**(-_k) * (-2 * _j + _k)**(2 * n + 1) * binomial(_k, _j) / _k, (_j, 0, _k), (_k, 1, 2 * n + 1)))
def test_catalan(): n = Symbol('n', integer=True) m = Symbol('n', integer=True, positive=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs(n, i) == c assert catalan(n).rewrite(Product).subs(n, i).doit() == c assert catalan(x) == catalan(x) assert catalan(2 * x).rewrite(binomial) == binomial(4 * x, 2 * x) / (2 * x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8 / (3 * pi) assert catalan(Rational(1, 2)).rewrite(factorial).rewrite(gamma) ==\ 8 / (3 * pi) assert catalan(3 * x).rewrite(gamma) == 4**( 3 * x) * gamma(3 * x + Rational(1, 2)) / (sqrt(pi) * gamma(3 * x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2, ), 1) assert catalan(n).rewrite(factorial) == factorial( 2 * n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma(0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4)) * catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(S.Half).evalf() assert str(c) == '0.848826363156775' c = catalan(I).evalf(3) assert str((re(c), im(c))) == '(0.398, -0.0209)'
def test_catalan(): assert catalan(1) == 1 assert catalan(2) == 2 assert catalan(3) == 5 assert catalan(4) == 14 assert catalan(x) == catalan(x) assert catalan(2*x).rewrite(binomial) == binomial(4*x, 2*x)/(2*x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8/(3*pi) assert catalan(3*x).rewrite(gamma) == 4**( 3*x)*gamma(3*x + Rational(1, 2))/(sqrt(pi)*gamma(3*x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2,), 1) assert diff(catalan(x), x) == (polygamma( 0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4))*catalan(x) c = catalan(0.5).evalf() assert str(c) == '0.848826363156775'
def test_catalan(): assert catalan(1) == 1 assert catalan(2) == 2 assert catalan(3) == 5 assert catalan(4) == 14 assert catalan(x) == catalan(x) assert catalan(2 * x).rewrite(binomial) == binomial(4 * x, 2 * x) / (2 * x + 1) assert catalan(Rational(1, 2)).rewrite(gamma) == 8 / (3 * pi) assert catalan(3 * x).rewrite(gamma) == 4**( 3 * x) * gamma(3 * x + Rational(1, 2)) / (sqrt(pi) * gamma(3 * x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2, ), 1) assert diff(catalan(x), x) == (polygamma(0, x + Rational(1, 2)) - polygamma(0, x + 2) + log(4)) * catalan(x) c = catalan(0.5).evalf() assert str(c) == '0.848826363156775'
def test_catalan(): n = Symbol("n", integer=True) m = Symbol("m", integer=True, positive=True) k = Symbol("k", integer=True, nonnegative=True) p = Symbol("p", nonnegative=True) catalans = [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786] for i, c in enumerate(catalans): assert catalan(i) == c assert catalan(n).rewrite(factorial).subs(n, i) == c assert catalan(n).rewrite(Product).subs(n, i).doit() == c assert unchanged(catalan, x) assert catalan(2 * x).rewrite(binomial) == binomial(4 * x, 2 * x) / (2 * x + 1) assert catalan(S.Half).rewrite(gamma) == 8 / (3 * pi) assert catalan(S.Half).rewrite(factorial).rewrite(gamma) == 8 / (3 * pi) assert catalan(3 * x).rewrite(gamma) == 4**( 3 * x) * gamma(3 * x + S.Half) / (sqrt(pi) * gamma(3 * x + 2)) assert catalan(x).rewrite(hyper) == hyper((-x + 1, -x), (2, ), 1) assert catalan(n).rewrite(factorial) == factorial( 2 * n) / (factorial(n + 1) * factorial(n)) assert isinstance(catalan(n).rewrite(Product), catalan) assert isinstance(catalan(m).rewrite(Product), Product) assert diff(catalan(x), x) == (polygamma(0, x + S.Half) - polygamma(0, x + 2) + log(4)) * catalan(x) assert catalan(x).evalf() == catalan(x) c = catalan(S.Half).evalf() assert str(c) == "0.848826363156775" c = catalan(I).evalf(3) assert str((re(c), im(c))) == "(0.398, -0.0209)" # Assumptions assert catalan(p).is_positive is True assert catalan(k).is_integer is True assert catalan(m + 3).is_composite is True
def test_Function_change_name(): assert mcode(abs(x)) == "abs(x)" assert mcode(ceiling(x)) == "ceil(x)" assert mcode(arg(x)) == "angle(x)" assert mcode(im(x)) == "imag(x)" assert mcode(re(x)) == "real(x)" assert mcode(conjugate(x)) == "conj(x)" assert mcode(chebyshevt(y, x)) == "chebyshevT(y, x)" assert mcode(chebyshevu(y, x)) == "chebyshevU(y, x)" assert mcode(laguerre(x, y)) == "laguerreL(x, y)" assert mcode(Chi(x)) == "coshint(x)" assert mcode(Shi(x)) == "sinhint(x)" assert mcode(Ci(x)) == "cosint(x)" assert mcode(Si(x)) == "sinint(x)" assert mcode(li(x)) == "logint(x)" assert mcode(loggamma(x)) == "gammaln(x)" assert mcode(polygamma(x, y)) == "psi(x, y)" assert mcode(RisingFactorial(x, y)) == "pochhammer(x, y)" assert mcode(DiracDelta(x)) == "dirac(x)" assert mcode(DiracDelta(x, 3)) == "dirac(3, x)" assert mcode(Heaviside(x)) == "heaviside(x, 1/2)" assert mcode(Heaviside(x, y)) == "heaviside(x, y)" assert mcode(binomial(x, y)) == "bincoeff(x, y)" assert mcode(Mod(x, y)) == "mod(x, y)"
def trigintegrate(f, x): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos >>> from sympy.integrals.trigonometry import trigintegrate >>> x = Symbol('x') >>> trigintegrate(sin(x)*cos(x), x) 1/2*sin(x)**2 >>> trigintegrate(sin(x)**2, x) x/2 - cos(x)*sin(x)/2 http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques """ pat, a,n,m = _pat_sincos(x) M = f.match(pat) if M is None: return n, m = M[n], M[m] # should always be there if n is S.Zero and m is S.Zero: return x a = M[a] if n.is_integer and n.is_integer: if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1-u**2)**((n-1)/2) * u**m uu = cos(a*x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1-u**2)**((m-1)/2) uu = sin(a*x) fi= sympy.integrals.integrate(ff, u) # XXX cyclic deps fx= fi.subs(u, uu) return fx / a # n & m are even else: # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (n > m) # NB: careful here, one of the m_ = not (n > m) # conditions *must* be true res = S.Zero if n_: # 2k 2 k i 2i # C = (1-S ) = sum(i, (-) * B(k,i) * S ) for i in range(0,m/2+1): res += (-1)**i * binomial(m/2,i) * Sin_2k_integrate(n/2+i, x) elif m_: # 2k 2 k i 2i # S = (1 -C ) = sum(i, (-) * B(k,i) * C ) for i in range(0,n/2+1): res += (-1)**i * binomial(n/2,i) * Cos_2k_integrate(m/2+i, x) return res.subs(x, a*x) / a
def rsolve_poly(coeffs, f, n, **hints): """ Given linear recurrence operator `\operatorname{L}` of order `k` with polynomial coefficients and inhomogeneous equation `\operatorname{L} y = f`, where `f` is a polynomial, we seek for all polynomial solutions over field `K` of characteristic zero. The algorithm performs two basic steps: (1) Compute degree `N` of the general polynomial solution. (2) Find all polynomials of degree `N` or less of `\operatorname{L} y = f`. There are two methods for computing the polynomial solutions. If the degree bound is relatively small, i.e. it's smaller than or equal to the order of the recurrence, then naive method of undetermined coefficients is being used. This gives system of algebraic equations with `N+1` unknowns. In the other case, the algorithm performs transformation of the initial equation to an equivalent one, for which the system of algebraic equations has only `r` indeterminates. This method is quite sophisticated (in comparison with the naive one) and was invented together by Abramov, Bronstein and Petkovsek. It is possible to generalize the algorithm implemented here to the case of linear q-difference and differential equations. Lets say that we would like to compute `m`-th Bernoulli polynomial up to a constant. For this we can use `b(n+1) - b(n) = m n^{m-1}` recurrence, which has solution `b(n) = B_m + C`. For example: >>> from sympy import Symbol, rsolve_poly >>> n = Symbol('n', integer=True) >>> rsolve_poly([-1, 1], 4*n**3, n) C0 + n**4 - 2*n**3 + n**2 References ========== .. [1] S. A. Abramov, M. Bronstein and M. Petkovsek, On polynomial solutions of linear operator equations, in: T. Levelt, ed., Proc. ISSAC '95, ACM Press, New York, 1995, 290-296. .. [2] M. Petkovsek, Hypergeometric solutions of linear recurrences with polynomial coefficients, J. Symbolic Computation, 14 (1992), 243-264. .. [3] M. Petkovsek, H. S. Wilf, D. Zeilberger, A = B, 1996. """ f = sympify(f) if not f.is_polynomial(n): return None homogeneous = f.is_zero r = len(coeffs) - 1 coeffs = [ Poly(coeff, n) for coeff in coeffs ] polys = [ Poly(0, n) ] * (r + 1) terms = [ (S.Zero, S.NegativeInfinity) ] *(r + 1) for i in xrange(0, r + 1): for j in xrange(i, r + 1): polys[i] += coeffs[j]*binomial(j, i) if not polys[i].is_zero: (exp,), coeff = polys[i].LT() terms[i] = (coeff, exp) d = b = terms[0][1] for i in xrange(1, r + 1): if terms[i][1] > d: d = terms[i][1] if terms[i][1] - i > b: b = terms[i][1] - i d, b = int(d), int(b) x = Dummy('x') degree_poly = S.Zero for i in xrange(0, r + 1): if terms[i][1] - i == b: degree_poly += terms[i][0]*FallingFactorial(x, i) nni_roots = roots(degree_poly, x, filter='Z', predicate=lambda r: r >= 0).keys() if nni_roots: N = [max(nni_roots)] else: N = [] if homogeneous: N += [-b - 1] else: N += [f.as_poly(n).degree() - b, -b - 1] N = int(max(N)) if N < 0: if homogeneous: if hints.get('symbols', False): return (S.Zero, []) else: return S.Zero else: return None if N <= r: C = [] y = E = S.Zero for i in xrange(0, N + 1): C.append(Symbol('C' + str(i))) y += C[i] * n**i for i in xrange(0, r + 1): E += coeffs[i].as_expr()*y.subs(n, n + i) solutions = solve_undetermined_coeffs(E - f, C, n) if solutions is not None: C = [ c for c in C if (c not in solutions) ] result = y.subs(solutions) else: return None # TBD else: A = r U = N + A + b + 1 nni_roots = roots(polys[r], filter='Z', predicate=lambda r: r >= 0).keys() if nni_roots != []: a = max(nni_roots) + 1 else: a = S.Zero def _zero_vector(k): return [S.Zero] * k def _one_vector(k): return [S.One] * k def _delta(p, k): B = S.One D = p.subs(n, a + k) for i in xrange(1, k + 1): B *= -Rational(k - i + 1, i) D += B * p.subs(n, a + k - i) return D alpha = {} for i in xrange(-A, d + 1): I = _one_vector(d + 1) for k in xrange(1, d + 1): I[k] = I[k - 1] * (x + i - k + 1)/k alpha[i] = S.Zero for j in xrange(0, A + 1): for k in xrange(0, d + 1): B = binomial(k, i + j) D = _delta(polys[j].as_expr(), k) alpha[i] += I[k]*B*D V = Matrix(U, A, lambda i, j: int(i == j)) if homogeneous: for i in xrange(A, U): v = _zero_vector(A) for k in xrange(1, A + b + 1): if i - k < 0: break B = alpha[k - A].subs(x, i - k) for j in xrange(0, A): v[j] += B * V[i - k, j] denom = alpha[-A].subs(x, i) for j in xrange(0, A): V[i, j] = -v[j] / denom else: G = _zero_vector(U) for i in xrange(A, U): v = _zero_vector(A) g = S.Zero for k in xrange(1, A + b + 1): if i - k < 0: break B = alpha[k - A].subs(x, i - k) for j in xrange(0, A): v[j] += B * V[i - k, j] g += B * G[i - k] denom = alpha[-A].subs(x, i) for j in xrange(0, A): V[i, j] = -v[j] / denom G[i] = (_delta(f, i - A) - g) / denom P, Q = _one_vector(U), _zero_vector(A) for i in xrange(1, U): P[i] = (P[i - 1] * (n - a - i + 1)/i).expand() for i in xrange(0, A): Q[i] = Add(*[ (v*p).expand() for v, p in zip(V[:, i], P) ]) if not homogeneous: h = Add(*[ (g*p).expand() for g, p in zip(G, P) ]) C = [ Symbol('C' + str(i)) for i in xrange(0, A) ] g = lambda i: Add(*[ c*_delta(q, i) for c, q in zip(C, Q) ]) if homogeneous: E = [ g(i) for i in xrange(N + 1, U) ] else: E = [ g(i) + _delta(h, i) for i in xrange(N + 1, U) ] if E != []: solutions = solve(E, *C) if not solutions: if homogeneous: if hints.get('symbols', False): return (S.Zero, []) else: return S.Zero else: return None else: solutions = {} if homogeneous: result = S.Zero else: result = h for c, q in list(zip(C, Q)): if c in solutions: s = solutions[c]*q C.remove(c) else: s = c*q result += s.expand() if hints.get('symbols', False): return (result, C) else: return result
def test_euler_failing(): # depends on dummy variables being implemented https://github.com/sympy/sympy/issues/5665 assert euler(2 * n).rewrite(Sum) == I * Sum( Sum((-1)**_j * 2**(-_k) * I**(-_k) * (-2 * _j + _k)**(2 * n + 1) * binomial(_k, _j) / _k, (_j, 0, _k)), (_k, 1, 2 * n + 1))
def trigintegrate(f, x): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos >>> from sympy.integrals.trigonometry import trigintegrate >>> from sympy.abc import x >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - cos(x)*sin(x)/2 http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques """ pat, a,n,m = _pat_sincos(x) ##m - cos ##n - sin M = f.match(pat) if M is None: return n, m = M[n], M[m] # should always be there if n is S.Zero and m is S.Zero: return x a = M[a] if n.is_integer and m.is_integer: if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1-u**2)**((n-1)/2) * u**m uu = cos(a*x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1-u**2)**((m-1)/2) uu = sin(a*x) fi= sympy.integrals.integrate(ff, u) # XXX cyclic deps fx= fi.subs(u, uu) return fx / a # n & m are even else: # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1-S ) = sum(i, (-) * B(k,i) * S ) if m > 0 : for i in range(0,m/2+1): res += (-1)**i * binomial(m/2,i) * sin_pow_integrate(n+2*i, x) elif m == 0: res=sin_pow_integrate(n,x) else: # m < 0 , |n| > |m| # / / # | | # | m n -1 m+1 n-1 n - 1 | m+2 n-2 # | cos (x) sin (x) dx = ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | m + 1 m + 1 | #/ / # # res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*trigintegrate(cos(x)**(m+2)*sin(x)**(n-2),x) elif m_: # 2k 2 k i 2i # S = (1 -C ) = sum(i, (-) * B(k,i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m,n >0 ; m,n belong to Z - {0} # n 2 # sin (x) term is expanded here interms of cos (x), and then integrated. for i in range(0,n/2+1): res += (-1)**i * binomial(n/2,i) * cos_pow_integrate(m+2*i, x) elif n == 0 : ## / ## | # | 1 # | _ _ _ # | m # | cos (x) # / res= cos_pow_integrate(m,x) else: # n < 0 , |m| > |n| # / / # | | # | m n 1 m-1 n+1 m - 1 | m-2 n+2 # | cos (x) sin (x) dx = _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | n + 1 n + 1 | #/ / # # res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*trigintegrate(cos(x)**(m-2)*sin(x)**(n+2),x) else : if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res=sympy.integrals.integrate((Rational(1,2)*sin(2*x))**m,x) elif (m == -n): if n < 0: ##Same as the scheme described above. res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*sympy.integrals.integrate(cos(x)**(m-2)*sin(x)**(n+2),x) ##the function argument to integrate in the end will be 1 , this cannot be integrated by trigintegrate. Hence use sympy.integrals.integrate. else: res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*sympy.integrals.integrate(cos(x)**(m+2)*sin(x)**(n-2),x) return res.subs(x, a*x) / a
def trigintegrate(f, x, conds='piecewise'): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos, tan, sec, csc, cot >>> from sympy.integrals.trigonometry import trigintegrate >>> from sympy.abc import x >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - sin(x)*cos(x)/2 >>> trigintegrate(tan(x)*sec(x), x) 1/cos(x) >>> trigintegrate(sin(x)*tan(x), x) -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x) http://en.wikibooks.org/wiki/Calculus/Integration_techniques See Also ======== sympy.integrals.integrals.Integral.doit sympy.integrals.integrals.Integral """ from sympy.integrals.integrals import integrate pat, a, n, m = _pat_sincos(x) f = f.rewrite('sincos') M = f.match(pat) if M is None: return n, m = M[n], M[m] if n.is_zero and m.is_zero: return x zz = x if n.is_zero else S.Zero a = M[a] if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: # Make sure to choose the positive one # otherwise an incorrect integral can occur. if n < 0 and m > 0: m_ = True n_ = False elif m < 0 and n > 0: n_ = True m_ = False # Both are negative so choose the smallest n or m # in absolute value for simplest substitution. elif (n < 0 and m < 0): n_ = n > m m_ = not (n > m) # Both n and m are odd and positive else: n_ = (n < m) # NB: careful here, one of the m_ = not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1 - u**2)**((n - 1) / 2) * u**m uu = cos(a * x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1 - u**2)**((m - 1) / 2) uu = sin(a * x) fi = integrate(ff, u) # XXX cyclic deps fx = fi.subs(u, uu) if conds == 'piecewise': return Piecewise((fx / a, Ne(a, 0)), (zz, True)) return fx / a # n & m are both even # # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1 - S ) = sum(i, (-) * B(k, i) * S ) if m > 0: for i in range(0, m // 2 + 1): res += ((-1)**i * binomial(m // 2, i) * _sin_pow_integrate(n + 2 * i, x)) elif m == 0: res = _sin_pow_integrate(n, x) else: # m < 0 , |n| > |m| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # -1 m+1 n-1 n - 1 | m+2 n-2 # ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # m + 1 m + 1 | # / res = (Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * trigintegrate(cos(x)**(m + 2) * sin(x)**(n - 2), x)) elif m_: # 2k 2 k i 2i # S = (1 - C ) = sum(i, (-) * B(k, i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m, n >0 ; m, n belong to Z - {0} # n 2 # sin (x) term is expanded here in terms of cos (x), # and then integrated. # for i in range(0, n // 2 + 1): res += ((-1)**i * binomial(n // 2, i) * _cos_pow_integrate(m + 2 * i, x)) elif n == 0: # / # | # | 1 # | _ _ _ # | m # | cos (x) # / # res = _cos_pow_integrate(m, x) else: # n < 0 , |m| > |n| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # 1 m-1 n+1 m - 1 | m-2 n+2 # _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # n + 1 n + 1 | # / res = (Rational(1, n + 1) * cos(x)**(m - 1) * sin(x)**(n + 1) + Rational(m - 1, n + 1) * trigintegrate(cos(x)**(m - 2) * sin(x)**(n + 2), x)) else: if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res = integrate((sin(2 * x) * S.Half)**m, x) elif (m == -n): if n < 0: # Same as the scheme described above. # the function argument to integrate in the end will # be 1 , this cannot be integrated by trigintegrate. # Hence use sympy.integrals.integrate. res = (Rational(1, n + 1) * cos(x)**(m - 1) * sin(x)**(n + 1) + Rational(m - 1, n + 1) * integrate(cos(x)**(m - 2) * sin(x)**(n + 2), x)) else: res = ( Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * integrate(cos(x)**(m + 2) * sin(x)**(n - 2), x)) if conds == 'piecewise': return Piecewise((res.subs(x, a * x) / a, Ne(a, 0)), (zz, True)) return res.subs(x, a * x) / a
def trigintegrate(f, x): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos, tan, sec, csc, cot >>> from sympy.integrals.trigonometry import trigintegrate >>> from sympy.abc import x >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - sin(x)*cos(x)/2 >>> trigintegrate(tan(x)*sec(x),x) 1/cos(x) >>> trigintegrate(sin(x)*tan(x),x) -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x) http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques See Also ======== sympy.integrals.integrals.Integral.doit sympy.integrals.integrals.Integral """ pat, a,n,m = _pat_sincos(x) pat1, s,t,q,r = _pat_gen(x) M_ = f.match(pat1) if M_ is None: return q = M_[q] r = M_[r] ### ### f = function1(written in terms of sincos) X function2(written in terms of sincos) ### if q is not S.Zero and r is not S.Zero: s = M_[s] t = M_[t] if s.args is not () and t.args is not () \ and Trig_Check(s) and Trig_Check(t): f = s._eval_rewrite_as_sincos(s.args[0])**q * t._eval_rewrite_as_sincos(t.args[0])**r if q is S.Zero and r is S.Zero: return x if q is S.Zero and r is not S.Zero: t = M_[t] if t.args is not () and Trig_Check(t): f = t._eval_rewrite_as_sincos(t.args[0])**r if r is S.Zero and q is not S.Zero: s = M_[s] if s.args is not () and Trig_Check(s): f = s._eval_rewrite_as_sincos(s.args[0])**q M= f.match(pat) # matching the rewritten function with the sincos pattern if M is None: return n, m = M[n], M[m] if n is S.Zero and m is S.Zero: return x a = M[a] if n.is_integer and m.is_integer: if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1-u**2)**((n-1)/2) * u**m uu = cos(a*x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1-u**2)**((m-1)/2) uu = sin(a*x) fi= sympy.integrals.integrate(ff, u) # XXX cyclic deps fx= fi.subs(u, uu) return fx / a # n & m are even else: # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1-S ) = sum(i, (-) * B(k,i) * S ) if m > 0 : for i in range(0,m/2+1): res += (-1)**i * binomial(m/2,i) * _sin_pow_integrate(n+2*i, x) elif m == 0: res=_sin_pow_integrate(n,x) else: # m < 0 , |n| > |m| # / / # | | # | m n -1 m+1 n-1 n - 1 | m+2 n-2 # | cos (x) sin (x) dx = ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | m + 1 m + 1 | #/ / # # res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*trigintegrate(cos(x)**(m+2)*sin(x)**(n-2),x) elif m_: # 2k 2 k i 2i # S = (1 -C ) = sum(i, (-) * B(k,i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m,n >0 ; m,n belong to Z - {0} # n 2 # sin (x) term is expanded here interms of cos (x), and then integrated. for i in range(0,n/2+1): res += (-1)**i * binomial(n/2,i) * _cos_pow_integrate(m+2*i, x) elif n == 0 : ## / ## | # | 1 # | _ _ _ # | m # | cos (x) # / res= _cos_pow_integrate(m,x) else: # n < 0 , |m| > |n| # / / # | | # | m n 1 m-1 n+1 m - 1 | m-2 n+2 # | cos (x) sin (x) dx = _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | n + 1 n + 1 | #/ / # # res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*trigintegrate(cos(x)**(m-2)*sin(x)**(n+2),x) else : if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res=sympy.integrals.integrate((Rational(1,2)*sin(2*x))**m,x) elif (m == -n): if n < 0: ##Same as the scheme described above. res= Rational(1,(n+1))*cos(x)**(m-1)*sin(x)**(n+1) + Rational(m-1,n+1)*sympy.integrals.integrate(cos(x)**(m-2)*sin(x)**(n+2),x) ##the function argument to integrate in the end will be 1 , this cannot be integrated by trigintegrate. Hence use sympy.integrals.integrate. else: res=Rational(-1,m+1)*cos(x)**(m+1)*sin(x)**(n-1) + Rational(n-1,m+1)*sympy.integrals.integrate(cos(x)**(m+2)*sin(x)**(n-2),x) return res.subs(x, a*x) / a
def test_euler_failing(): # depends on dummy variables being implemented https://github.com/sympy/sympy/issues/5665 assert euler(2*n).rewrite(Sum) == I*Sum(Sum((-1)**_j*2**(-_k)*I**(-_k)*(-2*_j + _k)**(2*n + 1)*binomial(_k, _j)/_k, (_j, 0, _k)), (_k, 1, 2*n + 1))
def trigintegrate(f, x, conds='piecewise'): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos, tan, sec, csc, cot >>> from sympy.integrals.trigonometry import trigintegrate >>> from sympy.abc import x >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - sin(x)*cos(x)/2 >>> trigintegrate(tan(x)*sec(x), x) 1/cos(x) >>> trigintegrate(sin(x)*tan(x), x) -log(sin(x) - 1)/2 + log(sin(x) + 1)/2 - sin(x) http://en.wikibooks.org/wiki/Calculus/Integration_techniques See Also ======== sympy.integrals.integrals.Integral.doit sympy.integrals.integrals.Integral """ from sympy.integrals.integrals import integrate pat, a, n, m = _pat_sincos(x) f = f.rewrite('sincos') M = f.match(pat) if M is None: return n, m = M[n], M[m] if n is S.Zero and m is S.Zero: return x zz = x if n is S.Zero else S.Zero a = M[a] if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1 - u**2)**((n - 1)/2) * u**m uu = cos(a*x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1 - u**2)**((m - 1)/2) uu = sin(a*x) fi = integrate(ff, u) # XXX cyclic deps fx = fi.subs(u, uu) if conds == 'piecewise': return Piecewise((zz, Eq(a, 0)), (fx / a, True)) return fx / a # n & m are both even # # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1 - S ) = sum(i, (-) * B(k, i) * S ) if m > 0: for i in range(0, m//2 + 1): res += ((-1)**i * binomial(m//2, i) * _sin_pow_integrate(n + 2*i, x)) elif m == 0: res = _sin_pow_integrate(n, x) else: # m < 0 , |n| > |m| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # -1 m+1 n-1 n - 1 | m+2 n-2 # ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # m + 1 m + 1 | # / res = (Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * trigintegrate(cos(x)**(m + 2)*sin(x)**(n - 2), x)) elif m_: # 2k 2 k i 2i # S = (1 - C ) = sum(i, (-) * B(k, i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m, n >0 ; m, n belong to Z - {0} # n 2 # sin (x) term is expanded here in terms of cos (x), # and then integrated. # for i in range(0, n//2 + 1): res += ((-1)**i * binomial(n//2, i) * _cos_pow_integrate(m + 2*i, x)) elif n == 0: # / # | # | 1 # | _ _ _ # | m # | cos (x) # / # res = _cos_pow_integrate(m, x) else: # n < 0 , |m| > |n| # / # | # | m n # | cos (x) sin (x) dx = # | # | #/ # / # | # 1 m-1 n+1 m - 1 | m-2 n+2 # _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | # n + 1 n + 1 | # / res = (Rational(1, n + 1) * cos(x)**(m - 1)*sin(x)**(n + 1) + Rational(m - 1, n + 1) * trigintegrate(cos(x)**(m - 2)*sin(x)**(n + 2), x)) else: if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res = integrate((Rational(1, 2)*sin(2*x))**m, x) elif (m == -n): if n < 0: # Same as the scheme described above. # the function argument to integrate in the end will # be 1 , this cannot be integrated by trigintegrate. # Hence use sympy.integrals.integrate. res = (Rational(1, n + 1) * cos(x)**(m - 1) * sin(x)**(n + 1) + Rational(m - 1, n + 1) * integrate(cos(x)**(m - 2) * sin(x)**(n + 2), x)) else: res = (Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**(n - 1) + Rational(n - 1, m + 1) * integrate(cos(x)**(m + 2)*sin(x)**(n - 2), x)) if conds == 'piecewise': return Piecewise((zz, Eq(a, 0)), (res.subs(x, a*x) / a, True)) return res.subs(x, a*x) / a
def trigintegrate(f, x): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos >>> from sympy.integrals.trigonometry import trigintegrate >>> x = Symbol('x') >>> trigintegrate(sin(x)*cos(x), x) 1/2*sin(x)**2 >>> trigintegrate(sin(x)**2, x) x/2 - cos(x)*sin(x)/2 http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques """ pat, a, n, m = _pat_sincos(x) M = f.match(pat) if M is None: return n, m = M[n], M[m] # should always be there if n is S.Zero and m is S.Zero: return x a = M[a] if n.is_integer and n.is_integer: if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1 - u**2)**((n - 1) / 2) * u**m uu = cos(a * x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1 - u**2)**((m - 1) / 2) uu = sin(a * x) fi = sympy.integrals.integrate(ff, u) # XXX cyclic deps fx = fi.subs(u, uu) return fx / a # n & m are even else: # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (n > m) # NB: careful here, one of the m_ = not (n > m) # conditions *must* be true res = S.Zero if n_: # 2k 2 k i 2i # C = (1-S ) = sum(i, (-) * B(k,i) * S ) for i in range(0, m / 2 + 1): res += (-1)**i * binomial(m / 2, i) * Sin_2k_integrate( n / 2 + i, x) elif m_: # 2k 2 k i 2i # S = (1 -C ) = sum(i, (-) * B(k,i) * C ) for i in range(0, n / 2 + 1): res += (-1)**i * binomial(n / 2, i) * Cos_2k_integrate( m / 2 + i, x) return res.subs(x, a * x) / a
def trigintegrate(f, x): """Integrate f = Mul(trig) over x >>> from sympy import Symbol, sin, cos >>> from sympy.integrals.trigonometry import trigintegrate >>> x = Symbol('x') >>> trigintegrate(sin(x)*cos(x), x) sin(x)**2/2 >>> trigintegrate(sin(x)**2, x) x/2 - cos(x)*sin(x)/2 http://en.wikibooks.org/wiki/Calculus/Further_integration_techniques """ pat, a, n, m = _pat_sincos(x) ##m - cos ##n - sin M = f.match(pat) if M is None: return n, m = M[n], M[m] # should always be there if n is S.Zero and m is S.Zero: return x a = M[a] if n.is_integer and m.is_integer: if n.is_odd or m.is_odd: u = _u n_, m_ = n.is_odd, m.is_odd # take smallest n or m -- to choose simplest substitution if n_ and m_: n_ = n_ and (n < m) # NB: careful here, one of the m_ = m_ and not (n < m) # conditions *must* be true # n m u=C (n-1)/2 m # S(x) * C(x) dx --> -(1-u^2) * u du if n_: ff = -(1 - u**2)**((n - 1) / 2) * u**m uu = cos(a * x) # n m u=S n (m-1)/2 # S(x) * C(x) dx --> u * (1-u^2) du elif m_: ff = u**n * (1 - u**2)**((m - 1) / 2) uu = sin(a * x) fi = sympy.integrals.integrate(ff, u) # XXX cyclic deps fx = fi.subs(u, uu) return fx / a # n & m are even else: # 2k 2m 2l 2l # we transform S (x) * C (x) into terms with only S (x) or C (x) # # example: # 100 4 100 2 2 100 4 2 # S (x) * C (x) = S (x) * (1-S (x)) = S (x) * (1 + S (x) - 2*S (x)) # # 104 102 100 # = S (x) - 2*S (x) + S (x) # 2k # then S is integrated with recursive formula # take largest n or m -- to choose simplest substitution n_ = (abs(n) > abs(m)) m_ = (abs(m) > abs(n)) res = S.Zero if n_: # 2k 2 k i 2i # C = (1-S ) = sum(i, (-) * B(k,i) * S ) if m > 0: for i in range(0, m / 2 + 1): res += (-1)**i * binomial( m / 2, i) * sin_pow_integrate(n + 2 * i, x) elif m == 0: res = sin_pow_integrate(n, x) else: # m < 0 , |n| > |m| # / / # | | # | m n -1 m+1 n-1 n - 1 | m+2 n-2 # | cos (x) sin (x) dx = ________ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | m + 1 m + 1 | #/ / # # res = Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**( n - 1) + Rational(n - 1, m + 1) * trigintegrate( cos(x)**(m + 2) * sin(x)**(n - 2), x) elif m_: # 2k 2 k i 2i # S = (1 -C ) = sum(i, (-) * B(k,i) * C ) if n > 0: # / / # | | # | m n | -m n # | cos (x)*sin (x) dx or | cos (x) * sin (x) dx # | | # / / # # |m| > |n| ; m,n >0 ; m,n belong to Z - {0} # n 2 # sin (x) term is expanded here interms of cos (x), and then integrated. for i in range(0, n / 2 + 1): res += (-1)**i * binomial( n / 2, i) * cos_pow_integrate(m + 2 * i, x) elif n == 0: ## / ## | # | 1 # | _ _ _ # | m # | cos (x) # / res = cos_pow_integrate(m, x) else: # n < 0 , |m| > |n| # / / # | | # | m n 1 m-1 n+1 m - 1 | m-2 n+2 # | cos (x) sin (x) dx = _______ cos (x) sin (x) + _______ | cos (x) sin (x) dx # | | # | n + 1 n + 1 | #/ / # # res = Rational(1, (n + 1)) * cos(x)**(m - 1) * sin(x)**( n + 1) + Rational(m - 1, n + 1) * trigintegrate( cos(x)**(m - 2) * sin(x)**(n + 2), x) else: if m == n: ##Substitute sin(2x)/2 for sin(x)cos(x) and then Integrate. res = sympy.integrals.integrate( (Rational(1, 2) * sin(2 * x))**m, x) elif (m == -n): if n < 0: ##Same as the scheme described above. res = Rational(1, (n + 1)) * cos(x)**(m - 1) * sin(x)**( n + 1 ) + Rational(m - 1, n + 1) * sympy.integrals.integrate( cos(x) **(m - 2) * sin(x)** (n + 2), x ) ##the function argument to integrate in the end will be 1 , this cannot be integrated by trigintegrate. Hence use sympy.integrals.integrate. else: res = Rational(-1, m + 1) * cos(x)**(m + 1) * sin(x)**( n - 1) + Rational( n - 1, m + 1) * sympy.integrals.integrate( cos(x)**(m + 2) * sin(x)**(n - 2), x) return res.subs(x, a * x) / a