Simultanous differential equations in Python - python

I wanna solve a simultaneous differential equation and based on Lorenz equations:
def f(xyz, t, rho, sigma, beta):
x, y, z = xyz
return [sigma * (y - x),
x * (rho - z) - y,
x * y - beta * z]
I Wrote this:
def f(xyz, t, rho, sigma, beta):
x, y, z = xyz
return [sigma * y(t).diff(t) + sigma * x + beta * y -77,
x + rho * y - 61]
So basically I have another differential of y in the first equation and I tried to take derivative but it says:
TypeError: 'numpy.float64' object is not callable"
Can you tell me How can I solve such problems and for second orders of those?

You have a linear system for the derivatives, call them xp, yp. Fortunately it is triangular, so you can solve it via back-substitution. So first solve for yp then insert that for xp.
def f(xy,t):
x,y = xy
yp = 61 - (4*x + y)
xp = 77 - (2*yp + 2*x + 5*x)
return xp,yp
In general you could employ a linear-system solver numpy.linalg.solve or a more general solver like scipy.optimize.fsolve to extract the derivatives from a system of implicit equations (as far as possible, DAE - systems of differential-algebraic equations can also have this form).

The problem is that when you write y(t), Python thinks you are calling a function called y with argument t, but y appears to be a decimal number, not a function.
Python has a dynamic type system, so when you write
x, y, z = xyz
Python will assign the variable y to the data type of the middle value of xyz

So do u want to solve Lorenz differential equations in Python?
The link below can help you very much with the answer you are trying to find
https://www.programmersought.com/article/82154360499/
or you can solve it like this:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from mpl_toolkits.mplot3d import Axes3D
def lorenz(state, t, sigma, beta, rho):
x, y, z = state
dx = sigma * (y - x)
dy = x * (rho - z) - y
dz = x * y - beta * z
return [dx, dy, dz]

Related

Sympy Not Symbolically Solving Equation at Solveset Call

Using Python 3.9.7 in VS code. I'm doing some stress analysis in python:
from math import sin, cos, tan, degrees, radians
from operator import eq
from sympy import *
x, y, z, a = symbols("x y z a")
vm_crit = ((x - y)**2 + (y - z)**2 + (z - x)**2)**(1/2) -(2**(1/2))*a
vm_crit_sub = vm_crit.subs(x, z)
vm_crit_solve = solveset(vm_crit_sub,y)
print(vm_crit_solve)
I get:
ConditionSet(y, Eq(-1.4142135623731*a + ((-y + z)**2 + (y - z)**2)**0.5, 0), Complexes)
The second argument is correct, but for some reason the function isn't solving for 'y'. If I get rid of the squares:
x, y, z, a = symbols("x y z a")
vm_crit = (x + y + z) - a
vm_crit_sub = vm_crit.subs(x, z)
vm_crit_solve = solveset(vm_crit_sub,y)
print(vm_crit_solve)
I get:
{a - 2*z}
This is correct.
In sympy do you have to expand before solving? If so, is there a way around it?
Thanks for any help.

Solving a boundary value problem DE in python

