Search code examples
rmathematical-optimization

r convert an r function with an embedded function into Rcpp


I have an R function that has two R functions embedded in it.

The structure is something like this:

  • f2 is the function to optimize over and
  • optimize is a base R function that runs f2 multiple times until it finds a minimum between 1 and 5 or ends up at an edge.

The embedding structure in R means that a is calculated once and read into optimize.

I can convert f1 and f2 to Rcpp functions and import the optimize function into Rcpp.

But when I put the cpp version of f2 inside the Rcpp version of f1, I get an error message that this type of embedding is not allowed.

I realize this is not a reproducible example. I couldn't figure out how to search for this type of construction in stack overflow so I'm looking for tips on how to find the right way to do this.

f1 <- function(x, y, z) {
     a <- x + y
     b <- x + b
     f2 <- function(z) {
         d <- z + a + b
     }
     out <- optimize(f2, c(1, 5))
     return(out)
}

Solution

  • What I see from your code is that f2 is a closure (it uses a and b, but it doesn't have them in the arguments list). The supposed reason is - I guess - because you thought optimize needs a monadic function (a function with just one argument) to optimize over. But that is not true.

    Look here in the documentation:

    optimize(f, interval, …, lower = min(interval), upper = max(interval), maximum = FALSE, tol = .Machine$double.eps^0.25)

    optimise(f, interval, …, lower = min(interval), upper = max(interval), maximum = FALSE, tol = .Machine$double.eps^0.25)

    with:

    f                  the function to be optimized. 
                       The function is either minimized or maximized over 
                       its first argument depending on the value of maximum.
    interval           a vector containing the end-points of the interval to be searched for the minimum.
    …                  additional named or unnamed arguments to be passed to f.
    lower              the lower end point of the interval to be searched.
    upper              the upper end point of the interval to be searched.
    maximum            logical. Should we maximize or minimize (the default)?
    tol                the desired accuracy.
    

    So you can give a and b after the interval as arguments.

    The solution is:

    f2 <- function(z, a, b) {
         d <- z + a + b
         return(d)
    }
    
    
    f1 <- function(x, y, z) {
         a <- x + y
         b <- x + b
         out <- optimize(f2, c(1, 5), a, b)
         return(out)
    }
    

    But in Rcpp ;) .