БлогNot. Основные прямые и итерационные методы решения СЛАУ в MathCAD

Помощь дата->рейтинг Поиск Почта RSS канал Статистика nickolay.info Домой

Основные прямые и итерационные методы решения СЛАУ в MathCAD

Как известно, решение систем линейных алгебраических уравнений (СЛАУ) - весьма распространённый на практике тип задач. Теорию можно почитать по ссылке, а здесь приведём основные расчёты как для прямых (аналитических), так и для итерационных (приближённых) методов решения СЛАУ.

Начнём с прямых. Классический метод обратной матрицы в MathCAD легко реализовать с помощью стандартной функции lsolve или же посредством операции обращения матрицы, код приводить не будем из-за его тривиальности.

Уже двое спросили "а как всё же найти решение методом обратной матрицы?" :)
Введя данные, как на картинке ниже, под данными написать одну из формул x:=A-1*b или x:=lsolve(A,b)
Затем ещё ниже сделать x=

А вот метод Крамера запрограммируем. Элемент вектора решения xi в нём получается в виде дроби, знаменателем которой является определитель матрицы системы, а числителем – определитель матрицы Ai, полученной из исходной заменой i-го столбца столбцом свободных членов b. Для удобства будем во всём документе нумеровать строки и столбцы матриц с единицы, то есть, установим значение системной переменной ORIGIN:=1. Также определим общие для всех методов матрицу и вектор правой части системы:

Определение тестовой СЛАУ
Определение тестовой СЛАУ

Условием существования и единственности решения СЛАУ во всех случаях является условие det A≠0, т.е., определитель матрицы A не равен нулю. Также имеет смысл сделать проверку полученного решения, посчитав значение невязки, равное норме разности векторов A*x (x - найденное решение) и b. В идеале невязка должна быть равной нулю, но из-за неизбежного накопления погрешностей операций над вещественными числами она окажется равна малому числу ε, соответствующему погрешности метода. В MathCAD скалярный оператор "модуль" с панели инструментов калькулятора в применении к разности векторов даст как раз значение невязки, проверим это утверждение на небольшом тесте:

Невязка
Невязка

С учётом всего сказанного, реализуем метод Крамера и проверку полученного решения:

Метод Крамера решения СЛАУ
Метод Крамера решения СЛАУ

В теле функции det - не модуль, а похожая внешне кнопка "Определитель" с панели "Матрицы"!

Классический метод Гаусса с приведением матрицы к верхнему треугольному виду подробно изучается в базовом курсе высшей математики. Реализуем самую простую его разновидность, выбирающую ведущий элемент на главной диагонали матрицы, то есть, работающую в предположении, что значение A1,1,≠0. Так как эта подпрограмма "нулевого" уровня, назовём её Gauss0, а более сложную Gauss напишем отдельно.

Простое программирование метода Гаусса в MathCAD
Простое программирование метода Гаусса в MathCAD

Для удобства вектор правой части b записан как (n+1)-й столбец матрицы A, такую матрицу системы называют расширенной.

Реализация более "полноценного" метода Гаусса с выбором ведущего элемента (и перестановкой при необходимости строк матрицы) выполнена в приложенном к статье документе MathCAD, по крайней мере, систему с нулями на главной диагонали матрицы подпрограмма Gauss решила. Её дополнительный параметр - погрешность ε, начиная с которой значение |Ai,j|<ε считается равным нулю. В случае ошибки (нет решения) подпрограмма возвращает вектор из n значений "бесконечность".

На практике нетрудно увидеть общие для всех прямых методов недостатки подхода - трудоёмкость вычислений, требующая брать обратные матрицы или считать определители, следующее из неё довольно быстрое накопление погрешности, наконец, невозможность найти решение с заранее заданной, а не заложенной в алгоритм точностью.

В определённой мере избежать этих недостатков позволяют итерационные методы, последовательно приближающие решение формулами вида xi(k+1) = f(xi(k)), где k=0,1,... - номер шага, до тех пор, пока выбранная мера разности между двумя соседними векторами приближениямй |x(k+1)-x(k)| не станет меньше заданного малого значения ε. В простейшем случае решение СЛАУ с матрицей размерности 2*2 методом Якоби (он же - метод простых итераций) будет выглядеть так:

Из первого уравнения выразим неизвестное x1, а из второго - x2, получаем систему:
x1 = (b1 - A1,2*x2) / A1,1
x2 = (b2 - A2,1*x1) / A2,2

Все неизвестные значения xi присутствуют и в левой, и в правой частях новых уравнений. Выбрав некоторый вектор начального приближения x(0), посчитаем по нему новое приближение x(1), затем подставим его в правые части уравнений и посчитаем x(2) и т.д. до выполнения условия сходимости. А оно, кстати, довольно просто - метод Якоби сходится, если матрица системы имеет диагональное преобладание, то есть, на главной диагонали находятся наибольшие в своих строках элементы. Наша тестовая матрица уже имеет диагональное преобладание, а в большинстве других случаев этого можно добиться, выполняя преобразования над уравнениями системы, подобные тем, что делает расширенная процедура Gauss.

Выбор вектора начального приближения x(0) на практике также обычно прост, принимают x(0)=b, то есть, вектору правой части системы. Можно и просто "занулить" вектор x(0).

Приходим к следующей процедуре решения:

Решение СЛАУ методом простых итераций (Якоби)
Решение СЛАУ методом простых итераций (Якоби)

Обратите внимание, что нам пришлось "схитрить" при расчёте сумм s1 и s2 - MathCAD просто не сможет вычислить сумму с нижним пределом суммирования =1 и верхним =0 (или нижним n и верхним n-1). По той же причине дополнительные проверки сделаны и в процедуре Gauss.

В основной "бесконечный" цикл подпрограммы имеет смысл добавить аварийный выход оператором break, например, по выполнении 10000 шагов.

Также, в этом и следующем методе в строчке с break точнее был бы критерий выхода |max(x1-x0)|≤ε, где | | - значок модуля числа с панели калькулятора.

Итерационный метод Гаусса-Зейделя отличается от метода простых итераций лишь тем, что для подсчета i–й компоненты (k+1)–го приближения к искомому вектору решения используются уже вычисленные на этом, т.е., (k+1)–м шаге новые значения первых i–1 компонент... а не просто берётся вектор x0 целиком с предыдущего шага. В нашей подпрограмме достаточно заменить x0 на x1 в операторе расчёта суммы s1 :) У меня точность решения на использованном тесте выросла при этом вчетверо.

 Прямые и итерационные методы решения СЛАУ: скачать документ .xmcd в архиве .zip (56 Кб)

P.S. И ещё про прямые "гауссоподобные" методы решения СЛАУ. Если Вам нужно не пошаговое программирование, а достаточно применения стандартных функций, есть способ проще. С помощью стандартной функции augment можно получить расширенную матрицу системы (поставив "рядом" матрицу A и вектор b), а с помощью rref привести матрицу к ступенчатому виду с единичным базисным минором. Потом останется извлечь решение с помощью метода submatrix (последний столбец матрицы, которую вернул метод rref).

Еще один способ решения СЛАУ методом Гаусса в MathCAD
Еще один способ решения СЛАУ методом Гаусса в MathCAD

теги: программирование mathcad

комментарии (1)

21.09.2013, 11:24; рейтинг: 27618

  свежие записипоиск по блогукомментироватьстатистика

Наверх Яндекс.Метрика
© PerS
вход