From 538280 @end|ng |rom gm@||@com  Fri Aug 11 00:19:37 2023
From: 538280 @end|ng |rom gm@||@com (Greg Snow)
Date: Thu, 10 Aug 2023 16:19:37 -0600
Subject: [Rd] 
 feature request: optim() iteration of functions that return
 multiple values
In-Reply-To: <87cz03nro4.fsf@enricoschumann.net>
References: <PAXP189MB1928AA39727C26A434F8D3FFD608A@PAXP189MB1928.EURP189.PROD.OUTLOOK.COM>
 <87cz03nro4.fsf@enricoschumann.net>
Message-ID: <CAFEqCdwJM6gOmD4YytYit3CrTRJBMjc2xFs4yVmNHJ1Eixj_mg@mail.gmail.com>

Another option that is similar to Enrico's is to use object oriented
programming with R6 or reference objects.  I prefer the R6 package
(which will still use an environment like Enrico, but with some
different syntax and a little easier if you want to do this multiple
times.

Here is some example code (this grows the vectors inefficiently, which
could be improved, but it is fast as is):

library(R6)

RB <- R6Class("RB",
    public=list(
      x = numeric(0),
      y = numeric(0),
      val=numeric(0),
      fun = function(x) {
        x1 <- x[1]
        x2 <- x[2]
        self$x <- c(self$x, x1)
        self$y <- c(self$y, x2)
        ans <- 100*(x2-x1*x1)^2 + (1-x1)^2
        self$val <- c(self$val, ans)
        ans
      }
    )
)

rb1 <- RB$new()
optim(c(-1.2, 1), rb1$fun)
plot(rb1$x, rb1$y, type='l')

rb2 <- RB$new()
optim(c(0,1), rb2$fun)
lines(rb2$x, rb2$y, col='blue')

library(optimx)

rb3 <- RB$new()
optimr(c(-1.2,1), rb3$fun)
lines(rb3$x, rb3$y, col='red')

rb4 <- RB$new()
optimr(c(-1.2,1), rb4$fun, method='hjn')
lines(rb4$x, rb4$y, col='forestgreen')

On Fri, Aug 4, 2023 at 2:22?AM Enrico Schumann <es at enricoschumann.net> wrote:
>
> On Thu, 03 Aug 2023, Sami Tuomivaara writes:
>
> > Dear all,
> >
> > I have used optim a lot in contexts where it would
> > useful to be able to iterate function myfun that, in
> > addition to the primary objective to be minimized
> > ('minimize.me'), could return other values such as
> > alternative metrics of the minimization, informative
> > intermediate values from the calculations, etc.
> >
> > myfun  <- function()
> > {
> > ...
> > return(list(minimize.me = minimize.me, R2 = R2, pval = pval, etc.))
> > }
> >
> > During the iteration, optim could utilize just the first value from the myfun return list; all the other values calculated and returned by myfun could be ignored by optim.
> > After convergence, the other return values of myfun
> > could be finally extracted and appended into the optim
> > return value (which is a list) as additional entry
> > e.g.: $aux <- list(R2, pval, etc.), (without
> > 'minimize.me' as it is already returned as $value).
> >
> > The usual ways for accessing optim return values, e.g.,
> > $par, $value, etc. are not affected.  Computational
> > cost may not be prohibitive either.  Is this feasible
> > to consider?
> >
>
> If you only wish to store additional information, you could do
> so with an environment, without changing optim.  For instance,
> like so (using the first example from ?optim):
>
>     data <- new.env()
>     data$i <- 0
>     data$fun.value <- numeric(1000)
>
>     fr <- function(x, data) {   ## Rosenbrock Banana function
>         x1 <- x[1]
>         x2 <- x[2]
>         ans <- 100 * (x2 - x1 * x1)^2 + (1 - x1)^2
>         data$i <- data$i + 1
>         data$fun.value[data$i] <- ans
>         ans
>     }
>     optim(c(-1.2,1), fr, data = data)
>     ## $par
>     ## [1] 1.000260 1.000506
>     ##
>     ## $value
>     ## [1] 8.825241e-08
>     ##
>     ## $counts
>     ## function gradient
>     ##      195       NA
>     ##
>     ## ....
>
>     data$i
>     ## 195
>
>     plot(data$fun.value[1:data$i])
>
>
>
>
> --
> Enrico Schumann
> Lucerne, Switzerland
> http://enricoschumann.net
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



-- 
Gregory (Greg) L. Snow Ph.D.
538280 at gmail.com



[Rd] feature request: optim() iteration of functions that return multiple values
Greg Snow