Home > database >  avoid negative values when resolving a ODE
avoid negative values when resolving a ODE

Time:12-07

I am trying to model the behavior of a made-up networks of 5 genes, but I have the problem that I get negative values, which it has not sense biologically speaking.

Is there a way to limit the values to zero?

I managed to do it when I represent the graph, but I don't know how to use the ifelse in the main equation.

Thank you very much-1

###################################################
###preliminaries
###################################################

library(deSolve)
library(ggplot2)
library(reshape2)

###################################################
### Initial values
###################################################

values <- c(A = 1,
            B = 1,
            D = 1,
            E = 20,
            R = 1)

###################################################
### Set of constants
###################################################

constants <- c(a = 1.2,
               b = 0.5,
               c = 1.2,
               d = 1.5,
               e = 0.3,
               f = 0.5,
               g = 1.5,
               h = 0.9,
               i = 1.3,
               j = 1.3,
               m = 0.8,
               n = 0.6,
               q = 1,
               t = 0.0075,
               u = 0.0009,
               Pa = 100,
               Pb = 0.05,
               Pd = 0.1,
               Pe = 10)

###################################################
### differential equations
###################################################

Dynamic_Model<-function(t, values, constants) {
  with(as.list(c(values, constants)),{
    
    dA <- Pa   a*D - j*A - R
    dB <- Pb   b*A   e*E - m*B 
    dD <- Pd   d*B   f*E - g*A - n*D
    dE <- Pe - h*B   i*E - q*E
    dR <- t*A*B - u*D*E 
    
    list(c(dA, dB, dD, dE, dR))
  })   
}

###################################################
### time
###################################################

times <- seq(0, 200, by = 0.01)

###################################################
### print ## Ploting
###################################################

out <- ode(y = values, times = times, func = Dynamic_Model, parms = constants)

out2 <- ifelse(out<0, 0, out)

out.df = as.data.frame(out2) 

out.m = melt(out.df, id.vars='time') 
p <- ggplot(out.m, aes(time, value, color = variable))   geom_point(size=0.5)   ggtitle("Dynamic Model")

CodePudding user response:

I agree completely with @Lutz Lehmann, that the negative values are a result of the structure of the model.

The system of equations allows that derivatives still become negative, even if the states are already below zero, i.e. the states can further decrease. We dont have information about what the states are, so the following is only a technical demonstration. Here a dimensonless Monod-type feedback function fb is implemented as a safeguard. It is normally close to one. The km value should be small enough to act only for state values close to zero, and it should not be too small to avoid numerical errors. It can be formulated individually for each state. Other function types are also possible.

library(deSolve)
library(ggplot2)
library(reshape2)

values <- c(A = 1,
            B = 1,
            D = 1,
            E = 20,
            R = 1)

constants <- c(a = 1.2,
               b = 0.5,
               c = 1.2,
               d = 1.5,
               e = 0.3,
               f = 0.5,
               g = 1.5,
               h = 0.9,
               i = 1.3,
               j = 1.3,
               m = 0.8,
               n = 0.6,
               q = 1,
               t = 0.0075,
               u = 0.0009,
               Pa = 100,
               Pb = 0.05,
               Pd = 0.1,
               Pe = 10,
               km = 0.001)

Dynamic_Model<-function(t, values, constants) {
  with(as.list(c(values, constants)),{
    
    fb <- function(x) x / (x km) # feedback
    
    dA <- (Pa   a*D - j*A - R)         * fb(A)
    dB <- (Pb   b*A   e*E - m*B)       * fb(B)
    dD <- (Pd   d*B   f*E - g*A - n*D) * fb(D)
    dE <- (Pe - h*B   i*E - q*E)       * fb(E)
    dR <- (t*A*B - u*D*E)              * fb(R)
    
    list(c(dA, dB, dD, dE, dR))
  })   
}

times <- seq(0, 200, by = 0.1)

out <- ode(y = values, times = times, func = Dynamic_Model, parms = constants)
plot(out)

Additional hints:

  • Removal of negative values afterwards (out2 <- ifelse(out<0, 0, out)) is just wrong.
  • Removal of negative values in the model function, i.e.

use the ifelse in the main

would also be wrong as it can lead to a severe violation of mass balance.

  • the time steps don't need to be very small. They are automatially adapted anyway by the solver. Too small time steps make your model slow and you get more outputs as needed.
  • some of your parameters are quite large, so that the model becomes very stiff.
  • Related