Beispiel #1
0
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))
Beispiel #2
0
def solve_ODE_second_order(eq, f):
    """
    solves many kinds of second order odes, different methods are used
    depending on the form of the given equation. Now the constanst
    coefficients case and a special case are implemented.
    """
    x = f.args[0]
    f = f.func

    #constant coefficients case: af''(x)+bf'(x)+cf(x)=0
    a = Wild('a', exclude=[x])
    b = Wild('b', exclude=[x])
    c = Wild('c', exclude=[x])

    r = eq.match(a * f(x).diff(x, x) + c * f(x))
    if r:
        return Symbol("C1") * C.sin(sqrt(
            r[c] / r[a]) * x) + Symbol("C2") * C.cos(sqrt(r[c] / r[a]) * x)

    r = eq.match(a * f(x).diff(x, x) + b * diff(f(x), x) + c * f(x))
    if r:
        r1 = solve(r[a] * x**2 + r[b] * x + r[c], x)
        if r1[0].is_real:
            if len(r1) == 1:
                return (Symbol("C1") + Symbol("C2") * x) * exp(r1[0] * x)
            else:
                return Symbol("C1") * exp(r1[0] * x) + Symbol("C2") * exp(
                    r1[1] * x)
        else:
            r2 = abs((r1[0] - r1[1]) / (2 * S.ImaginaryUnit))
            return (Symbol("C2") * C.cos(r2 * x) +
                    Symbol("C1") * C.sin(r2 * x)) * exp(
                        (r1[0] + r1[1]) * x / 2)

    #other cases of the second order odes will be implemented here

    #special equations, that we know how to solve
    t = x * C.exp(f(x))
    tt = a * t.diff(x, x) / t
    r = eq.match(tt.expand())
    if r:
        return -solve_ODE_1(f(x), x)

    t = x * C.exp(-f(x))
    tt = a * t.diff(x, x) / t
    r = eq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t)
        return solve_ODE_1(f(x), x)

    neq = eq * C.exp(f(x)) / C.exp(-f(x))
    r = neq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( t.diff(x,2)*r[a]/t ).expand() == eq
        return solve_ODE_1(f(x), x)

    raise NotImplementedError("solve_ODE_second_order: cannot solve " +
                              str(eq))
Beispiel #3
0
def solve_ODE_second_order(eq, f):
    """
    solves many kinds of second order odes, different methods are used
    depending on the form of the given equation. So far the constants
    coefficients case and a special case are implemented.
    """
    x = f.args[0]
    f = f.func

    #constant coefficients case: af''(x)+bf'(x)+cf(x)=0
    a = Wild('a', exclude=[x])
    b = Wild('b', exclude=[x])
    c = Wild('c', exclude=[x])

    r = eq.match(a*f(x).diff(x,x) + c*f(x))
    if r:
        return Symbol("C1")*C.sin(sqrt(r[c]/r[a])*x)+Symbol("C2")*C.cos(sqrt(r[c]/r[a])*x)

    r = eq.match(a*f(x).diff(x,x) + b*diff(f(x),x) + c*f(x))
    if r:
        r1 = solve(r[a]*x**2 + r[b]*x + r[c], x)
        if r1[0].is_real:
            if len(r1) == 1:
                return (Symbol("C1") + Symbol("C2")*x)*exp(r1[0]*x)
            else:
                return Symbol("C1")*exp(r1[0]*x) + Symbol("C2")*exp(r1[1]*x)
        else:
            r2 = abs((r1[0] - r1[1])/(2*S.ImaginaryUnit))
            return (Symbol("C2")*C.cos(r2*x) + Symbol("C1")*C.sin(r2*x))*exp((r1[0] + r1[1])*x/2)

    #other cases of the second order odes will be implemented here

    #special equations, that we know how to solve
    a = Wild('a')
    t = x*C.exp(f(x))
    tt = a*t.diff(x, x)/t
    r = eq.match(tt.expand())
    if r:
        return -solve_ODE_1(f(x), x)

    t = x*C.exp(-f(x))
    tt = a*t.diff(x, x)/t
    r = eq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( r[a]*t.diff(x,2)/t ) == eq.subs(f, t)
        return solve_ODE_1(f(x), x)

    neq = eq*C.exp(f(x))/C.exp(-f(x))
    r = neq.match(tt.expand())
    if r:
        #check, that we've rewritten the equation correctly:
        #assert ( t.diff(x,2)*r[a]/t ).expand() == eq
        return solve_ODE_1(f(x), x)

    raise NotImplementedError("solve_ODE_second_order: cannot solve " + str(eq))
    def eval(cls, n, m, theta, phi):
        n, m, theta, phi = [sympify(x) for x in (n, m, theta, phi)]

        # Handle negative index m and arguments theta, phi
        if m.could_extract_minus_sign():
            m = -m
            return S.NegativeOne**m * C.exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
        if theta.could_extract_minus_sign():
            theta = -theta
            return Ynm(n, m, theta, phi)
        if phi.could_extract_minus_sign():
            phi = -phi
            return C.exp(-2*I*m*phi) * Ynm(n, m, theta, phi)
