\name{hjn}
\alias{hjn}
\encoding{UTF-8}
\title{Compact R Implementation of Hooke and Jeeves Pattern Search Optimization}
\description{
  The purpose of \code{hjn} is to minimize an unconstrained or bounds
  (box) and mask constrained function 
  of several parameters by a Hooke and Jeeves pattern search. This 
  didactic code is
  entirely in R to allow users to explore and understand the method. It also
  allows bounds (or box) constraints and masks (equality constraints) to be
  imposed on parameters. 
}
\usage{
   hjn(par, fn, lower=-Inf, upper=Inf, bdmsk=NULL, control = list(trace=0), \dots)
}
\arguments{
 \item{par}{A numeric vector of starting estimates.}
 \item{fn}{A function that returns the value of the objective at the
   supplied set of parameters \code{par} using auxiliary data in \dots.
   The first argument of \code{fn} must be \code{par}. }
 \item{lower}{A vector of lower bounds on the parameters.}
 \item{upper}{A vector of upper bounds on the parameters.}
 \item{bdmsk}{An indicator vector, having 1 for each parameter that is "free" or
     unconstrained, and 0 for any parameter that is fixed or MASKED for the
     duration of the optimization.}
 \item{control}{
    An optional list of control settings.  
 }
 \item{\dots}{Further arguments to be passed to \code{fn}.}
}
\details{
   Functions \code{fn} must return a numeric value.

   The \code{control} argument is a list.
   \describe{
   \item{maxfeval}{A limit on the number of function evaluations used in the search.}
   \item{trace}{Set 0 (default) for no output, >0 for trace output
      (larger values imply more output).}
   \item{eps}{Tolerance used to calculate numerical gradients. Default is 1.0E-7. See 
      source code for \code{hjn} for details of application.}
   \item{\code{dowarn}}{= TRUE if we want warnings generated by optimx. Default is 
     TRUE.}
   \item{\code{tol}}{Tolerance used in testing the size of the pattern search step.}
   }
   
   Note that the control \code{maximize} should NOT be used. 
   
}
\value{
  A list with components:
  \item{par}{The best set of parameters found.}
  \item{value}{The value of the objective at the best set of parameters found.}
  \item{counts}{A two-element integer vector giving the number of calls to
          'fn' and 'gr' respectively. This excludes those calls needed
          to compute the Hessian, if requested, and any calls to 'fn'
          to compute a finite-difference approximation to the gradient.}
  \item{convergence}{An integer code. 
	 '0' indicates successful convergence.
         '1' indicates that the function evaluation count 'maxfeval' was reached.}
  \item{message}{A character string giving any additional information returned
          by the optimizer, or 'NULL'.}
}
\references{
       Nash JC (1979). Compact Numerical Methods for Computers: Linear 
       Algebra and Function Minimisation. Adam Hilger, Bristol. Second 
       Edition, 1990, Bristol: Institute of Physics Publications.
}
\seealso{\code{\link{optim}}}
\examples{
#####################
## Rosenbrock Banana function
fr <- function(x) {
    x1 <- x[1]
    x2 <- x[2]
    100 * (x2 - x1 * x1)^2 + (1 - x1)^2
}

ansrosenbrock0 <- hjn(fn=fr, par=c(1,2), control=list(maxfeval=2000, trace=0))
print(ansrosenbrock0) # use print to allow copy to separate file that 

#    can be called using source()
#####################
genrose.f<- function(x, gs=NULL){ # objective function
## One generalization of the Rosenbrock banana valley function (n parameters)
	n <- length(x)
        if(is.null(gs)) { gs=100.0 }
	fval<-1.0 + sum (gs*(x[1:(n-1)]^2 - x[2:n])^2 + (x[2:n] - 1)^2)
        return(fval)
}

xx<-rep(pi,10)
lower<-NULL
upper<-NULL
bdmsk<-NULL

cat("timings B vs U\n")
lo<-rep(-100,10)
up<-rep(100,10)
bdmsk<-rep(1,10)
tb<-system.time(ab<-hjn(xx,genrose.f, lower=lo, upper=up,
          bdmsk=bdmsk, control=list(trace=0, maxfeval=2000)))[1]
tu<-system.time(au<-hjn(xx,genrose.f, control=list(maxfeval=2000, trace=0)))[1]
cat("times U=",tu,"   B=",tb,"\n")
cat("solution hjnu\n")
print(au)
cat("solution hjnb\n")
print(ab)
cat("diff fu-fb=",au$value-ab$value,"\n")
cat("max abs parameter diff = ", max(abs(au$par-ab$par)),"\n")

######### One dimension test
sqtst<-function(xx) {
   res<-sum((xx-2)*(xx-2))
}

nn<-1
startx<-rep(0,nn)
onepar<-hjn(startx,sqtst,control=list(trace=1)) 
print(onepar)
}

\keyword{nonlinear}
\keyword{optimize}
