python - 使用 scipy.odeint 求解预定义函数的非线性 ODE
问题描述
我想求解形式为的非线性常微分方程
Theta2 = (C + j(Theta2))**-1 * (f(t) – g(Theta1) -h(Theta0))
其中 f()、g()、h() 和 j() 是已经定义的函数,它们以 Theta2、Theta1、Theta0 或 t 作为输入。Theta2 和 Theta1 是 Theta0 随时间 t 的二阶和一阶导数。
我一直在使用以下代码使用 SciPy.odeint 函数求解没有 j(Theta2) 项的方程:
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)
解决方案
方程可以重写为:
F(t, theta, theta')
theta'' = -------------------
a + b*theta''
其中 a 和 b 是常数,F 对应于 (f(t) – g(Theta1) -h(Theta0))。
它是 theta'' 的二阶多项式函数,有 2 个解(考虑 b!=0 和 a^2 + 4*b*F>0):
theta'' = -( sqrt(a^2 + 4*b*F) +/- a )/(2*b)
这个新方程的形式为 y' = f(t, y),可以使用常规 ODE 求解器求解。
这是一个使用solve_ivp的示例,它是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();
推荐阅读
- reactjs - 在 AntD 表格单元格内添加 AntD 图标
- skia - 如何在skia中从SkPicture生成skp文件?
- c# - 我如何在vscode中实时刷新代码
- nginx - 通过入口在特定子域上公开 tcp 服务(端口 5432)
- mysql - 对子查询使用主查询条件
- python - 语音识别太慢
- c - 我正在尝试使用指针合并两个排序的(int)数组,并且由于某种原因它存储了地址
- android - 完成 Firebase 函数(Uri 和字符串)Android Java 时出现 ClassCastException
- vim - Vim-airline 在底部产生间隙
- geometry - 检查矩形是否在三角形内的快速方法(2D)