Skip to content

using lsoda() and nls() together

3 messages · Benoit Boulinguiez, Thomas Petzoldt, Dieter Menne

#
Thanks to Dieter Menne and Spencer Graves I started to get my way through
lsoda()
Now I need to use it in with nls() to assess parameters

I have a go with a basic example

dy/dt = K1*conc

I try to assess the value of K1 from a simulated data set with a K1 close to
2.
Here is (I think) the best code that I've done so far even though it crashes
when I call nls()


--------------------------------------------------------------
x<-seq(0,10,,100)
y<-exp(2*x)
y<-rnorm(y,y,0.3*y)

test.model<-function(t,conc,parms){
	dy.dt = parms["K1"]*conc
	list(dy.dt)
	}

require(deSolve)
foo<-lsoda(c(conc=1),times=seq(0,10,,100),test.model,parms=c(K1=2))
foo
#####################use of nls

func<-function(K1) {
	foo<-lsoda(c(conc=1),times=seq(0,10,,100),test.model,parms=c(K1=K1))
	foo[,"conc"]
	}
nls(foo~func(K1),start=list(K1=1),data=data.frame(foo=y))

##################### have a look on the SSD ##################### y is the
vector of real data
SSD<-function(K1) {
	sum((y-func(K1))^2)
	}
data<-seq(1.5,2.1,,100)
plot(data,sapply(data,SSD),type="l")
--------------------------------------------------------------


Regards/Cordialement


Benoit Boulinguiez 


-----Message d'origine-----
De : spencerg [mailto:spencer.graves at prodsyse.com] 
Envoy? : vendredi 15 mai 2009 05:28
? : Benoit Boulinguiez
Cc : dieter.menne at menne-biomed.de; r-help at r-project.org
Objet : Re: [R] ode first step

      Have you looked at the vignette in the deSolve package? 


           (deS <- vignette('compiledCode')) # opens a "pdf" file
           Stangle(deS$file) # writes an R script file to "getwd()" 


      In spite of the name, this vignette includes an example entirely in R.
By comparing it with your code, I see that you do NOT provide a connection
between y, parms, K1, C0, m, V, K2 and q.  Something like the following
might work: 

kinetic.model<-function(t,y,parms){
	dq.dt = parms['K1']*y['C0'] - (parms['K1']*y['m']/y['V']+
parms['K2'])*y['q']
	list(dq.dt)
	}


      This may not be correct, but I hope the changes will help you see how
to make it work. 


      Bon Chance. 
      Spencer Graves
Benoit Boulinguiez wrote:
code
http://www.R-project.org/posting-guide.html
#
Hi Benoit,

your problem is not really a problem of lsoda. The reason of the "crash" 
is a violation of the statistical assumptions of least squares 
regression due to dependency of residual variance on x. Due to this, K1 
is varied over a very large range of values until numeric overflow occurs.

Note that you have an exponentially growing state, so log transformation 
will help:

	
res <- nls(log(foo) ~
   log(func(K1)),start=list(K1=1),data=data.frame(foo=y), trace=TRUE)

summary(res)


You may also consider using packages simecol (on CRAN) or FME (on 
R-Forge) that both support constrained optimization of ode systems.

Hope it helps

Thomas Petzoldt
#
bbouling wrote:
Not sure, but I believe you have taken the advice to produce reproducible
code too seriously and got trapped by the bold warning in nls:

Warning
Do not use nls on artificial "zero-residual" data.

The nls function uses a relative-offset convergence criterion that compares
the numerical imprecision at the current parameter estimates to the residual
sum-of-squares. This performs well on data of the form
...

Creating some noise in your data might help

Dieter