예제 #1
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                                     ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            if (solverParametrs is LOSParametrs)
            {
                LOSParametrs LOSParametrs = solverParametrs as LOSParametrs;

                Vector x, r, z, p;
                double alpha, betta;
                int    size, k;
                double Residual, pp, rightnorm;
                Vector Ax;
                Vector LAU, Ur;

                size = initialSolution.Size;
                x    = new Vector(size);
                r    = new Vector(size);
                z    = new Vector(size);
                p    = new Vector(size);
                Ax   = new Vector(size);
                LAU  = new Vector(size);
                Ur   = new Vector(size);

                x  = initialSolution;
                Ax = matrix.SourceMatrix.Multiply(x);
                r  = matrix.SSolve(rightPart - Ax);
                z  = matrix.QSolve(r);
                p  = matrix.SSolve(matrix.SourceMatrix.Multiply(z));

                rightnorm = matrix.SSolve(rightPart).Norm();
                Residual  = r.Norm() / rightnorm;

                solverLogger.AddIterationInfo(0, Residual);
                for (k = 1; k <= LOSParametrs.MaxIterations && Residual > LOSParametrs.Epsilon; k++)
                {
                    pp = p * p;

                    alpha = (p * r) / pp;
                    x     = x + z * alpha;
                    r     = r - p * alpha;

                    Ur  = matrix.QSolve(r);
                    LAU = matrix.SourceMatrix.Multiply(Ur);
                    LAU = matrix.SSolve(LAU);

                    betta = -(p * LAU) / pp;
                    z     = Ur + z * betta;
                    p     = LAU + p * betta;

                    Residual = r.Norm() / rightnorm;

                    if (System.Double.IsInfinity(Residual))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by LOS.");
                        return(x);
                    }

                    if (System.Double.IsNaN(Residual))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by LOS.");
                        return(x);
                    }

                    solverLogger.AddIterationInfo(k, Residual);
                }

                return(x);
            }
            else
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GaussSeidel");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GaussSeidel");
            }
        }
예제 #2
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution, ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            MSGParametrs ConGradParametrs = solverParametrs as MSGParametrs;

            if (ConGradParametrs == null)
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in MSG");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in MSG");
            }
            else
            {
                //prestart
                int oIter = 0;
                double alpha, beta, oNev, bNev, scalRO, scaleRN;
                Vector x = initialSolution, rNew, rOld, z, ap, p;
                rOld = rightPart - matrix.SourceMatrix.Multiply(x);
                z = matrix.QSolve(matrix.SSolve(rOld));
                p = z;
                ap = matrix.SourceMatrix.Multiply(p);
                bNev = rightPart.Norm();
                oNev = rOld.Norm() / bNev;
                scalRO = z * rOld;
                //  x = matrix.QSolve(x);
                solverLogger.AddIterationInfo(oIter, oNev);//logger
                if (System.Double.IsInfinity(oNev))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by MSG.");
                    return x;
                }

                if (System.Double.IsNaN(oNev))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by MSG.");
                    return x;
                }
                while (oIter < ConGradParametrs.MaxIterations && oNev > ConGradParametrs.Epsilon)
                {
                    alpha = scalRO / (ap * p);
                    x = x + p * alpha;
                     //if (oIter % 100 == 0)
                     //rNew = matrix.QMultiply(rightPart - matrix.SMultiply(matrix.SourceMatrix.Multiply(x)));
                     //else
                    rNew = rOld - ap * alpha;
                    z = matrix.QSolve(matrix.SSolve(rNew));
                    scaleRN = z * rNew;
                    beta = scaleRN / scalRO;
                    scalRO = scaleRN;
                    p = z + p * beta;
                    ap = matrix.SourceMatrix.Multiply(p);
                    rOld = rNew;
                    oIter++;

                    oNev = rNew.Norm() / bNev;
                    if (System.Double.IsInfinity(oNev))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by MSG.");
                        return x;
                    }

                    if (System.Double.IsNaN(oNev))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by MSG.");
                        return x;
                    }

                    solverLogger.AddIterationInfo(oIter, oNev);//logger
                }
                return x;
            }
        }
