我有一个形式的微分方程
dy(x)/dx = f(y,x)
我想为y
解决这个问题。
我有一个数组xs
,其中包含x
的所有值,我需要ys
。
仅针对x
的值,我可以为任何f(y,x)
评估y
。
我如何解决ys
,最好是在python中?
import numpy as np
# these are the only x values that are legal
xs = np.array([0.15, 0.383, 0.99, 1.0001])
# some made up function --- I don't actually have an analytic form like this
def f(y, x):
if not np.any(np.isclose(x, xs)):
return np.nan
return np.sin(y + x**2)
# now I want to know which array of ys satisfies dy(x)/dx = f(y,x)
答案 0 :(得分:0)
假设你可以使用像Euler这样简单的东西......
数值解决方案将依赖于以前的近似解。因此,如果您想要t = 1
处的解决方案,您可能需要t<1
处的近似解决方案。
我的建议是找出允许您达到所需时间的步长,然后在包含这些时间的间隔内找到近似解。
import numpy as np
#from your example, smallest step size required to hit all would be 0.0001.
a = 0 #start point
b = 1.5 #possible end point
h = 0.0001
N = float(b-a)/h
y = np.zeros(n)
t = np.linspace(a,b,n)
y[0] = 0.1 #initial condition here
for i in range(1,n):
y[i] = y[i-1] + h*f(t[i-1],y[i-1])
或者,您可以使用自适应步骤方法(我现在不准备解释)在您需要的时间之间采取更大的步骤。
或者,您可以使用较粗糙的网格找到一个间隔的近似解,并插入解。
其中任何一个都应该有用。
答案 1 :(得分:0)
我认为您应首先在常规网格上解决ODE,然后在固定网格上插入解决方案。您问题的大致代码
import numpy as np
from scipy.integrate import odeint
from scipy import interpolate
xs = np.array([0.15, 0.383, 0.99, 1.0001])
# dy/dx = f(x,y)
def dy_dx(y, x):
return np.sin(y + x ** 2)
y0 = 0.0 # init condition
x = np.linspace(0, 10, 200)# here you can control an accuracy
sol = odeint(dy_dx, y0, x)
f = interpolate.interp1d(x, np.ravel(sol))
ys = f(xs)