Численное решение систем линейных алгебраических уравнений прямыми методами. Вычисление определителя матрицы. Построение обратно. лаба 2. Отчет по лабораторной работе 2 по дисциплине Численный анализ
Скачать 494.57 Kb.
|
Министерство образования и науки Российской Федерации ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «ОРЕНБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ» Факультет математики и информационных технологий Кафедра компьютерной безопасности и математического обеспечения информационных систем ОТЧЕТ по лабораторной работе № 2 по дисциплине «Численный анализ» Численное решение систем линейных алгебраических уравнений прямыми методами. Вычисление определителя матрицы. Построение обратной матрицы Руководитель Канд. физ.-мат. наук, доцент _______________К.Р.Джукашев «_____»________________2021г. Исполнитель студент 18КБ(с)РЗПО _______________С.Ю. Маслабойников «_____»________________2021г. Оренбург 2021 Содержание1 Постановка задачи 3 2 Ход работы 3 2.1 Метод Гаусса 4 2.2 Метод Гаусса с выбором максимального элемента в строке 5 2.3 Метод Гаусса с выбором максимального элемента в столбце 6 2.4 Метод Гаусса с выбором максимального элемента в подматрице 6 2.5 LU метод 7 2.6 6. Оценка погрешности полученного решения по правой части 9 Вывод 10 1 Постановка задачиЦель: освоить алгоритмы прямых методов решения систем линейных алгебраических уравнений, условия их применения, возможности вычисления определителя и построение обратной матрицы. Задание: 2 Ход работыОбозначим: 2.1 Метод ГауссаБыло найдено решение СЛУ методом Гаусса. Программа выводит данные в следующем порядке: в области «Исходная матрица» программа выводит заданную матрицу, столбец свободных членов и результат, представленный нулевым столбцом, так как анализ еще не был проведен; в области «Ответ» программа выводит приведенную к диагональному виду систему уравнений, модифицированный в процессе решения столбец свободных членов, и вектор-столбец решение заданного СЛУ; в области «Погрешность» выводится погрешность для каждого ответа и, вычисленная на их основе, погрешность решения по левой части; 2.2 Метод Гаусса с выбором максимального элемента в строкеВ результате обратного хода полученные результаты подтвердились. 2.3 Метод Гаусса с выбором максимального элемента в столбцеНа основе данного метода были реализованы дополнительные функции нахождения определителя и обратной матрицы с помощью метода Гаусса. Результат вычислений можно видеть в полях «Определитель матрицы А» и «Обратная матрица методом Гаусса». Определитель для заданной матрицы был найден и равен 0,6590612. Обратная матрица была найдена и успешно проверена, умножением на исходную. 2.4 Метод Гаусса с выбором максимального элемента в подматрице2.5 LU методДанный метод подразумевает нахождение L- и U- матриц, таких, что их произведение будет являться исходной матрицей. После вычисления указанных матриц была проведена проверка, по итогу которой подтвердилась правильность их нахождения. После нахождение L- и U- матриц был вычислен вектор-столбец у, являющийся промежуточным вычислением для нахождения корней СЛУ данным методом. После данного шага было вычислено решение системы, которое совпало с показаниями других методов. Была также реализована функция вычисления определителя заданной матрицы. Показание совпали с вычислением методом Гаусса. 2.6 6. Оценка погрешности полученного решения по правой частиДля оценки погрешность полученного решения по правой части воспользуемся формулами: Найдем вектор , где - возмущенная правая часть, которая вычисляется путем подстановки полученного решения в систему , - точное значение правой части.
ВыводПри реализации методов Гаусса и LU-разложения для решения заданной системы получено решение устойчивое по правой части. Приложение using System; using System.Linq; namespace CHISAnal2 { /// /// метод Гаусса /// class GausMethod { public double[,] Matrix { get; private set; } public double[] RightPart { get; private set; } public double[] Answer { get; private set; } private int RowCount; private int ColumCount; public GausMethod(double[,] Matrix, double[] RightPart) { this.RightPart = RightPart.Clone() as double[]; this.Matrix = Matrix.Clone() as double[,]; RowCount = Matrix.GetLength(0); ColumCount = Matrix.GetLength(1); Answer = new double[RowCount]; } private void ModRow(int ModRowIndex) { int NonZeroElementRowIndex = ModRowIndex; if (Matrix[NonZeroElementRowIndex, ModRowIndex].CompareWith(0)) { for (int i = NonZeroElementRowIndex + 1; i < RowCount; i++) { if (Math.Abs(Matrix[i, ModRowIndex]).CompareWith(0)) { NonZeroElementRowIndex = i; break; } } //теперь найден ненулевой элемент ставим его на верхнее место if (NonZeroElementRowIndex != ModRowIndex)//если он нашел такой { double Temp; Temp = RightPart[NonZeroElementRowIndex]; RightPart[NonZeroElementRowIndex] = RightPart[ModRowIndex]; RightPart[ModRowIndex] = Temp; for (int i = 0; i < ColumCount; i++) { Temp = Matrix[NonZeroElementRowIndex, i]; Matrix[NonZeroElementRowIndex, i] = Matrix[ModRowIndex, i]; Matrix[ModRowIndex, i] = Temp; } } else { throw new Exception("Ошибка приведения матрицы!"); } } double del = Matrix[ModRowIndex, ModRowIndex]; RightPart[ModRowIndex] /= del; for (int i = ModRowIndex; i < ColumCount; i++) Matrix[ModRowIndex, i] /= del; } public int SolveMatrix() { if (RowCount != ColumCount) return 1; //нет решения for (int i = 0; i < RowCount - 1; i++) { ModRow(i); for (int j = i + 1; j < RowCount; j++) { double MultElement = Matrix[j, i]; for (int k = i; k < ColumCount; k++) Matrix[j, k] -= Matrix[i, k] * MultElement; RightPart[j] -= RightPart[i] * MultElement; } } ModRow(RowCount - 1); //ищем решение Answer = ReverceStep(RightPart); return 0; } private double[] ReverceStep(double[] RightPart) { double[] Result = new double[RowCount]; for (int i = RowCount - 1; i >= 0; i--) { Result[i] = RightPart[i]; for (int j = RowCount - 1; j > i; j--) Result[i] -= Matrix[i, j] * Result[j]; Result[i] /= Matrix[i, i]; } return Result; } public override String ToString() { String S = ""; for (int i = 0; i < RowCount; i++) { S += "\r\n"; for (int j = 0; j < ColumCount; j++) { S += $"{Math.Round(Matrix[i, j], 3),5}\t"; } S += $"\t\t{Math.Round(RightPart[i], 8),15}"; S += $"\t\t{Math.Round(Answer[i], 8),15}"; } return S; } } /// /// метод Гаусса с выбором ведущего элемента по строке /// class GausMethodMod1 { public double[,] Matrix { get; private set; } public double[] RightPart { get; private set; } public double[] Answer { get; private set; } private string[] Xs; private int RowCount; private int ColumCount; public GausMethodMod1(double[,] Matrix, double[] RightPart) { this.RightPart = RightPart.Clone() as double[]; this.Matrix = Matrix.Clone() as double[,]; RowCount = Matrix.GetLength(0); ColumCount = Matrix.GetLength(1); Answer = new double[RowCount]; Xs = new string[RowCount]; for (int i = 0; i < RowCount; i++) Xs[i] = $"x{i + 1}"; } private void SortColumns(int SortIndex) { double MaxElement = Matrix[SortIndex, SortIndex]; int MaxElementIndex = SortIndex; for (int i = 0; i < ColumCount; i++) { if (Math.Abs(MaxElement) < Math.Abs(Matrix[SortIndex, i])) { MaxElement = Matrix[SortIndex, i]; MaxElementIndex = i; } } //теперь найден максимальный элемент ставим его на первое значимое место if (MaxElementIndex > SortIndex)//если это не первый элемент { string tmp = Xs[MaxElementIndex]; Xs[MaxElementIndex] = Xs[SortIndex]; Xs[SortIndex] = tmp; double Temp; for (int i = 0; i < RowCount; i++) { Temp = Matrix[i, MaxElementIndex]; Matrix[i, MaxElementIndex] = Matrix[i, SortIndex]; Matrix[i, SortIndex] = Temp; } } } public int SolveMatrix() { if (RowCount != ColumCount) return 1; //нет решения for (int i = 0; i < RowCount - 1; i++) { SortColumns(i); for (int j = i + 1; j < RowCount; j++) { if (Matrix[i, i] != 0) //если главный элемент не 0, то производим вычисления { double MultElement = Matrix[j, i] / Matrix[i, i]; for (int k = i; k < ColumCount; k++) Matrix[j, k] -= Matrix[i, k] * MultElement; RightPart[j] -= RightPart[i] * MultElement; } //для нулевого главного элемента просто пропускаем данный шаг } } //ищем решение for (int i = RowCount - 1; i >= 0; i--) { Answer[i] = RightPart[i]; for (int j = RowCount - 1; j > i; j--) Answer[i] -= Matrix[i, j] * Answer[j]; if (Matrix[i, i] == 0) if (RightPart[i] == 0) return 2; //множество решений else return 1; //нет решения Answer[i] /= Matrix[i, i]; } double tmp = Answer[2]; Answer[2] = Answer[3]; Answer[3] = tmp; string tmptm = Xs[2]; Xs[2] = Xs[3]; Xs[3] = tmptm; return 0; } public override String ToString() { String S = ""; for (int i = 0; i < RowCount; i++) { S += "\r\n"; for (int j = 0; j < ColumCount; j++) { S += $"{Math.Round(Matrix[i, j], 3),5}\t"; } S += $"\t\t{Math.Round(RightPart[i], 8),15}"; S += $"\t\t{Xs[i]} = {Math.Round(Answer[i], 8),15}"; } return S; } } /// /// Решение СЛАУ с выбором ведущего элемента в столбце /// class GausMethodMod2 { public double[,] Matrix { get; private set; } public double[,] EMatrix { get; private set; } public double[] RightPart { get; private set; } public double[] Answer { get; private set; } private int RowCount; private int ColumCount; private double determinant = 1; public GausMethodMod2(double[,] Matrix, double[] RightPart) { this.RightPart = RightPart.Clone() as double[]; this.Matrix = Matrix.Clone() as double[,]; RowCount = Matrix.GetLength(0); ColumCount = Matrix.GetLength(1); EMatrix = new double[RowCount, ColumCount]; for (int i = 0; i < RowCount; i++) { EMatrix[i, i] = 1; } Answer = new double[RowCount]; } private void SortRows(int SortIndex) { double MaxElement = Matrix[SortIndex, SortIndex]; int MaxElementIndex = SortIndex; for (int i = SortIndex + 1; i < RowCount; i++) { if (Math.Abs(Matrix[i, SortIndex]) > Math.Abs(MaxElement)) { MaxElement = Matrix[i, SortIndex]; MaxElementIndex = i; } } //теперь найден максимальный элемент ставим его на верхнее место if (MaxElementIndex > SortIndex)//если это не первый элемент { double Temp; Temp = RightPart[MaxElementIndex]; RightPart[MaxElementIndex] = RightPart[SortIndex]; RightPart[SortIndex] = Temp; for (int i = 0; i < ColumCount; i++) { Temp = Matrix[MaxElementIndex, i]; Matrix[MaxElementIndex, i] = Matrix[SortIndex, i]; Matrix[SortIndex, i] = Temp; Temp = EMatrix[MaxElementIndex, i]; EMatrix[MaxElementIndex, i] = EMatrix[SortIndex, i]; EMatrix[SortIndex, i] = Temp; } determinant *= -1; } } public int SolveMatrix() { if (RowCount != ColumCount) return 1; //нет решения for (int i = 0; i < RowCount - 1; i++) { SortRows(i); for (int j = i + 1; j < RowCount; j++) { if (Matrix[i, i] != 0) //если главный элемент не 0, то производим вычисления { double MultElement = Matrix[j, i] / Matrix[i, i]; for (int k = i; k < ColumCount; k++) Matrix[j, k] -= Matrix[i, k] * MultElement; for (int k = 0; k < ColumCount; k++) EMatrix[j, k] -= EMatrix[i, k] * MultElement; RightPart[j] -= RightPart[i] * MultElement; } //для нулевого главного элемента просто пропускаем данный шаг } } //ищем решение Answer = ReverseStep(RightPart); return 0; } private double[] ReverseStep(double[] e) { double[] Result = new double[RowCount]; for (int i = RowCount - 1; i >= 0; i--) { Result[i] = e[i]; for (int j = RowCount - 1; j > i; j--) Result[i] -= Matrix[i, j] * Result[j]; Result[i] /= Matrix[i, i]; } return Result; } public double[,] GetReverseMatrix() { double[,] result = new double[RowCount, RowCount]; for (int i = 0; i < RowCount; i++) { double[] e = new double[RowCount]; for (int j = 0; j < RowCount; j++) e[j] = EMatrix[j, i]; double[] X = ReverseStep(e); for (int j = 0; j < RowCount; j++) result[j, i] = X[j]; } return result; } /// /// метод, осуществляющий поиск определителя матрицы методом Гаусса /// public double MatrixDeterminant() { //находим определитель for (int i = 0; i < RowCount; i++) { determinant *= Matrix[i, i]; } return determinant; } public override String ToString() { String S = ""; for (int i = 0; i < RowCount; i++) { S += "\r\n"; for (int j = 0; j < ColumCount; j++) { S += $"{Math.Round(Matrix[i, j], 3),5}\t"; } S += $"\t\t{Math.Round(RightPart[i], 8),15}"; S += $"\t\t{Math.Round(Answer[i], 8),15}"; } return S; } } /// /// метод Гаусса с выбором ведущего элемента по всей матрице /// class GausMethodMod3 { public double[,] Matrix { get; private set; } public double[] RightPart { get; private set; } public double[] Answer { get; private set; } private string[] Xs; private int RowCount; private int ColumCount; public GausMethodMod3(double[,] Matrix, double[] RightPart) { this.RightPart = RightPart.Clone() as double[]; this.Matrix = Matrix.Clone() as double[,]; RowCount = Matrix.GetLength(0); ColumCount = Matrix.GetLength(1); Answer = new double[RowCount]; Xs = new string[RowCount]; for (int i = 0; i < RowCount; i++) Xs[i] = $"x{i + 1}"; } private void SortRowAndColumns(int SortIndex) { double MaxElement = Matrix[SortIndex, SortIndex]; int MaxElementIndexColl = SortIndex; int MaxElementIndexRow = SortIndex; for (int i = SortIndex; i < RowCount; i++) { for (int j = SortIndex; j < ColumCount; j++) { if (Math.Abs(MaxElement) < Math.Abs(Matrix[i, j])) { MaxElement = Matrix[i, j]; MaxElementIndexColl = j; } } } SortRows(SortIndex, MaxElementIndexColl); SortCollumn(SortIndex, MaxElementIndexRow); } private void SortCollumn(int SortIndex, int MaxIndex) { string tmp = Xs[MaxIndex]; Xs[MaxIndex] = Xs[SortIndex]; Xs[SortIndex] = tmp; double Temp; for (int i = 0; i < RowCount; i++) { Temp = Matrix[i, MaxIndex]; Matrix[i, MaxIndex] = Matrix[i, SortIndex]; Matrix[i, SortIndex] = Temp; } } private void SortRows(int SortIndex, int MaxIndex) { double Temp; Temp = RightPart[MaxIndex]; RightPart[MaxIndex] = RightPart[SortIndex]; RightPart[SortIndex] = Temp; for (int i = 0; i < ColumCount; i++) { Temp = Matrix[MaxIndex, i]; Matrix[MaxIndex, i] = Matrix[SortIndex, i]; Matrix[SortIndex, i] = Temp; } } public int SolveMatrix() { if (RowCount != ColumCount) return 1; //нет решения for (int i = 0; i < RowCount - 1; i++) { SortRowAndColumns(i); for (int j = i + 1; j < RowCount; j++) { if (Matrix[i, i] != 0) //если главный элемент не 0, то производим вычисления { double MultElement = Matrix[j, i] / Matrix[i, i]; for (int k = i; k < ColumCount; k++) Matrix[j, k] -= Matrix[i, k] * MultElement; RightPart[j] -= RightPart[i] * MultElement; } //для нулевого главного элемента просто пропускаем данный шаг } } //ищем решение for (int i = RowCount - 1; i >= 0; i--) { Answer[i] = RightPart[i]; for (int j = RowCount - 1; j > i; j--) Answer[i] -= Matrix[i, j] * Answer[j]; if (Matrix[i, i] == 0) if (RightPart[i] == 0) return 2; //множество решений else return 1; //нет решения Answer[i] /= Matrix[i, i]; } return 0; } public override String ToString() { String S = ""; for (int i = 0; i < RowCount; i++) { S += "\r\n"; for (int j = 0; j < ColumCount; j++) { S += $"{Math.Round(Matrix[i, j], 3),5}\t"; } S += $"\t\t{Math.Round(RightPart[i], 8),15}"; S += $"\t\t{Xs[i]} = {Math.Round(Answer[i], 8),15}"; } return S; } } /// /// LU-алгоритм /// public class LU { public double[,] Matrix { get; private set; } public double[,] LMatrix { get; private set; } public double[,] UMatrix { get; private set; } public double[] RightPart { get; private set; } public double[] VectorY { get; private set; } public double[] Answer { get; private set; } private int ElmtCount; private double Determinant = 1; public LU(double[,] Matrix, double[] RightPart) { ElmtCount = Matrix.GetLength(0); this.RightPart = RightPart.Clone() as double[]; this.Matrix = Matrix.Clone() as double[,]; InitUMatrix(); InitLMatrix(); } private void InitUMatrix() { UMatrix = Matrix.Clone() as double[,]; } private void InitLMatrix() { LMatrix = new double[ElmtCount, ElmtCount]; for (int i = 0; i < ElmtCount; i++) for (int j = i; j < ElmtCount; j++) LMatrix[j, i] = Matrix[j, i] / Matrix[i, i]; } private void FindLAndUMatrix() { for (int k = 1; k < ElmtCount; k++) { for (int i = k - 1; i < ElmtCount; i++) for (int j = i; j < ElmtCount; j++) LMatrix[j, i] = UMatrix[j, i] / UMatrix[i, i]; for (int i = k; i < ElmtCount; i++) for (int j = k - 1; j < ElmtCount; j++) UMatrix[i, j] = UMatrix[i, j] - LMatrix[i, k - 1] * UMatrix[k - 1, j]; } } private double[] FindY() { double[] Result = new double[ElmtCount]; for (int i = 0; i < ElmtCount; i++) { Result[i] = RightPart[i]; for (int j = 0; j < i; j++) Result[i] -= LMatrix[i, j] * Result[j]; Result[i] /= LMatrix[i, i]; } return Result; } private double[] FindX(double[] VectorY) { double[] Result = new double[ElmtCount]; for (int i = ElmtCount - 1; i >= 0; i--) { Result[i] = VectorY[i]; for (int j = ElmtCount - 1; j > i; j--) Result[i] -= UMatrix[i, j] * Result[j]; Result[i] /= UMatrix[i, i]; } return Result; } public void SolveMatrix() { FindLAndUMatrix(); VectorY = FindY(); Answer = FindX(VectorY); } public double[,] GetMul() { double[,] ResMatrix = new double[ElmtCount, ElmtCount]; for (int i = 0; i < ElmtCount; i++) for (int j = 0; j < ElmtCount; j++) for (int k = 0; k < ElmtCount; k++) ResMatrix[i, j] += LMatrix[i, k] * UMatrix[k, j]; return ResMatrix; } public static void ShowMatrix(double[,] Matrix) { for (int i = 0; i < Matrix.GetLength(0); i++) { for (int j = 0; j < Matrix.GetLength(0); j++) { Console.Write($"{Math.Round(Matrix[i, j], 5),10}\t"); } Console.WriteLine(); } } public void ShowYVector() { Console.Write(String.Join("\n", VectorY)); } public void ShowXVector() { Console.Write(String.Join("\n", Answer)); } public double MatrixDeterminant() { //находим определитель for (int i = 0; i < ElmtCount; i++) { Determinant *= UMatrix[i, i]; } return Determinant; } } public static class Extention { public static bool CompareWith(this double val, double other) { return Math.Abs(val - other) < 0.0000001; } } class Program { static double[,] A = { { -1, 0.28, -0.17, 0.06 }, { 0.52, -1, 0.12, 0.17}, { 0.17, -0.18, 0, -0.79}, { 0.11, 0.22, 0.03, -0.95}}; static double[] B = { -21, 117, 0.81, -0.72 }; static void Main() { ShowSimpleGauss(); ShowGaussMode1(); ShowGaussMode2(); ShowGaussMode3(); ShowLU(); Console.ReadLine(); } static void ShowLU() { Console.WriteLine("\n\n\n\n\n\n\nLU РАЗЛОЖЕНИЕ\n\n"); LU lU = new LU(A, B); Console.WriteLine("\n\nИсходная матрица:\n"); LU.ShowMatrix(lU.Matrix); lU.SolveMatrix(); Console.WriteLine("\n\nL матрица:\n"); LU.ShowMatrix(lU.LMatrix); Console.WriteLine("\n\nU матрица:\n"); LU.ShowMatrix(lU.UMatrix); Console.WriteLine("\nПроверка (умножение матриц U и L)\n"); LU.ShowMatrix(lU.GetMul()); Console.WriteLine("\n\n\n"); Console.WriteLine("Вектор y:"); lU.ShowYVector(); Console.WriteLine("\n\n\n"); Console.WriteLine("Вектор x (ответ):"); lU.ShowXVector(); Console.WriteLine("\n\n\nОпределитель:\t" + lU.MatrixDeterminant()); Console.WriteLine("\n\nПогрешность:\n"); CalculateDelta(A, lU.Answer, B); } static void ShowSimpleGauss() { Console.WriteLine("МЕТОД ГАУССА обычный\n\n"); GausMethod gausMethod = new GausMethod(A, B); Console.WriteLine("Исходная матрица:\n" + gausMethod.ToString()); gausMethod.SolveMatrix(); Console.WriteLine("\n\n\n\nОтвет:\n" + gausMethod.ToString()); Console.WriteLine("\n\nПогрешность:\n"); CalculateDelta(A, gausMethod.Answer, B); } static void ShowGaussMode1() { Console.WriteLine("\n\n\n\n\n\n\nМЕТОД ГАУССА с выбором ведущего элемента в строке\n\n"); GausMethodMod1 gausMethod_mod1 = new GausMethodMod1(A, B); Console.WriteLine("Исходная матрица:\n" + gausMethod_mod1.ToString()); gausMethod_mod1.SolveMatrix(); Console.WriteLine("\n\n\n\nОтвет:\n" + gausMethod_mod1.ToString()); Console.WriteLine("\n\nПогрешность:\n"); CalculateDelta(A, gausMethod_mod1.Answer, B); } static void ShowGaussMode2() { Console.WriteLine("\n\n\n\n\n\n\nМЕТОД ГАУССА с выбором ведущего элемента в столбце\n\n"); GausMethodMod2 gausMethod_mod2 = new GausMethodMod2(A, B); Console.WriteLine("Исходная матрица:\n" + gausMethod_mod2.ToString()); gausMethod_mod2.SolveMatrix(); Console.WriteLine("\n\n\n\nОтвет:\n" + gausMethod_mod2.ToString()); Console.WriteLine("\n\n\tОпределитель матрицы А равен: " + gausMethod_mod2.MatrixDeterminant()); Console.WriteLine("\n\nОбратная матрица методом Гаусса:\n\n"); LU.ShowMatrix(gausMethod_mod2.GetReverseMatrix()); Console.WriteLine("\n\nПроверка обратной матрицы:\n\n"); LU.ShowMatrix(MultiplicationMatrix(gausMethod_mod2.GetReverseMatrix(), A)); Console.WriteLine("\n\nПогрешность:\n"); CalculateDelta(A, gausMethod_mod2.Answer, B); Console.WriteLine("\n\n\n\n\n\n\n\n"); } static void ShowGaussMode3() { Console.WriteLine("\n\n\n\n\n\n\nМЕТОД ГАУССА с выбором ведущего элемента по всей матрице\n\n"); GausMethodMod3 gausMethod_mod3 = new GausMethodMod3(A, B); Console.WriteLine("Исходная матрица:\n" + gausMethod_mod3.ToString()); gausMethod_mod3.SolveMatrix(); Console.WriteLine("\n\n\n\nОтвет:\n" + gausMethod_mod3.ToString()); Console.WriteLine("\n\nПогрешность:\n"); CalculateDelta(A, gausMethod_mod3.Answer, B); } static double[,] MultiplicationMatrix(double[,] matrix1, double[,] matrix2) { int height1 = matrix1.GetLength(0); int width1 = matrix1.GetLength(1); int width2 = matrix2.GetLength(1); double[,] result = new double[height1, width2]; for (int i = 0; i < height1; i++) for (int j = 0; j < width2; j++) for (int l = 0; l < width1; l++) result[i, j] += matrix1[i, l] * matrix2[l, j]; return result; } static public void CalculateDelta(double[,] Matrix, double[] Answer, double[] RightPath) { double[] deltas = new double[Matrix.GetLength(0)]; for (int i = 0; i < Matrix.GetLength(0); i++) { deltas[i] = 0; for (int k = 0; k < Answer.GetLength(0); k++) deltas[i] += Matrix[i, k] * Answer[k]; } for (int i = 0; i < Matrix.GetLength(0); i++) deltas[i] -= RightPath[i]; for (int i = 0; i < Matrix.GetLength(0); i++) Console.WriteLine("\t{0}{1} = {2}", "delta", i + 1, deltas[i]); double db = deltas.Max(v => Math.Abs(v)) / RightPath.Max(v => Math.Abs(v)); Console.WriteLine($"\n\n\tПогрешность решения по правой части = {db}"); } } } |