From ggrothendieck at gmail.com  Mon Jan 14 17:48:52 2008
From: ggrothendieck at gmail.com (Gabor Grothendieck)
Date: Mon, 14 Jan 2008 11:48:52 -0500
Subject: [Rd] as.function()
In-Reply-To: <478B4C88.6070205@stats.uwo.ca>
References: <39993FF2-8FE4-4FB9-A752-8A3ABAB18CEF@noc.soton.ac.uk>
	<478B4C88.6070205@stats.uwo.ca>
Message-ID: <971536df0801140848o4f77c3f4q14766d42038141a8@mail.gmail.com>

On Jan 14, 2008 6:50 AM, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:
> Robin Hankin wrote:
> > Hi
> >
> > [this after some considerable thought as to R-help vs R-devel]
> >
> >
> >
> > I want to write a (S3) method for as.function();
> > toy example follows.
> >
> > Given a matrix "a", I need to evaluate trace(ax) as a function of
> > (matrix) "x".
> >
> > Here's a trace function:
> >
> > tr <-  function (a)  {
> >      i <- seq_len(nrow(a))
> >      return(sum(a[cbind(i, i)]))
> > }
> >
> >
> > How do I accomplish the following:
> >
> >
> > a <- crossprod(matrix(rnorm(12),ncol=3))
> > class(a) <- "foo"
> >
> > f <- as.function(a)       # need help to write as.function.foo()
> > x <- diag(3)
> >
> > f(x)             #should give tr(ax)
> >
> > a <- 4
> > f(x)           # should still give tr(ax) even though "a" has been
> > reassigned.
> >
> >
> Brian's answer was what you want.  A less general version is this:
>
>  > as.function.foo <- function(x, ...) {
> +    function(b) tr(x %*% b)
> + }
>

This can also be done using the proto package.  p has two
components b and f.  q inherits f from p but has its own b.

library(proto)
p <- proto(b = 1:4, f = function(., x) sum(diag(x %*% .$b)))
q <- p$proto(b = 5:8)
p$f(1:4)
q$f(1:4)



[Rd] as.function()
Gabor Grothendieck