Sunteți pe pagina 1din 4

Recursive LU factorization of a matrix

Contents
Methodology of LU recursive factorization .................................................................................................. 1
Python code .................................................................................................................................................. 2
Permutation matrices .................................................................................................................................. 3

Methodology of LU recursive factorization


𝑎 𝑤𝑡
If for 𝐴 = (𝑎𝑖𝑗 )1≤𝑖,𝑗≤𝑚 ∈ 𝑀𝑚 (𝑅) we consider 𝐴 = ( 11 ) where 𝑤 𝑡 = (𝑎12 , … , 𝑎1𝑚 ), 𝑣 =
𝑣 𝐴′
1 0𝑡𝑚−1 𝑎11 𝑤𝑡
𝑡
(𝑎21 , … , 𝑎𝑚1 ) .If 𝑎11 ≠ 0 then we can write 𝐴 = ( 𝑣 ′
)( ′ (𝑣𝑤 𝑡 )) where 𝐴1 = 𝐴 −
𝑎
𝐼𝑚−1 0 𝑚−1 𝐴 − 𝑎
11 11
𝑣𝑤 𝑡
𝑎11
is called Schur complement.

We repeat the same transformation for 𝐴1 until we reach to a matrix of the order one.

ALGORITHM

S1. We read 𝒎 ∈ 𝑵∗ , 𝒎 ≥ 𝟐 and 𝑨 = (𝒂𝒊𝒋 ) ∈ 𝑴𝒎 (𝑹).


𝒊,𝒋=𝟏,𝒎

S2. For 𝒌 = 𝟏, 𝒎 − 𝟏:

If 𝒂𝒌𝒌 = 𝟎 then we cannot proceed further to the decomposition.

Else, (if 𝒂𝒌𝒌 ≠ 𝟎) ,then :


𝒂𝒋𝒌
𝒂𝒋𝒌 = 𝒂 , 𝒋 = 𝒌 + 𝟏, 𝒎
𝒌𝒌

The elements (𝒂𝒊𝒋 ) , transform into 𝒂𝒊𝒋 = 𝒂𝒊𝒋 − 𝒂𝒊𝒌 𝒂𝒌𝒋 .


𝒊,𝒋=𝒌+𝟏,𝒎

S3. If (𝒂𝒎𝒎 = 𝟎) then we cannot make the LU decomposition, else we write 𝑳, 𝑼:

