Пример #1
0
        private static void SelectMainElement(SquareMatrix matrix, VectorColumn freeElems, int pos)
        {
            var maxrow = pos;
            var size   = matrix.Size;

            for (int i = pos; i < size; i++)
            {
                if (Abs(matrix[i, pos]) > Abs(matrix[maxrow, pos]))
                {
                    maxrow = i;
                }
            }

            if (maxrow == pos)
            {
                return;
            }

            var temprow = new double[size + 1];

            for (int i = 0; i < size; i++)
            {
                temprow[i]        = matrix[pos, i];
                matrix[pos, i]    = matrix[maxrow, i];
                matrix[maxrow, i] = temprow[i];
            }

            temprow[size]     = freeElems[pos];
            freeElems[pos]    = freeElems[maxrow];
            freeElems[maxrow] = temprow[size];

            return;
        }
Пример #2
0
        public static VectorColumn Calculate(SquareMatrix matrix, VectorColumn freeElems)
        {
            if (matrix.Size != freeElems.Length)
            {
                throw new Exception(
                          "In GaussSolve.Calculate: " +
                          "Size of matrix isn't equal size of free element's vector.");
            }

            var det = matrix.GetDeterminant();

            if (det == 0)
            {
                throw new Exception("Determinant of matrix is 0. The system can't be solved.");
            }
            if (Abs(det) < 1)
            {
                Console.WriteLine("The system is poorly conditioned, solutions can not be calculated accurately.");
            }

            var _matrix    = new SquareMatrix(matrix.ToDoubleArray());
            var _freeElems = new VectorColumn(freeElems.ToDoubleArray());

            ToTriangle(_matrix, _freeElems);
            return(Reverce(_matrix, _freeElems));
        }
Пример #3
0
        public static VectorColumn CalculateClassic(SquareMatrix matrix, VectorColumn freeElems, double allowResidual)
        {
            if (matrix.Size != freeElems.Length)
            {
                throw new Exception(
                          "In SimpleIteration.CalculateClassic: " +
                          "Size of matrix isn't equal size of free element's vector.");
            }

            var det = matrix.GetDeterminant();

            if (det == 0)
            {
                throw new Exception("Determinant of matrix is 0. The system can't be solved.");
            }

            var invMatrix   = matrix.GetInvertibleMatrix();
            var deltaMatrix = GetDeltaMatrix(matrix.Size);
            var D           = invMatrix - deltaMatrix;
            var X           = new VectorColumn(freeElems.Length);

            var alpha = deltaMatrix * matrix;

            var beta = D * freeElems;

            while (MaxResidual(matrix, freeElems, X) > allowResidual)
            {
                X = alpha * X + beta;
            }

            return(X);
        }
Пример #4
0
        private static LSystem BuildSystem(Matrix mainEquations, BoundaryConditions boundaryConditions)
        {
            if (boundaryConditions.first.Length != X.Length + 1 ||
                boundaryConditions.second.Length != X.Length + 1 ||
                mainEquations.Rows != X.Length - 2 ||
                mainEquations.Columns != X.Length + 1)
            {
                throw new ArgumentException();
            }

            SquareMatrix matrix    = new SquareMatrix(X.Length);
            VectorColumn freeElems = new VectorColumn(X.Length);

            for (int row = 1; row < X.Length - 1; row++)
            {
                for (int column = 0; column < X.Length; column++)
                {
                    matrix[row, column] = mainEquations[row - 1, column];
                }
                freeElems[row] = mainEquations[row - 1, X.Length];
            }

            for (int column = 0; column < X.Length; column++)
            {
                matrix[0, column]            = boundaryConditions.first[column];
                matrix[X.Length - 1, column] = boundaryConditions.second[column];
            }

            freeElems[0]            = boundaryConditions.first[X.Length];
            freeElems[X.Length - 1] = boundaryConditions.second[X.Length];

            return(new LSystem(matrix, freeElems));
        }
Пример #5
0
        private static double Max(VectorColumn vector)
        {
            var max = Math.Abs(vector[0]);

            for (int i = 0; i < vector.Length; i++)
            {
                if (Math.Abs(vector[i]) > max)
                {
                    max = Math.Abs(vector[i]);
                }
            }
            return(max);
        }
Пример #6
0
        private static PowerSeries[] BuildSpline_M_i(VectorColumn M)
        {
            PowerSeries[] spline = new PowerSeries[X.Length - 1];

            for (int i = 0; i < X.Length - 1; i++)
            {
                spline[i] =
                    Y[i] * (1 - T(i))
                    + Y[i + 1] * T(i)
                    - H(i) * H(i) * T(i) / 6 * (1 - T(i))
                    * ((2 - T(i)) * M[i] + (1 + T(i)) * M[i + 1]);
            }

            return(spline);
        }
Пример #7
0
        private static PowerSeries[] BuildSpline_m_i(VectorColumn m)
        {
            PowerSeries[] spline = new PowerSeries[X.Length - 1];

            for (int i = 0; i < X.Length - 1; i++)
            {
                spline[i] =
                    Y[i] * (1 - T(i)) * (1 - T(i)) * (1 + 2 * T(i))
                    + Y[i + 1] * T(i) * T(i) * (3 - 2 * T(i))
                    + m[i] * H(i) * T(i) * (1 - T(i)) * (1 - T(i))
                    - m[i + 1] * H(i) * T(i) * T(i) * (1 - T(i));
            }

            return(spline);
        }
