public double[] Solve( Func <double[], double> f, double[] startValue, int nIter) { OptVector xOld = new OptVector(startValue); OptVector xNew = new OptVector(); OptVector derivativeOld = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, xOld.MinArray, 1)); OptVector[] oldInvHessian = OptimizationHelper.GetIdentity(startValue.Length); OptVector direction = OptVector.Mult(oldInvHessian, -1.0 * derivativeOld); OptVector derivativeNew = new OptVector(); for (int i = 0; i < nIter; i++) { StepSize = strongWolfeLineSearch.GetStepLength(f, direction, xOld, 4.0, MaxIterLineSearch); OptVector sk = StepSize * direction; xNew = xOld + sk; if (xNew.MinArray.Contains(double.NaN)) { break; } if (EarlyExit && CheckEarlyExit(xNew, xOld)) { break; } derivativeNew = new OptVector(numericalDerivative.EvaluatePartialDerivative(f, xNew.MinArray, 1)); OptVector yk = sk; OptVector[] newInvHessian = GetApproximateInverseHessianMatrix( oldInvHessian, yk, sk); direction = OptVector.Mult(newInvHessian, derivativeNew) * -1.0; xOld = xNew; oldInvHessian = newInvHessian; derivativeOld = derivativeNew; } return(xNew.MinArray); }
private OptVector[] GetApproximateInverseHessianMatrix( OptVector[] invHessian, OptVector yk, OptVector sk) { double denom = yk * sk; OptVector[] skyk = OptVector.Mult(sk, yk); OptVector[] yksk = OptVector.Mult(yk, sk); OptVector[] sksk = OptVector.Mult(sk, sk); OptVector[] v1 = OptVector.SubtractFromIdentity(OptVector.Div(skyk, denom)); OptVector[] v2 = OptVector.SubtractFromIdentity(OptVector.Div(yksk, denom)); OptVector[] v3 = OptVector.Div(sksk, denom); return(OptVector.Sum(OptVector.Mult(OptVector.Mult(v1, invHessian), v2), v3)); }