0

我在解决周期性差异 eq 模型时遇到问题。

模型的轨迹是循环的,我想在运行定义的循环时停止它。

为此,我在中运行以下根函数deSolve::ode

rootfun <- function (t, y, pars) {
        #message("rootfun")

        change <- detectChange(t, y)

        roots <- c(1, 1)

        if (any(change %in% c('turn_on', 'turn_off', 'recording_off'))) roots[1] <- 0
        if ('exit' %in% change) {
            message('exit')
            roots[2] <- 0
        }

        roots
    }

调用:

ode(y = stateVec, times = seq(tStart, tStop, by = tRes), func = dTempFun, parms = NULL,
                                                     events = list(func = eventfun, root = T, terminalroot = 2), verbose = T,
                                                     rootfunc = rootfun)

作为一个函数,detectChange当根被触发时给出系统的状态定义eventfun应该做什么。根有两个组件,当第一个为零时eventfun运行,而第二个为零时ode应该停止运行。

在输出中,我希望看到“退出”消息只出现一次,然后ode返回结果。

相反,我有以下输出:

eventfun

-------------------- 
Time settings 
--------------------
 
  Normal computation of output values of y(t) at t = TOUT 

-------------------- 
Integration settings 
--------------------
 
  Model function an R-function:  
  Jacobian not specified 

DLSODAR- A switch to the BDF (stiff) method has occurred    
at T (R1), the new step size is (R2): 315.184, 0.0208815                
eventfun
turn_on
root found at time 320.5
DLSODAR- A switch to the BDF (stiff) method has occurred    
at T (R1), the new step size is (R2): 321.846, 0.00643464                
eventfun
turn_off
root found at time 326.768
DLSODAR- A switch to the BDF (stiff) method has occurred    
at T (R1), the new step size is (R2): 327.483, 0.00632845                
eventfun
recording_off
root found at time 327.638
DLSODAR- A switch to the BDF (stiff) method has occurred    
at T (R1), the new step size is (R2): 327.996, 0.00735142                
eventfun
turn_on
root found at time 335.069
exit
exit
DLSODAR-  One or more components of g has a root  
      too near to the initial point.  

(“eventfun”是在事件函数运行时警告我的标志,“turn_on”、“turn_off”、“recording_off”是由根的第一个组件触发的事件类型,而“exit”仅在以下情况下打印第二个分量为零。)

最后,我们可以看到两个“退出”消息,然后是一个抱怨两个连续根的错误。如果我在每个周期都打印根,则可以看到第二个根分量两次都为零。

为什么会这样?不应该ode在第二个元素的根第一次为零时停止?对于像 deSolve 这样的简单模型,我没有同样的问题:无法理解如何使用根函数提前停止 ode 求解器

我发现正确停止的一个技巧ode是强制两个“退出”状态由非退出根事件分隔。

4

0 回答 0