########################################
  # EXAMPLE 1	
  # Various ways to solve the same model.
  ########################################
  
  # the model, 5 state variables
  f1 <- function  (t, y, parms)
  {
    ydot <- vector(len=5)
  
    ydot[1]<-  0.1*y[1] -0.2*y[2]
    ydot[2]<- -0.3*y[1] +0.1*y[2] -0.2*y[3]
    ydot[3]<-           -0.3*y[2] +0.1*y[3] -0.2*y[4]
    ydot[4]<-                     -0.3*y[3] +0.1*y[4] -0.2*y[5]
    ydot[5]<-                               -0.3*y[4] +0.1*y[5]
  
    return(list(ydot))
  }
  
  # the jacobian, written as a full matrix
  fulljac <- function  (t, y, parms)
  {
     jac <- matrix(nrow=5,ncol=5,byrow=TRUE, data=c(
                   0.1, -0.2,  0  ,  0  ,  0  ,
                  -0.3,  0.1, -0.2,  0  ,  0  ,
                   0  , -0.3,  0.1, -0.2,  0  ,
                   0  ,  0  , -0.3,  0.1, -0.2,
                   0  ,  0  ,  0  , -0.3,  0.1)    )
     return(jac)
  }
  
  # the jacobian, written in banded form
  bandjac <- function  (t, y, parms)
  {
     jac <- matrix(nrow=3,ncol=5,byrow=TRUE, data=c(
                   0  , -0.2, -0.2, -0.2, -0.2,
                   0.1,  0.1,  0.1,  0.1,  0.1,
                  -0.3, -0.3, -0.3, -0.3,    0)    )
     return(jac)
  }
  
  # initial conditions and output times 
  yini  <- 1:5
  times <- 1:20
  
  # default: stiff method, internally generated, full jacobian
  out   <- lsode(yini,times,f1,parms=0,jactype="fullint")
  
  # stiff method, user-generated full jacobian
  out2  <- lsode(yini,times,f1,parms=0,jactype="fullusr",
                jacfunc=fulljac)
  
  # stiff method, internally-generated banded jacobian
  # one nonzero band above (up) and below(down) the diagonal
  out3  <- lsode(yini,times,f1,parms=0,jactype="bandint",
                                bandup=1,banddown=1)
  
  # stiff method, user-generated banded jacobian
  out4  <- lsode(yini,times,f1,parms=0,jactype="bandusr",
                jacfunc=bandjac,bandup=1,banddown=1)
  
  # nono-stiff method
  out5  <- lsode(yini,times,f1,parms=0,mf=10)  
  
  ########################################
  # example 2: diffusion on a 2-D grid
  # partially specified jacobian
  ########################################
  
diffusion2D <- function(t,Y,par)
  {
   y <- matrix(nr=n,nc=n,data=Y)
   dY   <- r*y     #production
   #diffusion in X-direction; boundaries=0-concentration
   Flux <- -Dx * rbind(y[1,],(y[2:n,]-y[1:(n-1),]),-y[n,])/dx
   dY   <- dY - (Flux[2:(n+1),]-Flux[1:n,])/dx
   #diffusion in Y-direction
   Flux <- -Dy * cbind(y[,1],(y[,2:n]-y[,1:(n-1)]),-y[,n])/dy
   dY    <- dY - (Flux[,2:(n+1)]-Flux[,1:n])/dy
   return(list(as.vector(dY)))
  }
  # parameters
  dy    <- dx <- 1   # grid size
  Dy    <- Dx <- 1   # diffusion coeff, X- and Y-direction
  r     <- 0.025     # production rate
  times <- c(0,1)
  n  <- 50
  y  <- matrix(nr=n,nc=n,0.)
  pa <-par(ask=FALSE)
  # initial condition
  for (i in 1:n)
    for (j in 1:n)
      {dst <- (i-n/2)^2+(j-n/2)^2
       y[i,j]<-max(0.,1.-1./(n*n)*(dst-n)^2)
       }
  filled.contour(y,color.palette=terrain.colors)
  # jacfunc need not be estimated exactly;
  # a crude approximation, with a smaller bandwidth will do.
  # Here the half-bandwidth 1 is used, whereas the true
  # half-bandwidths are equal to n.
  # This corresponds to ignoring the y-direction coupling in the ODEs.
  print(system.time(
  for (i in 1:20)
  {
  out  <-  lsode(func=diffusion2D,y=as.vector(y),times=times,
            parms=NULL,jactype="bandint", bandup=1,banddown=1)
  filled.contour(matrix(nr=n,nc=n,out[2,-1]),zlim=c(0,1),
                color.palette=terrain.colors,main=i)
  y <- out[2,-1]
  }
  ))
  par(ask=pa)Run the code above in your browser using DataLab