def solve_ODE_first_order(eq, f): """ solves many kinds of first order odes, different methods are used depending on the form of the given equation. Now the linear and Bernoulli cases are implemented. """ from sympy.integrals.integrals import integrate x = f.args[0] f = f.func #linear case: a(x)*f'(x)+b(x)*f(x)+c(x) = 0 a = Wild('a', exclude=[f(x)]) b = Wild('b', exclude=[f(x)]) c = Wild('c', exclude=[f(x)]) r = eq.match(a*diff(f(x),x) + b*f(x) + c) if r: t = C.exp(integrate(r[b]/r[a], x)) tt = integrate(t*(-r[c]/r[a]), x) return (tt + Symbol("C1"))/t #Bernoulli case: a(x)*f'(x)+b(x)*f(x)+c(x)*f(x)^n = 0 n = Wild('n', exclude=[f(x)]) r = eq.match(a*diff(f(x),x) + b*f(x) + c*f(x)**n) if r: t = C.exp((1-r[n])*integrate(r[b]/r[a],x)) tt = (r[n]-1)*integrate(t*r[c]/r[a],x) return ((tt + Symbol("C1"))/t)**(1/(1-r[n])) #other cases of first order odes will be implemented here raise NotImplementedError("solve_ODE_first_order: Cannot solve " + str(eq))
def test_JointPSpace_margial_distribution(): from sympy.stats.joint_rv_types import MultivariateT from sympy import polar_lift T = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert marginal_distribution(T, T[1])(x) == sqrt(2)*(x**2 + 2)/( 8*polar_lift(x**2/2 + 1)**(S(5)/2)) assert integrate(marginal_distribution(T, 1)(x), (x, -oo, oo)) == 1
def compute_moment_generating_function(self, expr, **kwargs): if not self.domain.set.is_Interval: raise NotImplementedError("Moment generating function of multivariate expressions not implemented") d = self.compute_density(expr, **kwargs) x, t = symbols('x, t', real=True, cls=Dummy) mgf = integrate(exp(t * x) * d(x), (x, -oo, oo), **kwargs) return Lambda(t, mgf)
def test_JointPSpace_marginal_distribution(): T = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert marginal_distribution(T, T[1])(x) == sqrt(2) * (x**2 + 2) / ( 8 * polar_lift(x**2 / 2 + 1)**Rational(5, 2)) assert integrate(marginal_distribution(T, 1)(x), (x, -oo, oo)) == 1 t = MultivariateT('T', [0, 0, 0], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], 3) assert comp(marginal_distribution(t, 0)(1).evalf(), 0.2, .01)
def test_JointPSpace_margial_distribution(): from sympy.stats.joint_rv_types import MultivariateT from sympy import polar_lift T = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert marginal_distribution( T, T[1])(x) == sqrt(2) * (x**2 + 2) / (8 * polar_lift(x**2 / 2 + 1)**(5 / 2)) assert integrate(marginal_distribution(T, 1)(x), (x, -oo, oo)) == 1
def compute_characteristic_function(self, expr, **kwargs): if not self.domain.set.is_Interval: raise NotImplementedError("Characteristic function of multivariate expressions not implemented") d = self.compute_density(expr, **kwargs) x, t = symbols('x, t', real=True, cls=Dummy) cf = integrate(exp(I*t*x)*d(x), (x, -oo, oo), **kwargs) return Lambda(t, cf)
def test_MultivariateTDist(): from sympy.stats.joint_rv_types import MultivariateT t1 = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert(density(t1))(1, 1) == 1/(8*pi) assert integrate(density(t1)(x, y), (x, -oo, oo), \ (y, -oo, oo)).evalf() == 1 raises(ValueError, lambda: MultivariateT('T', [1, 2], [[1, 1], [1, -1]], 1)) t2 = MultivariateT('t2', [1, 2], [[x, 0], [0, y]], 1) assert density(t2)(1, 2) == 1/(2*pi*sqrt(x*y))
def compute_moment_generating_function(self, **kwargs): """ Compute the moment generating function from the PDF. Returns a Lambda. """ x, t = symbols('x, t', real=True, cls=Dummy) pdf = self.pdf(x) mgf = integrate(exp(t * x) * pdf, (x, self.set)) return Lambda(t, mgf)
def compute_characteristic_function(self, **kwargs): """ Compute the characteristic function from the PDF. Returns a Lambda. """ x, t = symbols('x, t', real=True, cls=Dummy) pdf = self.pdf(x) cf = integrate(exp(I*t*x)*pdf, (x, self.set)) return Lambda(t, cf)
def test_MultivariateTDist(): t1 = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) assert(density(t1))(1, 1) == 1/(8*pi) assert t1.pspace.distribution.set == ProductSet(S.Reals, S.Reals) assert integrate(density(t1)(x, y), (x, -oo, oo), \ (y, -oo, oo)).evalf() == 1 raises(ValueError, lambda: MultivariateT('T', [1, 2], [[1, 1], [1, -1]], 1)) t2 = MultivariateT('t2', [1, 2], [[x, 0], [0, y]], 1) assert density(t2)(1, 2) == 1/(2*pi*sqrt(x*y))
def test_JointPSpace_marginal_distribution(): T = MultivariateT('T', [0, 0], [[1, 0], [0, 1]], 2) got = marginal_distribution(T, T[1])(x) ans = sqrt(2) * (x**2 / 2 + 1) / (4 * polar_lift(x**2 / 2 + 1)**(S(5) / 2)) assert got == ans, got assert integrate(marginal_distribution(T, 1)(x), (x, -oo, oo)) == 1 t = MultivariateT('T', [0, 0, 0], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], 3) assert comp(marginal_distribution(t, 0)(1).evalf(), 0.2, .01)
def test_trigsimp_issues(): a, x, y = symbols('a x y') # issue 4625 - factor_terms works, too assert trigsimp(sin(x)**3 + cos(x)**2 * sin(x)) == sin(x) # issue 5948 assert trigsimp(diff(integrate(cos(x)/sin(x)**3, x), x)) == \ cos(x)/sin(x)**3 assert trigsimp(diff(integrate(sin(x)/cos(x)**3, x), x)) == \ sin(x)/cos(x)**3 # check integer exponents e = sin(x)**y / cos(x)**y assert trigsimp(e) == e assert trigsimp(e.subs(y, 2)) == tan(x)**2 assert trigsimp(e.subs(x, 1)) == tan(1)**y # check for multiple patterns assert (cos(x)**2/sin(x)**2*cos(y)**2/sin(y)**2).trigsimp() == \ 1/tan(x)**2/tan(y)**2 assert trigsimp(cos(x)/sin(x)*cos(x+y)/sin(x+y)) == \ 1/(tan(x)*tan(x + y)) eq = cos(2) * (cos(3) + 1)**2 / (cos(3) - 1)**2 assert trigsimp(eq) == eq.factor() # factor makes denom (-1 + cos(3))**2 assert trigsimp(cos(2)*(cos(3) + 1)**2*(cos(3) - 1)**2) == \ cos(2)*sin(3)**4 # issue 6789; this generates an expression that formerly caused # trigsimp to hang assert cot(x).equals(tan(x)) is False # nan or the unchanged expression is ok, but not sin(1) z = cos(x)**2 + sin(x)**2 - 1 z1 = tan(x)**2 - 1 / cot(x)**2 n = (1 + z1 / z) assert trigsimp(sin(n)) != sin(1) eq = x * (n - 1) - x * n assert trigsimp(eq) is S.NaN assert trigsimp(eq, recursive=True) is S.NaN assert trigsimp(1).is_Integer assert trigsimp(-sin(x)**4 - 2 * sin(x)**2 * cos(x)**2 - cos(x)**4) == -1
def test_JointPSpace_marginal_distribution(): from sympy.stats.joint_rv_types import MultivariateT from sympy import polar_lift T = MultivariateT("T", [0, 0], [[1, 0], [0, 1]], 2) assert marginal_distribution(T, T[1])(x) == sqrt(2) * (x**2 + 2) / ( 8 * polar_lift(x**2 / 2 + 1)**Rational(5, 2)) assert integrate(marginal_distribution(T, 1)(x), (x, -oo, oo)) == 1 t = MultivariateT("T", [0, 0, 0], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], 3) assert comp(marginal_distribution(t, 0)(1).evalf(), 0.2, 0.01)
def test_Normal(): m = Normal('A', [1, 2], [[1, 0], [0, 1]]) assert density(m)(1, 2) == 1 / (2 * pi) raises (ValueError,\ lambda: Normal('M',[1, 2], [[0, 0], [0, 1]])) n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]])) assert density(m)(x, y) == density(p)(x, y) assert marginal_distribution(n, 0, 1)(1, 2) == 1 / (2 * pi) assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1 raises(ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]]))
def compute_quantile(self, **kwargs): """ Compute the Quantile from the PDF. Returns a Lambda. """ x, p = symbols('x, p', real=True, cls=Dummy) left_bound = self.set.start pdf = self.pdf(x) cdf = integrate(pdf, (x, left_bound, x), **kwargs) quantile = solveset(cdf - p, x, self.set) return Lambda(p, Piecewise((quantile, (p >= 0) & (p <= 1) ), (nan, True)))
def expectation(self, expr, var, evaluate=True, **kwargs): """ Expectation of expression over distribution """ if evaluate: try: p = poly(expr, var) if p.is_zero: return S.Zero t = Dummy('t', real=True) mgf = self._moment_generating_function(t) if mgf is None: return integrate(expr * self.pdf(var), (var, self.set), **kwargs) deg = p.degree() taylor = poly(series(mgf, t, 0, deg + 1).removeO(), t) result = 0 for k in range(deg+1): result += p.coeff_monomial(var ** k) * taylor.coeff_monomial(t ** k) * factorial(k) return result except PolynomialError: return integrate(expr * self.pdf(var), (var, self.set), **kwargs) else: return Integral(expr * self.pdf(var), (var, self.set), **kwargs)
def test_messy(): from sympy.functions.elementary.complexes import re from sympy.functions.elementary.hyperbolic import (acosh, acoth) from sympy.functions.elementary.piecewise import Piecewise from sympy.functions.elementary.trigonometric import (asin, atan) from sympy.functions.special.bessel import besselj from sympy.functions.special.error_functions import (Chi, E1, Shi, Si) from sympy.integrals.transforms import (fourier_transform, laplace_transform) assert laplace_transform(Si(x), x, s) == ((-atan(s) + pi / 2) / s, 0, True) assert laplace_transform(Shi(x), x, s) == (acoth(s) / s, -oo, s**2 > 1) # where should the logs be simplified? assert laplace_transform(Chi(x), x, s) == ((log(s**(-2)) - log(1 - 1 / s**2)) / (2 * s), -oo, s**2 > 1) # TODO maybe simplify the inequalities? when the simplification # allows for generators instead of symbols this will work assert laplace_transform(besselj(a, x), x, s)[1:] == \ (0, (re(a) > -2) & (re(a) > -1)) # NOTE s < 0 can be done, but argument reduction is not good enough yet ans = fourier_transform(besselj(1, x) / x, x, s, noconds=False) assert tuple([ans[0].factor(deep=True).expand(), ans[1]]) == \ (Piecewise((0, (s > 1/(2*pi)) | (s < -1/(2*pi))), (2*sqrt(-4*pi**2*s**2 + 1), True)), s > 0) # TODO FT(besselj(0,x)) - conditions are messy (but for acceptable reasons) # - folding could be better assert integrate(E1(x)*besselj(0, x), (x, 0, oo), meijerg=True) == \ log(1 + sqrt(2)) assert integrate(E1(x)*besselj(1, x), (x, 0, oo), meijerg=True) == \ log(S.Half + sqrt(2)/2) assert integrate(1/x/sqrt(1 - x**2), x, meijerg=True) == \ Piecewise((-acosh(1/x), abs(x**(-2)) > 1), (I*asin(1/x), True))
def test_Normal(): m = Normal('A', [1, 2], [[1, 0], [0, 1]]) assert density(m)(1, 2) == 1/(2*pi) raises (ValueError,\ lambda: Normal('M',[1, 2], [[0, 0], [0, 1]])) n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]])) assert density(m)(x, y) == density(p)(x, y) assert marginal_distribution(n, 0, 1)(1, 2) == 1/(2*pi) assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1 N1 = Normal('N1', [1, 2], [[x, 0], [0, y]]) assert str(density(N1)(0, 0)) == "exp(-(4*x + y)/(2*x*y))/(2*pi*sqrt(x*y))" raises (ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]]))
def test_Normal(): m = Normal('A', [1, 2], [[1, 0], [0, 1]]) assert density(m)(1, 2) == 1 / (2 * pi) raises (ValueError,\ lambda: Normal('M',[1, 2], [[0, 0], [0, 1]])) n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]])) assert density(m)(x, y) == density(p)(x, y) assert marginal_distribution(n, 0, 1)(1, 2) == 1 / (2 * pi) assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1 N1 = Normal('N1', [1, 2], [[x, 0], [0, y]]) assert str(density(N1)(0, 0)) == "exp(-(4*x + y)/(2*x*y))/(2*pi*sqrt(x*y))" raises(ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]]))
def compute_cdf(self, **kwargs): """ Compute the CDF from the PDF. Returns a Lambda. """ x, z = symbols('x, z', real=True, cls=Dummy) left_bound = self.set.start # CDF is integral of PDF from left bound to z pdf = self.pdf(x) cdf = integrate(pdf.doit(), (x, left_bound, z), **kwargs) # CDF Ensure that CDF left of left_bound is zero cdf = Piecewise((cdf, z >= left_bound), (0, True)) return Lambda(z, cdf)
def _is_commutative_anti_derivative(A, t): r""" Helper function for determining if the Matrix passed is commutative with its antiderivative Explanation =========== This function checks if the Matrix $A$ passed is commutative with its antiderivative with respect to the independent variable $t$. .. math:: B(t) = \int A(t) dt The function outputs two values, first one being the antiderivative $B(t)$, second one being a boolean value, if True, then the matrix $A(t)$ passed is commutative with $B(t)$, else the matrix passed isn't commutative with $B(t)$. Parameters ========== A : Matrix The matrix which has to be checked t : Symbol Independent variable Examples ======== >>> from sympy import symbols, Matrix >>> from sympy.solvers.ode.systems import _is_commutative_anti_derivative >>> t = symbols("t") >>> A = Matrix([[1, t], [-t, 1]]) >>> B, is_commuting = _is_commutative_anti_derivative(A, t) >>> is_commuting True Returns ======= Matrix, Boolean """ B = integrate(A, t) is_commuting = ( B * A - A * B).applyfunc(expand).applyfunc(factor_terms).is_zero_matrix is_commuting = False if is_commuting is None else is_commuting return B, is_commuting
def compute_cdf(self, expr, **kwargs): if not self.domain.set.is_Interval: raise ValueError( "CDF not well defined on multivariate expressions") d = self.compute_density(expr, **kwargs) x, z = symbols('x, z', real=True, cls=Dummy) left_bound = self.domain.set.start # CDF is integral of PDF from left bound to z cdf = integrate(d(x), (x, left_bound, z), **kwargs) # CDF Ensure that CDF left of left_bound is zero cdf = Piecewise((cdf, z >= left_bound), (0, True)) return Lambda(z, cdf)
def marginal_distribution(self, *indices): count = self.component_count all_syms = [Symbol(str(Indexed(self.symbol, i))) for i in range(count)] sym = [Symbol(str(Indexed(self.symbol, i))) for i in indices] limits = list([i,] for i in all_syms if i not in sym) for i in range(len(limits)): if i not in indices: limits[i].append(self.distribution.set.args[i]) limits[i] = tuple(limits[i]) limits = tuple(limits) if self.distribution.is_Continuous: return Lambda(sym, integrate(self.distribution(*all_syms), limits)) if self.distribution.is_Discrete: return Lambda(sym, summation(self.distribution(all_syms), limits))
def solve_ODE_first_order(eq, f): """ solves many kinds of first order odes, different methods are used depending on the form of the given equation. Now the linear and Bernoulli cases are implemented. """ from sympy.integrals.integrals import integrate C1 = Symbol("C1") x = f.args[0] f = f.func #linear case: a(x)*f'(x)+b(x)*f(x)+c(x) = 0 a = Wild('a', exclude=[f(x)]) b = Wild('b', exclude=[f(x)]) c = Wild('c', exclude=[f(x)]) r = eq.match(a * diff(f(x), x) + b * f(x) + c) if r: t = exp(integrate(r[b] / r[a], x)) tt = integrate(t * (-r[c] / r[a]), x) return (tt + C1) / t #Bernoulli case: a(x)*f'(x)+b(x)*f(x)+c(x)*f(x)^n = 0 n = Wild('n', exclude=[f(x)]) r = eq.match(a * diff(f(x), x) + b * f(x) + c * f(x)**n) if r: if r[n] == 1: return C1 * exp(integrate(-(r[b] + r[c]), x)) # r[n] != 1 ie, the real bernoulli case t = exp((1 - r[n]) * integrate(r[b] / r[a], x)) tt = (r[n] - 1) * integrate(t * r[c] / r[a], x) return ((tt + C1) / t)**(1 / (1 - r[n])) #other cases of first order odes will be implemented here raise NotImplementedError("solve_ODE_first_order: Cannot solve " + str(eq))
def solve_ODE_first_order(eq, f): """ solves many kinds of first order odes, different methods are used depending on the form of the given equation. Now the linear case is implemented. """ from sympy.integrals.integrals import integrate x = f.args[0] f = f.func #linear case: a(x)*f'(x)+b(x)*f(x)+c(x) = 0 a = Wild('a', exclude=[f(x)]) b = Wild('b', exclude=[f(x)]) c = Wild('c', exclude=[f(x)]) r = eq.match(a * diff(f(x), x) + b * f(x) + c) if r: t = C.exp(integrate(r[b] / r[a], x)) tt = integrate(t * (-r[c] / r[a]), x) return (tt + Symbol("C1")) / t #other cases of first order odes will be implemented here raise NotImplementedError("solve_ODE_first_order: Cannot solve " + str(eq))
def test_quaternion_functions(): q = Quaternion(w, x, y, z) q1 = Quaternion(1, 2, 3, 4) q0 = Quaternion(0, 0, 0, 0) assert conjugate(q) == Quaternion(w, -x, -y, -z) assert q.norm() == sqrt(w**2 + x**2 + y**2 + z**2) assert q.normalize() == Quaternion(w, x, y, z) / sqrt(w**2 + x**2 + y**2 + z**2) assert q.inverse() == Quaternion(w, -x, -y, -z) / (w**2 + x**2 + y**2 + z**2) assert q.inverse() == q.pow(-1) raises(ValueError, lambda: q0.inverse()) assert q.pow(2) == Quaternion(w**2 - x**2 - y**2 - z**2, 2*w*x, 2*w*y, 2*w*z) assert q**(2) == Quaternion(w**2 - x**2 - y**2 - z**2, 2*w*x, 2*w*y, 2*w*z) assert q1.pow(-2) == Quaternion(Rational(-7, 225), Rational(-1, 225), Rational(-1, 150), Rational(-2, 225)) assert q1**(-2) == Quaternion(Rational(-7, 225), Rational(-1, 225), Rational(-1, 150), Rational(-2, 225)) assert q1.pow(-0.5) == NotImplemented raises(TypeError, lambda: q1**(-0.5)) assert q1.exp() == \ Quaternion(E * cos(sqrt(29)), 2 * sqrt(29) * E * sin(sqrt(29)) / 29, 3 * sqrt(29) * E * sin(sqrt(29)) / 29, 4 * sqrt(29) * E * sin(sqrt(29)) / 29) assert q1._ln() == \ Quaternion(log(sqrt(30)), 2 * sqrt(29) * acos(sqrt(30)/30) / 29, 3 * sqrt(29) * acos(sqrt(30)/30) / 29, 4 * sqrt(29) * acos(sqrt(30)/30) / 29) assert q1.pow_cos_sin(2) == \ Quaternion(30 * cos(2 * acos(sqrt(30)/30)), 60 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29, 90 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29, 120 * sqrt(29) * sin(2 * acos(sqrt(30)/30)) / 29) assert diff(Quaternion(x, x, x, x), x) == Quaternion(1, 1, 1, 1) assert integrate(Quaternion(x, x, x, x), x) == \ Quaternion(x**2 / 2, x**2 / 2, x**2 / 2, x**2 / 2) assert Quaternion.rotate_point((1, 1, 1), q1) == (S.One / 5, 1, S(7) / 5) n = Symbol('n') raises(TypeError, lambda: q1**n) n = Symbol('n', integer=True) raises(TypeError, lambda: q1**n)
def marginal_distribution(self, *indices): count = self.component_count orig = [Indexed(self.symbol, i) for i in range(count)] all_syms = [Symbol(str(i)) for i in orig] replace_dict = dict(zip(all_syms, orig)) sym = [Symbol(str(Indexed(self.symbol, i))) for i in indices] limits = list([i,] for i in all_syms if i not in sym) index = 0 for i in range(count): if i not in indices: limits[index].append(self.distribution.set.args[i]) limits[index] = tuple(limits[index]) index += 1 if self.distribution.is_Continuous: f = Lambda(sym, integrate(self.distribution(*all_syms), *limits)) elif self.distribution.is_Discrete: f = Lambda(sym, summation(self.distribution(*all_syms), *limits)) return f.xreplace(replace_dict)
def marginal_distribution(self, *indices): count = self.component_count orig = [Indexed(self.symbol, i) for i in range(count)] all_syms = [Symbol(str(i)) for i in orig] replace_dict = dict(zip(all_syms, orig)) sym = [Symbol(str(Indexed(self.symbol, i))) for i in indices] limits = list([i,] for i in all_syms if i not in sym) index = 0 for i in range(count): if i not in indices: limits[index].append(self.distribution.set.args[i]) limits[index] = tuple(limits[index]) index += 1 limits = tuple(limits) if self.distribution.is_Continuous: f = Lambda(sym, integrate(self.distribution(*all_syms), limits)) elif self.distribution.is_Discrete: f = Lambda(sym, summation(self.distribution(all_syms), limits)) return f.xreplace(replace_dict)
def test_units(): assert convert_to((5 * m / s * day) / km, 1) == 432 assert convert_to(foot / meter, meter) == Rational(3048, 10000) # amu is a pure mass so mass/mass gives a number, not an amount (mol) # TODO: need better simplification routine: assert str(convert_to(grams / amu, grams).n(2)) == '6.0e+23' # Light from the sun needs about 8.3 minutes to reach earth t = (1 * au / speed_of_light) / minute # TODO: need a better way to simplify expressions containing units: t = convert_to(convert_to(t, meter / minute), meter) assert t.simplify() == Rational(49865956897, 5995849160) # TODO: fix this, it should give `m` without `Abs` assert sqrt(m**2) == m assert (sqrt(m))**2 == m t = Symbol('t') assert integrate(t * m / s, (t, 1 * s, 5 * s)) == 12 * m * s assert (t * m / s).integrate((t, 1 * s, 5 * s)) == 12 * m * s
def test_Normal(): m = Normal('A', [1, 2], [[1, 0], [0, 1]]) assert density(m)(1, 2) == 1/(2*pi) raises (ValueError, lambda:m[2]) raises (ValueError,\ lambda: Normal('M',[1, 2], [[0, 0], [0, 1]])) n = Normal('B', [1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) p = Normal('C', Matrix([1, 2]), Matrix([[1, 0], [0, 1]])) assert density(m)(x, y) == density(p)(x, y) assert marginal_distribution(n, 0, 1)(1, 2) == 1/(2*pi) assert integrate(density(m)(x, y), (x, -oo, oo), (y, -oo, oo)).evalf() == 1 N = Normal('N', [1, 2], [[x, 0], [0, y]]) assert density(N)(0, 0) == exp(-2/y - 1/(2*x))/(2*pi*sqrt(x*y)) raises (ValueError, lambda: Normal('M', [1, 2], [[1, 1], [1, -1]])) # symbolic n = symbols('n', natural=True) mu = MatrixSymbol('mu', n, 1) sigma = MatrixSymbol('sigma', n, n) X = Normal('X', mu, sigma) assert density(X) == MultivariateNormalDistribution(mu, sigma)
def marginal_distribution(self, *indices): count = self.component_count if count.atoms(Symbol): raise ValueError("Marginal distributions cannot be computed " "for symbolic dimensions. It is a work under progress.") orig = [Indexed(self.symbol, i) for i in range(count)] all_syms = [Symbol(str(i)) for i in orig] replace_dict = dict(zip(all_syms, orig)) sym = tuple(Symbol(str(Indexed(self.symbol, i))) for i in indices) limits = list([i,] for i in all_syms if i not in sym) index = 0 for i in range(count): if i not in indices: limits[index].append(self.distribution.set.args[i]) limits[index] = tuple(limits[index]) index += 1 if self.distribution.is_Continuous: f = Lambda(sym, integrate(self.distribution(*all_syms), *limits)) elif self.distribution.is_Discrete: f = Lambda(sym, summation(self.distribution(*all_syms), *limits)) return f.xreplace(replace_dict)
def heurisch_wrapper(f, x, rewrite=False, hints=None, mappings=None, retries=3, degree_offset=0, unnecessary_permutations=None, _try_heurisch=None): """ A wrapper around the heurisch integration algorithm. Explanation =========== This method takes the result from heurisch and checks for poles in the denominator. For each of these poles, the integral is reevaluated, and the final integration result is given in terms of a Piecewise. Examples ======== >>> from sympy import cos, symbols >>> from sympy.integrals.heurisch import heurisch, heurisch_wrapper >>> n, x = symbols('n x') >>> heurisch(cos(n*x), x) sin(n*x)/n >>> heurisch_wrapper(cos(n*x), x) Piecewise((sin(n*x)/n, Ne(n, 0)), (x, True)) See Also ======== heurisch """ from sympy.solvers.solvers import solve, denoms f = sympify(f) if not f.has_free(x): return f*x res = heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch) if not isinstance(res, Basic): return res # We consider each denominator in the expression, and try to find # cases where one or more symbolic denominator might be zero. The # conditions for these cases are stored in the list slns. slns = [] for d in denoms(res): try: slns += solve(d, dict=True, exclude=(x,)) except NotImplementedError: pass if not slns: return res slns = list(uniq(slns)) # Remove the solutions corresponding to poles in the original expression. slns0 = [] for d in denoms(f): try: slns0 += solve(d, dict=True, exclude=(x,)) except NotImplementedError: pass slns = [s for s in slns if s not in slns0] if not slns: return res if len(slns) > 1: eqs = [] for sub_dict in slns: eqs.extend([Eq(key, value) for key, value in sub_dict.items()]) slns = solve(eqs, dict=True, exclude=(x,)) + slns # For each case listed in the list slns, we reevaluate the integral. pairs = [] for sub_dict in slns: expr = heurisch(f.subs(sub_dict), x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch) cond = And(*[Eq(key, value) for key, value in sub_dict.items()]) generic = Or(*[Ne(key, value) for key, value in sub_dict.items()]) if expr is None: expr = integrate(f.subs(sub_dict),x) pairs.append((expr, cond)) # If there is one condition, put the generic case first. Otherwise, # doing so may lead to longer Piecewise formulas if len(pairs) == 1: pairs = [(heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch), generic), (pairs[0][0], True)] else: pairs.append((heurisch(f, x, rewrite, hints, mappings, retries, degree_offset, unnecessary_permutations, _try_heurisch), True)) return Piecewise(*pairs)
def test_indefinite_1_bug(): assert integrate( (b + t)**(-a), t, meijerg=True) == -b / (b**a * (1 + t / b)**a * (a - 1)) - t / (b**a * (1 + t / b)**a * (a - 1))
def test_issue_13536(): from sympy.core.symbol import Symbol a = Symbol('a', positive=True) assert integrate(1 / x**2, (x, oo, a)) == -1 / a
def solve_ODE_first_order(a, b, f, x): """ a*f'(x)+b = 0 """ from sympy.integrals.integrals import integrate return integrate(-b/a, x) + Symbol("C1")
def pde_1st_linear_variable_coeff(eq, func, order, match, solvefun): r""" Solves a first order linear partial differential equation with variable coefficients. The general form of this partial differential equation is .. math:: a(x, y) \frac{df(x, y)}{dx} + a(x, y) \frac{df(x, y)}{dy} + c(x, y) f(x, y) - G(x, y) where `a(x, y)`, `b(x, y)`, `c(x, y)` and `G(x, y)` are arbitrary functions in `x` and `y`. This PDE is converted into an ODE by making the following transformation. 1] `\xi` as `x` 2] `\eta` as the constant in the solution to the differential equation `\frac{dy}{dx} = -\frac{b}{a}` Making the following substitutions reduces it to the linear ODE .. math:: a(\xi, \eta)\frac{du}{d\xi} + c(\xi, \eta)u - d(\xi, \eta) = 0 which can be solved using dsolve. The general form of this PDE is:: >>> from sympy.solvers.pde import pdsolve >>> from sympy.abc import x, y >>> from sympy import Function, pprint >>> a, b, c, G, f= [Function(i) for i in ['a', 'b', 'c', 'G', 'f']] >>> u = f(x,y) >>> ux = u.diff(x) >>> uy = u.diff(y) >>> genform = a(x, y)*u + b(x, y)*ux + c(x, y)*uy - G(x,y) >>> pprint(genform) d d -G(x, y) + a(x, y)*f(x, y) + b(x, y)*--(f(x, y)) + c(x, y)*--(f(x, y)) dx dy Examples ======== >>> from sympy.solvers.pde import pdsolve >>> from sympy import Function, diff, pprint, exp >>> from sympy.abc import x,y >>> f = Function('f') >>> eq = x*(u.diff(x)) - y*(u.diff(y)) + y**2*u - y**2 >>> pdsolve(eq) f(x, y) == F(x*y)*exp(y**2/2) + 1 References ========== - Viktor Grigoryan, "Partial Differential Equations" Math 124A - Fall 2010, pp.7 """ from sympy.integrals.integrals import integrate from sympy.solvers.ode import dsolve xi, eta = symbols("xi eta") f = func.func x = func.args[0] y = func.args[1] b = match[match['b']] c = match[match['c']] d = match[match['d']] e = -match[match['e']] if not d: # To deal with cases like b*ux = e or c*uy = e if not (b and c): if c: try: tsol = integrate(e/c, y) except NotImplementedError: raise NotImplementedError("Unable to find a solution" " due to inability of integrate") else: return Eq(f(x,y), solvefun(x) + tsol) if b: try: tsol = integrate(e/b, x) except NotImplementedError: raise NotImplementedError("Unable to find a solution" " due to inability of integrate") else: return Eq(f(x,y), solvefun(y) + tsol) if not c: # To deal with cases when c is 0, a simpler method is used. # The PDE reduces to b*(u.diff(x)) + d*u = e, which is a linear ODE in x plode = f(x).diff(x)*b + d*f(x) - e sol = dsolve(plode, f(x)) syms = sol.free_symbols - plode.free_symbols - set([x, y]) rhs = _simplify_variable_coeff(sol.rhs, syms, solvefun, y) return Eq(f(x, y), rhs) if not b: # To deal with cases when b is 0, a simpler method is used. # The PDE reduces to c*(u.diff(y)) + d*u = e, which is a linear ODE in y plode = f(y).diff(y)*c + d*f(y) - e sol = dsolve(plode, f(y)) syms = sol.free_symbols - plode.free_symbols - set([x, y]) rhs = _simplify_variable_coeff(sol.rhs, syms, solvefun, x) return Eq(f(x, y), rhs) dummy = Function('d') h = (c/b).subs(y, dummy(x)) sol = dsolve(dummy(x).diff(x) - h, dummy(x)) if isinstance(sol, list): sol = sol[0] solsym = sol.free_symbols - h.free_symbols - set([x, y]) if len(solsym) == 1: solsym = solsym.pop() etat = (solve(sol, solsym)[0]).subs(dummy(x), y) ysub = solve(eta - etat, y)[0] deq = (b*(f(x).diff(x)) + d*f(x) - e).subs(y, ysub) final = (dsolve(deq, f(x), hint='1st_linear')).rhs if isinstance(final, list): final = final[0] finsyms = final.free_symbols - deq.free_symbols - set([x, y]) rhs = _simplify_variable_coeff(final, finsyms, solvefun, etat) return Eq(f(x, y), rhs) else: raise NotImplementedError("Cannot solve the partial differential equation due" " to inability of constantsimp")
def test_issue_10680(): assert isinstance(integrate(x**log(x**log(x**log(x))),x), Integral)
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