General-purpose optimization
optim2.RdA unified interface to four optimization methods.
Arguments
- fun
(function)
A function to be minimized.- parameters
(numeric)
A numeric vector of initial values for each parameter to be optimized infun.- method
(string:
"optim")
A string for the optimization method. Must be one of:"nlm":stats::nlm(), a Newton-type line-search algorithm."nlminb":stats::nlminb(), box-constrained optimization via PORT routines."optim":stats::optim()with Nelder-Mead (the default method)."optim_constrained":stats::optim()withmethod = "L-BFGS-B".
- lower
(numeric:
-Inf)
Lower bound for each parameter. Either a scalar applied uniformly to all parameters, or a numeric vector of lengthlength(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 lengthlength(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. Whenmethod = "optim_constrained", do not passmethodvia...;"L-BFGS-B"is forced automatically and a duplicate argument will cause an error.
Value
A named list with five elements:
estimate: numeric vector of optimized parameter values, with length equal tolength(parameters).minimum: scalar numeric giving the value offunatestimate.iterations: scalar integer. For"nlm"and"nlminb", the number of optimizer iterations. For"optim"and"optim_constrained", the number of function evaluations (counts["function"]fromstats::optim());optim()does not report iteration counts, so this quantity is not directly comparable to the other methods.code: integer convergence code. For"nlm", codes 1–2 indicate probable convergence and codes 3–5 indicate potential failure; seestats::nlm()for definitions. For all other methods, 0 indicates success and a positive integer indicates failure; seestats::nlminb()andstats::optim()for method-specific codes.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"
#>