具有多个参数的 ODEINT(时间相关) [英] ODEINT with multiple parameters (time-dependent)

查看:42
本文介绍了具有多个参数的 ODEINT(时间相关)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 ODEINT 解决单个一阶 ODE.以下是代码.我希望在 3 个时间点获得 y 的 3 个值.我正在努力解决的问题是能够传递 mtnt 的第 n 个值来计算 dydt.我认为 ODEINT 会传递 mtnt 的所有 3 个值,而不是仅传递 0th、1st 或 2nd,具体取决于迭代.因此,我收到此错误:

<块引用>

RuntimeError: func (4) 返回的数组大小与 y0 (1) 的大小不匹配.

有趣的是,如果我替换初始条件,它是(并且应该是)单个值:a0= [2]*4,代码有效,但给了我一个 4X4 矩阵作为解决方案,这似乎不正确.

mt = np.array([3,7,4,2]) # 常量数组nt = np.array([5,1,9,3]) # 常量数组c1,c2,c3 = [-0.3,1.4,-0.5] # 系数para = [mt,nt] # 打包参数#测试ODE函数定义测试(y,t,额外):m,n = 额外dydt = c1*c2*m - c1*y - c3*n返回 dydta0= [2] # 初始条件tspan = range(len(mt)) # 定义 tspan#求解 ODEyt= odeint(test, a0,tspan,args=(para,))#绘制 ODEplt.plot(tspan,yt,'g')plt.title('多参数测试')plt.xlabel('时间')plt.ylabel('幅度')

一阶微分方程为:

<块引用>

dy/dt = c1*(c2*mt-y(t)) - c3*nt

这个方程代表鼠内分泌系统的一部分,我正在尝试建模.该系统类似于双罐系统,其中第一个罐接收特定激素 [以未知速率],但我们的传感器将在特定时间间隔(1 秒)检测该水平 (mt).然后这个水箱进入第二个水箱,在那里这个激素 (y) 的水平被另一个传感器检测到.我使用单独的变量标记了水平,因为检测水平的传感器彼此独立并且没有相互校准.'c2' 可以被认为是显示两个级别之间相关性的系数.此外,这种激素从罐 1 到罐 2 的转移是由扩散驱动的.这种激素会被生化过程进一步消耗(类似于第二个水箱的排水阀).目前尚不清楚哪些参数会影响消耗量;然而,另一个传感器可以检测在特定时间间隔(在这种情况下也是 1 秒)内消耗的激素 (nt) 量.

因此,mtnt 是特定时间点的激素浓度/水平.尽管代码中只有 4 个元素的长度,但在我的研究中这些数组要长得多.所有传感器都以 1 秒的间隔报告浓度 - 因此 tspan 由相隔 1 秒的时间点组成.

目标是用数学方法确定第二个罐中这种激素的浓度 (y),然后根据实验数据优化这些系数的值.我能够将这些数组 mtnt 传递给定义的 ODE 并在 MATLAB 中使用 ODE45 解决,没有问题.我在尝试用 Python 复制代码时遇到了这个 RunTimeError.

解决方案

正如我在评论中提到的,如果你想使用常微分方程对这个系统建模,你必须对 的值做出假设mn 之间的采样时间.一种可能的模型是使用线性插值.这是一个使用

请注意,不是仅在 sample_times(即在时间 0、1、2 和 3)生成解决方案,而是将 tspan 设置为一组更密集的点.这显示了模型在采样时间之间的行为.

I'm trying to solve a single first-order ODE using ODEINT. Following is the code. I expect to get 3 values of y for 3 time-points. The issue I'm struggling with is ability to pass nth value of mt and nt to calculate dydt. I think the ODEINT passes all 3 values of mt and nt, instead just 0th, 1st or 2nd, depending on the iteration. Because of this, I get this error:

RuntimeError: The size of the array returned by func (4) does not match the size of y0 (1).

