Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Fixed and Variable parameters to Optimx

This is a syntax question and probably has a simple solution but I can't find it covered anywhere on SO for the optimx package.

Minimal working example & Question

I have a function like:

ToOptimise = function(a,b,d,e){
(a-1)^2 + (b-2)^2 + (d-3)^2 +(e-4)^2
}

I can optimise select parameters in mle2 quite easily:

library(bbmle)

Calib2 = mle2(ToOptimise,
              start = list(a = 1, d = 10),
              fixed = list(b = 2, e = 2))

This is not really the right tool though as it is not a maximum likelihood problem.

I want to find a way to pass fixed and optimisable parameters to Optimx as easily

I plan to do several calibrations holding different parameters fixed at any time and so do not want to have to redo the function hardcoding in some parameters.

My attempt that don't work

library(optimx)

ToOptimiseVector = function(Theta){
  a = Theta[1]
  b = Theta[2]
  d = Theta[3]
  e = Theta[4]
  (a-1)^2 + (b-2)^2 + (d-3)^2 +(e-4)^2
}


Calib1  = optimx( par = c(1,2,1,2),
                  fn = ToOptimiseVector,
                  Theta[2] = 2, Theta[4] = 2)

Another related Question on Stack Overflow

Another optimx syntax question that does not look at fixed and optimisable parameters is:

  • R- Optimx for exponential function with 2 parameters - cannot evaluate function at initial parameter values
like image 612
Stuart Avatar asked Jun 13 '14 16:06

Stuart


2 Answers

Added a opt parameter to the fn. Just pass this opt vector into optimx(). Any non NA values will become fixed.

ToOptimiseVector <- function(Theta, opt = rep(NA, 4)){

# Check if any of opt is not NA
if (any(!sapply(opt, is.na))) {
     i = !sapply(opt, is.na)
# Fix non-NA values
     Theta[i] <- opt[i]
     }

a <- Theta[1]
b <- Theta[2]
d <- Theta[3]
e <- Theta[4]
return((a-1)^2 + (b-2)^2 + (d-3)^2 +(e-4)^2)
}

Seems to work.

Calib1  = optimx( par = c(1,2,1,2), fn = ToOptimiseVector, opt = c(NA, 2, NA, 2))

Calib2  = optimx( par = c(1,2,1,2), fn = ToOptimiseVector)

> Calib1
               p1       p2      p3       p4 value fevals gevals niter convcode kkt1  kkt2 xtimes
Nelder-Mead 0.9998974 5.517528 3.00022 10.83214     4    103     NA    NA        0 TRUE FALSE   0.02
BFGS        1.0000000 4.000000 3.00000  8.00000     4      6      3    NA        0 TRUE FALSE   0.00
> Calib2
              p1       p2     p3       p4        value fevals gevals niter convcode  kkt1 kkt2 xtimes
Nelder-Mead 1.000936 1.999793 3.0006 4.000256 1.344336e-06    227     NA    NA        0 FALSE TRUE   0.01
BFGS        1.000000 2.000000 3.0000 4.000000 3.566556e-23     16      3    NA        0  TRUE TRUE   0.00
like image 56
Vlo Avatar answered Nov 01 '22 07:11

Vlo


The trick is that the starting params and the arguments to the function to be optimized have to be aligned. Please see if the following helps you at all.

library(optimx)

ToOptimiseVector <- function(Theta){
  a <- Theta[1]
  b <- Theta[2]
  d <- Theta[3]
  e <- Theta[4]
  (a-1)^2 + (b-2)^2 + (d-3)^2 +(e-4)^2
}


start <- c(1,0,1,1)
start <- c(1,0,0,0)
start <- c(1,2,1,2)

Calib1  <- optimx( par=start,
                  fn = ToOptimiseVector)

This gives warning messages, but you do get a result.

 > Calib1
            p1 p2 p3 p4 value fevals gevals niter convcode kkt1 kkt2
Nelder-Mead  1  2  3  4     0      4      4    NA        0 TRUE TRUE
BFGS         1  2  3  4     0      4      4    NA        0 TRUE TRUE
            xtimes
Nelder-Mead      0
BFGS             0

Hope you can start with this and proceed.

like image 31
Ram Narasimhan Avatar answered Nov 01 '22 07:11

Ram Narasimhan