[Rd] Understanding some code within nls()

J C Nash pro|jcn@@h @end|ng |rom gm@||@com
Fri Jun 24 18:11:29 CEST 2022


In working to try to improve the nls() function, a Google Summer of Code contributor and
I have found our understanding of the setPars() function in nls() in base R to be
inadequate.

setPars <- function(newPars) {
    setPars(newPars)
    resid <<- .swts * (lhs - (rhs <<- getRHS())) # envir = thisEnv {2 x}
    dev   <<- sum(resid^2) # envir = thisEnv
    if(length(gr <- attr(rhs, "gradient")) == 1L) gr <- c(gr)
    QR <<- qr(.swts * gr) # envir = thisEnv
    (QR$rank < min(dim(QR$qr))) # to catch the singular gradient matrix
}

There is a similar but not identical function in the minpack.lm.

I'd be grateful if anyone who has ideas on how this function is working
(in particular why the recursive call and then the "<<-" assignments are
needed) would get in touch offline to profjcnash _at_ gmail.com. I suspect
a list discussion is not useful without some preparatory work to narrow
the queries.

My intention is to write up a 1-2 page explanation as a prelude to modifying
code to introduce Marquardt stabilizations and bounds-constrained parameters,
which nls() currently lacks. Also I have examples where minpack.lm seems
to be failing to get bounds constraints correct. The nlsr package (Duncan
Murdoch and myself) does get these correct, but focusses on solving the
nonlinear least squares problem, and lacks many useful features for modeling
that are found in nls(). However, nls() often fails due to "singular gradient"
or else needs to use altered calls to apply special methods.

Assuming some success, I'll post links to the list.

John Nash



More information about the R-devel mailing list