예제 #3
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                                     ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            GMRESParameters GMRESParameters = solverParametrs as GMRESParameters;

            if (GMRESParameters != null)
            {
                Vector[] V, H;
                Vector   residual, x, d, z, w, tmp;
                bool     continueCalculations;
                double   epsilon       = GMRESParameters.Epsilon;
                int      m             = GMRESParameters.M;
                int      maxIterations = GMRESParameters.MaxIterations;
                int      n             = rightPart.Size;

                x        = initialSolution;
                residual = rightPart - matrix.SourceMatrix.Multiply(x);
                residual = matrix.SSolve(residual);
                double rightPartNorm = matrix.SSolve(rightPart).Norm();
                double residualNorm  = residual.Norm();

                if (System.Double.IsInfinity(residualNorm / rightPartNorm))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by GMRES.");
                    return(x);
                }

                if (System.Double.IsNaN(residualNorm / rightPartNorm))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by GMRES.");
                    return(x);
                }

                x = matrix.QMultiply(initialSolution);

                V = new Vector[m];
                for (int i = 0; i < m; i++)
                {
                    V[i] = new Vector(n);
                }

                H = new Vector[m];
                for (int i = 0; i < m; i++)
                {
                    H[i] = new Vector(m + 1);
                }

                d = new Vector(m + 1);

                for (int k = 1; k <= maxIterations && residualNorm / rightPartNorm > epsilon; k++)
                {
                    d.Nullify();
                    V[0] = residual * (1.0 / residualNorm);

                    continueCalculations = true;
                    for (int j = 1; j <= m && continueCalculations; j++)
                    {
                        tmp = matrix.QSolve(V[j - 1]);
                        w   = matrix.SSolve(matrix.SourceMatrix.Multiply(tmp));

                        for (int l = 1; l <= j; l++)
                        {
                            H[j - 1][l - 1] = V[l - 1] * w;
                            w = w - V[l - 1] * H[j - 1][l - 1];
                        }

                        H[j - 1][j] = w.Norm();
                        if (Math.Abs(H[j - 1][j]) < 1e-10)
                        {
                            m = j;
                            continueCalculations = false;
                        }
                        else
                        {
                            if (j != m)
                            {
                                V[j] = w * (1.0 / H[j - 1][j]);
                            }
                        }
                    }

                    d[0] = residualNorm;
                    z    = solveMinSqrProblem(d, H, m);
                    x    = x + multiplyMatrixVector(z, V);

                    tmp          = rightPart - matrix.SourceMatrix.Multiply(matrix.QSolve(x));
                    residual     = matrix.SSolve(tmp);
                    residualNorm = residual.Norm();

                    if (System.Double.IsInfinity(residualNorm / rightPartNorm))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by GMRES.");
                        return(x);
                    }

                    if (System.Double.IsNaN(residualNorm / rightPartNorm))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by GMRES.");
                        return(x);
                    }

                    solverLogger.AddIterationInfo(k, residualNorm / rightPartNorm);
                }

                return(matrix.QSolve(x));
            }
            else
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GMRES");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GMRES");
            }
        }