𝟎, 𝟏 ≤ 𝒊 ≤ 𝒋 ≤ 𝒎
𝟎, 𝟏 ≤ 𝒋 ≤ 𝒊 ≤ 𝒎
𝑳 = (𝒍𝒊𝒋 ) ={ 𝟏, 𝒊 = 𝒋 , 𝑼 = (𝒖𝒊𝒋 ) = { 𝒂 , 𝒐𝒕𝒉𝒆𝒓𝒘𝒊𝒔𝒆 .
𝒊,𝒋=𝟏,𝒎 𝒊,𝒋=𝟏,𝒎 𝒊𝒋
𝒂𝒊𝒋 , 𝒐𝒕𝒉𝒆𝒓𝒘𝒊𝒔𝒆

The steps S2 and S3 can be transformed into the call 𝑳𝑼(𝒎, 𝑨) where 𝑳𝑼(𝒑, 𝑨) makes the
transformations in A starting with the line 𝒎 − 𝒑 + 𝟏 and ends if 𝒑 = 𝟏.

We have: 𝑳𝑼(𝒑, 𝑨)
K<- m-p+1

If 𝒂𝒌𝒌 = 𝟎 then the decomposition is not made, otherwise divide elements from column 𝒌 with 𝒂𝒌𝒌
under 𝒂𝒌𝒌 .

The right-bottom corner elements 𝒂𝒊𝒋 are transformed as described as in S2.

We recall 𝑳𝑼(𝒑 − 𝟏, 𝑨).

Python code
I will write the code for the first step, the first decomposition of A, and the small functions to extract
blocks of matrices as follows:
import numpy as np
def LU_tests():
def rewrite_matrix(A):
"I will write from matrix nxn A, a (n-1)x(n-1) matrix A1 from the "
"bottom-right corner, along with the remnants, a (n-1) line, (n-
1)col"
"and top-left corner element"
return A[1:np.shape(A)[0],1:np.shape(A)[1]]
def lower_right_corner(A):
return A[1:np.shape(A)[0],1:np.shape(A)[1]]
def transform_L(A):
sz = np.shape(A)[0]
v = A[1:sz,0]
L = np.zeros((sz,sz))
L[0,0]=1
L[1:sz,0] = np.transpose(v)/A[0,0]
L[1:sz,1:sz]=np.identity(sz-1)
return L
def transform_U(A):
sz = np.shape(A)[0]
A1 = A[1:sz,1:sz]
U = np.zeros((sz,sz))
w = A[0,1:sz]
v = A[1:sz,0]
U[0,0],a=A[0,0],A[0,0]
U[0,1:sz] = w
U[1:sz,1:sz] = A1 - np.outer(np.transpose(v),w)/a
"The right side above is called Schur complement"
return U
def Schur(A):
L = transform_L(A)
"only L is inferior triangular, U is yet to be redecomposed"
U = transform_U(A)
return L,U
return Schur
Now I will write the code for the transforming the matrix A into a new matrix 𝐴, that will be written as
𝐴 = 𝐿 + 𝑈, where 𝐿𝑈 = 𝐴.
def LU_recursive(A,p):
m = np.shape(A)[0]
if A[m-p,m-p]!=0 and p!=1:
v,w = A[m-p+1:m,m-p],A[m-p,m-p+1:m]
A[m-p+1:m,m-p] = A[m-p+1:m,m-p]/A[m-p,m-p]
A[m-p+1:m,m-p+1:m] = A[m-p+1:m,m-p+1:m] - np.outer(np.transpose(v),w)
LU_recursive(A,p-1)
return A
Now the final step of the decomposition:
def final_Schur_decomposition(A):
sz = np.shape(A)[0]
A = LU_recursive(A,sz)
def simply_LU(A):
"THis will simply write L,U from the elements of A where L[i,i]=1 and
"
"U[i,i] = 0. In simpler words, the inferior and superior diagonal
parts"
sz = np.shape(A)[0]
L,U = np.zeros((sz,sz)),A
L = np.diag(np.ones(sz))
for i in range(1,sz):
for j in range(0,i):
L[i,j] = A[i,j]
U[i,j] = 0
return L,U
return simply_LU(A)
Tests are also being carried out:
def test_final_dec():
A = np.array([[2,3,1,5],[6,13,5,19],[2,19,10,23],[4,10,11,31]])
B = A
print(final_Schur_decomposition(A)[0])
print(final_Schur_decomposition(A)[1])
print(B -
np.dot(final_Schur_decomposition(A)[0],final_Schur_decomposition(A)[1]))
Remark: B is the null matrix.

Permutation matrices
A special matrix derived from the identity matrix where 2 rows / columns are permutated is called a
permutation matrix.
1, 𝑖𝑓 𝑗 = 𝜎(𝑖)
𝑃 = (𝑝𝑖𝑗 ) = { , 𝜎 ∈ 𝑃𝑒𝑟𝑚({1,2, … , 𝑚}).
0, 𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒
Python code:
def permutation_matrix_tests():
def test1():
A = np.matrix([[0,1,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,1]])
print(A)
b1,b2,b3,b4 =
np.array([[0,1],[1,0]]),np.zeros((2,2)),np.zeros((2,2)),\
np.array([[0,1],[1,0]])
print(np.block([[b1,b2],[b3,b4]]))
test1()
def perm_matrix(n,i,j):
A = np.identity(n)
A[i-1,j-1],A[j-1,i-1]=1,1
A[i-1,i-1],A[j-1,j-1]=0,0
return A
print(perm_matrix(4,2,3))
def test2():
A = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(np.dot(A,perm_matrix(3,1,2)))
print(np.dot(perm_matrix(3,1,2),A))
test2()
Remark:
By multiplying a matrix with a permutation matrix at right, we permute two columns.
By multiplying a matrix with a permutation matrix at left, we permute two rows.
See test2() above in Python.

S-ar putea să vă placă și