def _get_general_solution(self, *, simplify: bool = True): x = self.ode_problem.sym (C1,) = self.ode_problem.get_numbered_constants(num=1) gensol = Eq(self.ly, (((C1 + Integral((self.cx/self.ax)*exp(Integral(self.bx/self.ax, x)),x)) * exp(-Integral(self.bx/self.ax, x))))) return [gensol]
def test_Integral(): assert mcode(Integral(sin(sin(x)), x)) == "Hold[Integrate[Sin[Sin[x]], x]]" assert mcode(Integral(exp(-x**2 - y**2), (x, -oo, oo), (y, -oo, oo))) == \ "Hold[Integrate[Exp[-x^2 - y^2], {x, -Infinity, Infinity}, " \ "{y, -Infinity, Infinity}]]"
def _get_general_solution(self, *, simplify: bool = True): P, Q = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym (C1,) = self.ode_problem.get_numbered_constants(num=1) gensol = Eq(fx, (((C1 + Integral(Q*exp(Integral(P, x)),x)) * exp(-Integral(P, x))))) return [gensol]
def _get_general_solution(self, *, simplify: bool = True): d, e, k = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym C1, C2 = self.ode_problem.get_numbered_constants(num=2) int = Integral(exp(Integral(self.g, self.y)), (self.y, None, fx)) gen_sol = Eq(int + C1 * Integral(exp(-Integral(self.h, x)), x) + C2, 0) return [gen_sol]
def _get_general_solution(self, *, simplify: bool = True): fx = self.ode_problem.func x = self.ode_problem.sym (C1, ) = self.ode_problem.get_numbered_constants(num=1) int = Integral(self.m2['coeff'] * self.m2[self.y] / self.m1[self.y], (self.y, None, fx)) gen_sol = Eq( int, Integral(-self.m1['coeff'] * self.m1[x] / self.m2[x], x) + C1) return [gen_sol]
def _get_general_solution(self, *, simplify: bool = True): g = self.wilds_match()[0] fx = self.ode_problem.func x = self.ode_problem.sym u = Dummy('u') g = g.subs(fx, u) C1, C2 = self.ode_problem.get_numbered_constants(num=2) inside = -2 * Integral(g, u) + C1 lhs = Integral(1 / sqrt(inside), (u, fx)) return [Eq(lhs, C2 + x), Eq(lhs, C2 - x)]
def _get_general_solution(self, *, simplify: bool = True): P, Q, n = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym (C1, ) = self.ode_problem.get_numbered_constants(num=1) if n == 1: gensol = Eq(log(fx), ((C1 + Integral((-P + Q), x)))) else: gensol = Eq(fx**(1 - n), ((C1 - (n - 1) * Integral( Q * exp(-n * Integral(P, x)) * exp(Integral(P, x)), x)) * exp(-(1 - n) * Integral(P, x)))) return [gensol]
def _get_general_solution(self, *, simplify: bool = True): m, n = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym (C1,) = self.ode_problem.get_numbered_constants(num=1) y = Dummy('y') m = m.subs(fx, y) n = n.subs(fx, y) gen_sol = Eq(Subs(Integral(m, x) + Integral(n - Integral(m, x).diff(y), y), y, fx), C1) return gen_sol
def _verify(self, fx) -> bool: P, Q = self.wilds() x = self.ode_problem.sym y = Dummy('y') m, n = self.wilds_match() try: if simplify(m) != 0: m = m.subs(fx,y) n = n.subs(fx,y) numerator= simplify(m.diff(y)-n.diff(x)) # The following few conditions try to convert a non-exact # differential equation into an exact one. # References : #1. Differential equations with applications # and historical notes - George E. Simmons #2. https://math.okstate.edu/people/binegar/2233-S99/2233-l12.pdf if numerator: # If (dP/dy - dQ/dx) / Q = f(x) # then exp(integral(f(x))*equation becomes exact factor = simplify(numerator/n) variables = factor.free_symbols if len(variables) == 1 and x == variables.pop(): factor = exp(Integral(factor).doit()) m *= factor n *= factor self._wilds_match[P] = m.subs(y, fx) self._wilds_match[Q] = n.subs(y, fx) return True else: # If (dP/dy - dQ/dx) / -P = f(y) # then exp(integral(f(y))*equation becomes exact factor = simplify(-numerator / m) variables = factor.free_symbols if len(variables) == 1 and y == variables.pop(): factor = exp(Integral(factor).doit()) m *= factor n *= factor self._wilds_match[P] = m.subs(y, fx) self._wilds_match[Q] = n.subs(y, fx) return True else: return True except NotImplementedError: # Differentiating the coefficients might fail because of things # like f(2*x).diff(x). See issue 4624 and issue 4719. pass return False
def __init__(self): if Parser.__instance is not None: raise Exception("Invalid initialistion of Parser.") Parser.__instance = self self.__transformations = standard_transformations \ + (function_exponentiation, convert_xor, convert_equals_signs) self.__global_dict = {} exec_('from sympy.core import *', self.__global_dict) exec_('from sympy.functions import *', self.__global_dict) exec_('from sympy.integrals import *', self.__global_dict) exclusions = ['sympify', 'SympifyError', 'Subs', 'evalf', 'evaluate'] for e in exclusions: self.__global_dict.pop(e) e, pi = sy.symbols('e pi') def func_check(name): return lambda e : isinstance(e, sy.Function) \ and getattr(e, 'name', None) == name self.__default_subs = [(e, np.exp(1)), (pi, np.pi)] self.__default_repl = [ (func_check('der'), lambda e: Derivative(*e.args)), (func_check('int'), lambda e: Integral(*e.args)) ] self.__default_trans = [(lambda x: isinstance(x, (Derivative, Integral)), lambda e: e.doit())] self.__invalid_atoms = (Derivative, Integral)
def _solve_variation_of_parameters(eq, func, roots, homogen_sol, order, match_obj, simplify_flag=True): r""" Helper function for the method of variation of parameters and nonhomogeneous euler eq. See the :py:meth:`~sympy.solvers.ode.single.NthLinearConstantCoeffVariationOfParameters` docstring for more information on this method. The parameter are ``match_obj`` should be a dictionary that has the following keys: ``list`` A list of solutions to the homogeneous equation. ``sol`` The general solution. """ f = func.func x = func.args[0] r = match_obj psol = 0 wr = wronskian(roots, x) if simplify_flag: wr = simplify(wr) # We need much better simplification for # some ODEs. See issue 4662, for example. # To reduce commonly occurring sin(x)**2 + cos(x)**2 to 1 wr = trigsimp(wr, deep=True, recursive=True) if not wr: # The wronskian will be 0 iff the solutions are not linearly # independent. raise NotImplementedError( "Cannot find " + str(order) + " solutions to the homogeneous equation necessary to apply " + "variation of parameters to " + str(eq) + " (Wronskian == 0)") if len(roots) != order: raise NotImplementedError( "Cannot find " + str(order) + " solutions to the homogeneous equation necessary to apply " + "variation of parameters to " + str(eq) + " (number of terms != order)") negoneterm = (-1)**(order) for i in roots: psol += negoneterm * Integral( wronskian([sol for sol in roots if sol != i], x) * r[-1] / wr, x) * i / r[order] negoneterm *= -1 if simplify_flag: psol = simplify(psol) psol = trigsimp(psol, deep=True) return Eq(f(x), homogen_sol.rhs + psol)
def get_sol_2F1_hypergeometric(eq, func, match_object): x = func.args[0] from sympy.simplify.hyperexpand import hyperexpand from sympy.polys.polytools import factor C0, C1 = get_numbered_constants(eq, num=2) a = match_object['a'] b = match_object['b'] c = match_object['c'] A = match_object['A'] sol = None if c.is_integer == False: sol = C0 * hyper([a, b], [c], x) + C1 * hyper([a - c + 1, b - c + 1], [2 - c], x) * x**(1 - c) elif c == 1: y2 = Integral( exp(Integral((-(a + b + 1) * x + c) / (x**2 - x), x)) / (hyperexpand(hyper([a, b], [c], x))**2), x) * hyper([a, b], [c], x) sol = C0 * hyper([a, b], [c], x) + C1 * y2 elif (c - a - b).is_integer == False: sol = C0 * hyper([a, b], [1 + a + b - c], 1 - x) + C1 * hyper( [c - a, c - b], [1 + c - a - b], 1 - x) * (1 - x)**(c - a - b) if sol: # applying transformation in the solution subs = match_object['mobius'] dtdx = simplify(1 / (subs.diff(x))) _B = ((a + b + 1) * x - c).subs(x, subs) * dtdx _B = factor(_B + ((x**2 - x).subs(x, subs)) * (dtdx.diff(x) * dtdx)) _A = factor((x**2 - x).subs(x, subs) * (dtdx**2)) e = exp(logcombine(Integral(cancel(_B / (2 * _A)), x), force=True)) sol = sol.subs(x, match_object['mobius']) sol = sol.subs(x, x**match_object['k']) e = e.subs(x, x**match_object['k']) if not A.is_zero: e1 = Integral(A / 2, x) e1 = exp(logcombine(e1, force=True)) sol = cancel((e / e1) * x**((-match_object['k'] + 1) / 2)) * sol sol = Eq(func, sol) return sol sol = cancel((e) * x**((-match_object['k'] + 1) / 2)) * sol sol = Eq(func, sol) return sol
def _sympy_(self, f, x, a, b): """ Convert this integral to the equivalent SymPy object The resulting SymPy integral can be evaluated using ``doit()``. EXAMPLES:: sage: integral(x, x, 0, 1, hold=True)._sympy_() Integral(x, (x, 0, 1)) sage: _.doit() 1/2 """ from sympy.integrals import Integral return Integral(f, (x, a, b))
def _verify(self, fx) -> bool: P, Q = self.wilds() x = self.ode_problem.sym y = Dummy('y') m, n = self.wilds_match() m = m.subs(fx, y) n = n.subs(fx, y) numerator = cancel(m.diff(y) - n.diff(x)) if numerator.is_zero: # Is exact return True else: # The following few conditions try to convert a non-exact # differential equation into an exact one. # References: # 1. Differential equations with applications # and historical notes - George E. Simmons # 2. https://math.okstate.edu/people/binegar/2233-S99/2233-l12.pdf factor_n = cancel(numerator / n) factor_m = cancel(-numerator / m) if y not in factor_n.free_symbols: # If (dP/dy - dQ/dx) / Q = f(x) # then exp(integral(f(x))*equation becomes exact factor = factor_n integration_variable = x elif x not in factor_m.free_symbols: # If (dP/dy - dQ/dx) / -P = f(y) # then exp(integral(f(y))*equation becomes exact factor = factor_m integration_variable = y else: # Couldn't convert to exact return False factor = exp(Integral(factor, integration_variable)) m *= factor n *= factor self._wilds_match[P] = m.subs(y, fx) self._wilds_match[Q] = n.subs(y, fx) return True
def _get_general_solution(self, *, simplify: bool = True): P, Q = self.wilds_match() fx = self.ode_problem.func x = self.ode_problem.sym (C1, ) = self.ode_problem.get_numbered_constants(num=1) if self.fxx is None or self.gx is None or self.kx is None: gensol = Eq(fx, (((C1 + Integral(Q * exp(Integral(P, x)), x)) * exp(-Integral(P, x))))) else: gensol = Eq(self.substituting, (((C1 + Integral( (self.gx / self.fxx) * exp(Integral(self.kx / self.fxx, x)), x)) * exp(-Integral(self.kx / self.fxx, x))))) return [gensol]
return components[:self.dim] class VectorMagnitude(Basic): def __init__(self, arg): self._args = Tuple(arg) def decompose(self): comps = self.args[0].components() return sqrt(sum([x*x for x in comps])) if __name__ == '__main__': from sympy import Function, exp from sympy.functions import Abs from sympy.integrals import Integral v1 = Vector('v1',dim=2) v2 = Vector('v2',dim=2) i = Symbol('i',integer=True) a = Symbol('a') print v1,type(v1) #e = 2*Integral(Abs(v1-v2),(v1,0.2)) V = Function('V') #V2 = V(i) e = Integral(exp(-a*V(v1)),v1) print e,e.subs(V(v1),V(Abs(v1)))
from sympy import * from sympy import sin, sqrt from sympy.abc import x, n from sympy.integrals import Integral x = Symbol('x') # example 1: finding the indefinite integral for function: x**2+8 = x**4 + 7*x**(3 + 8) # reminder: Indefinite integral is an integral with no lower or upper limit specified. integralex = Integral((x**2) + 8, x) print(integralex.doit()) # x**3/3 + 8*x # example 2: integrating the same function above (x**2+8), but we will perform a definite integral with # respect to a lower limit of 2 and an upper limit of 4. x = Symbol('x') integralex = Integral( (x**2) + 8, (x, 2, 4) ) # the second argument reads as: wrt x variable, with lower limit 2, and upper limit 4 print(integralex.doit())
def inverse(self): # don't use integrate here because fx has been replaced by _t # in the equation; integrals will not be correct while solve # is at work. return lambda expr: Integral(expr, var) + Dummy('C')
def _as_integral(self, f, t, s): from sympy import Integral, exp return Integral(f * exp(-s * t), (t, 0, oo))
def _as_integral(self, F, s, x): from sympy import Integral, I, oo c = self.__class__._c return Integral(F * x**(-s), (s, c - I * oo, c + I * oo))
def _as_integral(self, f, x, s): from sympy import Integral return Integral(f * x**(s - 1), (x, 0, oo))
def _as_integral(self, f, x, k): from sympy import Integral, exp, I a = self.__class__._a b = self.__class__._b return Integral(a * f * exp(b * I * x * k), (x, -oo, oo))
def _as_integral(self, F, s, t): from sympy import I, Integral, exp c = self.__class__._c return Integral(exp(s * t) * F, (s, c - I * oo, c + I * oo))
def euler_maclaurin(self, m=0, n=0, eps=0, eval_integral=True): """ Return an Euler-Maclaurin approximation of self, where m is the number of leading terms to sum directly and n is the number of terms in the tail. With m = n = 0, this is simply the corresponding integral plus a first-order endpoint correction. Returns (s, e) where s is the Euler-Maclaurin approximation and e is the estimated error (taken to be the magnitude of the first omitted term in the tail): >>> from sympy.abc import k, a, b >>> from sympy import Sum >>> Sum(1/k, (k, 2, 5)).doit().evalf() 1.28333333333333 >>> s, e = Sum(1/k, (k, 2, 5)).euler_maclaurin() >>> s -log(2) + 7/20 + log(5) >>> from sympy import sstr >>> print(sstr((s.evalf(), e.evalf()), full_prec=True)) (1.26629073187415, 0.0175000000000000) The endpoints may be symbolic: >>> s, e = Sum(1/k, (k, a, b)).euler_maclaurin() >>> s -log(a) + log(b) + 1/(2*b) + 1/(2*a) >>> e Abs(1/(12*b**2) - 1/(12*a**2)) If the function is a polynomial of degree at most 2n+1, the Euler-Maclaurin formula becomes exact (and e = 0 is returned): >>> Sum(k, (k, 2, b)).euler_maclaurin() (b**2/2 + b/2 - 1, 0) >>> Sum(k, (k, 2, b)).doit() b**2/2 + b/2 - 1 With a nonzero eps specified, the summation is ended as soon as the remainder term is less than the epsilon. """ from sympy.functions import bernoulli, factorial from sympy.integrals import Integral m = int(m) n = int(n) f = self.function if len(self.limits) != 1: raise ValueError("More than 1 limit") i, a, b = self.limits[0] if (a > b) == True: if a - b == 1: return S.Zero, S.Zero a, b = b + 1, a - 1 f = -f s = S.Zero if m: if b.is_Integer and a.is_Integer: m = min(m, b - a + 1) if not eps or f.is_polynomial(i): for k in range(m): s += f.subs(i, a + k) else: term = f.subs(i, a) if term: test = abs(term.evalf(3)) < eps if test == True: return s, abs(term) elif not (test == False): # a symbolic Relational class, can't go further return term, S.Zero s += term for k in range(1, m): term = f.subs(i, a + k) if abs(term.evalf(3)) < eps and term != 0: return s, abs(term) s += term if b - a + 1 == m: return s, S.Zero a += m x = Dummy('x') I = Integral(f.subs(i, x), (x, a, b)) if eval_integral: I = I.doit() s += I def fpoint(expr): if b is S.Infinity: return expr.subs(i, a), 0 return expr.subs(i, a), expr.subs(i, b) fa, fb = fpoint(f) iterm = (fa + fb) / 2 g = f.diff(i) for k in range(1, n + 2): ga, gb = fpoint(g) term = bernoulli(2 * k) / factorial(2 * k) * (gb - ga) if (eps and term and abs(term.evalf(3)) < eps) or (k > n): break s += term g = g.diff(i, 2, simplify=False) return s + iterm, abs(term)
def approximate(func, from_val, to_val, degree): """ Approximate given continuous function over real numbers, using a polynomial of given degree, with inner product defined as <f, g> = INTEGRATE f(x) * g(x) dx from a to b. :param func: Function to approximate represented in a string, with variable as 'x'. :param from_val: a as a string. :param to_val: b as a string. :param degree: Highest degree of result polynomial, as an integer. :return: Approximated polynomial function in string format. """ print('------ Started Calculating Approximation ------') print() print('f(x) = {0}'.format(func)) print() start_time = time.time() orth_basis = orthonormal_basis(_get_float_value(from_val), _get_float_value(to_val), degree) print('Orthonormal basis:') for idx, ele in enumerate(orth_basis): print('e{0} = {1}'.format(idx + 1, ele)) print() x = sp.Symbol('x') res = 0 func_str = '({0})'.format(func) for idx, e_j in enumerate(orth_basis): start_time_e_j = time.time() if idx is 0: print('Calculating projection on span(e{0}) --- '.format(idx + 1), end='') else: print( 'Calculating projection on span(e1,...,e{0}) --- '.format(idx + 1), end='') e_j_str = '({0})'.format( e_j.standard_coeff_rep(show_mul_op=True, double_stars=True)) product_str = '{0} * {1}'.format(func_str, e_j_str) func_product = parse_expr(product_str) tmp = Integral(func_product, (x, from_val, to_val)).as_sum(100, method="midpoint").n() tmp *= parse_expr(e_j_str) res += tmp end_time_e_j = time.time() print('%.2fs' % (end_time_e_j - start_time_e_j)) # Print the current result tmp_res = str(res) tmp_res = tmp_res.replace('**', '^') tmp_res = tmp_res.replace('*', '') tmp_res = Polynomial(tmp_res) print() print(' f{0}(x) = {1}'.format(idx + 1, tmp_res)) print() end_time = time.time() print() print("Duration: %.2fs" % (end_time - start_time)) print() print('------ Finished Calculating Approximation ------') res = str(res) res = res.replace('**', '^') res = res.replace('*', '') res = Polynomial(res) return res
def euler_maclaurin(self, m=0, n=0, eps=0, eval_integral=True): """ Return an Euler-Maclaurin approximation of self, where m is the number of leading terms to sum directly and n is the number of terms in the tail. With m = n = 0, this is simply the corresponding integral plus a first-order endpoint correction. Returns (s, e) where s is the Euler-Maclaurin approximation and e is the estimated error (taken to be the magnitude of the first omitted term in the tail): >>> from sympy.abc import k, a, b >>> from sympy import Sum >>> Sum(1/k, (k, 2, 5)).doit().evalf() 1.28333333333333 >>> s, e = Sum(1/k, (k, 2, 5)).euler_maclaurin() >>> s -log(2) + 7/20 + log(5) >>> from sympy import sstr >>> print(sstr((s.evalf(), e.evalf()), full_prec=True)) (1.26629073187415, 0.0175000000000000) The endpoints may be symbolic: >>> s, e = Sum(1/k, (k, a, b)).euler_maclaurin() >>> s -log(a) + log(b) + 1/(2*b) + 1/(2*a) >>> e Abs(1/(12*b**2) - 1/(12*a**2)) If the function is a polynomial of degree at most 2n+1, the Euler-Maclaurin formula becomes exact (and e = 0 is returned): >>> Sum(k, (k, 2, b)).euler_maclaurin() (b**2/2 + b/2 - 1, 0) >>> Sum(k, (k, 2, b)).doit() b**2/2 + b/2 - 1 With a nonzero eps specified, the summation is ended as soon as the remainder term is less than the epsilon. """ from sympy.functions import bernoulli, factorial from sympy.integrals import Integral m = int(m) n = int(n) f = self.function if len(self.limits) != 1: raise ValueError("More than 1 limit") i, a, b = self.limits[0] if (a > b) == True: if a - b == 1: return S.Zero,S.Zero a, b = b + 1, a - 1 f = -f s = S.Zero if m: if b.is_Integer and a.is_Integer: m = min(m, b - a + 1) if not eps or f.is_polynomial(i): for k in range(m): s += f.subs(i, a + k) else: term = f.subs(i, a) if term: test = abs(term.evalf(3)) < eps if test == True: return s, abs(term) elif not (test == False): # a symbolic Relational class, can't go further return term, S.Zero s += term for k in range(1, m): term = f.subs(i, a + k) if abs(term.evalf(3)) < eps and term != 0: return s, abs(term) s += term if b - a + 1 == m: return s, S.Zero a += m x = Dummy('x') I = Integral(f.subs(i, x), (x, a, b)) if eval_integral: I = I.doit() s += I def fpoint(expr): if b is S.Infinity: return expr.subs(i, a), 0 return expr.subs(i, a), expr.subs(i, b) fa, fb = fpoint(f) iterm = (fa + fb)/2 g = f.diff(i) for k in range(1, n + 2): ga, gb = fpoint(g) term = bernoulli(2*k)/factorial(2*k)*(gb - ga) if (eps and term and abs(term.evalf(3)) < eps) or (k > n): break s += term g = g.diff(i, 2, simplify=False) return s + iterm, abs(term)