【问题标题】:Fit differential equation with scipy用 scipy 拟合微分方程
【发布时间】:2019-05-14 23:44:19
【问题描述】:

如何拟合下面scipy教程的微分函数

Scipy Differential Equation Tutorial?

最后,我想拟合一些数据点,这些数据点遵循一组两个微分方程,总共有六个参数,但我想从一个简单的例子开始。到目前为止,我尝试了 scipy.optimize.curve_fitscipy.optimize.leastsq 函数,但我没有得到任何结果。

这就是我走了多远:

import numpy as np
import scipy.optimize as scopt
import scipy.integrate as scint
import scipy.optimize as scopt

def pend(y, t, b, c):
    theta, omega = y
    dydt = [omega, -b*omega - c*np.sin(theta)]
    return dydt


def test_pend(y, t, b, c):
    theta, omega = y
    dydt = [omega, -b*omega - c*np.sin(theta)]
    return dydt

b = 0.25
c = 5.0

y0 = [np.pi - 0.1, 0.0]
guess = [0.5, 4]
t = np.linspace(0, 1, 11)

sol = scint.odeint(pend, y0, t, args=(b, c))

popt, pcov = scopt.curve_fit(test_pend, guess, t, sol)

带有以下错误消息:

ValueError: too many values to unpack (expected 2)

我很抱歉,因为假设这是一个非常简单的问题,但我没有让它工作。所以提前谢谢。

【问题讨论】:

  • 能否请您发布完整的错误。意思是,在哪个变量或行上,你得到了这个错误
  • 你看scopt.curve_fit的文档了吗?您必须按顺序传递值:“函数名”后跟 xdata 和 ydata。那不是你在这里做的事情
  • 对不起,你是对的。我使用的拟合线是popt, pcov = scopt.curve_fit(test_pend, t, sol)

标签: python scipy curve-fitting ode


【解决方案1】:

您需要提供一个函数f(t,b,c),它给定一个参数或t 中的参数列表返回函数在参数处的值。这需要一些工作,要么通过确定t 的类型,要么通过使用任何一种方式的构造:

def f(t,b,c): 
    tspan = np.hstack([[0],np.hstack([t])])
    return scint.odeint(pend, y0, tspan, args=(b,c))[1:,0]

popt, pcov = scopt.curve_fit(f, t, sol[:,0], p0=guess)

返回popt = array([ 0.25, 5. ])

这可以扩展以适应更多参数,

def f(t, a0,a1, b,c): 
    tspan = np.hstack([[0],np.hstack([t])])
    return scint.odeint(pend, [a0,a1], tspan, args=(b,c))[1:,0]

popt, pcov = scopt.curve_fit(f, t, sol[:,0], p0=guess)

导致popt = [ 3.04159267e+00, -2.38543640e-07, 2.49993362e-01, 4.99998795e+00]


另一种可能性是显式计算与目标解的差异的平方范数,并将最小化应用于如此定义的标量函数。

 def f(param): 
     b,c = param
     t_sol = scint.odeint(pend, y0, t, args=(b,c))
     return np.linalg.norm(t_sol[:,0]-sol[:,0]);

res = scopt.minimize(f, np.array(guess))

返回res

      fun: 1.572327981969186e-08
 hess_inv: array([[ 0.00031325,  0.00033478],
                  [ 0.00033478,  0.00035841]])
      jac: array([ 0.06129361, -0.04859557])
  message: 'Desired error not necessarily achieved due to precision loss.'
     nfev: 518
      nit: 27
     njev: 127
   status: 2
  success: False
        x: array([ 0.24999905,  4.99999884])

【讨论】:

  • 感谢您的解决方案。所以我想我的主要问题是我想同时拟合两条“曲线”,即使我只需要拟合其中一条。
  • 从您的代码中我不会猜到那是您的问题。我看到的第一个问题是导数函数pendtest_pend 根本不适合那里的函数参数格式。可以尝试适应
猜你喜欢
  • 2012-02-28
  • 2022-07-16
  • 2021-06-05
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 2021-07-27
相关资源
最近更新 更多