Quasi-Newton methods is a framework of algorithims that is built on the Newton-Rhason method and the line search in this method is based on a $n*n$ matrix S, which serves as the same purpose as the inverse Hessian matrix in the Newton-Rhapson Method. The Quasi-Newton method is yet another framework of algorithims that do not rquire the Hessian. The expression in Quasi-Newton method can be given as $x_{k+1}=x_k-\alpha_kS_kg_k$

When $S_K=I$, it is the algorithim for the steepest-descent method. When $S_k=H^{-1}$, the algorithim is for the Newton-Rhapson method. The above equation of $x_{k+1}$ converges fastest when $S_k=H^{-1}$. Quasi-Newton methods combines the advantages of the steepest-descent and the conjugate-direction methods. They are among the most efficient methods and are used extensively in many applications.

Assume that the difference in successive $x_k$ is $\delta_k=x_{k+1}-x_k$ and the difference in successive gradient is $g_k$ is $\gamma_k=g_{k+1}-g_k$, then we have $\gamma_k=H\delta_k$. The Newton-Rhapson method determines the direction vector as $d_k=-S_kg_k$. The magnitude $\alpha_k$ can be determined by a line search minimizing the function $f(x_k+\alpha d_k)$. Now here we want to avoid inverting a matrix such as computing $S_k=H^{-1}$ and checking that $S_k$ is positive definite in each iteration, rather we simply want an updating rule for $S_{k+1}$ such as $S_{k+1}S_k+C_k$

Here $C_k$ is a $n*n$ correction matrix that can be computed form available data. In any definition of $C_k$, $S_{k+1}$ must satisfy these properties:

1. $S_{k+1}\gamma_k=\delta_k$.

2. Vectors $\{\delta_0,\delta_1,...,\delta_{n-1}\}$ must be conjugate direction vectors.

3. A positive definite $S_k$ must produce a positive definite $S_{k+1}$.

The second property states that the advantages of tyhe conjugat-direction method method applies to Quasi-Newton method. The third method states that the direction vector is valid in each iteration. There are many ways to define $C_k$ and they give rise to different variants of the Quasi-Newton method.

## Rank-One Method

The Rank-Method method is featured by the correction matrix $C_k$ has a unity rank. Now we assume that $S_{k+1}\gamma_k=\delta_k$.

Let $S_{k+1}=S_k\gamma_k+\beta\xi_k\xi_k^T\gamma_k$

And $\gamma^T_k(\delta_k-S_k\gamma_k)=\beta_k\gamma^T_k\xi_k\xi_k^T\gamma_k=\beta_k(\xi^T_k\gamma_k)^2$ $(\delta_k-S_k\gamma_k)(\delta_k-S_k\gamma_k)^T=\beta_k(\xi_k^T\gamma_k)^2\beta_k\xi_k\xi_k^T$

Then we have $\displaystyle \beta_k\xi_k\xi_k^T=\frac{(\delta_k-S_K\gamma_k)(\delta_k-S_k\gamma_k)^T}{\gamma_k^T(\delta_k-S_k\gamma_k)}$

Therefore, $S_{k+1}=S_k+\beta_k\xi_k\xi_k^T$.

There are two problems with this method. First, the positive definite $S_k$ may not give a positive definite $S_{k+1}$. In such a case, the next direction is not a good direction. Second, the denominator in the correction formula may approach or become equal to zero. If that happens, the method breaks down as $S_{k+1}$ is undefined.

## Davidon-Fletcher-Powell Method

The Davidon-Fletcher-Powell (DPF) method is similar to the rank-one method but it has one important advantage, that if the initial matrix $S_0$ s positive definite, then the subsequent matrices are always positive definite. Unlike the Raank-One method, every new direction is a descent direction.

The DPF formula is $\displaystyle S_{k+1}=S_k+\frac{\delta_k\delta_k^T}{\delta_k^T\gamma_k}-\frac{S_k\gamma_k\gamma_k^Ts_k}{\gamma_k^TS_k\gamma_k}$

The correction is an $n*n$ symmetric matrix of rank two.

## Broyden-Fletcher-Goldfarb-Shanno Method

The BFGS method formula is $\displaystyle S_{k+1}=S_k+(1+\frac{\gamma^T_kS_k\gamma_k}{\gamma_k^T\delta_k})\frac{\delta_k\delta_k^T}{\gamma^T_k\delta_k}-\frac{\delta_k\gamma_k^TS_k+S_k\gamma_k\delta_k^T}{\gamma_k^T\delta_k}$

The BFGS method has the following properies:

1. $S_{k+1}$ becomes identical to $H^{-1}$ for $=n-1$.

2. Direction vectors $\{\delta_i\}_{i1,2,...,n-1}$ form a conjugate set.

3. $S_{k+1}$ is the positive definite if $S_k$ is positive definite.

4. $\delta_k^T\gamma_k=\delta^T_kg_{k+1}-\delta^T_kg_k>0$.

BFGS method is the best method among all.

## Huang Family Method

