YAMP.Numerics.GMRESkSolver.Solve C# (CSharp) Method

Solve() public method

Solves the system of linear equations.
public Solve ( MatrixValue b ) : MatrixValue
b MatrixValue The vector b in A * x = b.
return MatrixValue
        public override MatrixValue Solve(MatrixValue b)
        {
            var k = Restart;
            MatrixValue x;

            if (X0 == null)
            {
                X0 = new MatrixValue(b.DimensionY, b.DimensionX);
            }
            else if (X0.DimensionX != b.DimensionX || X0.DimensionY != b.DimensionY)
            {
                throw new YAMPDifferentDimensionsException(X0, b);
            }

            H = new MatrixValue(k + 1, k);
            V = new MatrixValue(X0.DimensionY, k);
            c = new MatrixValue(k - 1, 1);
            s = new MatrixValue(k - 1, 1);
            gamma = new MatrixValue(k + 1, 1);
            var converged = false;

            do
            {
                var j = 0;
                x = X0.Clone();
                var r0 = b - A * x;
                var beta = r0.Abs().Re;

                H.Clear();
                V.Clear();
                gamma.Clear();

                gamma[1] = new ScalarValue(beta);
                c.Clear();
                s.Clear();

                V.SetColumnVector(1, r0 / gamma[1]);

                if (beta < Tolerance)
                {
                    break;
                }

                do
                {
                    j++;
                    i++;

                    var Avj = A * V.GetColumnVector(j);
                    var sum = new MatrixValue(Avj.DimensionY, Avj.DimensionX);

                    for (var m = 1; m <= j; m++)
                    {
                        var w = V.GetColumnVector(m);
                        H[m, j] = w.ComplexDot(Avj);
                        sum += H[m, j] * w;
                    }

                    var wj = Avj - sum;
                    H[j + 1, j] = wj.Abs();
                    Rotate(j);

                    if (H[j + 1, j].AbsSquare() == 0.0)
                    {
                        converged = true;
                        break;
                    }

                    V.SetColumnVector(j + 1, wj / H[j + 1, j]);
                    beta = gamma[j + 1].Abs();

                    if (beta < Tolerance)
                    {
                        converged = true;
                        break;
                    }
                }
                while (j < k);

                var y = new MatrixValue(j, 1);

                for (int l = j; l >= 1; l--)
                {
                    var sum = ScalarValue.Zero;

                    for (var m = l + 1; m <= j; m++)
                    {
                        sum += H[l, m] * y[m];
                    }

                    y[l] = (gamma[l] - sum) / H[l, l];
                }

                for (var l = 1; l <= j; l++)
                {
                    x += y[l] * V.GetColumnVector(l);
                }

                if (converged)
                {
                    break;
                }

                X0 = x;
            }
            while (i < MaxIterations);

            return x;
        }

Usage Example

示例#1
0
        public MatrixValue Function(MatrixValue M, MatrixValue phi)
        {
            if (M.IsSymmetric)
            {
                var cg = new CGSolver(M);
                return cg.Solve(phi);
            }
            else if (M.DimensionX == M.DimensionY && M.DimensionY > 64) // Is there a way to "guess" a good number for this?
            {
                var gmres = new GMRESkSolver(M);
                gmres.Restart = 30;
                return gmres.Solve(phi);
            }

            return M.Inverse() * phi;
        }
All Usage Examples Of YAMP.Numerics.GMRESkSolver::Solve