你能举一个自适应步长scipy.integrate.LSODA函数的简单例子吗?
Can you give a simple example of adaptive stepsize scipy.integrate.LSODA function?
我需要了解 scipy.integrate.LSODA 功能的机制。
我写了一个测试脚本,集成了一个简单的功能。根据LSODA webpage函数的输入可以是rhs函数,t_min,初始y和t_max。另一方面,当我 运行 代码时,我什么也得不到。我该怎么办?
import scipy.integrate as integ
import numpy as np
def func(t,y):
return t
y0=np.array([1])
t_min=1
t_max=10
N_max=100
t_min2=np.linspace(t_min,t_max,N_max)
first_step=0.01
solution=integ.LSODA(func,t_min,y0,t_max)
solution2=integ.odeint(func,y0,t_min2)
print(solution.t,solution.y,solution.nfev,'\n')
print(solution2)
给出解决方案
1 [ 1.] 0
[[ 1.00000000e+00]
[ 9.48773662e+00]
[ 9.00171421e+01]
[ 8.54058901e+02]
[ 8.10308559e+03]]
1.) 您只启动 LSODA
求解器 class 的一个实例,没有计算发生,只是用初始数据初始化数组。要获得类似 odeint
的界面,请使用带有选项 method='LSODA'
的 solve_ivp
。
2.) 如果没有选项 tfirst=True
,LSODA 求解器将求解 y'(t)=t
,而 odeint
将求解 y'(t)=y(t)
为了获得可比较的结果,还应该使公差相等,因为默认公差可能不同。因此可以调用方法
print "LSODA"
solution=integ.solve_ivp(func,[t_min, t_max],y0,method='LSODA', atol=1e-4, rtol=1e-6)
print "odeint"
solution2=integ.odeint(func,y0,t_min2, tfirst=True, atol=1e-4, rtol=1e-6)
即便如此,您也无法获得有关 odeint
内部步骤的信息,即使 FORTRAN 代码有一个选项,python 包装器也不会复制它。您可以向 ODE 函数 func
添加打印语句,以便您查看实际调用此函数的位置,这应该平均每个内部步骤使用 close-by 个参数进行 2 次调用。
此报告
LSODA
1.0 [1.]
1.00995134265 [1.00995134]
1.00995134265 [1.01005037]
1.01990268529 [1.02010074]
1.01990268529 [1.02019977]
10.0 [50.50009903]
10.0 [50.50009903]
odeint
1.0 [1.]
1.00109084546 [1.00109085]
1.00109084546 [1.00109204]
1.00218169092 [1.00218407]
1.00218169092 [1.00218526]
11.9106363102 [71.43162985]
LSODA
输出中报告的步骤是
[ 1. 1.00995134 1.01990269 10. ] [[ 1. 1.01005037 1.02019977 50.50009903]] 7
当然,high-order 方法会将线性多项式 y'=t
积分为二次多项式 y(t)=0.5*(t^2+1)
,基本上不会出现与步长无关的误差。
我需要了解 scipy.integrate.LSODA 功能的机制。
我写了一个测试脚本,集成了一个简单的功能。根据LSODA webpage函数的输入可以是rhs函数,t_min,初始y和t_max。另一方面,当我 运行 代码时,我什么也得不到。我该怎么办?
import scipy.integrate as integ
import numpy as np
def func(t,y):
return t
y0=np.array([1])
t_min=1
t_max=10
N_max=100
t_min2=np.linspace(t_min,t_max,N_max)
first_step=0.01
solution=integ.LSODA(func,t_min,y0,t_max)
solution2=integ.odeint(func,y0,t_min2)
print(solution.t,solution.y,solution.nfev,'\n')
print(solution2)
给出解决方案
1 [ 1.] 0
[[ 1.00000000e+00]
[ 9.48773662e+00]
[ 9.00171421e+01]
[ 8.54058901e+02]
[ 8.10308559e+03]]
1.) 您只启动 LSODA
求解器 class 的一个实例,没有计算发生,只是用初始数据初始化数组。要获得类似 odeint
的界面,请使用带有选项 method='LSODA'
的 solve_ivp
。
2.) 如果没有选项 tfirst=True
,LSODA 求解器将求解 y'(t)=t
,而 odeint
将求解 y'(t)=y(t)
为了获得可比较的结果,还应该使公差相等,因为默认公差可能不同。因此可以调用方法
print "LSODA"
solution=integ.solve_ivp(func,[t_min, t_max],y0,method='LSODA', atol=1e-4, rtol=1e-6)
print "odeint"
solution2=integ.odeint(func,y0,t_min2, tfirst=True, atol=1e-4, rtol=1e-6)
即便如此,您也无法获得有关 odeint
内部步骤的信息,即使 FORTRAN 代码有一个选项,python 包装器也不会复制它。您可以向 ODE 函数 func
添加打印语句,以便您查看实际调用此函数的位置,这应该平均每个内部步骤使用 close-by 个参数进行 2 次调用。
此报告
LSODA
1.0 [1.]
1.00995134265 [1.00995134]
1.00995134265 [1.01005037]
1.01990268529 [1.02010074]
1.01990268529 [1.02019977]
10.0 [50.50009903]
10.0 [50.50009903]
odeint
1.0 [1.]
1.00109084546 [1.00109085]
1.00109084546 [1.00109204]
1.00218169092 [1.00218407]
1.00218169092 [1.00218526]
11.9106363102 [71.43162985]
LSODA
输出中报告的步骤是
[ 1. 1.00995134 1.01990269 10. ] [[ 1. 1.01005037 1.02019977 50.50009903]] 7
当然,high-order 方法会将线性多项式 y'=t
积分为二次多项式 y(t)=0.5*(t^2+1)
,基本上不会出现与步长无关的误差。