GSoC'20 - Week 7
This week’s work involved increasing the capabilities of the dsolve_system
by incorporating strongly and weakly connected components. It will be explained below.
Connected Components
Some system of ODEs can be divided into independent sub-systems so that, these sub-systems can be solved separately and then the solutions can just be simply concatenated. Before moving on, it is observed that a first order system of ODEs in its canonical form has one unique solution: Picard–Lindelöf theorem
Using this theorem, the connected component division was used so that it was ensured that a sub-system will have only one solution.
Now, dividing a system into independent sub-systems was done using graph theory. Firstly, we look at our system of ODEs below:
x'(t) = x(t) + y(t)
y'(t) = x(t)
z'(t) = z(t) + 2*w(t)
w'(t) = z(t) + w(t)
Now, we have the nodes of the graph as the independent variables. A directed edge is drawn from one node to another if the first node’s representative ode has the term second node in its rhs. For example: a node will be drawn from x(t)
to y(t)
since there is a y(t)
in the characteristic equation for the dependent variable x(t)
. Using this, we get the graph below:
Insert graph1.png here.
Thus, it can be observed that we can solve for x(t), y(t)
and z(t), w(t)
separately. We are using this to solve systems of ODEs which cannot be solved together as a whole, when there is a non-linear component in one of the ODEs. But, even when there is a non-linear component, the system of ODEs is still solvable by using the concept of strongly connected components demonstrated in the following section.
Strongly connected components
In the previous section, we divided the sub-systems and aimed at solving them separately. In this section, we will look at the systems where they cannot be solved independently but with clever substitutions, they become solvable.
Lets look at an example to better understand the technique:
x'(t) = x(t) + 1
y'(t) = x(t)**4 + y(t)
We don’t have a solver to solve the particular system given above nor can we solve for x(t)
and y(t)
separately. But, lets look at the graph for the above system:
Insert graph2.png here.
This shows us that the second ODE is dependent on the first one but the first one isn’t. So, we can solve for the first one independently and then substitute the solution for x(t)
in the second ODE to get a non-homogeneous sub-system and solve for y(t)
.
Examples
Lets look at an example with dsolve_system
>>> f, g, h, k = symbols('f g h k', cls=Function)
>>> eqs = [Eq(Derivative(f(x), x), 2*f(x)),
...: Eq(Derivative(g(x), x), f(x)),
...: Eq(Derivative(h(x), x), h(x)),
...: Eq(Derivative(k(x), x), h(x)**4 + k(x))]
As it can be seen, we can solve the first component to get solutions for f(x)
and g(x)
. For the second component, first step would involve solving for h(x)
and then for k(x)
by substituting the value for h(x)
. The solution obtained is:
>>> sol = dsolve_system(eqs)
>>> sol
[[Eq(f(x), 2*C1*exp(2*x)),
Eq(g(x), C1*exp(2*x) + C2),
Eq(h(x), C3*exp(x)),
Eq(k(x), (C4 + Integral(C3**4*exp(3*x), x))*exp(x))]]
We can check the validity of the solution:
>>> checksysodesol(eqs, sol[0])
(True, [0, 0, 0, 0])
The solution obtained is correct.
Upcoming Week target
For the upcoming week, the target is to complete this PR and check for any shortcomings in the implementation.