nvm.RdA driver to call an
R implementation of a variable metric method for minimization
of nonlinear functions, possibly subject to bounds (box) constraints and masks
(fixed parameters). The algorithm is based on Nash (1979) Algorithm 21 for main structure,
which is itself drawn from Fletcher's (1970) variable metric code. This is also the basis
of optim() method 'BFGS' which, however, does not deal with bounds or masks, or
Rvmmin. In this method, an approximation to the inverse Hessian (B) is used to generate a
search direction t = - B %*% g, a simple backtracking line search is used until an
acceptable point is found, and the matrix B is updated using a BFGS formula. If no
acceptable point can be found, we reset B to the identity i.e., the search direction
becomes the negative gradient. If the search along the negative gradient is unsuccessful,
the method terminates.
The code is entirely in R to allow users to explore and understand the method.
However, nvm() is intended to be called via optimx::optimr() and NOT
called directly, as it has limited sanity checks on the problem provided, since
such checks are in the optimr() code.
The earlier Rvmmin() function
does have such checks, and was originally part of a separate package of the same
name. Rvmmin() can also be called via optimr(). It may give slightly
different results due to minor internal coding changes, and is kept available for
backward compatibility with other packages.
nvm(par, fn, gr, bds, control = list())A numeric vector of starting estimates.
A function that returns the value of the objective at the
supplied set of parameters par. This function is created within
optimr() and subsumes auxiliary data in ... supplied to that wrapper.
A function that returns the gradient of the objective at the
supplied set of parameters par. Note that this is usually generated within
the optimr() wrapper, where a gradient function or a reference to one of
the derivative approximation routines must be provided. See the documentation for
optimr() for details.
A list of information resulting from function bmchk giving
information on the status of the parameters and bounds and masks.
An optional list of control settings.
Function fn must return a numeric value.
Note that nvm is to be called from optimr and does
NOT allow dot arguments. It is intended to use the internal functions
efn and egr generated inside optimr() along with
bounds information from bmchk() available there.
The control argument is a list. See the documentation of ctrldefault().
The source codes Rvmmin and nvm for R are still a work
in progress, so users should watch the console output. The routine
nvm attempts to use minimal checking and works only with a
bounds constrained version of the algorithm, which may work as fast
as a specific routine for unconstrained problems. This is an open
question, and the author welcomes feedback.
A list with components:
The best set of parameters found.
The value of the objective at the best set of parameters found.
A vector of two integers giving the number of function and gradient evaluations.
An integer indicating the situation on termination of the function. 0
indicates that the method believes it has succeeded. Other values:
0indicates successful termination to an acceptable solution
1indicates that the iteration limit maxit
had been reached.
2indicates that a point with a small gradient norm has been found, which is likely a solution.
20indicates that the initial set of parameters is inadmissible, that is, that the function cannot be computed or returns an infinite, NULL, or NA value.
21indicates that an intermediate set of parameters is inadmissible.
A description of the situation on termination of the function.
Returned index describing the status of bounds and masks at the proposed solution. Parameters for which bdmsk are 1 are unconstrained or "free", those with bdmsk 0 are masked i.e., fixed. For historical reasons, we indicate a parameter is at a lower bound using -3 or upper bound using -1.
Fletcher, R (1970) A New Approach to Variable Metric Algorithms, Computer Journal, 13(3), pp. 317-322.
Nash, J C (1979, 1990) Compact Numerical Methods for Computers: Linear Algebra and Function Minimisation, Bristol: Adam Hilger. Second Edition, Bristol: Institute of Physics Publications.
# library(optimx)
## Rosenbrock Banana function
fr <- function(x) {
x1 <- x[1]
x2 <- x[2]
100 * (x2 - x1 * x1)^2 + (1 - x1)^2
}
grr <- function(x) { ## Gradient of 'fr'
x1 <- x[1]
x2 <- x[2]
c(-400 * x1 * (x2 - x1 * x1) - 2 * (1 - x1),
200 * (x2 - x1 * x1))
}
# Call is from optimr(). In this case, small final gradient
ansrosenbrock0 <- optimr(fn=fr,gr=grr, par=c(1,2), method="nvm")
print(ansrosenbrock0)
#> $par
#> [1] 1 1
#> attr(,"status")
#> [1] " " " "
#>
#> $value
#> [1] 0
#> attr(,"fname")
#> fr
#> attr(,"method")
#> [1] "nvm"
#> attr(,"ptype")
#> [1] "U"
#>
#> $counts
#> function gradient
#> 54 38
#>
#> $convergence
#> [1] 2
#>
#> $message
#> [1] NA
#>
#> $scounts
#> [1] 54 38 0
#>
#> attr(,"maximize")
#> [1] FALSE
#
# Test if 1-parameter problem is possible
#
cat("test n=1 problem using simple squares of parameter\n")
#> test n=1 problem using simple squares of parameter
sqtst<-function(xx) {
res<-sum((xx-2)*(xx-2))
}
nn<-1
startx<-rep(0,nn)
onepar<-optimr(startx,sqtst, gr="grfwd", method="nvm", control=list(trace=1))
#> parchanged = FALSE
#> Parameter scaling:[1] 1
#> Using numerical approximation ' grfwd ' to gradient in optimr()
#> nvm -- J C Nash 2009-2015 - an R implementation of Alg 21
#> Problem of size n= 1
#> Initial fn= 4
#> ig= 1 gnorm= 4 1 1 4
#> *ig= 2 gnorm= 2.39992 3 2 1.44
#> ig= 3 gnorm= 2.145996e-08 4 3 9.997854e-09
#> **********No acceptable point
#> Converged
#> Seem to be done nvm
print(onepar)
#> $par
#> [1] 1.9999
#> attr(,"status")
#> [1] " "
#>
#> $value
#> [1] 9.997854e-09
#> attr(,"fname")
#> [1] "(no_name)"
#> attr(,"method")
#> [1] "nvm"
#> attr(,"ptype")
#> [1] "U"
#>
#> $counts
#> function gradient
#> 14 3
#>
#> $convergence
#> [1] 0
#>
#> $message
#> [1] NA
#>
#> $scounts
#> [1] 14 3 0
#>
#> attr(,"maximize")
#> [1] FALSE