如何从scipy odeint返回普通变量?

balp4ylt  于 2022-11-09  发布在  其他
关注(0)|答案(1)|浏览(147)

我有一个R代码,用DeSolve软件包中的ode函数求解一个常微分方程。

f <- function(t, y, parms) {
  with(as.list(c(y, parms)),{
    rate <- M * A/(A + K) * A

    dA <- -rate + D * (IN - A)
    dB <- rate - D * B

    Total <- A + B

    Conserved<- dA + dB - D * (IN - A) + D * B

    return (list(c(dA, dB),
                 Total = Total, rate = rate, Conserved = Conserved))
  })
}

我想在python中复制这段代码,但是,我不知道如何返回普通变量的值,例如Totalrate,和Conserved。现在,我正在重新计算积分后的所有值,如下面的代码所示,但是我不知道如何重新计算变量Conserved

def f(C0, t):
    A, B = C0
    rate = M*A/(A+K)*B
    dA = - rate + D*(IN-A)
    dB = rate - D*B
    return [dA, dB]

times = np.arange(0, 0.05*365, 0.005)

C = odeint(f, C0, times)

DF = pd.DataFrame(C, columns=['A', 'B'])
DF['time'] = times
DF['Total'] = DF['A'] + DF['B']
DF['rate'] = M*DF['A']/(DF['A']+K)*DF['B']

你能帮我转换这个R码吗?

2w3kk1z5

2w3kk1z51#

Python的odeint不直接支持内部变量的输出,但是可以模拟这种行为。
巨蟒
首先创建一个包含所有变量的函数f2,为了简单起见,我们也输出时间t、导数dAdB和状态AB

import numpy as np
import scipy as sp
from scipy.integrate import odeint

def f2(C0, t):
    A, B = C0
    rate = M*A/(A+K) * A
    dA = - rate + D * (IN - A)
    dB =   rate - D * B
    Total = A + B
    Conserved = dA + dB - D * (IN - A) + D * B
    return [t, dA, dB, A, B, Total, rate, Conserved]

现在创建一个只返回导数的函数f

def f(C0, t):
  x = f2(C0, t)
  return(x[1], x[2])

我们还需要一些时间步长、初始变量和参数。由于OP没有提供值,让我们将其设置为任意值,例如1.0:

times = np.arange(0, 0.05*365, 0.005)
C0 = 1, 1
D  = 1
K  = 1
IN = 1
M  = 1

现在我们用odeint求解模型f

C  = odeint(f, C0, times)

最后,我们在一个循环中使用所有内部变量运行完整的函数,结果为odeint而不是C0

ret = [None] * len(C)

for i in np.arange(1, len(C)):
  ret[i] = f2(C[i], times[i])

# last row of the result

ret[len(C)-1]

这个过程本质上就是R的deSolve::ode内部处理这个问题的方式,首先它对ode系统进行积分,然后用积分后的状态运行第二遍,以获得内部变量。

这里为比较一个完整的R代码:

library(deSolve)

f <- function(t, y, parms) {
  with(as.list(c(y, parms)),{
    rate <- M * A/(A + K) * A
    dA <- -rate + D * (IN - A)
    dB <- rate - D * B
    Total <- A + B
    Conserved <- dA + dB - D * (IN - A) + D * B
    return (list(c(dA, dB),
                 Total = Total, rate = rate, Conserved = Conserved))
  })
}

times <- seq(0, 0.05*365, 0.005)
parms <- c(D=1, K=1, IN=1, M=1)
y0 <- c(A=1, B=1)

out <- ode(y0, times = times, f, parms)
tail(out, 1)

相关问题