curve_fit 具有未知系数的 ODE
curve_fit with ODE of unknown coefficients
我正在尝试求解方程 Iy'' + b|y'|y' + ky = 0 并将系数拟合到数据。
这是我目前的代码(准备运行):
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import pandas as pd
from scipy.optimize import curve_fit
# Define derivatives of function
def f(y, t, I, b, k):
theta, omega = y
derivs = [omega, -b / I * omega * abs(omega) - k / I * theta]
return derivs
# integrate the function
def yint(t, I, b, k, y0, y1):
y = odeint(f, [y0, y1], t, args=(I, b, k))
return y.ravel()
# define t and y to fit
y0 = [.5, 0]
t = np.arange(0, 3, .01)
y = np.cos(t)*np.e**(-.01*t)
# fit
vals, cov = curve_fit(yint, t, y, p0=[0.002245, 1e-5, 0.2492, y0[0], y[1]])
但是,当我 运行 函数时,我得到错误:
Traceback (most recent call last):
File "---", line 24, in <module>
vals, cov = curve_fit(yint, t, y, p0=[0.002245, 1e-5, 0.2492, y0[0], y[1]])
File "---.py", line 578, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "---.py", line 371, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "---.py", line 20, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "---.py", line 447, in _general_function
return function(xdata, *params) - ydata
ValueError: operands could not be broadcast together with shapes (600,) (300,)
关于如何解决这个问题有什么想法吗?
问题是函数 yint returns 一个形状为 (600,) 的数组,参数为形状 (300,)。再想一想 yint
:它通过将二阶微分方程表示为两个一阶方程组来求解二阶微分方程。所以 y = odeint(...)
的结果有两列,一列是解本身,第二列是它的导数。它的形状是(300,2)。将解决方案及其导数与 ravel
混合在一起没有意义。相反,您应该只采用实际的解决方案,这就是您适合的东西。
所以,替换
return y.ravel()
和
return y[:, 0]
我正在尝试求解方程 Iy'' + b|y'|y' + ky = 0 并将系数拟合到数据。
这是我目前的代码(准备运行):
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import pandas as pd
from scipy.optimize import curve_fit
# Define derivatives of function
def f(y, t, I, b, k):
theta, omega = y
derivs = [omega, -b / I * omega * abs(omega) - k / I * theta]
return derivs
# integrate the function
def yint(t, I, b, k, y0, y1):
y = odeint(f, [y0, y1], t, args=(I, b, k))
return y.ravel()
# define t and y to fit
y0 = [.5, 0]
t = np.arange(0, 3, .01)
y = np.cos(t)*np.e**(-.01*t)
# fit
vals, cov = curve_fit(yint, t, y, p0=[0.002245, 1e-5, 0.2492, y0[0], y[1]])
但是,当我 运行 函数时,我得到错误:
Traceback (most recent call last):
File "---", line 24, in <module>
vals, cov = curve_fit(yint, t, y, p0=[0.002245, 1e-5, 0.2492, y0[0], y[1]])
File "---.py", line 578, in curve_fit
res = leastsq(func, p0, args=args, full_output=1, **kw)
File "---.py", line 371, in leastsq
shape, dtype = _check_func('leastsq', 'func', func, x0, args, n)
File "---.py", line 20, in _check_func
res = atleast_1d(thefunc(*((x0[:numinputs],) + args)))
File "---.py", line 447, in _general_function
return function(xdata, *params) - ydata
ValueError: operands could not be broadcast together with shapes (600,) (300,)
关于如何解决这个问题有什么想法吗?
问题是函数 yint returns 一个形状为 (600,) 的数组,参数为形状 (300,)。再想一想 yint
:它通过将二阶微分方程表示为两个一阶方程组来求解二阶微分方程。所以 y = odeint(...)
的结果有两列,一列是解本身,第二列是它的导数。它的形状是(300,2)。将解决方案及其导数与 ravel
混合在一起没有意义。相反,您应该只采用实际的解决方案,这就是您适合的东西。
所以,替换
return y.ravel()
和
return y[:, 0]