I am trying to solve the following set of DE's:
dx' = cos(a)
dy' = sin(a)
dF' = - b * x * cos(a) + sin(a)
da' = (b * x * sin(a) + cos(a)) / F
with the conditions:
x(0) = y(0) = x(1) = 0
y(1) = 0.6
F(0) = 0.38
a(0) = -0.5
I tried following a similar problem, but I just can't get it to work. Is it possible, that my F(0) and a(0) are completely off, I am not even sure about them.
import numpy as np
from scipy.integrate import solve_bvp
import matplotlib.pyplot as plt
beta = 5
def fun(x, y):
x, dx, y, dy, F, dF, a, da, = y;
dxds=np.cos(a)
dyds=np.sin(a)
dFds=-beta * x * np.cos(a) + np.sin(a)
dads=(beta * x * np.sin(a) + np.cos(a) ) / F
return dx, dxds, dy, dyds, dF, dFds, da, dads
def bc(ya, yb):
return ya[0], yb[0], ya[2], yb[2] + 0.6, ya[4] + 1, yb[4] + 1, ya[6], yb[6]
x = np.linspace(0, 0.5, 10)
y = np.zeros((8, x.size))
y[4] = 0.38
y[6] = 2.5
res = solve_bvp(fun, bc, x, y)
print(res.message)
x_plot = np.linspace(0, 0.5, 200)
plt.plot(x_plot, res.sol(x_plot)[0])
I think that you have foremost a physics problem, translating the physical situation into an ODE system.
x(s) and y(s) are the coordinates of the rope where s is the length along the rope. Consequently, (x'(s),y'(s)) is a unit vector that is uniquely characterized by its angle a(s), giving
x'(s) = cos(a(s))
y'(s) = sin(a(s))
To get the shape, one now has to consider the mechanics. The assumption seems to be that the rope rotates without spiraling around the rotation axis, staying in one plane. Additionally, from the equilibrium of forces you also get that the other two equations are indeed first order, not second order equations. So your state only has 4 components and the ODE system function thus has to be
def fun(s, u):
x, y, F, a = u;
dxds=np.cos(a)
dyds=np.sin(a)
dFds=-beta * x * np.cos(a) + np.sin(a)
dads=(beta * x * np.sin(a) + np.cos(a) ) / F
return dxds, dyds, dFds, dads
Now there are only 4 boundary condition slots available, which are the coordinates of the start and end of the rope.
def bc(ua, ub):
return ua[0], ub[0], ua[1], ub[1] - 0.6
Additionally, the interval length for s is also the rope length, so a value of 0.5 is impossible for the given coordinates on the pole, try 1.0. There is some experimentation needed to get an initial guess that does not lead to a singular Jacobian in the BVP solver. In the end I get the solution in the x-y plane
with the components

Solve Non linear ODE of predefined functions with scipy.odeint