예제 #4
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution, ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            BCGStabParametrs ConGradParametrs = solverParametrs as BCGStabParametrs;

            if (ConGradParametrs == null)
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in BSGStab");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in BSGSTab");
            }
            else
            {
                int    oIter = 0;
                double nPi, oPi, alpha, w, oNev, bNev, betta;
                oPi = alpha = w = 1;
                int    size = rightPart.Size;
                Vector x, r, rTab, s, t, z, sqt, y;
                Vector v = new Vector(size);
                Vector p = new Vector(size);
                v.Nullify();
                p.Nullify();
                x    = initialSolution;
                r    = rightPart - matrix.SourceMatrix.Multiply(x);
                rTab = r;
                bNev = rightPart.Norm();
                oNev = r.Norm() / bNev;
                solverLogger.AddIterationInfo(oIter, oNev);//logger
                if (System.Double.IsInfinity(oNev))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by BSG Stab.");
                    return(x);
                }

                if (System.Double.IsNaN(oNev))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by BSG Stab.");
                    return(x);
                }
                while (oIter < ConGradParametrs.MaxIterations && oNev > ConGradParametrs.Epsilon)
                {
                    nPi   = rTab * r;
                    betta = (nPi / oPi) * (alpha / w);
                    p     = r + (p - v * w) * betta;
                    y     = matrix.QSolve(matrix.SSolve(p));
                    v     = matrix.SourceMatrix.Multiply(y);
                    alpha = nPi / (rTab * v);
                    x     = x + y * alpha;//УТОЧНИТЬ!!!!!!!!!!!!!!!
                    s     = r - v * alpha;
                    if (s.Norm() / bNev < ConGradParametrs.Epsilon)
                    {
                        return(x);
                    }
                    z   = matrix.QSolve(matrix.SSolve(s));
                    t   = matrix.SourceMatrix.Multiply(z);
                    sqt = matrix.QSolve(matrix.SSolve(t));
                    w   = (z * sqt) / (sqt * sqt);
                    x   = x + z * w;//УТОЧНИТЬ!!!!!!!!!!!!!!!!!!!
                    r   = s - t * w;

                    oPi = nPi;
                    oIter++;
                    oNev = r.Norm() / bNev;

                    if (System.Double.IsInfinity(oNev))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by BSG Stab.");
                        return(x);
                    }

                    if (System.Double.IsNaN(oNev))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by BSG Stab.");
                        return(x);
                    }
                    solverLogger.AddIterationInfo(oIter, oNev);//logger
                }

                return(x);
            }
        }
예제 #5
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                                     ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            GMRESParameters GMRESParameters = solverParametrs as GMRESParameters;
            if (GMRESParameters != null)
            {
                Vector[] V, H;
                Vector residual, x, d, z, w, tmp;
                bool continueCalculations;
                double epsilon = GMRESParameters.Epsilon;
                int m = GMRESParameters.M;
                int maxIterations = GMRESParameters.MaxIterations;
                int n = rightPart.Size;

                x = initialSolution;
                residual = rightPart - matrix.SourceMatrix.Multiply(x);
                residual = matrix.SSolve(residual);
                double rightPartNorm = matrix.SSolve(rightPart).Norm();
                double residualNorm = residual.Norm();

                if (System.Double.IsInfinity(residualNorm / rightPartNorm))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by GMRES.");
                    return x;
                }

                if (System.Double.IsNaN(residualNorm / rightPartNorm))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by GMRES.");
                    return x;
                }

                x = matrix.QMultiply(initialSolution);

                V = new Vector[m];
                for (int i = 0; i < m; i++)
                    V[i] = new Vector(n);

                H = new Vector[m];
                for (int i = 0; i < m; i++)
                    H[i] = new Vector(m + 1);

                d = new Vector(m + 1);

                for (int k = 1; k <= maxIterations && residualNorm / rightPartNorm > epsilon; k++)
                {
                    d.Nullify();
                    V[0] = residual * (1.0 / residualNorm);

                    continueCalculations = true;
                    for (int j = 1; j <= m && continueCalculations; j++)
                    {
                        tmp = matrix.QSolve(V[j - 1]);
                        w = matrix.SSolve(matrix.SourceMatrix.Multiply(tmp));

                        for (int l = 1; l <= j; l++)
                        {
                            H[j - 1][l - 1] = V[l - 1] * w;
                            w = w - V[l - 1] * H[j - 1][l - 1];
                        }

                        H[j - 1][j] = w.Norm();
                        if (Math.Abs(H[j - 1][j]) < 1e-10)
                        {
                            m = j;
                            continueCalculations = false;
                        }
                        else
                        {
                            if(j != m)
                                V[j] = w * (1.0 / H[j - 1][j]);
                        }
                    }

                    d[0] = residualNorm;
                    z = solveMinSqrProblem(d, H, m);
                    x = x + multiplyMatrixVector(z, V);

                    tmp = rightPart - matrix.SourceMatrix.Multiply(matrix.QSolve(x));
                    residual = matrix.SSolve(tmp);
                    residualNorm = residual.Norm();

                    if (System.Double.IsInfinity(residualNorm / rightPartNorm))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by GMRES.");
                        return x;
                    }

                    if (System.Double.IsNaN(residualNorm / rightPartNorm))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by GMRES.");
                        return x;
                    }

                    solverLogger.AddIterationInfo(k, residualNorm / rightPartNorm);
                }

                return matrix.QSolve(x);
            }
            else {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GMRES");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GMRES");

            }
        }
