DirtStats DirtStats - 3 months ago 11
R Question

How do I pass constant parameters through an optimization function that calls another function in R?

I am trying to minimize a function that is conceptually similar to this:

minim<-function(a,b,state){
if(state=="TRUE"){out<-2*a^2+b}else{out<-2*a^3-b}
return(out) }


And I am calling GenSA like this (I wish to optimize on
a
and
b
only and not optimize
state
):

upper_limits<-c(10,10)
lower_limits<-c(-10,-10)
params<-c(1,1)

minim<-function(a,b,state){
if(state=="TRUE"){out<-2*a^2+b}else{out<-2*a^3-b}
return(out)
}

minim_state_TRUE_fit<-GenSA(par=params,function(params) minim(params[1],params[2]),
lower=lower_limits, upper=upper_limits,
control=list(max.time=100),state="TRUE")


And the error I get is:

Error in fn(par, ...) : unused argument (state = "TRUE")


GenSA
is supposed to be able to accept additional arguments that it will pass to the function being called. It appears that
state="TRUE"
is not being passed to
minim
for some reason. Am I coding this incorrectly? I have not been able to find an example of
GenSA
use where an additional argument is used to check my R grammar.

Answer

You are optimizing the function function(params) minim(params[1],params[2]). This function does not contain the argument state. You can fix this like this:

minim <- function(a, b, state) {
  if (state) {
    out <- 2 * a^2 + b
  } else {
    out<-2 * a^3 - b
  }
  return(out)
}

fn = function(params, state) minim(params[1],params[2], state)

minim_state_TRUE_fit<-GenSA(par=params,fn = fn, 
                            lower=lower_limits, upper=upper_limits, 
                            control=list(max.time=100), state = TRUE)

Also note that I changed state = "TRUE" to state = TRUE. If you're using it for a logical test it's better to change it into a logical if possible.

Comments