I want to solve a non linear ordinary differential equation of the form
Theta2 = (C + j(Theta2))**-1 * (f(t) – g(Theta1) -h(Theta0))
Where f(), g(), h(), and j() are functions already defined that take Theta2, Theta1, Theta0 or t as an input. Theta2 and Theta1 are the second and first derivative of Theta0 with time t.
I have been solving the equation without the j(Theta2) term using the SciPy.odeint function using the following code:
from scipy.integrate import odeint
def ODE():
def g(Theta, t):
Theta0 = Theta[0]
Theta1 = Theta[1]
Theta2 = (1/C)*( f(t) - g(Theta1) - h(Theta0))
return Theta1, Theta2
init = 0, 0 # Initial conditions on theta0 and theta1 (velocity) at t=0
sol=odeint(g, init, t)
A = sol[:,1]
B = sol[:,0]
return(A, B)
The equation could be re-written as:
F(t, theta, theta')
theta'' = -------------------
a + b*theta''
where a and b are constants, and F corresponds to (f(t) – g(Theta1) -h(Theta0)).
It is a second order polynomial function of theta'', with 2 solutions (considering b!=0 and a^2 + 4*b*F>0) :
theta'' = -( sqrt(a^2 + 4*b*F) +/- a )/(2*b)
This new equation is of the form y' = f(t, y) which could be solved using regular ODE solver.
Here is an example using solve_ivp which is the replacement for odeint:
import numpy as np
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
a = 20
b = 1
def f(t, y, dydt):
return t + y**2
def ode_function_plus(t, Y):
y = Y[0]
dydt = Y[1]
d2y_dt2 = -(np.sqrt(a**2 + 4*b*f(t, y, dydt)) + a )/(2*b)
return [dydt, d2y_dt2]
def ode_function_minus(t, Y):
y = Y[0]
dydt = Y[1]
d2y_dt2 = -(np.sqrt(a**2 + 4*b*f(t, y, dydt)) - a )/(2*b)
return [dydt, d2y_dt2]
# Solve
t_span = [0, 4]
Y0 = [10, 1]
sol_plus = solve_ivp(ode_function_plus, t_span, Y0)
sol_minus = solve_ivp(ode_function_minus, t_span, Y0)
print(sol_plus.message)
# Graph
plt.plot(sol_plus.t, sol_plus.y[0, :], label='solution +a');
plt.plot(sol_minus.t, sol_minus.y[0, :], label='solution -a');
plt.xlabel('time'); plt.ylabel('y'); plt.legend();

Differential Equations - ODEINT

I have to solve two differential equations by ODEINT in Python, the equations:
y''(t) = (l*q)/a * (1/y(p) * [1 - z'(p)*u]
z''(t) = a * (1/y(p) * y'(p)*u
So I was told to make:
y1=y
y2=y'
z1=z
z2=z'
and
y1' = y2
y2' = y'' = (l*q)/a * (1/y(p) * [1 - z'(p)*u]
z1' = z2
z2' = z''(t) = a * (1/y(p) * y'(p)*u
and now I have to solve these 4 equations. l, q, a, u are known.
I tried something like this:
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def rownanie(y, t, l, q, a, u):
y1, y2, z1, z2 = y
dydt = [y2, ((l*q)/a)*(1/y1)*(1-z2*u), z2, (a*y2*u)/y1]
return dydt
l = 1
q = 1
a = 10
u = 0.25
y0 = 0
z0 = 0
t = np.linspace(0, 10, 101)
sol = odeint(rownanie, y0, z0, t, args=(l,q,a,u))
print(sol)
Need help with this
If you read the docs, you'll see odeint
Solves the initial value problem for stiff or non-stiff systems of first order ode-s:
dy/dt = func(y, t, ...) [or func(t, y, ...)]
where y can be a vector
This conversion is a standard mathematical way of transforming a second order ODE into a first order vector ODE.
You therefore create a new vector variable (I'll call it Y to avoid confusion), consisting of the vector Y = [y, y_prime, z, z_prime]: Your implementation of the function is correct.
Also note that in order to be solved numerically you need to specify the initial conditions of all the vector, in this case y0, z0, y'0 and z'0. As Thomas pointed out, you need to specify these values as the initial value of the vector when you call odeint.
import math
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def rownanie(Y, t, l, q, a, u):
y1, y2, z1, z2 = Y
dydt = [y2, ((l*q)/a)*(1/y1)*(1-z2*u), z2, (a*y2*u)/y1]
return dydt
l = 1
q = 1
a = 10
u = 0.25
y0 = 0
z0 = 0
y0_prime, z0_prime = 0, 0 # you need to specify a value for these too
t = np.linspace(0, 10, 101)
sol = odeint(rownanie, [y0, y0_prime, z0, z0_prime], t, args=(l,q,a,u))
print(sol)

Chain rule in sympy

I'm trying some basic practice with SymPy. I would like to take a second derivative symbolically of a function in rectangular coordinates with respect to the radius parameter in polar coordinates.
I'd like a nice chain rule symbolic expression where it calculates what it can and leaves unevaluated what can't be simplified further.
from sympy import *
init_session()
x, y, r, t = symbols('x y r t') # r (radius), t (angle theta)
f, g = symbols('f g', cls=Function)
g = f(x,y)
x = r * cos(t)
y = r* sin(t)
Derivative(g,r, 2).doit()
This code yields 0. Is there a way to get a symbolic representation of the answer, rather than 0?
Short answer:
Your commands are out of order.
Long answer:
x, y, r, t = symbols('x y r t') # r (radius), t (angle theta)
f, g = symbols('f g', cls=Function)
g = f(x,y)
Now x,y are Symbols, f is a Function and g is an applied Function i.e. the symbols x,y applied to f as f(x,y).
x = r * cos(t)
y = r* sin(t)
Now you redefine x and y as expressions of r and t. This does not affect g in the slightest!
Derivative(g,r, 2).doit()
Now you derive g wrt r. As g is still defined via the initial symbols x,y it does not depend on r, thus the derivative is zero.
To achieve what you want use this:
from sympy import *
r, t = symbols('r t') # r (radius), t (angle theta)
f = symbols('f', cls=Function)
x = r* cos(t)
y = r* sin(t)
g = f(x,y)
Derivative(g,r, 2).doit()
I also dropped all unnecessary Symbol definitions.

Categories

Resources