Inheritance: ICloneable
示例#1
0
 public static Vector operator *(Vector v, double multiple)
 {
     Vector vector = new Vector(v.Size);
     for (int index = 0; index < v.Size; index++)
     {
         vector[index] = multiple * v[index];
     }
     return vector;
 }
示例#2
0
 private void UpdateDgvResult(src.Vector_.Vector vec)
 {
     if (this.dgvRightPart.InvokeRequired)
     {
         this.Invoke(new UpdateDgvResultCallback(UpdateDgvResult), new object[] { vec });
     }
     else
     {
         updateDgvResult(vec);
     }
 }
示例#3
0
 private void updateDgvInitial(src.Vector_.Vector vec)
 {
     tabControl1.SelectedIndex = 1;
     ClearDgv(dgvInitial);
     if (vec.Size > maxDrawSize)
     {
         dgvInitial.Rows.Add("Vector is too big to draw");
         return;
     }
     for (var i = 0; i < vec.Size; i++)
     {
         dgvInitial.Rows.Add(vec[i].ToString());
     }
 }
示例#4
0
        private void updateDgvRightPart(src.Vector_.Vector vec)
        {
            tabControl1.SelectedIndex = 0;
            ClearDgv(dgvRightPart);
            if (vec.Size > maxDrawSize)
            {
                dgvRightPart.Rows.Add("Vector is too big to draw");
                return;
            }
            for (var i = 0; i < vec.Size; i++)
            {
                String[] strs = new String[1];
                strs[0] = vec[i].ToString();

                dgvRightPart.Rows.Add(strs);
            }
        }
示例#5
0
        private void updateDgvResult(src.Vector_.Vector vec)
        {
            tabControl1.SelectedIndex = 2;
            ClearDgv(dgvResult);

            if (vec == null)
            {
                return;
            }

            if (vec.Size > maxDrawSize)
            {
                dgvResult.Rows.Add("Vector is too big to draw");
                return;
            }
            for (var i = 0; i < vec.Size; i++)
            {
                dgvResult.Rows.Add(vec[i].ToString());
            }
        }
示例#6
0
        public void TestProfileFormatJacobi()
        {
            int predCoeff = 0;

            Vector expectedAnswer = new Vector(dim);
            for (int i = 0; i < dim; i++)
                expectedAnswer[i] = i + 1;

            var matrix = generateProfileMatrix(predCoeff);
            var rightPart = generateRightPart(matrix, expectedAnswer);

            Jacobi solver = new Jacobi();
            EmptyPreconditioner precond = EmptyPreconditioner.Create(matrix);
            Vector answer = solver.Solve(precond, rightPart, new Vector(dim), Logger.Instance, Logger.Instance, new JacobiParametrs(eps, maxIter));

            Console.Write("Generate complete...\n");
            for (int i = 0; i < dim; i++) {
                Console.Write(expectedAnswer[i].ToString() + "\t" + answer[i].ToString() + "\n");
                Assert.AreEqual(expectedAnswer[i], answer[i], 0.001, "Not equal!");
            }
        }
示例#7
0
 public abstract Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                 ILogger logger,ISolverLogger solverLogger, ISolverParametrs solverParametrs);
 public Vector SSolve(Vector x)
 {
     return lLTmatrix.LSolve(x, true);
 }
示例#9
0
        public override Vector USolve(Vector x, bool UseDiagonal)
        {
            if (x.Size != _count)
                throw new Exception("Несовпадение длин у операндов USolve");

            Vector vector = (Vector)x.Clone();
            if (UseDiagonal)
            {
                for (int row = _count - 1; row >= 0; row--)
                {
                    vector[row] /= _di[row];
                    int start = row - (_ig[row + 1] - _ig[row]);
                    for (int column = _ig[row + 1] - 1, index = row - 1; index >= start; column--, index--)
                        vector[index] -= _au[column] * vector[row];
                }
            }

            else
            {
                for (int row = _count - 1; row >= 0; row--)
                {
                    int start = row - (_ig[row + 1] - _ig[row]);
                    for (int column = _ig[row + 1] - 1, index = row - 1; index >= start; column--, index--)
                        vector[index] -= _au[column] * vector[row];
                }
            }

            return vector;
        }
示例#10
0
 public abstract Vector UtMult(Vector x, bool UseDiagonal);
