Министерство образования науки РФ. Высшего профессионального учреждения Тверского государственный технический университет. Кафедра программного обеспечения. Методы вычислений Лабораторная работа №5 1 вариант выполнил студент группы ПИН 1106 Александренков А.Ю. проверил Грязнов Е. Н. Виноградов С. Ю. Тверь,2012 Задание: 1. Напишите программу решения систем линейных алгебраических уравнений методом Гаусса (схема единственного деления). 2. Напишите программу решения систем линейных алгебраических уравнений методом Гаусса с выбором главного элемента по столбцу. 3. Напишите программу решения систем линейных алгебраических уравнений методом вращений. Теория Ме́тод Га́усса — классический метод решения системы линейных алгебраических уравнений (СЛАУ). Это метод последовательного исключения переменных, когда с помощью элементарных преобразований система уравнений приводится к равносильной системе ступенчатого (или треугольного) вида, из которой последовательно, начиная с последних (по номеру) переменных, находятся все остальные переменные Листинг Form. /// <summary> /// Лаб 5 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonLab5Start_Click(object sender, EventArgs e) { int count_x = Convert.ToInt32(numericUpDown1.Value); double[] x = new double[count_x]; double[] b = new double[count_x]; double[,] a = new double[count_x, count_x]; try { for (int i = 0; i < count_x; i++) { for (int j = 0; j < count_x; j++) { if (dataGridViewLab5A.Rows[i].Cells[j].Value != null) a[i, j] = Convert.ToDouble(dataGridViewLab5A.Rows[i].Cells[j].Value); else throw new FormatException(); } } } catch (FormatException) { MessageBox.Show("Неверный формат ввода в матрице 'a'"); return; } try { for (int i = 0; i < count_x; i++) { if (dataGridViewLab5B.Rows[i].Cells[0].Value != null) b[i] = Convert.ToDouble(dataGridViewLab5B.Rows[i].Cells[0].Value); else throw new FormatException(); } } catch (FormatException) { MessageBox.Show("Неверный формат ввода в матрице 'b'"); return; } bool flag = true; if (comboBoxLab5Way.SelectedIndex == 0) { x = Lab5.Gauss_del.get_x(a, b); } else if (comboBoxLab5Way.SelectedIndex == 1) { x = Lab5.GaussGI.Get_X(a, b); } else if (comboBoxLab5Way.SelectedIndex == 2) { x = Lab5.Rotate.Get_X(a, b); } else { flag = false; } if (flag) { for (int i = 0; i < count_x; i++) { dataGridViewLab5X.Rows[i].Cells[0].Value = x[i].ToString(); } } else { MessageBox.Show("Вы не выбрали метод решения!"); } } /// <summary> /// Проверка для лаб 5 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonLab5Control_Click(object sender, EventArgs e) { int count_x = 2; double[] x = new double[count_x]; double[] b = { 1, 4 }; double[,] a = { { 1, 2 }, { 2, 5 } }; for (int i = 0; i < count_x; i++) { for (int j = 0; j < count_x; j++) { dataGridViewLab5A.Rows[i].Cells[j].Value = a[i, j].ToString(); } dataGridViewLab5B.Rows[i].Cells[0].Value = b[i].ToString(); } } Листинг dll. using using using using System; System.Collections.Generic; System.Linq; System.Text; namespace Методы_вычислений { /// <summary> /// Класс лабораторной работы № 5 /// </summary> class Lab5 { /// <summary> /// Класс метода Гаусса с единственным делением /// </summary> public static class Gauss_del { /// <summary> /// Получить массив Х /// </summary> /// <param name="a">массив индексов</param> /// <param name="b">массив значений</param> /// <returns>массив Х</returns> public static double[] get_x(double[,] a, double[] b) { int k = a.GetLength(1); double[] x = new double[k];//размерность Х равна размерности второй размерности А(столбцы) //прямой ход for (int i = 0; i < k; i++) { for (int j = i + 1; j < k; j++) { double q = a[j, i] / a[i, i]; for (int m = 0; m < k; m++) { a[j, m] = a[j, m] - q * a[i, m]; } b[j] = b[j] - b[i] * q; } } //обратный ход for (int i = k - 1; i >= 0; i--) { x[i] = b[i]; for (int j = k - 1; j > i; j--) { x[i] = x[i] - x[j] * a[i, j]; } x[i] /= a[i, i]; } return x; } } /// <summary> /// Класс метода Гаусса с поиском главного элемента (по столбцу) /// </summary> public static class GaussGI { /// <summary> /// Получить массив X /// </summary> /// <param name="a">Массив индексов</param> /// <param name="b">Массив значений уравнений</param> /// <returns>Массив корней</returns> public static double[] Get_X(double[,] a, double[] b) { int k = a.GetLength(1); double[] x = new double[k];//размерность Х равна размерности второй размерности А(столбцы) //прямой ход for (int i = 0; i < k; i++) { //Ищем максимальный элемент double max_value = Math.Abs(a[i, i]); int max_index = i; for (int j = i + 1; j < k; j++) { if (a[j, i] > max_value) { max_value = Math.Abs(a[i, j]); max_index = j; } } //меняем строки местами for (int j = 0; j < k; j++) { double tmp_a = a[i, j]; a[i, j] = a[max_index, j]; a[max_index, j] = tmp_a; } double tmp_b = b[i]; b[i] = b[max_index]; b[max_index] = tmp_b; //зануляем for (int j = { double q for (int { a[j, } i + 1; j < k; j++) = a[j, i] / a[i, i]; m = 0; m < k; m++) m] = a[j, m] - q * a[i, m]; b[j] = b[j] - b[i] * q; } } //Обратный ход for (int i = k - 1; i >= 0; i--) { x[i] = b[i]; for (int j = k - 1; j > i; j--) { x[i] = x[i] - x[j] * a[i, j]; } x[i] /= a[i, i]; } return x; } } /// <summary> /// Класс метода вращений /// </summary> public static class Rotate { /// <summary> /// Получить массив X /// </summary> /// <param name="a">Массив индексов</param> /// <param name="b">Массив значений уравнений</param> /// <returns>Массив корней</returns> public static double[] Get_X(double[,] a, double[] b) { int k = a.GetLength(1); double[] x = new double[k];//размерность Х равна размерности второй размерности А(столбцы) double c, s; //double[,] a2 = new double[k, k]; //double[] b2 = new double[k]; //Вращения for (int i = 0; i < k - 1; i++) { c = a[i, i] / Math.Sqrt(Math.Pow(a[i, i], 2) + Math.Pow(a[i + 1, i], 2)); s = a[i + 1, i] / Math.Sqrt(Math.Pow(a[i, i], 2) + Math.Pow(a[i + 1, i], 2)); double b2; for (int j = i; j < k; j++) { double a2; a2 = a[i, j]; a[i, j] = c * a[i, j] + s * a[i + 1, j]; a[i + 1, j] = -s * a2 + c * a[i + 1, j]; } b2 = b[i]; b[i] = c * b[i] + s * b[i + 1]; b[i + 1] = -s * b2 + c * b[i + 1]; } //Обратный ход for (int i = k - 1; i >= 0; i--) { x[i] = b[i]; for (int j = k - 1; j > i; j--) { x[i] = x[i] - x[j] * a[i, j]; } x[i] /= a[i, i]; } return x; } } } }