public double GetAlpha(
            OptVector[] A,
            OptVector p,
            double num)
        {
            var denom = p * OptVector.Mult(A, p);

            if (denom == 0.0)
            {
                return(1.0);
            }

            return(num / denom);
        }
        public OptVector Solve(
            OptVector[] A,
            OptVector b,
            OptVector startX,
            int nIter)
        {
            OptVector[] normA = A;
            OptVector   normb = b;

            if (!OptVector.Equals(A, OptVector.Transpose(A)))
            {
                OptVector[] At = OptVector.Transpose(A);
                normA = OptVector.Mult(At, A);
                normb = OptVector.Mult(At, b);
            }

            OptVector rNew  = normb - OptVector.Mult(normA, startX);
            OptVector p     = rNew;
            OptVector x     = new OptVector(startX);
            double    r2Old = rNew * rNew;

            double alpha = 1.0;
            double beta  = 1.0;

            for (int i = 0; i < nIter; i++)
            {
                alpha = GetAlpha(normA, p, r2Old);

                x = x + alpha * p;

                rNew = rNew - alpha * OptVector.Mult(normA, p);

                double r2New = rNew * rNew;

                if (r2New < Precision)
                {
                    return(x);
                }

                beta = GetBeta(r2New, r2Old);

                p = rNew + beta * p;

                r2Old = r2New;
            }

            return(x);
        }
        static void TestFunc()
        {
            OptVector a = new OptVector(new double[] { 1, 2 });
            OptVector b = new OptVector(new double[] { 3, 4 });

            OptVector c = new OptVector(new double[] { 1, 3 });
            OptVector d = new OptVector(new double[] { 4, 7 });

            var res = OptVector.Mult(a, b);

            var res1 = OptVector.SubtractFromIdentity(res);

            var res2 = OptVector.Div(res, 2);

            OptVector[] aa = new OptVector[] { a, b };
            OptVector[] bb = new OptVector[] { c, d };

            var res3 = OptVector.Mult(res, bb);
            var res4 = OptVector.Sum(res, bb);

            var res5 = OptVector.Mult(res, c);
        }
        static void TestCGMethod()
        {
            MINRES   minres = new MINRES();
            CGMethod cg     = new CGMethod();

            OptVector[] A2 = new OptVector[3];
            A2[0] = new OptVector(new double[] { 2, 1, 3 });
            A2[1] = new OptVector(new double[] { 2, 6, 8 });
            A2[2] = new OptVector(new double[] { 6, 8, 18 });

            OptVector b2 = new OptVector(new double[] { 1, 3, 5 });

            var minresSol = minres.Solve(A2, b2, new OptVector(new double[3]), 50);
            var sol2      = cg.Solve(A2, b2, new OptVector(new double[3]), 50);

            OptVector[] A = new OptVector[3];
            A[0] = new OptVector(new double[] { 2, 0, 1 });
            A[1] = new OptVector(new double[] { 1, 6, 0 });
            A[2] = new OptVector(new double[] { 3, 2, 3 });

            OptVector x = new OptVector(new double[] { 2, 5, 7 });

            var sol  = cg.Solve(A, x, new OptVector(new double[3]), 50);
            var solm = minres.Solve(A, x, new OptVector(new double[3]), 50);

            OptVector[] A1 = new OptVector[3];
            A1[0] = new OptVector(new double[] { 3, 1, -6 });
            A1[1] = new OptVector(new double[] { 2, 1, -5 });
            A1[2] = new OptVector(new double[] { 6, -3, 3 });

            OptVector b1 = new OptVector(new double[] { -10, -8, 0 });

            var sol1  = cg.Solve(A1, b1, new OptVector(new double[3]), 200);
            var solm1 = minres.Solve(A1, b1, new OptVector(new double[3]), 200);

            OptVector diff  = b1 - OptVector.Mult(A1, solm1);
            OptVector diff1 = b1 - OptVector.Mult(A1, sol1);
        }