示例#11
0
        public override Vector UtSolve(Vector x, bool UseDiagonal)
        {
            if (n == x.Size)
            {

                Vector result = (Vector)x.Clone();
                if (UseDiagonal)
                {
                    result[0] /= di[0];
                    // Обработка части al, где есть 0
                    for (int i = 1; i < bandWidth; i++)// обрабатываем i строку
                    {
                        for (int j = bandWidth - i; j < bandWidth; j++)
                            result[i] -= au[i][j] * result[j + i - bandWidth];
                        result[i] /= di[i];
                    }
                    //Обработка без 0
                    for (int i = bandWidth; i < n; i++)
                    {
                        for (int j = i - bandWidth; j < i; j++)
                            result[i] -= au[i][j - i + bandWidth] * result[j];
                        result[i] /= di[i];
                    }
                }
                else
                {
                    // Обработка части al, где есть 0
                    for (int i = 1; i < bandWidth; i++)// обрабатываем i строку
                        for (int j = bandWidth - i; j < bandWidth; j++)
                            result[i] -= au[i][j] * result[j + i - bandWidth];
                    //Обработка без 0
                    for (int i = bandWidth; i < n; i++)
                        for (int j = i - bandWidth; j < i; j++)
                            result[i] -= au[i][j - i + bandWidth] * result[j];
                }

                return result;
            }
            else
                throw new Exception("Ленточный формат: Несовпадение размерностей матрицы и вектора при обратном (T) ходе");
        }
示例#12
0
        public override Vector USolve(Vector x, bool UseDiagonal)
        {
            if (n == x.Size)
            {
                //Vector result = new Vector(n);
                // Разобраться с присваиванием, пока обобщенно написано
                //result =  x;
                Vector result = (Vector) x.Clone();
                if (UseDiagonal)
                {
                    result[n - 1] /= di[n - 1];
                    // без 0
                    for (int i = n - 1; i >= bandWidth; i--)
                    {
                        for (int j = bandWidth - 1; j >= 0; j--)
                            result[i + j - bandWidth] -= au[i][j] * result[i];
                        result[i - 1] /= di[i - 1];
                    }
                    // с 0
                    for (int i = bandWidth - 1; i > 0; i--)
                    {
                        for (int j = bandWidth - 1; j >= bandWidth - i; j--)
                            result[i + j - bandWidth] -= au[i][j] * result[i];
                        result[i - 1] /= di[i - 1];
                    }

                }
                else
                {
                    // без 0
                    for (int i = n - 1; i >= bandWidth; i--)
                        for (int j = bandWidth - 1; j >= 0; j--)
                            result[i + j - bandWidth] -= au[i][j] * result[i];
                    // с 0
                    for (int i = bandWidth - 1; i > 0; i--)
                        for (int j = bandWidth - 1; j >= bandWidth - i; j--)
                            result[i + j - bandWidth] -= au[i][j] * result[i];

                }

                return result;

            }
            else
                throw new Exception("Ленточный формат: Несовпадение размерностей матрицы и вектора при обратном ходе");
        }
示例#13
0
 public static Vector Mult(Vector v1, Vector v2)
 {
     if (v1.Size == v2.Size)
     {
         Vector vector = new Vector(v1.Size);
         for (int index = 0; index < v1.Size; index++)
         {
             vector[index] = v1[index] * v2[index];
         }
         return vector;
     }
     else
         throw new Exception("Несовпадение длин у операндов при умножении векторов");
 }
示例#14
0
 // Возведение каждого элемента вектора в степень -1
 public static Vector Inverse(Vector v)
 {
     Vector vector = new Vector(v.Size);
     for (int index = 0; index < v.Size; index++)
     {
         vector[index] = 1.0 / v[index];
     }
     return vector;
 }
示例#15
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");

            }
        }
