Implementing BFGS: a Variable Metric Method
## 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>