I have a system of differential equations like this
dy/dt = f(t,y,y1,y2,....,yn,x),
dy1/dt = f(t,y,y1,y2,..yn,x),
.
.
.
dyn/dt = f(t,y,y1,y2,..yn,x),
x(t) = f(t,y1,y2,...yn,x)
And I have the values y_i(0),x(0)
If I had dx/dt then simply using scipy.integrate IVP I could solve this. I can't calculate the derivative of x(t) it's too complex . Can I simulate this system in python without finding dx/dt ?
No problem, define
def derivatives(t,y):
xt = func_x(t,y);
dy = func_y(t,y,xt)
return dy
where func_y takes scalar (t,xt) and vector (y) arguments and returns a vector of the same size as y. This then works well with solve_ivp.
Related
I am trying to solve a physics problem that involves the following equation,
As you can see, sigma could be any function and K1 is a Bessel function. The differential equation has to be solved for Y(x), but x is involved in the integral. In addition, we have another parameter m being a free parameter in the integral and outside the integral. Do you have any idea to solve this?
Sympy does not solve this since it has no analytical solution.
My idea was the following,
I write the integral as a function of x, m.
def get_integral(x,m):
integrand = lambda s: f(s,x,m)
integral = quad(integrand,4*m**2, + np.inf)[0]
return integral
Then write the derivative,
def dYdx(x,Y,m):
x1 = f(x,m))
x2 = get_integral(x,m)
x3 = Y**2-Y_0(x,m)**2
return x1*x2*x3
So I use odeint to solve it like,
solution = odeint(dYdx, y0=0, t = x_array,tfirst=True,args =(m,))
But as you can see I need to solve it for different values of x,s, and m. So that I have an array having the following structure
solution_array = [x,Y,m,integral_value]
for each time I evaluate x and m.
I have numerically integrated a system of differential equations and now want to invert the solution in order to use it later in my code. Any help will be greatly appreciated.
System of differential equations:
def evolution(a,z):
w=0
q,y,h,v,x=a
dq = -(2*q**2+q-1)/(z+1)
dx = -(-x*(x-q)+2*(x+q)-3*(-v+x+q)+2)/(z+1)
dy = (2*q**2+q-1)/(z+1)
dv = (-x*(x-q)+2*(x+q)-3*(-v+x+q)+2+(-v+x+q)*(x-2*q+1)+2*q**2+q-1)/(z+1)
dh=h*(1+q)/(z+1)
dadt = [dq,dy,dh,dv,dx]
return dadt
Initial conditions: (Note that I take the initial conditions at z=20 and integrate backwards)
x0=0
h0=54.0176
q0=0.499
y0=1-q0
v0=0.5
N=3000
t=np.linspace(20.0,0.0,N)
a0=[q0,y0,h0,v0,x0]
sol=odeint(evolution,a0,t)
plt.plot(t,sol[:,1])
plt.show()
I am essentially plotting y=R(z) and want to get z(R) so that I can solve the differential equation v(z(R))=f/f'(R) i.e. get f(R)
I want to integrate the following equation:
d^2[Ψ(z)] / dz^2 = A * ρ(z)
Where Ψ (unknown) and ρ (known) are 1-D arrays and A is a constant.
I have already performed a Taylor expansion, i.e.
d^2[Ψ(z_0)] / dz^2 = [Ψ(z0+Δz) - 2Ψ(z0) + Ψ(z0-Δz)] / [Δz^2]
And successfully solve it by building a matrice.
Now, I would like to know if there is a Python (preferably) or Matlab function that can solve this function without having to do a Taylor expansion.
I have tried numpy.trapz and scipy.integrate.quad, but it seems that these functions only return the area under the curve, i.e. a number, and I am interested to get an array or a function (solving for Ψ).
What you want to do is to solve the differential equation. Because it is a second order differential equation, you should modify your function to make it a system of first order ODEs. So you have to create a function like this:
Assuming ρ=rho
def f(z, y):
return np.array([y[1], A*rho(z)])
where y is a vector containing Ψ in the first position and its derivative in the second position. Then, f returns a vector containing the first and second derivatives of Ψ.
Once done that, you can use scipy.integrate.solve_ivp to solve the problem:
scipy.integrate.solve_ivp(f, [z_start, z_final], y0, method='RK45', z_eval)
where y0 are the initial conditions of Ψ (the value of Ψ and its derivative at z_start). z_eval is the points where you want to store the solution. The solution will be an array containing the values of Ψ and its derivative.
You could integrate rho twice using an indefinite integral . e.g.
import numpy as np
x=np.arange(0,3.1,0.1)
rho = x**3 # replace your rho here....
indef_integral1 = [np.trapz(rho[0:i],x[0:i]) for i in range(2,len(rho))]
indef_integral2 = [np.trapz(indef_integral1[0:i],x[0:i]) for i in range(2,len(indef_integral1))]
I would like to solve the following formulas numerically in Python;
In Mathematica, you can input multiple differential equations and solve it at the same time. Is there a way to do the similar thing with Scipy?
edit: yes, I have looked at scipy.integrate.odeint already, but I'm still not sure how I can solve multiple equations that correlates each other at the same time. Does anyone have suggestion for that?
Eventually I figured out myself and I'm writing down for other people who might be clueless like me;
in odeint, you give three parameters model, y, and t where model is a function that takes in y and t then return dydt, y is the initial value of y, and t is the variable you're trying to take integral over. If you have multiple differential equations that are dependent on each other, you can just pass in all of them to odeint. In my case,
t = np.linspace(0, 20) # range of t
y0 = [No_0, Na_0, Ni_0, Nn_0] # initial condition for each Ns
def model(y, t):
No, Na, Ni, Nn = y
dNodt = -k_oa * No
dNadt = k_oa * No - k_ai * Na
dNidt = k_ai * Na - k_in * Ni
dNndt = k_in * Ni
return [dNodt, dNadt, dNidt, dNndt]
y = odeint(model, y0, t)
You can define multiple differential equations you want to solve within the model you define, and pass in to odeint along with the initial values for all species.
Have a loot at SciPy's Integration package:
https://docs.scipy.org/doc/scipy/reference/integrate.html
specifically at odeint to solve systems of ODE's:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html#scipy.integrate.odeint
I have a university project in which we are asked to simulate a satellite approach to Mars using ODE's and SciPy's odeint function.
I manage to simulate it in 2D by making a second-order ODE into two first-order ODE's. However I am stuck in the time limitation because my code is using SI units therefore running in seconds and Python's linspace limits does not even simulate one complete orbit.
I tried converting the variables and constants to hours and kilometers but now the code keeps giving errors.
I followed this method:
http://bulldog2.redlands.edu/facultyfolder/deweerd/tutorials/Tutorial-ODEs.pdf
And the code is:
import numpy
import scipy
from scipy.integrate import odeint
def deriv_x(x,t):
return array([ x[1], -55.3E10/(x[0])**2 ]) #55.3E10 is the value for G*M in km and hours
xinit = array([0,5251]) # this is the velocity for an orbit of period 24 hours
t=linspace(0,24.0,100)
x=odeint(deriv_x, xinit, t)
def deriv_y(y,t):
return array([ y[1], -55.3E10/(y[0])**2 ])
yinit = array([20056,0]) # this is the radius for an orbit of period 24 hours
t=linspace(0,24.0,100)
y=odeint(deriv_y, yinit, t)
I don't know how to copy/paste the error code from PyLab so I took a PrintScreen of the error:
Second error with t=linspace(0.01,24.0,100) and xinit=array([0.001,5251]):
If anyone has any suggestions on how to improve the code I will be very grateful.
Thank you very much!
odeint(deriv_x, xinit, t)
uses xinit as its initial guess for x. This value for x is used when evaluating deriv_x.
deriv_x(xinit, t)
raises a divide-by-zero error since x[0] = xinit[0] equals 0, and deriv_x divides by x[0].
It looks like you are trying to solve the second-order ODE
r'' = - C rhat
---------
|r|**2
where rhat is the unit vector in the radial direction.
You appear to be separating the x and y coordinates into separate second-order ODES:
x'' = - C y'' = - C
----- and -----
x**2 y**2
with initial conditions x0 = 0 and y0 = 20056.
This is very problematic. Among the problems is that when x0 = 0, x'' blows up. The original second-order ODE for r'' does not have this problem -- the denominator does not blow up when x0 = 0 because y0 = 20056, and so r0 = (x**2+y**2)**(1/2) is far from zero.
Conclusion: Your method of separating the r'' ODE into two ODEs for x'' and y'' is incorrect.
Try searching for a different way to solve the r'' ODE.
Hint:
What if your "state" vector is z = [x, y, x', y']?
Can you write down a first-order ODE for z' in terms of x, y,
x' and y'?
Can you solve it with one call to integrate.odeint?