예제 #1
0
        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);
        }
예제 #2
0
        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));
        }