Hello Everyone,
I've been trying to solve bugs related to the ODE Solver .I would like my proposal to be in this area since I've got a general idea of the source code. I found the following features missing in ode.py. I could possibly integrate these ideas into a single project called "Improving ODE solver in sympy" for my SOC proposal.
Most of my references are from Differential Equations with Applications abd Historical Notes from George F. Simmons
1 . Solving a set of homogenous equations with constant coefficients:
Right now sympy has no support for solving a system of differential equations. I would like to implement a method by which a two system diff. equation can be solved when there are constant coefficients. If a function of t is also present in the system of differential equations, then try using variation of parameters to solve the system.The actual session would be something like this. I thought of trying to implement it in dsolve, but wouldn't it make things a bit messy? So maybe use another function called dsolve_system(?)
>>> from sympy import *
>>> from sympy.abc import x, y, t
>>> f1 = Derivative(x, t)
>>> f2 = Derivative(y, t)
>>> eq1 = f1 - 3*x - (4*y)
>>> eq2 = f2 - x + y
>>> dsolve_system(eq1, eq2)
Output: [x = 2 * C1 * exp(t) + C2 * (1 + 2*t) * exp(t) , y = C1 * exp(t) + C2 * t * exp(t)]
>>> eq1 = f1 + 3*sin(x) - (4*y)
>>> dsolve_system(eq1, eq2)
Output: ValueError: dsolve_system can work only when there are constant coefficients.
I have studied methods to implement this only when there are constant coefficients, if there are methods to do this when the coefficients are functions of x and y do let me know i'll read them up.
2.Power series solution of homogenous second order linear equations:
The user can input the point about which the power series solution can be found. If not the point can be assumed to be zero.
Implementing it in dsolve might be a pain, because the user would want the equation upto n terms and sometimes the nth term.
So, define a SeriesSolve class, evaluate a general term and return when a method called term is called (The simplest way I could think of, feel free to criticize me)
Something like this, maybe
>>> from sympy.solvers.ode import SeriesSolve
Lets look at various cases.
>>> f = Function('f')(x)
>>> d1 = Derivative(f, x)
>>> d2 = Derivative(f, x, x)
>>> eq = (1 - x**2)*d2 - (2*x)d1 + 6 * f
>>> series = SeriesSolve(eq)
>>> series.term(0)
Output: [A0 , A1]
>>> series.term(2)
Output: [-3 *A0 , - 2 * A1 / 3)
>>> series = SeriesSolve(eq, point = 2)
>>> series.term(0)
Output : [A0 , A1]
>>> series.term(2)
Output: [A0 , -2*A1/3]
>>> series.equation(n)
#Can give the first n terms of both the series.
And if the given point is singular check if it is regular, If regular attempt to find the Frobenius series solution.
>>> eq = (2*x**2)*d2 + x * (2*x + 1)*d1 - f
>>> series = SeriesSolve(eq)
>>> series.term(1)
Output: [(-2 / 5)*A0 , - A1]
>>> series.equation(n)
Same goes, first n terms of both the series
If the roots of the indicial equation are equal, return a ValueError. If the second series cannot be found, just return the first series.
If point is not regular, return ValueError
>>> eq = (2*x**3)*d2 + x * (2*x + 1)*d1 - f
Output: ValueError: Point is irregular singular, power series solution cannot be found.
And if the equation is of the form of a Gauss HyperGeometric one, apply the short-cut , transform it into a GHE , and get the general solution.
If possible try and implement initial value conditions. Since till now there seems to be no support for values like f'(0) I suppose the easiest way would be
>>> equation = SeriesSolve(eq, point = x, (point1 , value of function) , (point2, value of derivative of function))
* This would be a bit tough in the case where there is a three recursion formula, where I'm not sure but I shall verify this as soon as possible.
* In cases like Frobenius Series Solution, sometimes there might be only one series, then simply ignore the second condition?
3.Implementing Laplace transform to solve equations of second degree with initial conditions.
Laplace transforms could be used in a simpler way to solve the above mentioned equations.
This could be again implemented in dsolve, but since initial conditions aren't specified, this could again be a big pain.
>>> from sympy.solvers.ode import laplace_eq
>>> laplace_eq(d2 - 4*d1 + 4*f , (0 , 0) , (0, 3))
Output:
3 * x * exp(2*x)
This could be extended to nth order, but supplying initial conditions and finding laplace inverse would then become difficult
These are the ideas I had done as part of my coursework last semester. Please do tell me , if they are trivial(which I hope not) , places where I could improve, maybe new methods that I could try and read up to fit in a period of ten weeks , so that the possibilty of me getting selected could increase.
Regards,
Manoj Kumar,
Mech Undergrad.
BPGC
Blog