[Rd] confint/nls

Ben Bolker bolker at zoo.ufl.edu
Sun Jan 8 01:22:45 CET 2006


   I have found some "issues" (bugs?) with nls confidence intervals ...
some with the relatively new "port" algorithm, others more general
(but possibly in the "well, don't do that" category).  I have
corresponded some with Prof. Ripley about them, but I thought I
would just report how far I've gotten in case anyone else has
thoughts.  (I'm finding the code in stats/nls.R and stats/nle-profile.R
quite dense & scary ...)
   All of this has been done with R-devel from 3 Jan 2006; the changes
that Prof. Ripley already made to allow confint.nls not to crash
when algorithm="port" are in R-devel, not R-patched.

   a synopsis of the problems with confint():

with a 1-parameter model (is confint not appropriate for 1-parameter
models? it doesn't say so in the docs [by the way, "normality" is
misspelled as "nornality" in ?confint]):

    algorithm=default or plinear: get a complaint from qr.qty ('qr' and 
'y' must have the same number of rows)
    port: "cannot allocate vector of size [large]" [caused by C code
looking for dims when they aren't there]

   2-parameter models:
    default OK
    port "cannot allocate vector"
    plinear 	"Error in xy.coords"

3-parameter models are OK

   I can fix the 2-parameter port case by adding drop=FALSE in
appropriate places, but I wanted to check in just in case
there are better/more efficient ways than my slogging through
one case at a time ...

   apologies for the long message, but I am temporarily cut
off from any way to post these files to the web.

   cheers
     Ben Bolker

code that tests various combinations of numbers of parameters
and algorithms:
-----------
resmat = array(dim=c(3,2,3),
dimnames=list(npar=1:3,c("fit","confint"),c("default","plinear","port")))
resmat.fix <- resmat
## sim. values
npts=1000
set.seed(1001)
x = runif(npts)
b = 0.7
y = x^b+rnorm(npts,sd=0.05)
a =0.5
y2 = a*x^b+rnorm(npts,sd=0.05)
c = 1.0
y3 = a*(x+c)^b+rnorm(npts,sd=0.05)
d = 0.5
y4 = a*(x^d+c)^b+rnorm(npts,sd=0.05)

testfit <- function(model,start,alg) {
   tryfit <- try(fit <- 
nls(model,start=start,algorithm=alg,control=list(maxiter=200)))
   if (class(tryfit)!="try-error") {
     fitcode="OK"
     tryci <- try(confint(fit))
     if (class(tryci)!="try-error") {
       cicode="OK"
     } else cicode = as.character(tryci)
   } else {
     fitcode = as.character(tryfit)
     cicode="?"
   }
   c(fitcode,cicode)
}

m1 = c(y~x^b,y2~a*x^b,y3~a*(x+exp(logc))^b)
m2 = c(y2~x^b,y3~(x+exp(logc))^b,y4~(x^d+exp(logc))^b)
s1 = list(c(b=1),c(a=1,b=1),c(a=1,b=1,logc=0))
s2 = list(c(b=1),c(b=1,logc=0),c(b=1,logc=0,d=0.5))

for (p in 1:3) {
   resmat[p,,"default"] <- testfit(m1[[p]],start=s1[[p]],alg=NULL)
   resmat[p,,"port"] <- testfit(m1[[p]],start=s1[[p]],alg="port")
}

for (p in 1:3) {
   resmat[p,,"plinear"] <- testfit(m2[[p]],start=s2[[p]],alg="plinear")
}

print(resmat)
set.seed(1002)
example(nls,local=TRUE)

diffs:
--
*** /usr/local/src/R/R-devel/src/library/stats/R/nls.R  2006-01-07 
10:57:08.000000000 -0500
--- nlsnew.R    2006-01-07 19:18:53.000000000 -0500
***************
*** 266,277 ****
       gradSetArgs[[1]] <- (~attr(ans, "gradient"))[[2]]
       gradCall <-
           switch(length(gradSetArgs) - 1,
!                call("[", gradSetArgs[[1]], gradSetArgs[[2]]),
!                call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]]),
                  call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]],
!                     gradSetArgs[[3]]),
                  call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]],
!                     gradSetArgs[[3]], gradSetArgs[[4]]))
       getRHS.varying <- function()
       {
           ans <- getRHS.noVarying()
--- 266,277 ----
       gradSetArgs[[1]] <- (~attr(ans, "gradient"))[[2]]
       gradCall <-
           switch(length(gradSetArgs) - 1,
!                call("[", gradSetArgs[[1]], gradSetArgs[[2]],drop=FALSE),
!                call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]],drop=FALSE),
                  call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]],
!                     gradSetArgs[[3]],drop=FALSE),
                  call("[", gradSetArgs[[1]], gradSetArgs[[2]], 
gradSetArgs[[2]],
!                     gradSetArgs[[3]], gradSetArgs[[4]],drop=FALSE))
       getRHS.varying <- function()
       {
           ans <- getRHS.noVarying()
***************
*** 331,337 ****
                       else {
                           vary
                       }, envir = thisEnv)
!              gradCall[[length(gradCall)]] <<- useParams
                if(all(useParams)) {
                    assign("setPars", setPars.noVarying, envir = thisEnv)
                    assign("getPars", getPars.noVarying, envir = thisEnv)
--- 331,337 ----
                       else {
                           vary
                       }, envir = thisEnv)
!              gradCall[[length(gradCall)-1]] <<- useParams
                if(all(useParams)) {
                    assign("setPars", setPars.noVarying, envir = thisEnv)
                    assign("getPars", getPars.noVarying, envir = thisEnv)



More information about the R-devel mailing list