简体   繁体   中英

How to make the roots calculated within the function available to be used outside the function

I am trying to execute the following code where the main function (LV) includes another function (fun_sp) for finding the root at each time point. The root is called p. As per my understanding, p is dependent upon a variable C which is a vector and changes at each time point, so p should also be a vector that changes at each time point. But when I output p, I get a single value only. Am I understanding it wrongly ? Any inputs will be helpful ?


library(deSolve)

library(rootSolve)

ka = 0.1; CL = 0.2; Ke = 0.3; R = 10; KD = 0.1

LV <- function(time,state, params)

{
C <- state[1]

P <- state[2]

fun_sp <- function(p){p + ((C/R)*p/(p+(KD/R))) -1}

p <<- uniroot.all(fun_sp, c(0,1))

fb <- p/(p+(KD/R))

dC <- fb*ka*C - CL*C + P*CL - Ke*C

dP <- CL*C - P*CL 

list(c(dC, dP))
}

state_ini = c(C=100,P=0)

time = c(seq(1, 24 , 1))

fv <- ode(state_ini, time, LV, parms, method = "lsoda", rtol=1e-6, atol=1e-6, verbose=FALSE)

p

fv = as.data.frame(fv)

str(fv)

Your variable "p" will be overwritten in each iteration of the LV function. The good news is, that internal results can be stored in the output matrix by adding them to the return value (that is a list) as additional arguments (eg root=p) after the vector of the derivatives (in your case c(dC, dP)) like follows:

list(c(dC, dP), root=p)

Your example may then read as follows and the global assignment operator <<- is not anymore needed :

library(deSolve)
library(rootSolve)

ka <- 0.1; CL <- 0.2; Ke <- 0.3; R <- 10; KD <- 0.1

LV <- function(time,state, params) {
  C <- state[1]
  P <- state[2]

  fun_sp <- function(p){p + ((C/R)*p/(p+(KD/R))) -1}

  p <- uniroot.all(fun_sp, c(0,1))
  fb <- p/(p+(KD/R))
  dC <- fb*ka*C - CL*C + P*CL - Ke*C
  dP <- CL*C - P*CL 
  list(c(dC, dP), root=p)
}

state_ini = c(C=100,P=0)
time = c(seq(1, 24 , 1))
fv <- ode(state_ini, time, LV, parms, method = "lsoda", rtol=1e-6, atol=1e-6)

fv

Note however, that uniroot.all may return more than one value, so you may consider to use the 'basic' uniroot function (without .all) from the stats package.

Hope it helps, Thomas

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM