Skip to contents

A unified interface to four optimization methods.

Usage

optim2(fun, parameters, method = "optim", lower = -Inf, upper = Inf, ...)

Arguments

fun

(function)
A function to be minimized.

parameters

(numeric)
A numeric vector of initial values for each parameter to be optimized in fun.

method

(string: "optim")
A string for the optimization method. Must be one of:

lower

(numeric: -Inf)
Lower bound for each parameter. Either a scalar applied uniformly to all parameters, or a numeric vector of length length(parameters) with one bound per parameter. Used only by "nlminb" and "optim_constrained"; ignored by "nlm" and "optim".

upper

(numeric: Inf)
Upper bound for each parameter. Either a scalar applied uniformly to all parameters, or a numeric vector of length length(parameters) with one bound per parameter. Used only by "nlminb" and "optim_constrained"; ignored by "nlm" and "optim".

...

Additional arguments passed to the corresponding method. When method = "optim_constrained", do not pass method via ...; "L-BFGS-B" is forced automatically and a duplicate argument will cause an error.

Value

A named list with five elements:

  1. estimate: numeric vector of optimized parameter values, with length equal to length(parameters).

  2. minimum: scalar numeric giving the value of fun at estimate.

  3. iterations: scalar integer. For "nlm" and "nlminb", the number of optimizer iterations. For "optim" and "optim_constrained", the number of function evaluations (counts["function"] from stats::optim()); optim() does not report iteration counts, so this quantity is not directly comparable to the other methods.

  4. code: integer convergence code. For "nlm", codes 1–2 indicate probable convergence and codes 3–5 indicate potential failure; see stats::nlm() for definitions. For all other methods, 0 indicates success and a positive integer indicates failure; see stats::nlminb() and stats::optim() for method-specific codes.

  5. message: character string describing the convergence outcome.

Examples

#----------------------------------------------------------------------------
# optim2() example
#----------------------------------------------------------------------------
library(bkmodel)

# Linear regression
# residuals should be normal with mean 0 and unknown standard deviation sigma
x1 <- 1:100
set.seed(1)
epsilon <- rnorm(100)
y <- 4 + x1*2 + epsilon

nll <- function(par, y, x1){
  alpha <- par[1]
  beta1 <- par[2]
  sigma <- par[3]
  resid <- y - alpha - beta1 * x1
  -sum(dnorm(resid, mean = 0, sigma, log = TRUE))
}

res_lm <- lm(y ~ x1)
res_lm
#> 
#> Call:
#> lm(formula = y ~ x1)
#> 
#> Coefficients:
#> (Intercept)           x1  
#>       4.132        2.000  
#> 

res_optim <- optim(
  fn = nll,
  par = c(alpha = mean(y),
          beta1 = 0,
          sigma = 1),
  y = y,
  x1 = x1
) |>
  suppressWarnings()
res_optim
#> $par
#>     alpha     beta1     sigma 
#> 4.1332085 1.9995561 0.8935312 
#> 
#> $value
#> [1] 130.6446
#> 
#> $counts
#> function gradient 
#>      190       NA 
#> 
#> $convergence
#> [1] 0
#> 
#> $message
#> NULL
#> 

res_optim2 <- optim2(
  fun = nll,
  parameters = c(alpha = mean(y),
                 beta1 = 0,
                 sigma = 1),
  method = "optim",
  y = y,
  x1 = x1
) |>
  suppressWarnings()
res_optim2
#> $estimate
#>     alpha     beta1     sigma 
#> 4.1332085 1.9995561 0.8935312 
#> 
#> $minimum
#> [1] 130.6446
#> 
#> $iterations
#> [1] 190
#> 
#> $code
#> [1] 0
#> 
#> $message
#> [1] "Found probable solution."
#> 

res_nlm <- optim2(
  fun = nll,
  parameters = c(alpha = mean(y),
                 beta1 = 0,
                 sigma = 1),
  method = "nlm",
  y = y,
  x1 = x1
) |>
  suppressWarnings()
res_nlm
#> $estimate
#>     alpha     beta1     sigma 
#> 4.1316655 1.9995489 0.8936023 
#> 
#> $minimum
#> [1] 130.6444
#> 
#> $iterations
#> [1] 59
#> 
#> $code
#> [1] 2
#> 
#> $message
#> [1] "Successive iterates within tolerance, found probable solution."
#> 

res_nlminb <- optim2(
  fun = nll,
  parameters = c(alpha = mean(y),
                 beta1 = 0,
                 sigma = 1),
  method = "nlminb",
  lower = c(-Inf, -Inf, 1e-6),
  y = y,
  x1 = x1
)
res_nlminb
#> $estimate
#>     alpha     beta1     sigma 
#> 4.1316654 1.9995489 0.8936021 
#> 
#> $minimum
#> [1] 130.6444
#> 
#> $iterations
#> [1] 34
#> 
#> $code
#> [1] 0
#> 
#> $message
#> [1] "relative convergence (4)"
#> 

res_optim_constrained <- optim2(
  fun = nll,
  parameters = c(alpha = mean(y),
                 beta1 = 0,
                 sigma = 1),
  method = "optim_constrained",
  lower = c(-Inf, -Inf, 1e-6),
  y = y,
  x1 = x1
)
res_optim_constrained
#> $estimate
#>     alpha     beta1     sigma 
#> 4.1317064 1.9995477 0.8936346 
#> 
#> $minimum
#> [1] 130.6444
#> 
#> $iterations
#> [1] 64
#> 
#> $code
#> [1] 0
#> 
#> $message
#> [1] "CONVERGENCE: REL_REDUCTION_OF_F <= FACTR*EPSMCH"
#>