python - 使用 scipy 拟合微分方程,得到“对象对于所需数组来说太深”
问题描述
我正在尝试将曲线拟合到微分方程。为了简单起见,我只是在这里做逻辑方程。我写了下面的代码,但我得到下面显示的错误。我不太确定我做错了什么。
import numpy as np
import pandas as pd
import scipy.optimize as optim
from scipy.integrate import odeint
df_yeast = pd.DataFrame({'cd': [9.6, 18.3, 29., 47.2, 71.1, 119.1, 174.6, 257.3, 350.7, 441., 513.3, 559.7, 594.8, 629.4, 640.8, 651.1, 655.9, 659.6], 'td': np.arange(18)})
N0 = 1
parsic = [5, 2]
def logistic_de(t, N, r, K):
return r*N*(1 - N/K)
def logistic_solution(t, r, K):
return odeint(logistic_de, N0, t, (r, K))
params, _ = optim.curve_fit(logistic_solution, df_yeast['td'], df_yeast['cd'], p0=parsic);
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
ValueError: object too deep for desired array
---------------------------------------------------------------------------
error Traceback (most recent call last)
<ipython-input-94-2a5a467cfa43> in <module>
----> 1 params, _ = optim.curve_fit(logistic_solution, df_yeast['td'], df_yeast['cd'], p0=parsic);
~/SageMath/local/lib/python3.9/site-packages/scipy/optimize/minpack.py in curve_fit(f, xdata, ydata, p0, sigma, absolute_sigma, check_finite, bounds, method, jac, **kwargs)
782 # Remove full_output from kwargs, otherwise we're passing it in twice.
783 return_full = kwargs.pop('full_output', False)
--> 784 res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
785 popt, pcov, infodict, errmsg, ier = res
786 ysize = len(infodict['fvec'])
~/SageMath/local/lib/python3.9/site-packages/scipy/optimize/minpack.py in leastsq(func, x0, args, Dfun, full_output, col_deriv, ftol, xtol, gtol, maxfev, epsfcn, factor, diag)
420 if maxfev == 0:
421 maxfev = 200*(n + 1)
--> 422 retval = _minpack._lmdif(func, x0, args, full_output, ftol, xtol,
423 gtol, maxfev, epsfcn, factor, diag)
424 else:
error: Result from function call is not a proper array of floats.
解决方案
@hpaulj 指出了返回值形状的问题,logistic_solution
并表明修复可以消除您报告的错误。
但是,代码中还有另一个问题。该问题不会产生错误,但会导致您的测试问题(逻辑微分方程)的解不正确。默认情况下,odeint
期望t
计算微分方程的函数的参数是第二个参数。要么更改前两个参数的顺序,要么logistic_de
将参数添加tfirst=True
到您的调用中odeint
。第二个选项更好一些,因为如果您决定尝试使用该功能而logistic_de
不是.scipy.integrate.solve_ivp
odeint
推荐阅读
- java - 使用 vertx 时 Logback 未创建输出日志文件
- ruby-on-rails - 如何修复 AWS 弹性 beanstalkd 中的捆绑错误
- java - 在下面的一段 java 代码中获取 StackOverflowError
- swift - 如何在不覆盖最后一个字符的情况下设置 NSTextField 的最大长度?
- reactjs - TypeError:Object(...) is not a function in export Default
- command-line - 无法从命令行通过 hugo 创建新帖子
- python - Jupyter-notebook numpy.core.umath 导入失败
- java - 关于使用 smali 库的问题
- java - 如何在谷歌地图的多边形上绘制折线?
- c# - 如何在基础架构的 ASP.net MVC 网格中实现远程分页?