求解固定网格上的常微分方程(最好是在python中)

时间:2016-09-21 18:05:33

标签: python math mathematical-optimization numerical-methods differential-equations

我有一个形式的微分方程

dy(x)/dx = f(y,x)

我想为y解决这个问题。

我有一个数组xs,其中包含x的所有值,我需要ys

仅针对x的值,我可以为任何f(y,x)评估y

我如何解决ys,最好是在python中?

MWE

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)

2 个答案:

答案 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)

但是dy_dx(y,x)应该总是返回一些合理的东西(不是np.none)。 这是本案例的图纸 enter image description here