Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve differential equation using Python builtin function odeint?

I want to solve this differential equations with the given initial conditions:

(3x-1)y''-(3x+2)y'+(6x-8)y=0, y(0)=2, y'(0)=3

the ans should be

y=2*exp(2*x)-x*exp(-x)

here is my code:

def g(y,x):
    y0 = y[0]
    y1 = y[1]
    y2 = (6*x-8)*y0/(3*x-1)+(3*x+2)*y1/(3*x-1)
    return [y1,y2]

init = [2.0, 3.0]
x=np.linspace(-2,2,100)
sol=spi.odeint(g,init,x)
plt.plot(x,sol[:,0])
plt.show()

but what I get is different from the answer. what have I done wrong?

like image 441
Physicist Avatar asked Jan 07 '15 13:01

Physicist


People also ask

How do you solve a differential equation in Python?

Differential equations are solved in Python with the Scipy. integrate package using function odeint or solve_ivp. t: Time points at which the solution should be reported. Additional internal points are often calculated to maintain accuracy of the solution but are not reported.

How does Odeint function work?

The odeint (ordinary differential equation integration) library is a collection of advanced numerical algorithms to solve initial-value problems of ordinary differential equations. It is written in C++ using modern programming techniques to provide high generality at optimal performance.

What is the difference between Odeint and Solve_ivp?

odeint came first and is uses lsoda from the FORTRAN package odepack to solve ODEs. solve_ivp is a more general solution that lets use decide which integrator to use to solve ODEs. If you define the method param as method='LSODA' then this will use the same integrator as odeint .

What algorithm does Odeint use?

odeint , which uses the LSODA algorithm.


1 Answers

There are several things wrong here. Firstly, your equation is apparently

(3x-1)y''-(3x+2)y'-(6x-8)y=0; y(0)=2, y'(0)=3

(note the sign of the term in y). For this equation, your analytical solution and definition of y2 are correct.

Secondly, as the @Warren Weckesser says, you must pass 2 parameters as y to g: y[0] (y), y[1] (y') and return their derivatives, y' and y''.

Thirdly, your initial conditions are given for x=0, but your x-grid to integrate on starts at -2. From the docs for odeint, this parameter, t in their call signature description:

odeint(func, y0, t, args=(),...):

t : array A sequence of time points for which to solve for y. The initial value point should be the first element of this sequence.

So you must integrate starting at 0 or provide initial conditions starting at -2.

Finally, your range of integration covers a singularity at x=1/3. odeint may have a bad time here (but apparently doesn't).

Here's one approach that seems to work:

import numpy as np
import scipy as sp
from scipy.integrate import odeint
import matplotlib.pyplot as plt

def g(y, x):
    y0 = y[0]
    y1 = y[1]
    y2 = ((3*x+2)*y1 + (6*x-8)*y0)/(3*x-1)
    return y1, y2

# Initial conditions on y, y' at x=0
init = 2.0, 3.0
# First integrate from 0 to 2
x = np.linspace(0,2,100)
sol=odeint(g, init, x)
# Then integrate from 0 to -2
plt.plot(x, sol[:,0], color='b')
x = np.linspace(0,-2,100)
sol=odeint(g, init, x)
plt.plot(x, sol[:,0], color='b')

# The analytical answer in red dots
exact_x = np.linspace(-2,2,10)
exact_y = 2*np.exp(2*exact_x)-exact_x*np.exp(-exact_x)
plt.plot(exact_x,exact_y, 'o', color='r', label='exact')
plt.legend()

plt.show()

enter image description here

like image 103
xnx Avatar answered Sep 21 '22 18:09

xnx