LUP-разложение (LUP-декомпозиция) — представление данной матрицы в виде произведения где матрица является нижнетреугольной с единицами на главной диагонали, — верхнетреугольная общего вида, а — т. н. матрица перестановок, получаемая из единичной матрицы путём перестановки строк или столбцов. Такое разложение можно осуществить для любой невырожденной матрицы. LUP-разложение используется для вычисления обратной матрицы по компактной схеме, вычисления решения системы линейных уравнений. По сравнению с алгоритмом LU-разложения алгоритм LUP-разложения может обрабатывать любые невырожденные матрицы и при этом обладает более высокой вычислительной устойчивостью.
Пусть , , . На практике как правило вместо матрицы перестановок P используют вектор перестановок получаемый из вектора путём перестановки элементов соответствующих номерам строк переставляемых в матрице P. Например, если
то так как матрица P получена путём перестановки первой и второй строки.
Вычисление LUP-разложения ведётся в несколько шагов. Пусть матрица C = A. На каждом i-м шаге сначала производится поиск опорного (ведущего) элемента — максимального по модулю элемента среди элементов i-го столбца, находящихся не выше i-й строки, после чего строка с опорным элементом меняется местами с i-й строкой. Одновременно производится такой же обмен в матрице P. При этом, если матрица невырождена, то опорный элемент гарантированно будет отличен от нуля. После этого все элементы текущего i-го столбца, находящиеся ниже i-й строки, делятся на опорный. Далее из всех элементов находящихся ниже i-й строки и i-го столбца (то есть таких что j>i и k>i) вычитается произведение . После этого счётчик i увеличивается на единицу и процесс повторяется пока i<n где n — размерность исходной матрицы. После того как все шаги будут выполнены матрица C будет представлять собой следующую сумму:
Ниже представлен программный код приведённого выше алгоритма на языке C++. Здесь Matrix — некоторый контейнер, поддерживающий операцию индексирования. Обратите внимание, что отсчёт ведётся с нуля, а не с единицы.
voidLUP(constMatrix&A,Matrix&C,Matrix&P){//n - размерность исходной матрицыconstintn=A.Rows();C=A;//загружаем в матрицу P единичную матрицуP=IdentityMatrix();for(inti=0;i<n;i++){//поиск опорного элементаdoublepivotValue=0;intpivot=-1;for(introw=i;row<n;row++){if(fabs(C[row][i])>pivotValue){pivotValue=fabs(C[row][i]);pivot=row;}}if(pivotValue!=0){//меняем местами i-ю строку и строку с опорным элементомP.SwapRows(pivot,i);C.SwapRows(pivot,i);for(intj=i+1;j<n;j++){C[j][i]/=C[i][i];for(intk=i+1;k<n;k++)C[j][k]-=C[j][i]*C[i][k];}}}}//теперь матрица C = L + U - E
Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Алгоритмы: построение и анализ = Introduction to Algorithms / Под ред. И. В. Красикова. — 2-е изд. — М.: Вильямс, 2005. — 1296 с. — ISBN 5-8459-0857-4.