Example #5
0
        private OptVector[] CalculateLagrangianHessian(
            Func <double[], double> lagrangian,
            OptVector[] lagrangianHessian,
            OptVector xNew,
            OptVector xOld,
            OptVector step)
        {
            OptVector s = step;
            OptVector y = new OptVector(numericalDerivative.EvaluatePartialDerivative(lagrangian, xNew.MinArray, 1)) -
                          new OptVector(numericalDerivative.EvaluatePartialDerivative(lagrangian, xOld.MinArray, 1));

            OptVector[] yy = OptVector.Mult(y, y);
            double      ys = y * s;

            OptVector partialDenom = OptVector.Mult(lagrangianHessian, s);

            OptVector[] num   = OptVector.Mult(partialDenom, OptVector.Mult(s, lagrangianHessian));
            double      denom = -1.0 * s * partialDenom;

            #region Positive definiteness

            if (ys < 1E-15)
            {
                double theta = 0.999999;

                OptVector yNew  = new OptVector(y);
                double    ysNew = ys;

                while (ysNew < lambda * s * partialDenom &&
                       theta >= 0.0)
                {
                    yNew = y * theta + (1.0 - theta) * partialDenom;

                    ysNew = yNew * s;

                    theta = theta - 1E-5;
                }

                y  = yNew;
                ys = ysNew;

                yy = OptVector.Mult(y, y);
            }

            #endregion

            if (ys == 0.0)
            {
                if (step.Length() > 0)
                {
                    return(OptVector.GetIdentity(xNew.Count, step));
                }

                return(OptVector.GetIdentity(xNew.Count));
            }

            OptVector[] addParam1 = OptVector.Div(yy, ys);
            OptVector[] addParam2 = OptVector.Div(num, denom);

            return(OptVector.Sum(OptVector.Sum(lagrangianHessian, addParam1), addParam2));
        }
Example #6
0
        public OptVector Solve(
            OptVector[] A,

            OptVector b,
            OptVector startX,
            int nIter)
        {
            OptVector[] symmA = A;
            OptVector   normb = b;

            //Symmetrize matrix
            if (CheckSymmetry)
            {
                OptVector[] At = OptVector.Transpose(A);

                if (!OptVector.Equals(A, At))
                {
                    symmA = OptVector.Mult(At, A);
                    normb = OptVector.Mult(At, b);
                }
            }



            OptVector v0 = new OptVector(b.Count);
            OptVector v1 = normb - OptVector.Mult(symmA, startX);

            double    beta1 = v1.Length();
            double    betaN = 0.0;
            double    n     = beta1;
            double    c0    = 1.0;
            double    c1    = 1.0;
            double    s0    = 0.0;
            double    s1    = 0.0;
            OptVector w0    = new OptVector(v1.Count);
            OptVector w_1   = new OptVector(v1.Count);
            OptVector x     = new OptVector(startX);

            for (int i = 0; i < nIter; i++)
            {
                //Calculate Lanczos Vectors
                OptVector v     = (1.0 / beta1) * v1;
                OptVector Av    = OptVector.Mult(symmA, v);
                double    alpha = v * Av;
                v1    = Av - alpha * v - beta1 * v0;
                betaN = v1.Length();

                //Calculate QR factors
                double lambda = c1 * alpha - c0 * s1 * beta1;
                double p1     = Math.Sqrt(lambda * lambda + betaN * betaN);
                double p2     = s1 * alpha + c0 * c1 * beta1;
                double p3     = s0 * beta1;

                //Calculate New Givens Rotations
                c0 = c1;
                c1 = lambda / p1;

                s0 = s1;
                s1 = betaN / p1;

                //Update Solution
                OptVector w = (1.0 / p1) * (v - p3 * w_1 - p2 * w0);

                x = x + c1 * n * w;
                n = -s1 * n;

                residual = Math.Abs(n);

                if (residual < precisionConst)
                {
                    break;
                }

                beta1 = betaN;
                v0    = v;
                w_1   = w0;
                w0    = w;
            }

            return(x);
        }