def test_Relational(): assert mcode(Eq(x, y)) == "x == y" assert mcode(Ne(x, y)) == "x != y" assert mcode(Le(x, y)) == "x <= y" assert mcode(Lt(x, y)) == "x < y" assert mcode(Gt(x, y)) == "x > y" assert mcode(Ge(x, y)) == "x >= y"
def test_trigintegrate_odd(): assert trigintegrate(Rational(1), x) == x assert trigintegrate(x, x) is None assert trigintegrate(x**2, x) is None assert trigintegrate(sin(x), x) == -cos(x) assert trigintegrate(cos(x), x) == sin(x) assert trigintegrate(sin(3 * x), x) == -cos(3 * x) / 3 assert trigintegrate(cos(3 * x), x) == sin(3 * x) / 3 y = Symbol("y") assert trigintegrate(sin(y * x), x) == Piecewise( (-cos(y * x) / y, Ne(y, 0)), (0, True)) assert trigintegrate(cos(y * x), x) == Piecewise( (sin(y * x) / y, Ne(y, 0)), (x, True)) assert trigintegrate(sin(y * x)**2, x) == Piecewise( ((x * y / 2 - sin(x * y) * cos(x * y) / 2) / y, Ne(y, 0)), (0, True)) assert trigintegrate(sin(y * x) * cos(y * x), x) == Piecewise( (sin(x * y)**2 / (2 * y), Ne(y, 0)), (0, True)) assert trigintegrate(cos(y * x)**2, x) == Piecewise( ((x * y / 2 + sin(x * y) * cos(x * y) / 2) / y, Ne(y, 0)), (x, True)) y = Symbol("y", positive=True) # TODO: remove conds='none' below. For this to work we would have to rule # out (e.g. by trying solve) the condition y = 0, incompatible with # y.is_positive being True. assert trigintegrate(sin(y * x), x, conds="none") == -cos(y * x) / y assert trigintegrate(cos(y * x), x, conds="none") == sin(y * x) / y assert trigintegrate(sin(x) * cos(x), x) == sin(x)**2 / 2 assert trigintegrate(sin(x) * cos(x)**2, x) == -cos(x)**3 / 3 assert trigintegrate(sin(x)**2 * cos(x), x) == sin(x)**3 / 3 # check if it selects right function to substitute, # so the result is kept simple assert trigintegrate(sin(x)**7 * cos(x), x) == sin(x)**8 / 8 assert trigintegrate(sin(x) * cos(x)**7, x) == -cos(x)**8 / 8 assert (trigintegrate(sin(x)**7 * cos(x)**3, x) == -sin(x)**10 / 10 + sin(x)**8 / 8) assert (trigintegrate(sin(x)**3 * cos(x)**7, x) == cos(x)**10 / 10 - cos(x)**8 / 8) # both n, m are odd and -ve, and not necessarily equal assert trigintegrate(sin(x)**-1 * cos(x)**-1, x) == -log(sin(x)**2 - 1) / 2 + log(sin(x))
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