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; }
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)); }
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); }
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)); }
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); }
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); }
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); }
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); }
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)); }
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); }
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; }); } }
private static double MaxResidual(Matrix matrix, VectorColumn freeElems, VectorColumn solutions) => Max(new VectorColumn((matrix * solutions - freeElems).ToDoubleArray()));
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); }