В численном анализе и линейной алгебре нижне-верхнее ( LU ) разложение или факторизация разлагает матрицу на множители как произведение нижней треугольной матрицы и верхней треугольной матрицы (см. матричное разложение ). Иногда произведение также включает в себя матрицу перестановки . LU-разложение можно рассматривать как матричную форму исключения Гаусса . Компьютеры обычно решают квадратные системы линейных уравнений , используя LU-разложение, и это также ключевой шаг при обращении матрицы или вычислении определителя матрицы. Разложение LU было введено польским астрономом Тадеушем Банахевичем в 1938 году. [1] Цитата: «Похоже, что Гаусс и Дулитл применяли метод [исключения] только к симметричным уравнениям. Более поздние авторы, например, Эйткен, Банахевич, Дуайер и Краут … подчеркивали использование метода или его вариаций в связи с несимметричными проблемами … Банахевич … видел суть … что основная проблема на самом деле заключается в факторизации матриц, или «разложении», как он ее называл». [2] Иногда его также называют LR- разложением (множители на левые и правые треугольные матрицы).
Пусть A — квадратная матрица. LU-факторизация относится к факторизации A с надлежащим порядком или перестановкой строк и/или столбцов на два множителя — нижнюю треугольную матрицу L и верхнюю треугольную матрицу U :
В нижней треугольной матрице все элементы выше диагонали равны нулю, в верхней треугольной матрице все элементы ниже диагонали равны нулю. Например, для матрицы A размером 3 × 3 ее LU-разложение выглядит так:
Без надлежащего порядка или перестановок в матрице факторизация может не материализоваться. Например, легко проверить (расширив матричное умножение ), что . Если , то по крайней мере один из и должен быть равен нулю, что подразумевает, что либо L , либо U является сингулярным . Это невозможно, если A несингулярна (обратима). Это процедурная проблема. Ее можно устранить, просто переупорядочив строки A так, чтобы первый элемент переставленной матрицы был ненулевым. Та же проблема на последующих этапах факторизации может быть устранена тем же способом; см. базовую процедуру ниже.
Оказывается, что для LU-факторизации достаточно правильной перестановки в строках (или столбцах). LU-факторизация с частичным поворотом (LUP) часто относится к LU-факторизации только с перестановками строк:
где L и U снова являются нижней и верхней треугольными матрицами, а P является матрицей перестановки , которая при умножении слева на A переупорядочивает строки A. Оказывается, что все квадратные матрицы могут быть факторизованы в этой форме, [3] и факторизация численно устойчива на практике. [4] Это делает разложение LUP полезным методом на практике.
LU -разложение с полным поворотом включает перестановки как строк, так и столбцов:
где L , U и P определены как и прежде, а Q — матрица перестановок , которая переупорядочивает столбцы A. [5]
Нижне -диагонально-верхнее (LDU) разложение — это разложение вида
где D — диагональная матрица , а L и U — унитреугольные матрицы , что означает, что все элементы на диагоналях L и U равны единице.
Выше мы потребовали, чтобы A была квадратной матрицей, но все эти разложения можно обобщить и на прямоугольные матрицы. [6] В этом случае L и D являются квадратными матрицами, обе из которых имеют то же количество строк, что и A , а U имеет точно такие же размеры, как A . Верхний треугольный следует интерпретировать как имеющий только нулевые элементы ниже главной диагонали, которая начинается в верхнем левом углу. Аналогично, более точным термином для U является то, что это ступенчатая форма строк матрицы A .
Разложим на множители следующую матрицу 2х2:
Один из способов найти LU-разложение этой простой матрицы — просто решить линейные уравнения путем проверки. Расширение умножения матриц дает
Эта система уравнений недоопределена . В этом случае любые два ненулевых элемента матриц L и U являются параметрами решения и могут быть произвольно установлены в любое ненулевое значение. Поэтому, чтобы найти уникальное LU-разложение, необходимо наложить некоторое ограничение на матрицы L и U. Например, мы можем удобно потребовать, чтобы нижняя треугольная матрица L была единичной треугольной матрицей, так что все элементы ее главной диагонали были установлены в единицу. Тогда система уравнений имеет следующее решение:
Подстановка этих значений в LU-разложение выше дает
Любая квадратная матрица допускает факторизацию LUP и PLU . [3] Если обратима , то она допускает факторизацию LU (или LDU ) тогда и только тогда, когда все ее ведущие главные миноры [7] ненулевые [8] (например, не допускает факторизацию LU или LDU ). Если является вырожденной матрицей ранга , то она допускает факторизацию LU , если первые ведущие главные миноры ненулевые, хотя обратное неверно. [9]
Если квадратная обратимая матрица имеет LDU (факторизацию со всеми диагональными элементами L и U, равными 1), то факторизация уникальна. [8] В этом случае LU- факторизация также уникальна, если мы требуем, чтобы диагональ (или ) состояла из единиц.
В общем случае любая квадратная матрица может иметь одно из следующих свойств:
В случае 3 можно приблизиться к LU-факторизации, изменив диагональный элемент на , чтобы избежать нулевого ведущего главного минора. [10]
Если A — симметричная (или эрмитова , если A — комплексная) положительно определенная матрица , мы можем устроить так, чтобы U было сопряженной транспонированной матрицей L. То есть мы можем записать A как
Это разложение называется разложением Холецкого . Если положительно определено, то разложение Холецкого существует и является единственным. Более того, вычисление разложения Холецкого более эффективно и численно более устойчиво, чем вычисление некоторых других LU-разложений.
Для (не обязательно обратимой) матрицы над любым полем известны точные необходимые и достаточные условия, при которых она имеет LU-факторизацию. Условия выражаются в терминах рангов определенных подматриц. Алгоритм исключения Гаусса для получения LU-разложения также был распространен на этот наиболее общий случай. [11]
Когда факторизация LDU существует и является уникальной, существует закрытая (явная) формула для элементов L , D и U в терминах отношений определителей определенных подматриц исходной матрицы A . [12] В частности, , а для , является отношением -й главной подматрицы к -й главной подматрице. Вычисление определителей является вычислительно затратным , поэтому эта явная формула не используется на практике.
Следующий алгоритм по сути является модифицированной формой исключения Гаусса . Вычисление разложения LU с использованием этого алгоритма требует операций с плавающей точкой, игнорируя члены низшего порядка. Частичный поворот добавляет только квадратичный член; это не относится к полному повороту. [13]
Для матрицы N × N определите как исходную, неизмененную версию матрицы . Верхний индекс в скобках (например, ) матрицы — это версия матрицы. Матрица — это матрица, в которой элементы ниже главной диагонали уже были исключены до 0 посредством исключения Гаусса для первых столбцов.
Ниже приведена матрица, которая поможет нам запомнить обозначения (где каждое представляет собой любое действительное число в матрице):
В ходе этого процесса мы постепенно изменяем матрицу с помощью строчных операций, пока она не станет матрицей , в которой все элементы ниже главной диагонали равны нулю. В ходе этого мы одновременно создадим две отдельные матрицы и , такие, что .
Мы определяем окончательную матрицу перестановки как единичную матрицу, в которой все те же строки поменялись местами в том же порядке, что и в матрице, пока она преобразуется в матрицу . Для нашей матрицы мы можем начать с обмена строк, чтобы обеспечить желаемые условия для n-го столбца. Например, мы можем поменять строки, чтобы выполнить частичное поворотное преобразование, или мы можем сделать это, чтобы установить поворотный элемент на главной диагонали на ненулевое число, чтобы мы могли завершить исключение Гаусса.
Для нашей матрицы мы хотим установить каждый элемент ниже на ноль (где — элемент в n-м столбце главной диагонали). Мы обозначим каждый элемент ниже как (где ). Чтобы установить на ноль, мы устанавливаем для каждой строки . Для этой операции . После того как мы выполнили операции над строками для первых столбцов, мы получили верхнюю треугольную матрицу , которая обозначается как .
Мы также можем создать нижнюю треугольную матрицу, обозначенную как , путем непосредственного ввода ранее вычисленных значений с помощью приведенной ниже формулы.
Если нам дана матрица, мы выберем реализацию частичного поворота и, таким образом, поменяем местами первую и вторую строки, так что наша матрица и первая итерация нашей матрицы соответственно станут После того, как мы поменяли местами строки, мы можем исключить элементы ниже главной диагонали в первом столбце, выполнив следующее: После того, как эти строки были вычтены, мы получили из матрицы Поскольку мы реализуем частичный поворот, мы меняем местами вторую и третью строки нашей производной матрицы и текущую версию нашей матрицы соответственно, чтобы получить Теперь мы исключаем элементы ниже главной диагонали во втором столбце, выполнив следующее : Поскольку в нашей текущей итерации ниже главной диагонали нет ненулевых элементов , это вычитание строк выводит нашу окончательную матрицу (обозначаемую как ) и окончательную матрицу: После того, как мы также поменяли местами соответствующие строки, мы получаем нашу окончательную матрицу: Теперь эти матрицы имеют такое отношение, что .
Если бы мы вообще не меняли строки во время этого процесса, мы могли бы выполнять операции над строками одновременно для каждого столбца , установив , где — единичная матрица N × N , в которой ее n -й столбец заменен транспонированным вектором . Другими словами, нижняя треугольная матрица
Выполнение всех операций над строками для первых столбцов с использованием формулы эквивалентно нахождению разложения Обозначим так, что .
Теперь давайте вычислим последовательность . Мы знаем, что имеет следующую формулу.
Если есть две нижние треугольные матрицы с 1 на главной диагонали, и ни одна из них не имеет ненулевого элемента под главной диагональю в том же столбце, что и другая, то мы можем включить все ненулевые элементы в их том же месте в произведение двух матриц. Например:
Наконец, перемножаем и генерируем объединенную матрицу, обозначенную как (как упоминалось ранее). Используя матрицу , получаем
Очевидно, что для того, чтобы этот алгоритм работал, необходимо иметь на каждом шаге (см. определение ). Если это предположение в какой-то момент не выполняется, необходимо поменять n -ю строку на другую строку ниже, прежде чем продолжить. Вот почему LU-разложение в общем случае выглядит как .
Обратите внимание, что разложение, полученное с помощью этой процедуры, является разложением Дулиттла : главная диагональ L состоит исключительно из 1 s. Если бы мы продолжили удалять элементы выше главной диагонали, добавляя кратные столбцам ( вместо удаления элементов ниже диагонали, добавляя кратные строкам ) , мы бы получили разложение Краута , где главная диагональ U состоит из 1 s.
Другой (эквивалентный) способ получения разложения Краута заданной матрицы A состоит в получении разложения Дулиттла транспонированной матрицы A. Действительно, если — LU-разложение, полученное с помощью алгоритма, представленного в этом разделе, то, взяв и , мы получим , — разложение Краута.
Кормен и др. [14] описывают рекурсивный алгоритм для разложения LUP.
Дана матрица A , пусть P 1 — матрица перестановок такая, что
где , если в первом столбце A есть ненулевая запись ; или взять P 1 как единичную матрицу в противном случае. Теперь пусть , если ; или в противном случае. Мы имеем
Теперь мы можем рекурсивно найти LUP-разложение . Пусть . Поэтому
что является LUP - разложением A.
Можно найти приближение низкого ранга к разложению LU с помощью рандомизированного алгоритма. При наличии входной матрицы и желаемого низкого ранга рандомизированный LU возвращает матрицы перестановок и нижние/верхние трапециевидные матрицы размера и соответственно, такие, что с высокой вероятностью , где — константа, зависящая от параметров алгоритма, а — -ое сингулярное значение входной матрицы . [15]
Если две матрицы порядка n можно умножить за время M ( n ), где M ( n ) ≥ n a для некоторого a > 2, то LU-разложение можно вычислить за время O( M ( n )). [16] Это означает, например, что существует алгоритм O( n 2,376 ), основанный на алгоритме Копперсмита–Винограда .
Были разработаны специальные алгоритмы для факторизации больших разреженных матриц . Эти алгоритмы пытаются найти разреженные множители L и U. В идеале стоимость вычислений определяется количеством ненулевых элементов, а не размером матрицы.
Эти алгоритмы используют свободу обмена строками и столбцами для минимизации заполнения (записей, которые изменяются с начального нуля на ненулевое значение во время выполнения алгоритма).
Общую трактовку упорядочений, минимизирующих заполнение, можно осуществить с помощью теории графов .
Дана система линейных уравнений в матричной форме
мы хотим решить уравнение для x , учитывая A и b . Предположим, что мы уже получили LUP-разложение A , такое что , поэтому .
В этом случае решение осуществляется в два логических этапа:
В обоих случаях мы имеем дело с треугольными матрицами ( L и U ), которые можно решить напрямую прямой и обратной подстановкой без использования процесса исключения Гаусса (однако нам нужен этот процесс или эквивалент для вычисления самого LU- разложения).
Вышеуказанную процедуру можно многократно применять для решения уравнения несколько раз для разных b . В этом случае быстрее (и удобнее) выполнить LU-разложение матрицы A один раз, а затем решить треугольные матрицы для разных b , а не использовать гауссово исключение каждый раз. Матрицы L и U можно было бы считать «закодированными» для процесса гауссова исключения.
Стоимость решения системы линейных уравнений составляет приблизительно операций с плавающей точкой, если размер матрицы составляет . Это делает ее вдвое быстрее алгоритмов, основанных на QR-разложении , которое стоит около операций с плавающей точкой при использовании отражений Хаусхолдера . По этой причине LU-разложение обычно предпочтительнее. [17]
При решении систем уравнений b обычно рассматривается как вектор с длиной, равной высоте матрицы A. Однако при обращении матрицы вместо вектора b мы имеем матрицу B , где B — матрица размером n на p , так что мы пытаемся найти матрицу X (также матрицу размером n на p ):
Мы можем использовать тот же алгоритм, представленный ранее, для решения для каждого столбца матрицы X. Теперь предположим, что B — единичная матрица размера n . Из этого следует, что результат X должен быть обратным A. [18]
Учитывая LUP-разложение квадратной матрицы A , определитель A можно вычислить напрямую как
Второе уравнение следует из того факта, что определитель треугольной матрицы — это просто произведение ее диагональных элементов, а определитель матрицы перестановок равен (−1)· S , где S — число перестановок строк в разложении.
В случае LU-разложения с полным поворотом также равно правой части приведенного выше уравнения, если мы допустим, что S будет общим числом обменов строк и столбцов.
Тот же метод легко применяется к LU-разложению, устанавливая P равным единичной матрице.
/* ВХОД: A - массив указателей на строки квадратной матрицы размером N * Tol - малое число допуска для обнаружения сбоя, когда матрица близка к вырожденной * ВЫХОД: Матрица A изменена, она содержит копию обеих матриц LE и U как A=(LE)+U, так что P*A=L*U. * Матрица перестановки хранится не как матрица, а в целочисленном векторе P размером N+1 * содержащем индексы столбцов, где матрица перестановки имеет "1". Последний элемент P[N]=S+N, * где S - количество перестановок строк, необходимых для вычисления определителя, det(P)=(-1)^S */ int LUPDecompose ( double ** A , int N , double Tol , int * P ) { int i , j , k , imax ; double maxA , * ptr , absA ; for ( i = 0 ; i <= N ; i ++ ) P [ i ] = i ; //Единичная матрица перестановок, P[N], инициализированная с помощью N для ( i = 0 ; i < N ; i ++ ) { maxA = 0.0 ; imax = i ; для ( k = i ; k < N ; k ++ ) если (( absA = fabs ( A [ k ][ i ])) > maxA ) { maxA = absA ; imax = k ; } if ( maxA < Tol ) return 0 ; //неудача, матрица вырожденная если ( imax != i ) { //поворот P j = P [ i ]; P [ i ] = P [ imax ]; P [ imax ] = j ; // поворот строк A ptr = A [ i ]; A [ i ] = A [ imax ]; A [ imax ] = ptr ; //подсчет опорных элементов, начиная с N (для определителя) P [ N ] ++ ; } для ( j = i + 1 ; j < N ; j ++ ) { A [ j ][ i ] /= A [ i ][ i ]; для ( k = i + 1 ; k < N ; k ++ ) A [ j ][ k ] -= A [ j ][ i ] * A [ i ][ k ]; } } return 1 ; //разложение выполнено } /* ВХОД: A,P заполнены в LUPDecompose; b - вектор правой части; N - размерность * ВЫХОД: x - вектор решения A*x=b */ void LUPSolve ( double ** A , int * P , double * b , int N , double * x ) { для ( int i = 0 ; i < N ; i ++ ) { x [ i ] = b [ P [ i ]]; для ( int k = 0 ; k < i ; k ++ ) x [ i ] -= A [ i ][ k ] * x [ k ]; } для ( int i = N - 1 ; i >= 0 ; i -- ) { для ( int k = i + 1 ; k < N ; k ++ ) x [ i ] -= A [ i ][ k ] * x [ k ]; х [ я ] /= А [ я ][ я ]; } } /* ВХОД: A,P заполнены в LUPDecompose; N - размерность * ВЫХОД: IA - обратная исходной матрица */ void LUPInvert ( double ** A , int * P , int N , double ** IA ) { for ( int j = 0 ; j < N ; j ++ ) { for ( int i = 0 ; i < N ; i ++ ) { IA [ i ][ j ] = P [ i ] == j ? 1.0 : 0.0 ; для ( int k = 0 ; k < i ; k ++ ) IA [ i ][ j ] -= A [ i ][ k ] * IA [ k ][ j ]; } для ( int i = N - 1 ; i >= 0 ; i -- ) { для ( int k = i + 1 ; k < N ; k ++ ) IA [ i ][ j ] -= A [ i ][ k ] * IA [ k ][ j ]; IA [ i ][ j ] /= A [ i ][ i ]; } } } /* ВХОД: A,P заполнены в LUPDecompose; N - размерность. * ВЫХОД: Функция возвращает определитель исходной матрицы */ double LUPDeterminant ( double ** A , int * P , int N ) { двойной det = A [ 0 ][ 0 ]; для ( int i = 1 ; i < N ; i ++ ) det *= A [ i ][ i ]; возврат ( P [ N ] - N ) % 2 == 0 ? дет : - дет ; }
public class SystemOfLinearEquations { public double [] SolveUsingLU ( double [,] matrix , double [] rightPart , int n ) { // разложение матрицы double [,] lu = new double [ n , n ]; double sum = 0 ; for ( int i = 0 ; i < n ; i ++ ) { for ( int j = i ; j < n ; j ++ ) { sum = 0 ; for ( int k = 0 ; k < i ; k ++ ) sum += lu [ i , k ] * lu [ k , j ]; lu [ i , j ] = matrix [ i , j ] - sum ; } for ( int j = i + 1 ; j < n ; j ++ ) { sum = 0 ; для ( int k = 0 ; k < i ; k ++ ) сумма += lu [ j , k ] * lu [ k , i ]; lu [ j , i ] = ( 1 / lu [ i , i ]) * ( matrix [ j , i ] - сумма ); } } // lu = L+UI // найти решение Ly = b double [] y = new double [ n ]; for ( int i = 0 ; i < n ; i ++ ) { sum = 0 ; for ( int k = 0 ; k < i ; k ++ ) sum += lu [ i , k ] * y [ k ]; y [ i ] = rightPart [ i ] - sum ; } // найти решение Ux = y double [] x = new double [ n ]; for ( int i = n - 1 ; i >= 0 ; i -- ) { sum = 0 ; for ( int k = i + 1 ; k < n ; k ++ ) sum += lu [ i , k ] * x [ k ]; x [ i ] = ( 1 / lu [ i , i ]) * ( y [ i ] - sum ); } return x ; } }
функция LU = LUDecompDoolittle ( A ) n = длина ( A ); LU = A ; % разложение матрицы, метод Дулиттла для i = 1 : 1 : n для j = 1 :( i - 1 ) LU ( i , j ) = ( LU ( i , j ) - LU ( i , 1 :( j - 1 )) * LU ( 1 :( j - 1 ), j )) / LU ( j , j ); конец j = i : n ; LU ( i , j ) = LU ( i , j ) - LU ( i , 1 :( i - 1 )) * LU ( 1 :( i - 1 ), j ); конец %LU = L+UI конец функция x = SolveLinearSystem ( LU, B ) n = длина ( LU ); y = нули ( размер ( B )); % найти решение Ly = B для i = 1 : n y ( i ,:) = B ( i ,:) - LU ( i , 1 : i ) * y ( 1 : i ,:); конец % найти решение Ux = y x = нули ( размер ( B )); для i = n :( - 1 ): 1 x ( i ,:) = ( y ( i ,:) - LU ( i ,( i + 1 ): n ) * x (( i + 1 ): n ,:)) / LU ( i , i ); конец конец A = [ 4 3 3 ; 6 3 3 ; 3 4 3 ] LU = LUDecompDoolittle ( A ) B = [ 1 2 3 ; 4 5 6 ; 7 8 9 ; 10 11 12 ] ' x = РешитьЛинейнуюСистему ( LU , B ) A * x
Ссылки
Компьютерный код
Онлайн ресурсы