示例#16
0
        Vector solveMinSqrProblem(Vector d, Vector[] H, int m)
        {
            int m2 = H.Length;
            Vector result = new Vector(m2);
            Vector[] H_previous, H2;
            Vector d1, d2;
            double ci, si, tmp;

            double[] tmp1, tmp2;
            tmp1 = new double[m];
            tmp2 = new double[m];
            double tmp11, tmp22;

            H_previous = new Vector[m2];
            for (int i = 0; i < m2; i++)
                H_previous[i] = H[i];

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

            d1 = d;//размер m2+1
            d2 = new Vector(m);

            for (int i = 0; i < m; i++)
            {
                tmp = Math.Sqrt(H_previous[i][i] * H_previous[i][i] +
                                            H[i][i + 1] * H[i][i + 1]);
                ci = H_previous[i][i] / tmp;
                si = H[i][i + 1] / tmp;

            #region H_prev=R*H_prev
                //расчитываем заранее элементы строк, где блок синусов-косинусов
                for (int l = 0; l < m; l++)
                {
                    tmp1[l] = H_previous[l][i] * ci + H_previous[l][i + 1] * si;
                    tmp2[l] = -H_previous[l][i] * si + H_previous[l][i + 1] * ci;
                }

                //заполняем строки,где блок синусов-косинусов
                for (int l = 0; l < m; l++)
                {

                    H_previous[l][i] = tmp1[l];
                    H_previous[l][i + 1] = tmp2[l];
                }

            #endregion

            #region d1=R*d1
                //рассчитываем элементы вектора, где блок синусов-косинусов
                tmp11 = d1[i] * ci + d1[i + 1] * si;
                tmp22 = -d1[i] * si + d1[i + 1] * ci;

                //заполняем элементы вектора, где блок синусов-косинусов
                //остальные не изменяются
                d1[i] = tmp11;
                d1[i + 1] = tmp22;
            #endregion
            }

            //исключаем m+1-ю строку и m+1-й элемент
            for (int j = 0; j < m; j++)
            {
                for (int i = 0; i < m; i++)
                    H2[j][i] = H_previous[j][i];
                d2[j] = d1[j];
            }

            //находим неизвестный вектор из СЛАУ H2*result=d2
            for (int i = m - 1; i >= 0; i--)
            {
                result[i] = d2[i];
                for (int j = i + 1; j < m; j++)
                {
                    result[i] -= result[j] * H2[j][i];
                }
                result[i] = result[i] / H2[i][i];
            }
            return result;
        }
示例#17
0
        Vector multiplyMatrixVector(Vector vector, Vector[] matrix)
        {
            int n_lines = matrix[0].Size;
            int n_columns = matrix.Length;
            Vector result = new Vector(n_lines);
            result.Nullify();

            if(vector.Size == n_columns)
            {
                for (int j = 0; j < n_columns; j++)
                    for (int i = 0; i < n_lines; i++)
                        result[i] += matrix[j][i] * vector[j];
            }
            else
                throw new Exception("GMRES: Несовпадение длины вектора и числа столбцов матрицы");

            return result;
        }
示例#18
0
        public override Vector UtSolve(Vector x, bool UseDiagonal)
        {
            if (x.Size != _count)
                throw new Exception("Несовпадение длин у операндов UtSolve");

            Vector vector = new Vector(_count);
            if (UseDiagonal)
            {
                for (int row = 0; row < _count; row++)
                {
                    double sumRow = 0;
                    int index = row - (_ig[row + 1] - _ig[row]);
                    for (int column = _ig[row]; index < row; column++, index++)
                        sumRow += _au[column] * vector[index];
                    vector[row] = (x[row] - sumRow) / _di[row];
                }
            }

            else
            {
                for (int row = 0; row < _count; row++)
                {
                    double sumRow = 0;
                    int index = row - (_ig[row + 1] - _ig[row]);
                    for (int column = _ig[row]; index < row; column++, index++)
                        sumRow += _au[column] * vector[index];
                    vector[row] = x[row] - sumRow;
                }
            }

            return vector;
        }
示例#19
0
        public override Vector UtMult(Vector x, bool UseDiagonal)
        {
            if (x.Size != _count)
                throw new Exception("Несовпадение длин у операндов UtMult");

            Vector vector = new Vector(_count);

            for (int column = 0; column < _count; column++)
            {
                int index = _ig[column];
                for (int row = column - (_ig[column + 1] - index); row < column; row++, index++)
                    vector[column] += _au[index] * x[row];
            }

            if (UseDiagonal)
                for (int index = 0; index < _count; index++)
                    vector[index] += _di[index] * x[index];
            return vector;
        }