Beispiel #5
0
 def _eval_expand_func(self, **hints):
     n, m, theta, phi = self.args
     rv = (sqrt(
         (2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m)) *
           C.exp(I * m * phi) * assoc_legendre(n, m, C.cos(theta)))
     # We can do this because of the range of theta
     return rv.subs(sqrt(-cos(theta)**2 + 1), sin(theta))
Beispiel #6
0
 def _eval_expand_func(self, **hints):
     n, m, theta, phi = self.args
     rv = (
         sqrt((2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m))
         * C.exp(I * m * phi)
         * assoc_legendre(n, m, C.cos(theta))
     )
     # We can do this because of the range of theta
     return rv.subs(sqrt(-cos(theta) ** 2 + 1), sin(theta))
 def fdiff(self, argindex=4):
     if argindex == 1:
         # Diff wrt n
         raise ArgumentIndexError(self, argindex)
     elif argindex == 2:
         # Diff wrt m
         raise ArgumentIndexError(self, argindex)
     elif argindex == 3:
         # Diff wrt theta
         n, m, theta, phi = self.args
         return (m * C.cot(theta) * Ynm(n, m, theta, phi) +
                 sqrt((n - m)*(n + m + 1)) * C.exp(-I*phi) * Ynm(n, m + 1, theta, phi))
     elif argindex == 4:
         # Diff wrt phi
         n, m, theta, phi = self.args
         return I * m * Ynm(n, m, theta, phi)
     else:
         raise ArgumentIndexError(self, argindex)
Beispiel #8
0
 def eval(cls, n, x):
     if not n.is_Number:
         # Symbolic result L_n(x)
         # L_{n}(-x)  --->  exp(-x) * L_{-n-1}(x)
         # L_{-n}(x)  --->  exp(x) * L_{n-1}(-x)
         if n.could_extract_minus_sign():
             return C.exp(x) * laguerre(n-1, -x)
         # We can evaluate for some special values of x
         if x == S.Zero:
             return S.One
         elif x == S.NegativeInfinity:
             return S.Infinity
         elif x == S.Infinity:
             return S.NegativeOne**n * S.Infinity
     else:
         # n is a given fixed integer, evaluate into polynomial
         if n.is_negative:
             raise ValueError("The index n must be nonnegative integer (got %r)" % n)
         else:
             return laguerre_poly(n, x, 0)
Beispiel #9
0
 def eval(cls, n, x):
     if not n.is_Number:
         # Symbolic result L_n(x)
         # L_{n}(-x)  --->  exp(-x) * L_{-n-1}(x)
         # L_{-n}(x)  --->  exp(x) * L_{n-1}(-x)
         if n.could_extract_minus_sign():
             return C.exp(x) * laguerre(n - 1, -x)
         # We can evaluate for some special values of x
         if x == S.Zero:
             return S.One
         elif x == S.NegativeInfinity:
             return S.Infinity
         elif x == S.Infinity:
             return S.NegativeOne**n * S.Infinity
     else:
         # n is a given fixed integer, evaluate into polynomial
         if n.is_negative:
             raise ValueError(
                 "The index n must be nonnegative integer (got %r)" % n)
         else:
             return laguerre_poly(n, x, 0)
Beispiel #10
0
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))
Beispiel #11
0
 def fdiff(self, argindex=1):
     if argindex == 1:
         return 2*C.exp(-self.args[0]**2)/sqrt(S.Pi)
     else:
         raise ArgumentIndexError(self, argindex)
Beispiel #12
0
 def _eval_rewrite_as_exp(self, arg):
     neg_exp, pos_exp = C.exp(-arg), C.exp(arg)
     return (pos_exp + neg_exp) / (pos_exp - neg_exp)
Beispiel #13
0
 def _eval_rewrite_as_exp(self, arg):
     return (C.exp(arg) + C.exp(-arg)) / 2
Beispiel #14
0
 def _eval_rewrite_as_exp(self, arg):
     neg_exp, pos_exp = C.exp(-arg), C.exp(arg)
     return (pos_exp + neg_exp) / (pos_exp - neg_exp)
Beispiel #15
0
 def fdiff(self, argindex=1):
     if argindex == 1:
         return 2 * C.exp(-self.args[0]**2) / sqrt(S.Pi)
     else:
         raise ArgumentIndexError(self, argindex)
Beispiel #16
0
 def _eval_rewrite_as_exp(self, arg):
     return (C.exp(arg) - C.exp(-arg)) / 2
Beispiel #17
0
 def _eval_expand_func(self, **hints):
     n, m, theta, phi = self.args
     return (sqrt(
         (2 * n + 1) / (4 * pi) * C.factorial(n - m) / C.factorial(n + m)) *
             C.exp(I * m * phi) * assoc_legendre(n, m, C.cos(theta)))
 def _eval_expand_func(self, **hints):
     n, m, theta, phi = self.args
     return (sqrt((2*n + 1)/(4*pi) * C.factorial(n - m)/C.factorial(n + m)) *
             C.exp(I*m*phi) * assoc_legendre(n, m, C.cos(theta)))