Huang method is a general formula that includes the rank-one, DFP, BFGS, Pearson and McCormick ethods. It has the following form $\displaystyle S_{k+1}=S_k+\frac{\delta_k(\theta\delta_k+\phi S^T_k\gamma_k)^T}{(\theta\delta_k+\phi S^T_k\gamma_k)^T\gamma_k}-\frac{S_k\gamma_k(\psi\delta_k+\omega S^T_k\gamma_k)^T}{(\psi\delta_k+\omega S^T_k\gamma_k)^T\gamma_k}$ $\theta,\, \phi,\, \psi$ and $\omega$ are independent parameters.

By letting $theta=1,\, \phi=-1,\, \psi=1,\, \omega=-1,$ we have the Rank-One formula.

By letting $theta=1,\, \phi=0,\, \psi=0,\, \omega=1,$ we have the DFP formula.

By letting $theta=1,\, \phi=0,\, \psi=1,\, \omega=0,$ we have the McCormick formula: $\displaystyle S_{k+1}=S_k+\frac{(\delta_k-S_k\gamma_k)\delta^T_k}{\delta_k^T\gamma_k}$

By letting $theta=0,\, \phi=1,\, \psi=0,\, \omega=1,$ we have the Pearson Formula: $\displaystyle S_{k+1}=S_k+\frac{(\delta_k-S_k\gamma_k)\gamma_k^TS_k}{\gamma_k^TS_k\gamma_k}$

By letting $\displaystyle \frac{\phi}{\theta}=\frac{-\gamma_k\delta^T_k}{\gamma_k\delta_k^T+\gamma^T_kS_k\gamma_k},\,\psi=1,\, \omega=0,$ we have the BFGS formula.

The following code minimizes the Himmelblau function $f(x_1,x_2)=(x_1^2+x_2-11)^2+(x_1+x_2^2-7)^2$ using different Quasi-Newton methods.

				
//The Himmelblau function:
// f(x) = (x1^2 + x2 - 11)^2 + (x1 + x2^2 - 7)^2

val f: RealScalarFunction f= object : new RealScalarFunction() {
override fun Double evaluate(Vector x) {
double x1 = x.get(1),
double x2 = x.get(2),

double result = pow(x1 * x1 + x2 - 11, 2),
result += 12 * pow(x1 + x2 * x2 - 7, 2),
return result
}
override public int dimensionofDomain() {
return 2
}
override public int dimensionofRange() {
return 1
}
}

val g: RealVectorFunction g = object : new RealVectorFunction() {
override fun evaluate(Vector x): {
double x1 = x.get(1),
double x2 = x.get(2),

double w1 = x1 * x1 + x2 - 11,
double w2 = x1 + x2 * x2 -7,

double[] result = new double,
result = 4 * w1 * x1 + 2 * w2,
result = 2 * w1 + 4 * w2 * x2,
return new DenseVector (result)
}
override public int dimensionofDomain() {
return 2
}
override public int dimensionofRange() {
return 2
}
}

val problem: C2OptimProblem = new C2OptimProblemImpl(f, g)
val solver : QuasiNewtonMinimizer RankOneMinimizer = new RankOneMinimizer(
1e-16,
15)
val soln1: RankOneMinimizer.solve(problem)
val xmin1: soln1.search(new DenseVector(new double[]{6, 6}))
val fmin1= f.evaluate(xmin1)
System.out.println(String.format("f(%s) = %.16f", xmin1.toString(), fmin1))

val solver : QuasiNewtonMinimizer DFPMinimizer = new DFPMinimizer(
1e-16,
15)
val soln2: DFPMinimizer.solve(problem)
val xmin2: soln2.search(new DenseVector(new double[]{6, 6}))
val fmin2= f.evaluate(xmin2)
System.out.println(String.format("f(%s) = %.16f", xmin2.toString(), fmin2))

val solver : QuasiNewtonMinimizer BFGSMinimizer = new BFGSMinimizer(
false,
1e-16,
15)
val soln3: BFGSMinimizer.solve(problem)
val xmin3: soln3.search(new DenseVector(new double[]{6, 6}))
val fmin3= f.evaluate(xmin3)
System.out.println(String.format("f(%s) = %.16f", xmin3.toString(), fmin3))

val solver : QuasiNewtonMinimizer HuangMinimizer = new HuangMinimizer(
0,
1,
0,
1,
1e-16,
15)
val soln4: HuangMinimizer.solve(problem)
val xmin4: soln4.search(new DenseVector(new double[]{6, 6}))
val fmin4= f.evaluate(xmin4)
System.out.println(String.format("f(%s) = %.16f", xmin4.toString(), fmin4))

val solver : QuasiNewtonMinimizer PearsonMinimizer = new PearsonMinimizer(
1e-16,
15)
val soln5: PearsonMinimizer.solve(problem)
val xmin5: soln5.search(new DenseVector(new double[]{6, 6}))
val fmin5= f.evaluate(xmin5)
System.out.println(String.format("f(%s) = %.16f", xmin5.toString(), fmin5))



The output is:

				
f([3.000000, 2.000000]) = 0.000000000000000
f([3.000000, 2.000000]) = 0.000000000000000
f([3.000000, 2.000000]) = 0.000000000000000
f([3.000000, 2.000000]) = 0.000000000000000
f([3.000000, 2.000000]) = 0.000000000000000



The Quasi-Newton methods are much more efficient than any of the Conjugate-Drection methods. They take less iterations than the Conjugate-Direction methods and give etter accuracy and precision.