示例#20
0
        public override Vector TMultiply(Vector x)
        {
            Vector result = new Vector(n);
            result.Nullify();
            if (n == x.Size)
            {
                // Верхний треугольник
                // Обработка части au, где есть 0
                for (int i = 1; i < bandWidth; i++)// обрабатываем i строку
                    for (int j = bandWidth - i; j < bandWidth; j++)
                        result[i] += au[i][j] * x[j + i - bandWidth];
                //Обработка без 0
                for (int i = bandWidth; i < n; i++)
                    for (int j = i - bandWidth; j < i; j++)
                        result[i] += au[i][j - i + bandWidth] * x[j];

                //Диагональ
                for (int i = 0; i < n; i++)
                    result[i] += di[i] * x[i];

                //Нижний треугольник
                for (int j = 0; j < bandWidth; j++)
                {
                    for (int i = bandWidth - j; i < n; i++)
                        result[i - bandWidth + j] += al[i][j] * x[i];
                }

                return result;
            }
            throw new Exception("Ленточный формат: Несовпадение размерностей матрицы и вектора при умножении(T)");
        }
示例#21
0
        public override Vector UMult(Vector x, bool UseDiagonal)
        {
            if (n == x.Size)
            {
                Vector result = new Vector(n);
                result.Nullify();
                for (int j = 0; j < bandWidth; j++)
                {
                    for (int i = bandWidth - j; i < n; i++)
                        result[i - bandWidth + j] += au[i][j] * x[i];
                }

                if (UseDiagonal)
                {
                    for (int i = 0; i < n; i++)
                        result[i] += di[i] * x[i];
                }

                return result;
            }
            else
                throw new Exception("Ленточный формат: Несовпадение размерностей матрицы и вектора при умножении верхнего треугольника");
        }
示例#22
0
        public object Clone()
        {
            var vec = _vector.Clone() as double[];

            Vector newvec = new Vector(vec);
            return newvec;
        }
示例#23
0
        public override Vector UtMult(Vector x, bool UseDiagonal)
        {
            if (n == x.Size)
            {
                Vector result = new Vector(n);
                result.Nullify();
                if (UseDiagonal)
                {
                    result[0] = di[0] * x[0];
                    // Обработка части al, где есть 0
                    for (int i = 1; i < bandWidth; i++)// обрабатываем i строку
                    {
                        for (int j = bandWidth - i; j < bandWidth; j++)
                            result[i] += au[i][j] * x[j + i - bandWidth];
                        result[i] += di[i] * x[i];
                    }
                    //Обработка без 0
                    for (int i = bandWidth; i < n; i++)
                    {
                        for (int j = i - bandWidth; j < i; j++)
                            result[i] += au[i][j - i + bandWidth] * x[j];
                        result[i] += di[i] * x[i];
                    }
                }
                else
                {
                    // Обработка части al, где есть 0
                    for (int i = 1; i < bandWidth; i++)// обрабатываем i строку
                        for (int j = bandWidth - i; j < bandWidth; j++)
                            result[i] += au[i][j] * x[j + i - bandWidth];
                    //Обработка без 0
                    for (int i = bandWidth; i < n; i++)
                        for (int j = i - bandWidth; j < i; j++)
                            result[i] += au[i][j - i + bandWidth] * x[j];
                }

                return result;
            }
            else
                throw new Exception("Ленточный формат: Несовпадение размерностей матрицы и вектора при умножении верхнего(T) треугольника");
        }
示例#24
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;
            }
        }
示例#25
0
 public abstract Vector TMultiply(Vector x);
示例#26
0
 public override Vector USolve(Vector x, bool UseDiagonal)
 {
     if (x.Size != n)
         throw new Exception("Несовпадение длин у операндов при USolve");
     else
     {
         int i, j;
         Vector v;
         if (UseDiagonal == true)// Деление на динагональ
         {
             v = (Vector)x.Clone();// в смысле копирование элементов
             for (i = n - 1; i >= 0; i--)
             {
                 v[i] /= di[i];
                 for (j = ia[i]; j < ia[i + 1]; j++)
                     v[ja[j]] -= au[j] * v[i];
             }
             return v;
         }
         else// Без деления на диагональ
         {
             v = (Vector)x.Clone();// в смысле копирование элементов
             for (i = n - 1; i >= 0; i--)
                 for (j = ia[i]; j < ia[i + 1]; j++)
                     v[ja[j]] -= au[j] * v[i];
             return v;
         }
     }
 }
示例#27
0
 public abstract Vector UtSolve(Vector x, bool UseDiagonal);
