[Rd] Seeking opinions on possible change to nls() code
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Fri Aug 20 17:35:18 CEST 2021
>>>>> J C Nash
>>>>> on Fri, 20 Aug 2021 11:06:25 -0400 writes:
> In our work on a Google Summer of Code project
> "Improvements to nls()", the code has proved sufficiently
> entangled that we have found (so far!) few
> straightforward changes that would not break legacy
> behaviour. One issue that might be fixable is that nls()
> returns no result if it encounters some computational
> blockage AFTER it has already found a much better "fit"
> i.e. set of parameters with smaller sum of squares. Here
> is a version of the Tetra example:
time=c( 1, 2, 3, 4, 6 , 8, 10, 12, 16)
conc = c( 0.7, 1.2, 1.4, 1.4, 1.1, 0.8, 0.6, 0.5, 0.3)
NLSdata <- data.frame(time,conc)
NLSstart <-c(lrc1=-2,lrc2=0.25,A1=150,A2=50) # a starting vector (named!)
NLSformula <-conc ~ A1*exp(-exp(lrc1)*time)+A2*exp(-exp(lrc2)*time)
tryit <- try(nls(NLSformula, data=NLSdata, start=NLSstart, trace=TRUE))
print(tryit)
> If you run this, tryit does not give information that the
> sum of squares has been reduced from > 60000 to < 2, as
> the trace shows.
> Should we propose that this be changed so the returned
> object gives the best fit so far, albeit with some form of
> message or return code to indicate that this is not
> necessarily a conventional solution? Our concern is that
> some examples might need to be adjusted slightly, or we
> might simply add the "try-error" class to the output
> information in such cases.
> Comments are welcome, as this is as much an infrastructure
> matter as a computational one.
Hmm... many years ago, we had introduced the 'warnOnly=TRUE'
option to nls() i.e., nls.control() exactly for such cases,
where people would still like to see the solution:
So,
------------------------------------------------------------------------------
> try2 <- nls(NLSformula, data=NLSdata, start=NLSstart, trace=TRUE,
control = nls.control(warnOnly=TRUE))
61215.76 (3.56e+03): par = (-2 0.25 150 50)
2.175672 (2.23e+01): par = (-1.9991 0.3171134 2.618224 -1.366768)
1.621050 (7.14e+00): par = (-1.960475 -2.620293 2.575261 -0.5559918)
Warning message:
In nls(NLSformula, data = NLSdata, start = NLSstart, trace = TRUE, :
singular gradient
> try2
Nonlinear regression model
model: conc ~ A1 * exp(-exp(lrc1) * time) + A2 * exp(-exp(lrc2) * time)
data: NLSdata
lrc1 lrc2 A1 A2
-22.89 96.43 156.70 -156.68
residual sum-of-squares: 218483
Number of iterations till stop: 2
Achieved convergence tolerance: 7.138
Reason stopped: singular gradient
> coef(try2)
lrc1 lrc2 A1 A2
-22.88540 96.42686 156.69547 -156.68461
> summary(try2)
Error in chol2inv(object$m$Rmat()) :
element (3, 3) is zero, so the inverse cannot be computed
>
------------------------------------------------------------------------------
and similar for vcov(), of course, where the above error
originates.
{ I think GSoC (andr other) students should start by studying and
exploring relevant help pages before drawing conclusions
......
but yes, I've been born in the last millennium ...
}
;-)
Have a nice weekend!
Martin
More information about the R-devel
mailing list