具有未知系数的ODE的curve_fit

时间:2017-09-10 00:52:38

标签: python numpy scipy curve-fitting ode

我正在尝试解决等式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,) 

有关如何解决这个问题的想法吗?

1 个答案:

答案 0 :(得分:1)

问题是函数yint为shape(300,)的参数返回一个shape(600,)数组。再想一想yint:它通过将二阶微分方程表示为两个一阶方程的系统来求解二阶微分方程。因此y = odeint(...)的结果有两列,一列用于解决方案本身,第二列用于其衍生物。它的形状是(300,2)。将解决方案及其衍生物与ravel一起捣乱是没有意义的。相反,你应该只采取实际的解决方案,这是你适合的事情。

所以,替换

   return y.ravel()

   return y[:, 0]