예제 #6
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution, ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            BCGStabParametrs ConGradParametrs = solverParametrs as BCGStabParametrs;
            if (ConGradParametrs == null)
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in BSGStab");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in BSGSTab");
            }
            else
            {
                int oIter = 0;
                double nPi, oPi, alpha, w, oNev, bNev, betta;
                oPi = alpha = w = 1;
                int size = rightPart.Size;
                Vector x, r, rTab, s, t, z, sqt, y;
                Vector v = new Vector(size);
                Vector p = new Vector(size);
                v.Nullify();
                p.Nullify();
                x = initialSolution;
                r = rightPart - matrix.SourceMatrix.Multiply(x);
                rTab = r;
                bNev = rightPart.Norm();
                oNev = r.Norm() / bNev;
                solverLogger.AddIterationInfo(oIter, oNev);//logger
                if (System.Double.IsInfinity(oNev))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by BSG Stab.");
                    return x;
                }

                if (System.Double.IsNaN(oNev))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by BSG Stab.");
                    return x;
                }
                while (oIter < ConGradParametrs.MaxIterations && oNev > ConGradParametrs.Epsilon)
                {
                    nPi = rTab * r;
                    betta = (nPi / oPi) * (alpha / w);
                    p = r + (p - v * w) * betta;
                    y= matrix.QSolve(matrix.SSolve(p));
                    v = matrix.SourceMatrix.Multiply(y);
                    alpha = nPi / (rTab * v);
                    x = x + y * alpha;//УТОЧНИТЬ!!!!!!!!!!!!!!!
                    s = r - v * alpha;
                    if (s.Norm() / bNev < ConGradParametrs.Epsilon) return x;
                    z = matrix.QSolve(matrix.SSolve(s));
                    t = matrix.SourceMatrix.Multiply(z);
                    sqt = matrix.QSolve(matrix.SSolve(t));
                    w = (z * sqt) / (sqt * sqt);
                    x = x + z * w;//УТОЧНИТЬ!!!!!!!!!!!!!!!!!!!
                    r = s - t * w;

                    oPi = nPi;
                    oIter++;
                    oNev = r.Norm() / bNev;

                    if (System.Double.IsInfinity(oNev))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by BSG Stab.");
                        return x;
                    }

                    if (System.Double.IsNaN(oNev))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by BSG Stab.");
                        return x;
                    }
                    solverLogger.AddIterationInfo(oIter, oNev);//logger
                }

                return x;
            }
        }
