Save values used by optim at each iteration step

773 views
Skip to first unread message

Guillaume Théroux Rancourt

unread,
Sep 4, 2015, 2:43:10 PM9/4/15
to Davis R Users' Group
Hi!

I'm using the optim() function and I'm trying to see if it is possible to save the values used at each iteration (or at each n iteration). For example (from optim() help):

fr
<- function(x) { ## Rosenbrock Banana function
 x1
<- x[1]
 x2
<- x[2]
 
100 * (x2 - x1 * x1)^2 + (1 - x1)^2
}
optim
(c(-1.2,1), fr, control=list(trace=T))


takes somewhere between 195 function evaluations to converge. Addind trace=T gives the results of the function (for my function the SSE), but I'm interested in the values used to get to the SSE.
The function I'm trying to optimize runs into local minimums and I'm interested in knowing where those are. Has anyone ever tried that? Could that be achieved by "dumping" the values in a file? Not sure how to do it within optim() or within the function to be optimized. Stackoverflow hasn't been of much help...

Thanks!

Guillaume

Vince S. Buffalo

unread,
Sep 4, 2015, 2:54:08 PM9/4/15
to davi...@googlegroups.com
One way to log and peak at whatever you want is with closures:

frwrap <-  function() {
  res <- list()
  iter <- 1
  fr <- function(x) { ## Rosenbrock Banana function
    x1 <- x[1]
    x2 <- x[2]
    out <- 100 * (x2 - x1 * x1)^2 + (1 - x1)^2
    res[iter] <<- out
    iter <<- iter + 1
    out
  }
  fr
}

func <- frwrap()
optim(c(-1.2,1), func)
as.list(environment(func))

I *think* (but am not sure) that R's lists now grow geometrically making this somewhat efficient. But I may be wrong. If performance is a concern (which it usually isn't when you're debugging stuff) this may not be the best solution (but is certainly orders of magnitude faster than writing to disk).

HTH,
Vince


--
Check out our R resources at http://www.noamross.net/davis-r-users-group.html
---
You received this message because you are subscribed to the Google Groups "Davis R Users' Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to davis-rug+...@googlegroups.com.
Visit this group at http://groups.google.com/group/davis-rug.
For more options, visit https://groups.google.com/d/optout.



--
Vince Buffalo
@vsbuffalo :: vincebuffalo.com
Coop Lab :: Population Biology Graduate Group
University of California, Davis

Noam Ross

unread,
Sep 4, 2015, 5:54:44 PM9/4/15
to davi...@googlegroups.com

Another way to do this is to set the trace control option to a non-zero value like so:

 optim(..., control=list(trace=1))

This will print the output to the console. If you’re just debugging and want to inspect the values, this may be enough. Depending on the algorithm you choose, the way it is displayed is different, and values greater than 1 can provide more data. If you want to capture the trace information as text, you can use capture.output():

trace_data = capture.output(optim(..., control=list(trace=1)))

This will get the trace information as text, but you’ll need to parse it to get numbers.

If you use the nloptr package , which is an excellent alternative to optim, I’ve written a small package, tracer, specifically for this purpose: https://github.com/noamross/tracer. tracer::nloptr_tr() is a drop-in replacement for nloptr() which captures the trace information.

(And I’d be happy for contributions to tracer to parse optim() outputs).

Noam Ross

unread,
Sep 4, 2015, 5:57:41 PM9/4/15
to davi...@googlegroups.com
Ah, sorry, I didn't read the second half of your message right and missed you're already using `trace=T`.  Do try `trace=2` or higher to see if it prints the input values.  Again, it the exact output depends on the algorithm you are using.
Reply all
Reply to author
Forward
0 new messages