Interestingly, if I replace the initial condition, which is (and should be) a single value as: a0= [2]*4, the code works, but gives me a 4X4 matrix as solution, which seems incorrect.

mt = np.array([3,7,4,2]) # Array of constants
nt = np.array([5,1,9,3]) # Array of constants
c1,c2,c3 = [-0.3,1.4,-0.5] # co-efficients
para = [mt,nt] # Packing parameters

#Test ODE function
def test (y,t,extra):
    m,n = extra
    dydt = c1*c2*m - c1*y - c3*n
    return dydt

a0= [2]  # Initial Condition
tspan = range(len(mt)) # Define tspan

#Solving the ODE
yt= odeint(test, a0,tspan,args=(para,)) 
#Plotting the ODE
plt.plot(tspan,yt,'g')
plt.title('Multiple Parameters Test')
plt.xlabel('Time')
plt.ylabel('Magnitude')

The first order differential equation is:

dy/dt = c1*(c2*mt-y(t)) - c3*nt

This equation represents a part of murine endocrine system, which I am trying to model. The system is analogous to a two-tank system, where the first tank receives a specific hormone [at an unknown rate] but our sensor will detect that level (mt) at specific time intervals (1 second). This tank then feeds into the second tank, where the level of this hormone (y) is detected by another sensor. I labeled the levels using separate variables because the sensors that detect the levels are independent of each other and are not calibrated to each other. 'c2' may be considered as the co-efficient that shows the correlation between the two levels. Also, the transfer of this hormone from tank 1 to tank 2 is diffusion-driven. This hormone is further consumed by a biochemical process (similar to a drain valve for the second tank). At the moment, it is unclear which parameters affect the consumption; however, another sensor can detect the amount of hormone (nt) being consumed at a specific time interval (1 second, in this case too).

Thus, mt and nt are the concentrations/levels of the hormone at specific time points. although only 4-element in length in the code, these arrays are much longer in my study. All sensors report the concentrations at 1 second interval - hence tspan consists of time points separated by 1 second.

The objective is to determine the concentration of this hormone in the second tank (y) mathematically and then optimize the values of these coefficients based on the experimental data. I was able to pass these arrays mt and nt to the defined ODE and solve using ODE45 in MATLAB with no issue. I've been running into this RunTimeError, while trying to replicate the code in Python.

解决方案

As I mentioned in a comment, if you want to model this system using an ordinary differential equation, you have to make an assumption about the values of m and n between sample times. One possible model is to use linear interpolation. Here's a script that uses scipy.interpolate.interp1d to create the functions mfunc(t) and nfunc(t) based on the samples mt and nt.

import numpy as np
from scipy.integrate import odeint
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt

mt = np.array([3,7,4,2])  # Array of constants
nt = np.array([5,1,9,3])  # Array of constants

c1, c2, c3 = [-0.3, 1.4, -0.5] # co-efficients

# Create linear interpolators for m(t) and n(t).
sample_times = np.arange(len(mt))
mfunc = interp1d(sample_times, mt, bounds_error=False, fill_value="extrapolate")
nfunc = interp1d(sample_times, nt, bounds_error=False, fill_value="extrapolate")

# Test ODE function
def test (y, t):
    dydt = c1*c2*mfunc(t) - c1*y - c3*nfunc(t)
    return dydt

a0 = [2]  # Initial Condition
tspan = np.linspace(0, sample_times.max(), 8*len(sample_times)+1)
#tspan = sample_times

# Solving the ODE
yt = odeint(test, a0, tspan)

# Plotting the ODE
plt.plot(tspan, yt, 'g')
plt.title('Multiple Parameters Test')
plt.xlabel('Time')
plt.ylabel('Magnitude')
plt.show()

Here is the plot created by the script:

Note that instead of generating the solution only at sample_times (i.e. at times 0, 1, 2, and 3), I set tspan to a denser set of points. This shows the behavior of the model between sample times.

这篇关于具有多个参数的 ODEINT(时间相关)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