12.5 Implementing BFGS: a Variable Metric Method

VMmin
## function (x0, func, MaxIter = 9999, Tol = 1e-04) 
## {
##     StopFlag = 0
##     if (MaxIter <= 0) 
##         StopFlag = StopFlag + 32
##     Fmin = func(x0)
##     if (is.infinite(Fmin) || is.nan(Fmin)) 
##         StopFlag = StopFlag + 16
##     if (StopFlag > 0) 
##         return(StopFlag)
##     w = 0.2
##     RefPoint = 0.1
##     AccTol = Tol
##     AbsTol = -Inf
##     RelTol = Tol * Tol
##     DimX = length(x0)
##     B = matrix(nrow = DimX, ncol = DimX)
##     y = vector(length = DimX)
##     CurGr = vector(length = DimX)
##     p = vector(length = DimX)
##     CurX = x0
##     CurGr = Grad(func, x0)
##     FnCount = 1
##     GrCount = 1
##     Iter = 1
##     SmallXCount = 0
##     ResetIter = GrCount
##     while (SmallXCount != DimX || ResetIter != GrCount) {
##         if (ResetIter == GrCount) 
##             B = diag(1, DimX)
##         PrevX = CurX
##         PrevGr = CurGr
##         p = -B %*% CurGr
##         GrDot = t(p) %*% CurGr
##         if (GrDot < 0) {
##             StepLen = 1
##             AccPoint = FALSE
##             while (SmallXCount != DimX & !AccPoint) {
##                 CurX = PrevX + StepLen * p
##                 SmallXCount = sum(((RefPoint + CurX) == (RefPoint + 
##                   PrevX)))
##                 if (SmallXCount < DimX) {
##                   CurF = func(CurX)
##                   FnCount = FnCount + 1
##                   AccPoint = is.finite(CurF) && (CurF <= Fmin + 
##                     GrDot * StepLen * AccTol)
##                   if (!AccPoint) 
##                     StepLen = w * StepLen
##                 }
##             }
##             if (!((CurF > AbsTol) && (abs(CurF - Fmin) > RelTol * 
##                 (abs(Fmin) + RelTol)))) {
##                 SmallXCount = DimX
##                 Fmin = CurF
##             }
##             if (SmallXCount < DimX) {
##                 Fmin = CurF
##                 CurGr = Grad(func, CurX)
##                 GrCount = GrCount + 1
##                 Iter = Iter + 1
##                 y = CurGr - PrevGr
##                 p = StepLen * p
##                 d1 = as.double(t(p) %*% y)
##                 if (d1 > 0) {
##                   Tv = B %*% y
##                   d2 = as.double(1 + t(y) %*% Tv/d1)
##                   B = B + (d2 * p %*% t(p) - p %*% t(Tv) - Tv %*% 
##                     t(p))/d1
##                 }
##                 else {
##                   ResetIter = GrCount
##                 }
##             }
##             else {
##                 if (ResetIter < GrCount) {
##                   SmallXCount = 0
##                   ResetIter = GrCount
##                 }
##             }
##         }
##         else {
##             if (ResetIter == GrCount) {
##                 SmallXcount = DimX
##                 StopFlag = StopFlag + 4
##             }
##             else {
##                 ResetIter = GrCount
##                 SmallXCount = 0
##             }
##         }
##         if (Iter >= MaxIter) {
##             StopFlag = StopFlag + 8
##             break
##         }
##         if (GrCount - ResetIter > 2 * DimX) 
##             ResetIter = GrCount
##     }
##     return(list(par = as.vector(CurX), value = CurF, FnCount = FnCount, 
##         GrCount = GrCount, convergence = StopFlag, grad = CurGr))
## }
## <bytecode: 0x000001e2ac5dc6f0>
## <environment: namespace:math>