Метод Гаусса — Жордана

Материал из testwiki
Перейти к навигации Перейти к поиску

Шаблон:Дзт Метод Гаусса — Жордана (метод полного исключения неизвестных) — метод, который используется для решения квадратных систем линейных алгебраических уравнений, нахождения обратной матрицы, нахождения координат вектора в заданном базисе или отыскания ранга матрицы. Метод является модификацией метода Гаусса. Назван в честь К. Ф. Гаусса и немецкого геодезиста и математика Вильгельма Йордана[1].

Алгоритм

  1. Выбирают первый слева столбец матрицы, в котором есть хоть одно отличное от нуля значение.
  2. Если самое верхнее число в этом столбце ноль, то меняют всю первую строку матрицы с другой строкой матрицы, где в этой колонке нет нуля.
  3. Все элементы первой строки делят на верхний элемент выбранного столбца.
  4. Из оставшихся строк вычитают первую строку, умноженную на первый элемент соответствующей строки, с целью получить первым элементом каждой строки (кроме первой) ноль.
  5. Далее проводят такую же процедуру с матрицей, получающейся из исходной матрицы после вычёркивания первой строки и первого столбца.
  6. После повторения этой процедуры n1 раз получают верхнюю треугольную матрицу
  7. Вычитают из предпоследней строки последнюю строку, умноженную на соответствующий коэффициент, с тем, чтобы в предпоследней строке осталась только 1 на главной диагонали.
  8. Повторяют предыдущий шаг для последующих строк. В итоге получают единичную матрицу и решение на месте свободного вектора (с ним необходимо проводить все те же преобразования).

Расширенный алгоритм для нахождения обратной матрицы

Пусть дано:

A=(a11a12a1na21a22a2nan1an2ann)a110I=(100010001)

Прямой ход (алгоритм образования нулей под главной диагональю)

  • Разделим первую строку матрицы А на a11 получим: a1j1=a1ja11, j — столбец матрицы А.
  • Повторяем действия для матрицы I, по формуле: b1s1=b1sa11, s — столбец матрицы I
Получим:
A=(1a121a1n1a21a22a2nan1an2ann)I=(b11100010001)
  • Будем образовывать 0 в первом столбце : a2j1=a2ja1j1a21 ,, anj1=anja1j1an1
  • Повторяем действия для матрицы І, по формулам : b2s1=b2sb1s1a21 ,, bns1=bnsb1s1an1
Получим:
A=(1a121a1n10a221a2n10an21ann1)I=(b11100b21110bn1101)
  • продолжаем выполнять аналогичные операции, используя формулы : aijk=aijkaiiaijk=aijk1akjkaikk1
при условии, что k=1n,i=k+1n,j=1n
  • Повторяем действия для матрицы І, по формулам : bikk=bikkaiibisk=bisk1bkskaikk1
при условии, что k=1n,i=k+1n,s=1n
Получим :
A=(1a121a1n101a2n2001)I=(b11100b212b2220bn1nbn2nbnnn)

Обратный ход (алгоритм образования нулей над главной диагональю)

Используем формулу: aijk1=aijk1aijkaiki, при условии, что k=n1,i=1k1,j=1n

Повторяем действия для матрицы І, по формуле : bisk1=bisk1biskaiki, при условии, что k=n1,i=1k1,s=1n

Окончательно получаем :

A=(100010001)I=A1

Пример

Для решения следующей системы уравнений:

{a+b+c=04a+2b+c=19a+3b+c=3

Запишем её в виде матрицы 3×4, где последний столбец является свободным членом:

(111|0421|1931|3)

Проведём следующие действия:

  • К строке 2 добавим: −4 × Строку 1.
  • К строке 3 добавим: −9 × Строку 1.

Получим:

(1 1 1|0023|1068|3)
  • К строке 3 добавим: −3 × Строку 2.
  • Строку 2 делим на −2
(111| 00132|12001| 0)
  • К строке 1 добавим: −1 × Строку 3.
  • К строке 2 добавим: −3/2 × Строку 3.
(110| 0010|12001| 0)
  • К строке 1 добавим: −1 × Строку 2.
(100| 12010|12001| 0)

В правом столбце получаем решение:

a=12; b=12; c=0 .

Реализация алгоритма на языке программирования C#

namespace Gauss_Jordan_Method
{
    class Maths
    {
        /// <summary>
        /// Метод Гаусса-Жордана (Обратная матрица)
        /// </summary>
        /// <param name="Matrix">Начальная матрица</param>
        /// <returns></returns>
        public static double[,] GaussJordan(double[,] Matrix)
        {
            int n = Matrix.GetLength(0); //Размерность начальной матрицы

            double[,] xirtaM = new double[n, n]; //Единичная матрица (искомая обратная матрица)
            for (int i = 0; i < n; i++)
                xirtaM[i, i] = 1;

            double[,] Matrix_Big = new double[n, 2*n]; //Общая матрица, получаемая скреплением Начальной матрицы и единичной
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    Matrix_Big[i, j] = Matrix[i, j];
                    Matrix_Big[i, j + n] = xirtaM[i, j];
                }

            //Прямой ход (Зануление нижнего левого угла)
            for (int k = 0; k < n; k++) //k-номер строки
            {
                for (int i = 0; i < 2*n; i++) //i-номер столбца
                    Matrix_Big[k, i] = Matrix_Big[k, i] / Matrix[k, k]; //Деление k-строки на первый член !=0 для преобразования его в единицу
                for (int i = k + 1; i < n; i++) //i-номер следующей строки после k
                {
                    double K = Matrix_Big[i, k] / Matrix_Big[k, k]; //Коэффициент
                    for (int j = 0; j < 2*n; j++) //j-номер столбца следующей строки после k
                        Matrix_Big[i, j] = Matrix_Big[i, j] - Matrix_Big[k, j] * K; //Зануление элементов матрицы ниже первого члена, преобразованного в единицу
                }
                for (int i = 0; i < n; i++) //Обновление, внесение изменений в начальную матрицу
                    for (int j = 0; j < n; j++)
                        Matrix[i, j] = Matrix_Big[i, j];
            }

            //Обратный ход (Зануление верхнего правого угла)
            for (int k = n - 1; k > -1; k--) //k-номер строки
            {
                for (int i = 2*n - 1; i > -1; i--) //i-номер столбца
                    Matrix_Big[k, i] = Matrix_Big[k, i] / Matrix[k, k];
                for (int i = k - 1; i > -1; i--) //i-номер следующей строки после k
                {
                    double K = Matrix_Big[i, k] / Matrix_Big[k, k];
                    for (int j = 2*n - 1; j > -1; j--) //j-номер столбца следующей строки после k
                        Matrix_Big[i, j] = Matrix_Big[i, j] - Matrix_Big[k, j] * K;
                }
            }

            //Отделяем от общей матрицы
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    xirtaM[i, j] = Matrix_Big[i, j + n];

            return xirtaM;        
        }
    }
}

Примечания

Шаблон:Примечания

Литература

Ссылки

Шаблон:Нет сносок Шаблон:Методы решения СЛАУ

  1. Транскрипция фамилии Йордан как «Жордан» является ошибочной, но она общепринята и встречается в большинстве русскоязычных источников.