Пример #8
0
        private static VectorColumn Reverce(SquareMatrix triangleMatrix, VectorColumn freeElems)
        {
            var size      = triangleMatrix.Size;
            var solutions = new VectorColumn(size);

            for (int i = size - 1; i >= 0; i--)
            {
                double accum = 0.0;
                for (int j = size - 1; j > i; j--)
                {
                    accum += triangleMatrix[i, j] * solutions[j];
                }
                solutions[i] = (freeElems[i] - accum) / triangleMatrix[i, i];
            }
            return(solutions);
        }
Пример #9
0
        public static Spline Calculate_M_i(double[] x, double[] y)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("y", "Array of function's values must has same length as array of arguments.");
            }

            X = x;
            Y = y;

            Matrix             mainEquations      = PrepareEquations_M_i();
            BoundaryConditions boundaryConditions = GetBoundaryConditions_M_i();

            LSystem      system    = BuildSystem(mainEquations, boundaryConditions);
            VectorColumn solutions = Tridiagonal.Calculate(system);

            return(new Spline(BuildSpline_M_i(solutions), X));
        }
Пример #10
0
        public static VectorColumn CalculateZeidel(SquareMatrix smatrix, VectorColumn freeElems, double allowResidual)
        {
            if (smatrix.Size != freeElems.Length)
            {
                throw new Exception(
                          "In SimpleIteration.CalculateZeidel: " +
                          "Size of matrix isn't equal size of free element's vector.");
            }

            var det = smatrix.GetDeterminant();

            if (det == 0)
            {
                throw new Exception("Determinant of matrix is 0. The system can't be solved.");
            }

            var invMatrix   = smatrix.GetInvertibleMatrix();
            var deltaMatrix = GetDeltaMatrix(smatrix.Size);
            var D           = invMatrix - deltaMatrix;
            var X           = new VectorColumn(freeElems.Length);

            var alpha = deltaMatrix * smatrix;

            var beta = D * freeElems;

            while (MaxResidual(smatrix, freeElems, X) > allowResidual)
            {
                for (int i = 0; i < X.Length; i++)
                {
                    var buf = 0.0;
                    for (int j = 0; j < X.Length; j++)
                    {
                        buf += alpha[i, j] * X[j];
                    }
                    X[i] = buf + beta[i];
                }
            }

            return(X);
        }
Пример #11
0
        private static void ToTriangle(SquareMatrix matrix, VectorColumn freeElems)
        {
            var size = matrix.Size;

            for (int i = 0; i < size - 1; i++)
            {
                SelectMainElement(matrix, freeElems, i);

                Parallel.For(i + 1, size, Matrix.options, j => {
                    if (matrix[j, i] == 0)
                    {
                        return;
                    }
                    var cf = matrix[j, i] / matrix[i, i];

                    for (int k = 0; k < size; k++)
                    {
                        matrix[j, k] -= matrix[i, k] * cf;
                    }

                    freeElems[j] -= freeElems[i] * cf;
                });
            }
        }
Пример #12
0
 private static double MaxResidual(Matrix matrix, VectorColumn freeElems, VectorColumn solutions) =>
 Max(new VectorColumn((matrix * solutions - freeElems).ToDoubleArray()));
Пример #13
0
        public static VectorColumn Calculate(SquareMatrix matrix, VectorColumn freeElems)
        {
            if (matrix.Size != freeElems.Length)
            {
                throw new Exception(
                          "In Tridiagonal.Calculate: " +
                          "Size of matrix isn't equal size of free element's vector.");
            }

            var n = freeElems.Length;

            var a = new VectorColumn(n);
            var b = new VectorColumn(n);
            var c = new VectorColumn(n);
            var d = new VectorColumn(n);

            for (int i = 0; i < n; i++)
            {
                if (i > 0)
                {
                    a[i] = matrix[i, i - 1];
                }
                b[i] = -matrix[i, i];
                if (i < n - 1)
                {
                    c[i] = matrix[i, i + 1];
                }
                d[i] = freeElems[i];
            }

            for (int i = 0; i < n; i++)
            {
                if (Abs(b[i]) < Abs(a[i]) + Abs(c[i]))
                {
                    throw new Exception(
                              "In Tridiagonal.Calculate: " +
                              "There is no diagonal domination, the system can't be solved.");
                }
            }

            var xi  = new VectorColumn(n + 1);
            var eta = new VectorColumn(n + 1);

            for (int i = 0; i < n; i++)
            {
                xi[i + 1]  = c[i] / (b[i] - a[i] * xi[i]);
                eta[i + 1] = (a[i] * eta[i] - d[i]) / (b[i] - a[i] * xi[i]);
            }

            var solutions = new VectorColumn(n + 1);

            for (int i = n - 1; i >= 0; i--)
            {
                solutions[i] = xi[i + 1] * solutions[i + 1] + eta[i + 1];
            }

            var _solutions = new VectorColumn(n);

            for (int i = 0; i < n; i++)
            {
                _solutions[i] = solutions[i];
            }

            return(_solutions);
        }