【问题标题】:Is there a way to recursively call on an ODE variable in Python?有没有办法在 Python 中递归调用 ODE 变量?
【发布时间】:2021-08-15 00:28:13
【问题描述】:

我正在尝试使用 ODE 系统来使用 Python 拟合曲线。 然而,这两个方程都需要在任何时间点 t 调用自身。 如果我们的两个方程是

S'(t) = (a-b-c) * S(t)

R'(t) = (a-b) * R(t) + mN(t)

如何将这些传递给 odeint?

到目前为止,这段代码正在抛出错误

UnboundLocalError: local variable 'R' referenced before assignment

我不知道如何解决这个问题。任何建议或帮助将不胜感激。谢谢!

from scipy.optimize import minimize
from scipy.optimize import curve_fit
from scipy import integrate
import numpy as np
import pylab as plt

xdata = np.array([0,1,2,3,6,7,8,9,10,13,14,15,16,17,22,23,24,27,28,29,30,31,34,35,36,37,38,41,42,43,44,45,48,49,50,51,52])
ydata = np.array([100, 97.2912199,91.08273896,86.28651363,70.58056853,49.00137427,47.50069587,48.22363999,47.22288896,42.59400221,29.35959158,30.47252256,30.85180297,33.44706703,41.93176936,44.2826702,46.51306081,57.32118321,62.58641733,53.23377307,50.4804287,51.59281055,67.82561566,61.28460679,65.49713333,67.99324793,74.55147631,104.5586471,98.97800534,94.31637549,99.0441014,109.6035876,151.0500311,135.2589923,135.2083231,145.1832811,169.0801019])

xdata = np.array(xdata, dtype=float)
ydata = np.array(ydata, dtype=float)

def model(y, x, a, b, c, m):
  S = (a - b - c) * y[0]
  R = (a - b) * R + x*(m *S)
  return S, R

def fit_odeint1(x, a, b, c, m):
    return integrate.odeint(model, (S0, R0), x, args=(a, b, c, m))[:,0]

def fit_odeint2(x, a, b, c, m):
    return integrate.odeint(model, (S0, R0), x, args=(a, b, c, m))[:,1]

S0 = ydata[0]
R0 = 0

popt, pcov = curve_fit(fit_odeint1, xdata, ydata)
fitted1 = fit_odeint1(xdata, *popt)

absError = fitted1 - ydata
SE = np.square(absError) # squared errors
MSE = np.mean(SE) # mean squared errors
RMSE = np.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (np.var(absError) / np.var(ydata))

print("RMSE "+str(RMSE))
print("R^2 "+str(Rsquared))
print()

popt, pcov = curve_fit(fit_odeint2, xdata, ydata)
fitted2 = fit_odeint2(xdata, *popt)

absError = fitted2 - ydata
SE = np.square(absError) # squared errors
MSE = np.mean(SE) # mean squared errors
RMSE = np.sqrt(MSE) # Root Mean Squared Error, RMSE
Rsquared = 1.0 - (np.var(absError) / np.var(ydata))

print("RMSE "+str(RMSE))
print("R^2 "+str(Rsquared))
print()

plt.plot(xdata, ydata, 'D', color='purple')
plt.plot(xdata, fitted1, '--', color='lightcoral')
plt.plot(xdata, fitted2, '--', color='mediumaquamarine')
plt.show()```

【问题讨论】:

    标签: python recursion ode


    【解决方案1】:

    UnboundLocalError 是由于您的 model 函数而发生的。您正在尝试分配给 R 变量,但也尝试在表达式计算期间使用它(因此它没有分配值):

    def model(y, x, a, b, c, m):
        S = (a - b - c) * y[0]
        R = (a - b) * R + x*(m *S)
        return S, R
    

    您缺少的概念是,在 R'(t) 方程 (R'(t) = (a-b) * R(t) + mN(t)) 中,R'(t)R(t) 不同,因此您应该为它们设置不同的变量。

    【讨论】:

    • 另外,以前的S'(t) 已经不同于S(t)
    • 那么最好使用这样的东西:def model(y, x, a, b, c, m): Stdt = (a - b - c) * y[0] Rtdt = (a - b) * R + x*(m *S) return Stdt, Rtdt 然后设置初始条件?
    • @ChairmanMeow 是的,这就是我要做的。 StdtRtdt 以及 SR 可能是随时间演变的向量,并且每次执行您的函数时,它都会生成一个新的(StdtRtdt)样本
    • 太酷了!实现起来会是什么样子?
    猜你喜欢
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 2023-04-10
    • 2020-03-10
    • 2011-04-15
    • 2012-05-12
    • 2019-07-04
    • 1970-01-01
    相关资源
    最近更新 更多