在固定网格上求解常微分方程(最好使用python)

在固定网格上求解常微分方程(最好使用python),python,math,mathematical-optimization,numerical-methods,differential-equations,Python,Math,Mathematical Optimization,Numerical Methods,Differential Equations,我有一个形式的微分方程 dy(x)/dx=f(y,x) 我想为y解决的问题 我有一个数组xs,其中包含x的所有值,我需要ys 仅对于x的那些值,我可以对任何y计算f(y,x) 我如何求解ys,最好是用python MWE 假设你可以使用一些简单的东西,比如前向欧拉 数值解将依赖于以前的近似解。因此,如果你想在t=1得到一个解,你很可能需要在t得到一个近似解,我认为你应该首先在规则网格上求解ODE,然后在固定网格上插值解。您的问题的近似代码 import numpy as np from scip

我有一个形式的微分方程

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

我想为
y
解决的问题

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

仅对于
x
的那些值,我可以对任何
y
计算
f(y,x)

我如何求解
ys
,最好是用python

MWE
假设你可以使用一些简单的东西,比如前向欧拉


数值解将依赖于以前的近似解。因此,如果你想在
t=1
得到一个解,你很可能需要在
t得到一个近似解,我认为你应该首先在规则网格上求解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)。 这是这个箱子的图纸

你能对分析形式发表意见吗?我有量的向量。实际方程类似于
f(y,x)=4pi c z1 x**2*积分_x^1 z2/x**2 y dx-z3
,其中
c
是常数,
z1,z2,z3
是向量。积分必须以数值形式进行。y也是矢量吗?y本身不是矢量,但我寻求的解是矢量。从我收集的数据来看,ODE是标量的,但有矢量参数?在这个例子中,我使用的是向量和数组,所以数值解是数组。嗨,基于这个答案,我不确定我是否完全清楚。基于您对linspace的使用,在我看来,您似乎在尝试引入应执行此计算的
x
(或在您的示例中,
t
)的值。但实际上,这些值已经预先定义好了。或者我误解了你的解?没错,邻域空间会告诉我们近似解的计算位置。你不能跳转到一个远离初始条件的时间点来计算答案,我对此有点困惑。在我的示例中,对于不在xs数组中的x值,f(y,x)将返回NAN。那么,y[i]对于几乎所有的量不是都是NAN吗?如果函数返回NAN,那么如果当前时间与您想要的时间不接近(根据您的示例),那么您就有点麻烦了。例如,如果你想知道t=10时的解,你需要t=10附近的近似解。如果您仍然感到困惑,请告诉我,我会改写我的答案。
t
的使用让我感到困惑。什么是
t
?它是经过多少次迭代的计数吗?或者是我的
x
?问题是我不能为任意的x值调用dy_dx。(我想我可以插值,但仅此而已。)dy(x)/dx=f(y,x)是一个柯西问题,f(y,x)应该连续才能得到正确的解。插值可以解决这个问题(理论上)。在另一种情况下,你不能用流行的数值方法(如龙格库塔法)来求解它
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])
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)