using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Numerics; using static lab9.MyGauss; namespace lab9 { public class MyMatrix : IEnumerable> { public MyMatrix() { InsideMatrix = new List>(); } public MyMatrix(IEnumerable> matrix) { InsideMatrix = new List>(); foreach (var item in matrix) { InsideMatrix.Add(item.ToList()); } } public int ColumnsCount => InsideMatrix[0].Count(); public int RowsCount => InsideMatrix.Count(); public List> InsideMatrix; public int getRank { get { var _data = Upper(InsideMatrix); int result = 0; foreach (var row in _data) { result += IsItNull(row) ? 1 : 0; } return result; } } ******* static MyMatrix toUp(IEnumerable> matrix) //к верхней треугольной { var _data = new List>(); foreach (var row in matrix) { _data.Add(row.ToList()); } for (int i = 1; i < _data.Count(); ++i) { for (int k = 0; k < i; ++k) { if (_data[k][k] != 0) { var multiplier = _data[i][k] / _data[k][k]; for (int j = 0; j < _data[0].Count; j++) { _data[i][j] -= _data[k][j] * multiplier; } } } } return new MyMatrix(_data); } ******* static MyMatrix toLow(IEnumerable> matrix) //к нижней треугольной { var _data = new List>(); foreach (var row in matrix) { _data.Add(row.ToList()); } for (int i = _data.Count - 2; i >= 0; --i) { for (int k = _data.Count - 1; k > i; --k) { if (_data[k][k] != 0) { var multiplier = _data[i][k] / _data[k][k]; for (int j = 0; j < _data[0].Count; j++) { _data[i][j] -= _data[k][j] * multiplier; } } } } return new MyMatrix(_data); } public static MyMatrix Upper(IEnumerable> matrix) { return toUp(matrix); } public MyMatrix Upper() { return toUp(InsideMatrix); } public MyMatrix Lower() { return toLow(InsideMatrix); } ******* static bool IsItNull(IEnumerable row) { foreach (var elem in row) { if (elem != 0) { return true; } } return false; } public void AddColumn(IEnumerable column) { if (column.Count() != InsideMatrix.Count()) { Console.WriteLine("Размер введеного столбца не совпадает с размером столбца текущей матрицы"); } for (int i = 0; i < InsideMatrix.Count(); ++i) { InsideMatrix[i].Add(column.ElementAt(i)); } } public void AddRow(IEnumerable row) { if (InsideMatrix.Count() != 0 && row.Count() != InsideMatrix[0].Count()) { Console.WriteLine("Размер введеной строки не совпадает с размером строки текущей матрицы"); } InsideMatrix.Add(row.ToList()); } public void Add(params double[] row) { AddRow(row); } public IEnumerator> GetEnumerator() { return InsideMatrix.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return InsideMatrix.GetEnumerator(); } public List this[int index] { get => InsideMatrix[index]; set => InsideMatrix[index] = value; } public double this[int row, int column] { get { return InsideMatrix[row][column]; } set => InsideMatrix[row][column] = value; } } public class MyGauss { public MyMatrix MatrixA; public List VectorB; ******* MyMatrix extMatrix; public MyGauss( MyMatrix inputA, IEnumerable inputB) { MatrixA = inputA; VectorB = new List(inputB); extMatrix = new MyMatrix(MatrixA); extMatrix.AddColumn(inputB); SwapRowsUntilNotNull(); } ******* void SwapRowsUntilNotNull() { int numRows = extMatrix.InsideMatrix.Count; int numCols = extMatrix.InsideMatrix[0].Count; for (int i = 0; i < numRows; i++) { if (extMatrix.InsideMatrix[i][0] != 0) { for (int j = 0; j < numCols; j++) { double temp = extMatrix.InsideMatrix[0][j]; extMatrix.InsideMatrix[0][j] = extMatrix.InsideMatrix[i][j]; extMatrix.InsideMatrix[i][j] = temp; } break; } } } public howManySolutions SoultionsCounter() { if (!(MatrixA.getRank == extMatrix.getRank)) { return howManySolutions.noneSolutions; } if (MatrixA.getRank == MatrixA.ColumnsCount) { return howManySolutions.singleSolution; } return howManySolutions.infiniteSolutions; } public IEnumerable Single() { extMatrix = extMatrix.Upper(); extMatrix = extMatrix.Lower(); for (int i = 0; i < extMatrix.RowsCount; i++) { extMatrix[i][extMatrix.ColumnsCount - 1] /= extMatrix[i][i]; extMatrix[i][i] = 1; } return extMatrix.Select(x => x.Last()); } public MyMatrix Inf() { extMatrix = extMatrix.Upper(); extMatrix = extMatrix.Lower(); for (int i = 0; i < extMatrix.RowsCount; i++) { double val = extMatrix[i][i]; for (int j = 0; j < extMatrix.ColumnsCount; j++) { extMatrix[i][j] /= val * -1 ; } extMatrix[i][extMatrix.InsideMatrix.Count - 1] *= -1; } return extMatrix; } } public enum howManySolutions { noneSolutions, singleSolution, infiniteSolutions } public class mySeidel { public mySeidel(MyMatrix MatrixA, List inputB) { seidelMatrix = MatrixA; seidelBVector = inputB; } public MyMatrix seidelMatrix; public List seidelBVector; public List seidelApprox; public IEnumerable FindSeidel(double eps) { seidelApprox = new List(); for (int i = 0; i < seidelBVector.Count; i++) { double approx; if (seidelMatrix[i, i] == 0) { approx = 0; } else { approx = seidelBVector[i] / seidelMatrix[i, i]; } seidelApprox.Add(approx); } //начальное приближение for (int i = 0; i < seidelApprox.Count; i++) //Свап строк { double maxElement = seidelMatrix[i, i]; int maxIndex = i; for (int j = i + 1; j < seidelApprox.Count; j++) { if (seidelMatrix[j, i] > maxElement) { maxElement = seidelMatrix[j, i]; maxIndex = j; } } if (maxIndex != i) { for (int j = 0; j < seidelApprox.Count; j++) { double temp = seidelMatrix[i, j]; seidelMatrix[i, j] = seidelMatrix[maxIndex, j]; seidelMatrix[maxIndex, j] = temp; } double tempB = seidelBVector[i]; seidelBVector[i] = seidelBVector[maxIndex]; seidelBVector[maxIndex] = tempB; } } var previous = new List(seidelApprox); do //ход Зейделя { previous = new List(seidelApprox); for (int i = 0; i < seidelApprox.Count; ++i) { double sum = 0.0; for (int j = 0; j < seidelApprox.Count; j++) { if (j != i) { sum += seidelMatrix[i, j] * seidelApprox[j]; } } seidelApprox[i] = (seidelBVector[i] - sum) / seidelMatrix[i, i]; } } while (!Norm(seidelApprox, previous, eps)); return seidelApprox; } public static bool Norm(ListcurrentX, ListPreviousX, double eps) { double norm = 0.0; for (int i = 0; i < currentX.Count; i++) { norm += Math.Pow(currentX[i] - PreviousX[i], 2.0); } return Math.Sqrt(norm) < eps; } } class Program { public void MyTask() { Console.WriteLine("Метод Гаусса: "); var infMatrix = new MyMatrix { { 4, 7, 7, 5}, { 1, 5, 3, 6 }, }; var infVectorB = new List { 17, 5 }; var taskMatrix = new MyMatrix { { 1, -2, 16, 0 }, { 10, -1, 0, 1 }, { 0, 12, 1, -1 }, { 0, 2, 0, 16 } }; var taskVectorB = new List { 31, 0, -28, 29 }; var gauss = new MyGauss(taskMatrix, taskMatrix); foreach (var row in taskMatrix) { foreach (var elem in row) { Console.Write($"{elem}\t"); } Console.WriteLine(); } Console.WriteLine(); if (gauss.SoultionsCounter() == howManySolutions.noneSolutions) { Console.WriteLine("СЛАУ решения не имеет"); } else if (gauss.SoultionsCounter() == howManySolutions.singleSolution) { var singleSol = gauss.Single().ToList(); for (int i = 0; i < singleSol.Count(); i++) { Console.Write($"x{i + 1} = {singleSol[i]}"); Console.WriteLine(); } } else if (gauss.SoultionsCounter() == howManySolutions.infiniteSolutions) { var infSol = gauss.Inf(); for (int i = 0; i < infSol.RowsCount; i++) { Console.Write($"x{i + 1} = {-infSol[i][infSol.ColumnsCount - 1]}"); for (int j = 0; j < infSol.ColumnsCount - 1; j++) { double tmp = infSol[i, j]; if ((tmp == 0) || (j == i)) continue; if (tmp > 0) Console.Write(" + "); Console.Write($"{tmp} * x{j + 1}"); } Console.WriteLine(); } } Console.WriteLine(); double eps = 0.001; Console.WriteLine("\n\nМетод Зейделя: "); var seidelMatrix = new MyMatrix { { 1, -2, 16, 0 }, { 10, -1, 0, 1 }, { 0, 12, 1, -1 }, { 0, 2, 0, 16 } }; var seidelVectorB = new List { 31, 0, -28, 29 }; var seidel = new mySeidel(seidelMatrix, seidelVectorB); foreach (var row in seidelMatrix) { foreach (var elem in row) { Console.Write($"{elem}\t"); } Console.WriteLine(); }; Console.WriteLine(); seidel.FindSeidel(eps); foreach (var value in seidel.seidelApprox) { Console.Write($"x{seidel.seidelApprox.IndexOf(value) + 1} = {value}\n"); } } static void Main(string[] args) { Program test = new Program(); test.MyTask(); } } }