示例#28
0
 public override Vector UtSolve(Vector x, bool UseDiagonal)
 {
     if (x.Size != n)
         throw new Exception("Несовпадение длин у операндов при UtSolve");
     else
     {
         int i, j;
         double result;
         Vector v = new Vector(n);
         if (UseDiagonal == true)// Деление на динагональ
         {
             for (i = 0; i < n; i++)
             {
                 result = 0;
                 for (j = ia[i]; j < ia[i + 1]; j++)
                     result += au[j] * v[ja[j]];
                 v[i] = (x[i] - result) / di[i];
             }
             return v;
         }
         else// Без деления на диагональ
         {
             for (i = 0; i < n; i++)
             {
                 result = 0;
                 for (j = ia[i]; j < ia[i + 1]; j++)
                     result += au[j] * v[ja[j]];
                 v[i] = (x[i] - result);
             }
             return v;
         }
     }
 }
示例#29
0
 public override Vector TMultiply(Vector x)
 {
     if (x.Size != n)
         throw new Exception("Несовпадение длин у операндов при TMultiply");
     else
     {
         int i, j;
         Vector v = new Vector(n);
         for (i = 0; i < n; i++)
         {
             v[i] = di[i] * x[i];
             for (j = ia[i]; j < ia[i + 1]; j++)
             {
                 v[i] += au[j] * x[ja[j]];
                 v[ja[j]] += al[j] * x[i];
             }
         }
         return v;
     }
 }
示例#30
0
 public static Vector operator +(Vector v1, Vector v2)
 {
     if (v1.Size == v2.Size)
     {
         Vector vector = new Vector(v1.Size);
         for (int index = 0; index < v1.Size; index++)
         {
             vector[index] = v1[index] + v2[index];
         }
         return vector;
     }
     else
         throw new Exception("Несовпадение длин у операндов при сложении");
 }
示例#31
0
        public override Vector UtMult(Vector x, bool UseDiagonal)
        {
            if (x.Size != n)
                throw new Exception("Несовпадение длин у операндов при UtMult");
            else
            {
                int i, j;
                Vector v = new Vector(n);
                if (UseDiagonal == true)//  если умножение с диагональю
                {
                    for (i = 0; i < n; i++)
                    {
                        v[i] = di[i] * x[i];
                        for (j = ia[i]; j < ia[i + 1]; j++)
                            v[i] += au[j] * x[ja[j]];
                    }
                    return v;
                }
                else// если без диагонали
                {
                    for (i = 0; i < n; i++)
                        for (j = ia[i]; j < ia[i + 1]; j++)
                            v[i] += au[j] * x[ja[j]];

                    return v;
                }
            }
        }
 public Vector QSolve(Vector x)
 {
     return lLTmatrix.USolve(x, true);
 }
示例#33
0
        public override Vector Solve(IPreconditioner matrix, Vector rightPart, Vector initialSolution,
                                     ILogger logger,  ISolverLogger solverLogger, ISolverParametrs solverParametrs)
        {
            JacobiParametrs JacParametrs = solverParametrs as JacobiParametrs;

            if (JacParametrs != null)
            {
                Vector x, r, diagonal;
                int size, k;
                double relativeResidual, w, rightPartNorm;
                Vector Db, Dx, Lx, Ux, DULx;

                size = initialSolution.Size;
                x = new Vector(size);
                r = new Vector(size);
                diagonal = new Vector(size);

                x = initialSolution;
                w = JacParametrs.Relaxation;
                diagonal = matrix.SourceMatrix.Diagonal;
                rightPartNorm = rightPart.Norm();

                Dx = Vector.Mult(diagonal, x);
                Lx = matrix.SourceMatrix.LMult(x, false);
                Ux = matrix.SourceMatrix.UMult(x, false);
                r = Lx + Dx + Ux - rightPart;
                relativeResidual = r.Norm() / rightPartNorm;

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

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

                Db = Vector.Division(rightPart, diagonal);

                solverLogger.AddIterationInfo(0, relativeResidual);

                for (k = 1; k <= solverParametrs.MaxIterations && relativeResidual > solverParametrs.Epsilon; k++)
                {
                    DULx = Vector.Division(Ux + Lx, diagonal);

                    x = (Db - DULx) * w + x * (1 - w);

                    Dx = Vector.Mult(diagonal, x);
                    Lx = matrix.SourceMatrix.LMult(x, false);
                    Ux = matrix.SourceMatrix.UMult(x, false);
                    r = Lx + Dx + Ux - rightPart;
                    relativeResidual = r.Norm() / rightPartNorm;

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

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

                    solverLogger.AddIterationInfo(k, relativeResidual);
                }

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

            }
        }
 public Vector SMultiply(Vector x)
 {
     return lLTmatrix.LMult(x, true);
 }