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 bool CheckEarlyExit( OptVector xNew, OptVector xOld) { OptVector diff = xNew - xOld; double result = 0.0; foreach (var value in diff.MinArray) { result += value * value; } return(result < Precision); }
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)); }
public static OptVector[] Mult(OptVector[] a, OptVector[] b) { OptVector[] result = new OptVector[a.Length]; for (int i = 0; i < a.Length; i++) { double[] v = new double[a.Length]; for (int j = 0; j < a.Length; j++) { v[j] = a[i] * GetColumn(b, j); } result[i] = new OptVector(v); } return(result); }
public static OptVector[] Mult(OptVector a, OptVector b) { OptVector[] result = new OptVector[a.minArray.Length]; for (int i = 0; i < a.minArray.Length; i++) { double[] v = new double[a.minArray.Length]; for (int j = 0; j < a.minArray.Length; j++) { v[j] = a.minArray[i] * b.minArray[j]; } result[i] = new OptVector(v); } return(result); }
public OptVector(OptVector v) { minArray = new double[v.minArray.Length]; Array.Copy(v.minArray, minArray, v.minArray.Length); }