使用 scipy 拟合 ODE 时如何修复此 TypeError?
How can I fix this TypeError when fitting ODE with scipy?
我想使用 scipy
包调整简单 ODE 的参数。我有一种感觉,它是可以忍受的。我知道这个 post 但我认为我的问题不同。
首先我们导入所需的包:
import numpy as np
from scipy import integrate, optimize
我们使用符合新 scipy.interpolate.solve_ivp 方法的签名定义 ODE:
def GGM_ODE(t, C, r, p):
return r*np.power(C, p)
我们定义了具有符合经典签名的集成 ODE 解决方案 scipy.optimize.curve_fit:
def GGM_sol(t, C, r, p):
return integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))
我们通过解决给定参数集的 IV 问题来创建合成数据集:
t = np.arange(0, 21)
sol = GGM_sol(t, 1, 0.5, 0.7)
这非常有效。
最后,我们尝试通过拟合集成解来调整参数:
popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)
不幸的是,最后一步失败并出现神秘错误(至少对我来说是神秘的,因为我对 scipy
的构建方式没有足够的了解):
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-45-22b0c3097986> in <module>
----> 1 popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
761 # Remove full_output from kwargs, otherwise we're passing it in twice.
762 return_full = kwargs.pop('full_output', False)
--> 763 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
764 popt, pcov, infodict, errmsg, ier = res
765 ysize = len(infodict['fvec'])
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
386 if not isinstance(args, tuple):
387 args = (args,)
--> 388 shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
389 m = shape[0]
390
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
25 output_shape=None):
---> 26 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
27 if (output_shape is not None) and (shape(res) != output_shape):
28 if (output_shape[0] != 1):
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in func_wrapped(params)
461 if transform is None:
462 def func_wrapped(params):
--> 463 return func(xdata, *params) - ydata
464 elif transform.ndim == 1:
465 def func_wrapped(params):
TypeError: unsupported operand type(s) for -: 'OdeResult' and 'float'
我可以看到这个错误是经典的 TypeError
关于差分运算符的不兼容操作数。它声称它不能将 float
减去 OdeResult
对象。它也只涉及 optimize
包而不是 integrate
。
我不明白为什么会出现此错误。
我必须在我的函数签名或函数调用中更改什么才能使 curve_fit
工作?或者还有什么我错过的吗?
正如错误消息所说,solve_ivp returns 包含解决方案数据的解决方案对象。尝试
def GGM_sol(t, C, r, p):
res = integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))
return res.y[0]
仅获取解决方案值。
我想使用 scipy
包调整简单 ODE 的参数。我有一种感觉,它是可以忍受的。我知道这个 post 但我认为我的问题不同。
首先我们导入所需的包:
import numpy as np
from scipy import integrate, optimize
我们使用符合新 scipy.interpolate.solve_ivp 方法的签名定义 ODE:
def GGM_ODE(t, C, r, p):
return r*np.power(C, p)
我们定义了具有符合经典签名的集成 ODE 解决方案 scipy.optimize.curve_fit:
def GGM_sol(t, C, r, p):
return integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))
我们通过解决给定参数集的 IV 问题来创建合成数据集:
t = np.arange(0, 21)
sol = GGM_sol(t, 1, 0.5, 0.7)
这非常有效。
最后,我们尝试通过拟合集成解来调整参数:
popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)
不幸的是,最后一步失败并出现神秘错误(至少对我来说是神秘的,因为我对 scipy
的构建方式没有足够的了解):
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-45-22b0c3097986> in <module>
----> 1 popt, pcov = optimize.curve_fit(GGM_sol, t, sol.y)
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
761 # Remove full_output from kwargs, otherwise we're passing it in twice.
762 return_full = kwargs.pop('full_output', False)
--> 763 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
764 popt, pcov, infodict, errmsg, ier = res
765 ysize = len(infodict['fvec'])
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
386 if not isinstance(args, tuple):
387 args = (args,)
--> 388 shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
389 m = shape[0]
390
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in _check_func(checker, argname, thefunc, x0, args, numinputs, output_shape)
24 def _check_func(checker, argname, thefunc, x0, args, numinputs,
25 output_shape=None):
---> 26 res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
27 if (output_shape is not None) and (shape(res) != output_shape):
28 if (output_shape[0] != 1):
~\AppData\Local\Continuum\anaconda3\lib\site-packages\scipy\optimize\minpack.py in func_wrapped(params)
461 if transform is None:
462 def func_wrapped(params):
--> 463 return func(xdata, *params) - ydata
464 elif transform.ndim == 1:
465 def func_wrapped(params):
TypeError: unsupported operand type(s) for -: 'OdeResult' and 'float'
我可以看到这个错误是经典的 TypeError
关于差分运算符的不兼容操作数。它声称它不能将 float
减去 OdeResult
对象。它也只涉及 optimize
包而不是 integrate
。
我不明白为什么会出现此错误。
我必须在我的函数签名或函数调用中更改什么才能使 curve_fit
工作?或者还有什么我错过的吗?
正如错误消息所说,solve_ivp returns 包含解决方案数据的解决方案对象。尝试
def GGM_sol(t, C, r, p):
res = integrate.solve_ivp(GGM_ODE, (t[0], t[-1]), [C], t_eval=t, args=(r, p))
return res.y[0]
仅获取解决方案值。