Beispiel #1
0
        public static bool TryFindRootWithJacobianStep(Func <Real[], Real[]> f,
                                                       Real[] initialGuess,
                                                       Real accuracy,
                                                       int maxIterations,
                                                       Real jacobianStepSize,
                                                       out Real[] root)
        {
            DenseVector denseVector1 = new DenseVector(initialGuess);

            Real[]      numArray     = f(initialGuess);
            DenseVector denseVector2 = new DenseVector(numArray);
            Real        num1         = ToReal(denseVector2.L2Norm());

            Matrix <Real> approximateJacobian =
                Broyden.CalculateApproximateJacobian(f, initialGuess, numArray, jacobianStepSize);

            for (int index = 0; index <= maxIterations; ++index)
            {
                DenseVector denseVector3 = (DenseVector)(-approximateJacobian.LU().Solve(denseVector2));
                DenseVector denseVector4 = denseVector1 + denseVector3;
                DenseVector denseVector5 = new DenseVector(f(denseVector4.Values));
                Real        num2         = ToReal(denseVector5.L2Norm());

                if (num2 > num1)
                {
                    Real num3 = num1 * num1;
                    Real num4 = num3 / (num3 + num2 * num2);
                    if (num4 == 0.0)
                    {
                        num4 = ToReal(0.0001);
                    }
                    denseVector3 = num4 * denseVector3;
                    denseVector4 = denseVector1 + denseVector3;
                    denseVector5 = new DenseVector(f(denseVector4.Values));
                    num2         = ToReal(denseVector5.L2Norm());
                }

                if (num2 < accuracy)
                {
                    root = denseVector4.Values;

                    return(true);
                }

                Matrix <Real> matrix =
                    (denseVector5 - denseVector2 - approximateJacobian.Multiply(denseVector3)).ToColumnMatrix()
                    * denseVector3.Multiply(ToReal(1.0) / Math.Pow(ToReal(denseVector3.L2Norm()), ToReal(2.0)))
                    .ToRowMatrix();

                approximateJacobian += matrix;
                denseVector1         = denseVector4;
                denseVector2         = denseVector5;
                num1 = num2;
            }

            root = null;

            return(false);
        }
Beispiel #2
0
 /// <summary>Find a solution of the equation f(x)=0.</summary>
 /// <param name="f">The function to find roots from.</param>
 /// <param name="initialGuess">Initial guess of the root.</param>
 /// <param name="accuracy">Desired accuracy. The root will be refined until the accuracy or the maximum number of iterations is reached.</param>
 /// <param name="maxIterations">Maximum number of iterations. Usually 100.</param>
 /// <param name="root">The root that was found, if any. Undefined if the function returns false.</param>
 /// <returns>True if a root with the specified accuracy was found, else false.</returns>
 public static bool TryFindRoot(Func <Real[], Real[]> f,
                                Real[] initialGuess,
                                Real accuracy,
                                int maxIterations,
                                out Real[] root)
 {
     return(Broyden.TryFindRootWithJacobianStep(f,
                                                initialGuess,
                                                accuracy,
                                                maxIterations,
                                                ToReal(0.0001),
                                                out root));
 }