예제 #7
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            if (solverParametrs is LOSParametrs)
            {
                LOSParametrs LOSParametrs = solverParametrs as LOSParametrs;

                Vector x, r, z, p;
                double alpha, betta;
                int size, k;
                double Residual,pp,rightnorm;
                Vector Ax;
                Vector LAU, Ur;

                size = initialSolution.Size;
                x = new Vector(size);
                r = new Vector(size);
                z = new Vector(size);
                p = new Vector(size);
                Ax = new Vector(size);
                LAU = new Vector(size);
                Ur = new Vector(size);

                x = initialSolution;
                Ax = matrix.SourceMatrix.Multiply(x);
                r = matrix.SSolve(rightPart - Ax);
                z = matrix.QSolve(r);
                p = matrix.SSolve(matrix.SourceMatrix.Multiply(z));

                rightnorm = matrix.SSolve(rightPart).Norm();
                Residual = r.Norm()/rightnorm;

                solverLogger.AddIterationInfo(0, Residual);
                for (k = 1; k <= LOSParametrs.MaxIterations && Residual > LOSParametrs.Epsilon; k++)
                {
                    pp = p*p;

                    alpha = (p * r) / pp;
                    x = x + z * alpha;
                    r = r - p * alpha;

                    Ur = matrix.QSolve(r);
                    LAU = matrix.SourceMatrix.Multiply(Ur);
                    LAU = matrix.SSolve(LAU);

                    betta = - (p * LAU) / pp;
                    z = Ur + z * betta;
                    p = LAU + p * betta;

                    Residual = r.Norm() / rightnorm;

                    if (System.Double.IsInfinity(Residual))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by LOS.");
                        return x;
                    }

                    if (System.Double.IsNaN(Residual))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by LOS.");
                        return x;
                    }

                    solverLogger.AddIterationInfo(k, Residual);

                }

                return x;
            }
            else {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GaussSeidel");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in GaussSeidel");

            }
        }
예제 #8
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution, ILogger logger, ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            MSGParametrs ConGradParametrs = solverParametrs as MSGParametrs;

            if (ConGradParametrs == null)
            {
                logger.Error("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in MSG");
                throw new Exception("Incorrect " + solverParametrs.GetType().Name.ToString() + " as a  SolverParametrs in MSG");
            }
            else
            {
                //prestart
                int    oIter = 0;
                double alpha, beta, oNev, bNev, scalRO, scaleRN;
                Vector x = initialSolution, rNew, rOld, z, ap, p;
                rOld   = rightPart - matrix.SourceMatrix.Multiply(x);
                z      = matrix.QSolve(matrix.SSolve(rOld));
                p      = z;
                ap     = matrix.SourceMatrix.Multiply(p);
                bNev   = rightPart.Norm();
                oNev   = rOld.Norm() / bNev;
                scalRO = z * rOld;
                //  x = matrix.QSolve(x);
                solverLogger.AddIterationInfo(oIter, oNev);//logger
                if (System.Double.IsInfinity(oNev))
                {
                    logger.Error("Residual is infinity. It is impossible to solve this SLAE by MSG.");
                    return(x);
                }

                if (System.Double.IsNaN(oNev))
                {
                    logger.Error("Residual is NaN. It is impossible to solve this SLAE by MSG.");
                    return(x);
                }
                while (oIter < ConGradParametrs.MaxIterations && oNev > ConGradParametrs.Epsilon)
                {
                    alpha = scalRO / (ap * p);
                    x     = x + p * alpha;
                    //if (oIter % 100 == 0)
                    //rNew = matrix.QMultiply(rightPart - matrix.SMultiply(matrix.SourceMatrix.Multiply(x)));
                    //else
                    rNew    = rOld - ap * alpha;
                    z       = matrix.QSolve(matrix.SSolve(rNew));
                    scaleRN = z * rNew;
                    beta    = scaleRN / scalRO;
                    scalRO  = scaleRN;
                    p       = z + p * beta;
                    ap      = matrix.SourceMatrix.Multiply(p);
                    rOld    = rNew;
                    oIter++;

                    oNev = rNew.Norm() / bNev;
                    if (System.Double.IsInfinity(oNev))
                    {
                        logger.Error("Residual is infinity. It is impossible to solve this SLAE by MSG.");
                        return(x);
                    }

                    if (System.Double.IsNaN(oNev))
                    {
                        logger.Error("Residual is NaN. It is impossible to solve this SLAE by MSG.");
                        return(x);
                    }

                    solverLogger.AddIterationInfo(oIter, oNev);//logger
                }
                return(x);
            }
        }