gyeo-ri.com

LU 분해(LU Decomposition) - (2) 해 도출(Forward/Back Substitution) 본문

Study Note/선형대수학

LU 분해(LU Decomposition) - (2) 해 도출(Forward/Back Substitution)

겨리_Gyeori 2021. 1. 11. 20:55

*LU분해의 과정에 관한 내용은 이전 포스팅 참조

 

 

  가우스-조르당 소거법 포스팅에서 Ax=b를 다음과 같이 정의하였다.

 

(221213123)(xyz)=(111110)

 

 

  이때, LU 분해를 통해 행렬 A를 분해할 수 있다.

 

A=LU=(200210119/2)(111/2012001)

 

 

  따라서, 연립방정식 Ax=bLUx=b와 같다

 

 

  여기서 Ux=z로 정의하면 식을

Lz=b

로 표현할 수 있는데, 이것은 u가 해인 새로운 방정식으로 볼 수 있다.

(U는 3x3, x는 3x1이므로 Ux=z는 3x1의 열벡터 형태이다)

 

 

 

1. Forward Substitution

  u는 방정식의 첨가행렬 [L|b]을 기본행 연산을 통해 [I|z]로 변환하여 구할 수 있다. 이때, 계수행렬에 해당하는 L은 하삼각행렬이므로, 첫 원소를 제외한 모든 열의 원소가 0인 1행부터 순차적으로 아래 행을 소거, 단위행렬(I)을 만드는 Forward Substitution을 수행할 수 있다. 이는 가우스-조르당 소거법에서 사용하는 Back Substitution과 소거 방향만 다른 동일한 연산이다.

 

 

[L|b]=[200 |11210|11119/2|10][I|z]=[100|11/2010|0001|1]

 

연산 결과, zT=[[11/2,0,1]]이다.

 

 

 

Forward Substitution 과정을 파이썬 함수로 구현한 코드는 다음과 같다(전체 코드는 Github 참조)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def forward_substitution(aug_matrix):
    mcol = len(aug_matrix[0])
    for col in range(mcol-1):
        for row in range(col+1,mcol-1): #col/row를 파이썬 인덱스에 맞게 적용
            const = aug_matrix[row][col]/aug_matrix[col][col] * -1  #constraint
            print(col+1,"행을",round(const,2), "만큼 상수배하여", row+1"행의", col+1,"열을 소거")
            aug_matrix[row] += const * aug_matrix[col]
            print(np.around(aug_matrix,2)) #출력을 위한 반올림
            print()
    
    for i in range(mcol-1): #행의 갯수만큼
        aug_matrix[i] /= aug_matrix[i][i] # 각 행의 선행원소를 1로 만들어 줌
            
    
    print("선행원소를 1로 만드는 연산")
    print(aug_matrix)
    
    return aug_matrix[:,-1].reshape(1,-1#실제 해는 마지막 열(앞은 계수행렬 = 단위행렬), 열벡터 형태로 반환
cs

 

  LU 분해 과정에서 계수행렬(L)이 하삼각행렬로 분해되었으므로, forward_substitution 함수는 첫 행부터 상수배 후 다음 행에 덧셈(뺄셈)하는 연산만을 수행하여 계수행렬을 대각행렬로 만들 수 있다. 마지막으로, 해를 구하기 위해 계수행렬의 대각원소(=각 행의 선행원소)를 1로 만들어 반환한다.

 

  실제 파이썬 연산 결과도 동일한 z를 반환한다.

 

 

 

 

 

 

 

2. Back Substitution

  Forward Substitution의 결과로 z의 값이 도출되었으므로, 앞서 새로 정의한 방정식 Ux=z의 해 x를 구하기 위한 첨가행렬을 다음과 같이 나타낼 수 있다.

 

 

  [U|z]=[111/2|11/2012|0001|1]

 

첨가행렬 [U|z]은 행사다리꼴 형태(상삼각행렬 + 열벡터)이며, 이를 가우스-조르당 소거법과 같이 Back Substitution 하면 방정식의 최종 해 x를 구할 수 있다.

 

x=(321)

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def back_substitution(aug_matrix):
    mcol = len(aug_matrix[0])
    for col in range(mcol-2,0,-1):
        for row in range(col-1,-1,-1): #col/row를 파이썬 인덱스에 맞게 적용
            const = aug_matrix[row][col]/aug_matrix[col][col] * -1 #
            print(col+1,"행을", round(const,2), "만큼 상수배하여", row+1"행의", col+1,"열을 소거")
            aug_matrix[row] += const * aug_matrix[col]
            print(np.around(aug_matrix,2)) #출력을 위한 반올림
    
    
    for i in range(mcol-1): #행의 갯수만큼
        aug_matrix[i] /= aug_matrix[i][i] # 각 행의 선행원소를 1로 만들어 줌
    
    return aug_matrix
cs

 

 

  Back Substitution은 Forward Substitution과 반복 위치만 다르고, 전체적으로 동일한 연산이다. 마찬가지로 대각행렬을 구하는 소거 연산을 수행한 후 필요에 따라 선행원소를 1로 만들어주는 연산을 적용한다.

 

 

 

 

함수의 결과로 3,2,1을 원소로 가지는 행렬이 반환된다. 이전 포스팅에서 구현한 가우스-조르당 소거법 연산의 결과와도 동일한 값이다.

 

 

 

 

 

참고자료

1. 프로그래머를 위한 선형대수(히라오카 카즈유키 저, 이창신 옮김) - 길벗(2017)

2. [Youtube] 쑤튜브 : 10분 선형대수 강의 모음(youtu.be/x-Ewz1ukXEA)

Comments