'optimization - Passing objective and gradient function arguments as list

I have a function that evaluates the gradient and output simultaneously. I want to optimize it with respect to an objective function. How do I pass the objective and gradient as a list to optimx? The example below illustrates the problem:

Suppose I want to find the smallest non-negative root of the polynomial x^4 - 3*x^2 + 2*x + 3. Its gradient is 4*x^3 - 6*x + 2. I use the method nlminb in optimx, as shown below.

optimx(par = 100, method = "nlminb", fn = function(x) x^4 - 3*x^2 + 2*x + 3, 
                                     gr=function(x) 4*x^3 - 6*x + 2, lower = 0)

This works fine, and I get the following output:

       p1 value fevals gevals niter convcode kkt1 kkt2 xtimes
nlminb  1     3     27     24    23        0 TRUE TRUE      0

Now suppose I define the function fngr, which returns both the objective and gradient as a list:

fngr <- function(x) {
  fn <- x^4 - 3*x^2 + 2*x + 3
  gr <- 4*x^3 - 6*x + 2
  return (list(fn = fn, gr = gr))
}

I tried to call optimx as follows:

do.call(optimx, c(list(par = 100, lower = 0, method="nlminb"), fngr))

This returned the following error:

Error in optimx.check(par, optcfg$ufn, optcfg$ugr, optcfg$uhess, lower,  : 
  Function provided is not returning a scalar number

What is the right way to define fngr and the call to optimx when I want to pass the objective and gradient as a list?

Thanks.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source