Doug Bates cries "foul!" in the following terms:
> Bill Venables <William.Venables@cmis.CSIRO.AU> writes:
>
> > > > foo1 <- deriv(z ~ 2*x + 3*y, c("x","y"), function(x,y) {})
> > > > foo1
> > > function(x, y)
> > > {
> > > .value <- (2 * x) + (3 * y)
> > > .actualArgs <- match.call()[c("x", "y")]
> > > if(all(unlist(lapply(as.list(.actualArgs), is.name)))) {
> > > .grad <- array(0, c(length(.value), 2), list(NULL, c("x", "y")))
> > > .grad[, "x"] <- 2
> > > .grad[, "y"] <- 3
> > > dimnames(.grad) <- list(NULL, .actualArgs)
> > > attr(.value, "gradient") <- .grad
> > > }
> > > .value
> > > }
> > > > foo1(1,1)
> > > [1] 5
> > > > attr(foo1(1,1), "gradient")
> > > NULL
> >
> > It is a bug that was introduced into S-PLUS 4.x and has remained
> > safely ensconced there ever since, even S-PLUS 5.1 for Unix is
> > affected. It seems to be a classic case of fixing something that
> > simply isn't broken.
>
> Ahem. Aren't we rewriting history a bit here?
No, I don't think so.
> The "someone" who improved deriv was me and I did it because a
> certain Bill Venables had a long-standing bug report against
> the previous version of deriv.
I must admit to a tremendous sense of "deja-vu all over again"
when I saw this question, but the full details did not come back
to me straight away.
> The previous version of deriv only assigns the correct names to the
> columns of the gradient when the user calling the function uses
> exactly the same names for the actual arguments as were used for the
> formal arguments. That is, the previous version of deriv assigned the
> column names using the formal arguments. As _you_ pointed out to me,
> this is incorrect. It should use the actual arguments, which this
> version does.
Ahem. I did point out a bug, yes, but obviously not clearly
enough. It was to do with nls ignoring the dimnames that had
been given to the gradient matrix. For example if you did
fn <- deriv(~b1*v/(w - th), c("b1", "th"), function(v, w, b1, th) {})
all was well, but if you did
fn <- deriv(~b1*v/(w - th), c("th", "b1"), function(v, w, b1, th) {})
you shot yourself in the foot. nls() seemed to be assuming that
the variables of differentiation were given in the same
left-to-right order as they occurred in the formula, even though
deriv() had carefully labelled the gradient matrix columns
otherwise.
If you don't believe me, watch this.
> fn <- deriv(~b*v/(w - th), c("b", "th"), function(v, w, b, th) {})
> fm <- nls(Time ~ fn(Viscosity, Wt, b, th), stormer,
start=list(b=10, th=1), trace = T)
121582 : 10 1
6490.86 : 29.3539 4.9199
912.426 : 29.207 2.72204
825.112 : 29.3967 2.23148
825.051 : 29.4013 2.21823
> gn <- deriv(~b*v/(w - th), c("th", "b"), function(v, w, b, th) {})
> fm <- nls(Time ~ gn(Viscosity, Wt, b, th), stormer,
start=list(b=10, th=1), trace = T)
121582 : 10 1
34100.4 : 11.96 10.677
31959.3 : 9.63781 14.5165
Error in nls(Time ~ gn(Viscosity, Wt, b, t..: step factor reduced
below minimum
Dumped
If nls() had been using the dimnames on the gradient matrix the
iterations should have been identical.
That was done using S-PLUS 3.4 but the output is EXACTLY the same
for S-PLUS 5.1, so the change to deriv() did not fix the problem.
I rest my case.
It took me a hell of a long time to work out what was going wrong
and I did very carefully document it in a bug report to MathSoft,
but I said it was a problem with nls() (and allies), not with
deriv(). In fact the problem seems to be that while deriv() is
working, nls() is not using the result properly. I can only
assume the message became garbled somewhere between Seattle and
Madison.
> When the actual arguments are not variables, there is no
> derivative so it is not evaluated. How do you differentiate a
> function with respect to a constant?
Nope. Sorry Doug, but I really don't agree with this. I'm sure
you misunderstood me.
> I realize that this change is inconvenient and confusing. My
> suggestion is to modify deriv so the function produced by deriv
> will always return the gradient but only assigns names to the
> columns when the actual arguments are names.
That would make Tim happier, but I reckon that the problem lies
with nls() deep down, not with deriv().
[For the idle on-lookers I should say that Doug and I are really
very good friends and I hope a little robust debate, even in
public like this, never changes that.]
Bill Venables.
--
Bill Venables, Statistician, CMIS Environmetrics Project
CSIRO Marine Labs, PO Box 120, Cleveland, Qld, AUSTRALIA. 4163
Tel: +61 7 3826 7251 Email: Bill.Venables@cmis.csiro.au
Fax: +61 7 3826 7304 http://www.cmis.csiro.au/bill.venables/
-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news
|