JiTCODE:如何实现 if 条件?



我正在尝试用JiTCODE解决一个动态的食物网。该网络的一个方面是将经历阈值的人口设置为零。所以我得到了一个不可微分的方程。有没有办法在JiTCODE中实现它? 另一个类似的问题是网络的Heaviside依赖性。

示例代码:

import numpy as np
from jitcode import jitcode, y, t
def f():
for i in range(N):
if i <5:
#if y(N-1) > y(N-2): #Heavyside, how to make the if-statement
#yield (y(i)*y(N-2))**(0.02)
#else:
yield (y(i)*y(N-1))**(0.02)
else:
#if y(i) > thr:
#yield y(i)**(0.2) #?? how to set the population to 0 ??
#else:
yield y(i)**(0.3)
N = 10
thr = 0.0001 
initial_value = np.zeros(N)+1
ODE = jitcode(f)
ODE.set_integrator("vode",interpolate=True)
ODE.set_initial_value(initial_value,0.0)        

Python 条件将在代码生成期间进行评估,而不是在模拟期间(使用生成的代码)。因此,您不能在此处使用它们。相反,您需要使用特殊的conditional对象来提供步进函数的合理平滑近似(或自己构建这样的东西):

def f():
for i in range(N):
if i<5:
yield ( y(i)*conditional(y(N-1),y(N-2),y(N-2),y(N-1)) )**0.2
else:
yield y(i)**conditional(y(i),thr,0.2,0.3)

例如,您可以将要评估conditional(y(i),thr,0.2,0.3)视为0.2(如果y(i)>thr),否则0.3(在模拟时)。

如何将人口设置为 0 ??

你不能在JiTCODE或一般的微分方程框架内进行这种不连续的跳转。通常,你会使用急剧的人口下降来模拟这一点,可能会引入延迟(从而引入 JiTCDDE)。如果您确实需要这个,您可以:

  • 在每个积分步骤后检测阈值交叉,并使用各自的初始条件重新初始化积分器。如果你只是想完全杀死低于生殖阈值的种群,这似乎是一个有效的解决方案。

  • 实现二进制开关动态变量。

另请参阅此 GitHub 问题。

最新更新