Chapter 12

연립방정식의 직접 해법

LinearBook 3장과 4장에서 소거, 후진 대입, A=LUA = LU, 행 교환, 띠 행렬을 배웠고, 16장에서 조건수와 후방 안정성을 맛보았습니다. 이 장은 같은 알고리즘을 계산하는 사람의 눈으로 다시 봅니다. 연산이 정확히 몇 번인지, 피벗팅이 무엇을 지키고 무엇은 못 지키는지(성장 인자), 대칭 양정치 행렬에서 비용을 절반으로 줄이는 촐레스키 분해, O(n)O(n) 토머스 알고리즘의 안정 조건, 답이 몇 자리까지 믿을 만한지 알려 주는 조건수 한계, 단정밀도로 분해하고 배정밀도 답을 얻는 반복 개선, 그리고 10⁶ 미지수의 희소 행렬에서 메모리를 정하는 채움과 재배열까지 다룹니다.

이 수식이 없었다면구조 해석과 회로 해석

다리, 비행기 날개, 반도체 칩 단면을 유한 요소로 나누면 수십만에서 수천만 개의 미지수를 가진 연립방정식 Ku=fK\mathbf u = \mathbf f가 나옵니다. 회로 시뮬레이터는 시간 걸음마다 노드 전압에 대한 연립방정식을 풉니다. 이 방정식들이 현실적인 시간에 풀리는 것은 행렬이 거의 0으로 차 있고(희소), 대칭 양정치인 경우가 많으며(촐레스키), 피벗팅과 재배열로 반올림 오차와 메모리를 동시에 통제하는 직접 해법 라이브러리가 있기 때문입니다. 1940년대 말 튜링(Alan Turing)은 소거의 반올림 오차를 분석하며 "조건수"라는 이름을 붙였고, 1960년대 윌킨슨(James H. Wilkinson)의 후방 오차 분석이 부분 피벗팅 소거를 믿고 쓸 수 있는 근거를 주었습니다.

A x = b→피벗팅 + 분해→PA = LU, A = LLᵀ→구조·회로·FEM 해석기

가우스 소거의 연산 수

미지수가 10배면 시간은 1000배

미지수 1,000개짜리 계를 푸는 데 0.1초가 걸렸습니다. 같은 프로그램으로 10,000개짜리를 풀면 몇 초가 걸릴까요? 메모리는 몇 배가 필요할까요? 답을 미리 알아야 계산을 설계할 수 있습니다.

열 우선 순서로 쓴 LU 분해의 핵심은 세 겹의 반복문입니다. kk번째 단계에서 피벗 아래의 n−kn - k개 행마다 승수를 하나 구하고(나눗셈), 남은 (n−k)×(n−k)(n - k)\times(n - k) 부분 행렬을 갱신합니다(곱셈과 뺄셈).

for k = 1 … n−1
  for i = k+1 … n
    a[i,k] ← a[i,k] / a[k,k]              // 승수 ℓᵢₖ를 그 자리에 저장
    for j = k+1 … n
      a[i,j] ← a[i,j] − a[i,k]·a[k,j]    // 슈어 보수 갱신: 곱 1 + 뺄셈 1
// 끝나면 a의 아래 삼각 = L(대각 1 생략), 위 삼각 = U
정리 12.1 (LU 분해와 대입의 연산 수) 크기 nn인 LU 분해의 부동소수점 연산 수(곱셈·뺄셈·나눗셈 각각 1회로 셈)는
∑m=1n−1(2m2+m)=23n3−12n2−16n≈23n3,\sum_{m=1}^{n-1}\bigl(2m^2 + m\bigr) = \frac23n^3 - \frac12n^2 - \frac16n \approx \frac23n^3,
전진 대입 Ly=bL\mathbf y = \mathbf b와 후진 대입 Ux=yU\mathbf x = \mathbf y는 각각 약 n2n^2회다. 따라서 분해 한 번이 대입 한 번의 약 nn배 비용이다.

셈. 단계 kk에서 m=n−km = n - k라 하면 나눗셈 mm번, 곱셈·뺄셈 m2m^2번씩이다. ∑m=1n−1m2=(n−1)n(2n−1)6\sum_{m=1}^{n-1}m^2 = \frac{(n-1)n(2n-1)}{6}, ∑m=n(n−1)2\sum m = \frac{n(n-1)}{2}를 넣어 정리하면 위 식이다. ∎

그래서 문제 상자의 답은 10310^3배, 약 100초입니다. 메모리는 n2n^2이라 100배(배정밀도 104×10410^4\times10^4 행렬은 800 MB)입니다. 실제 라이브러리(LAPACK의 dgetrf)는 같은 연산을 블록 단위로 묶어 행렬–행렬 곱(BLAS 3단계)으로 바꿉니다. 연산 수는 같지만 캐시에 올린 데이터를 여러 번 재사용하므로, 위의 단순한 세 겹 반복보다 수십 배 빠르게 돕니다.

작업연산 수(주항)n = 1000일 때
LU 분해 PA=LUPA = LU23n3\tfrac23n^36.7×10⁸
촐레스키 A=LLTA = LL^{\mathsf T} (4절)13n3\tfrac13n^33.3×10⁸
전진 + 후진 대입 (우변 하나)2n22n^22.0×10⁶
역행렬 A−1A^{-1} 전체2n32n^32.0×10⁹
토머스 알고리즘 (삼중대각, 5절)8n8n8.0×10³

표의 넷째 줄이 "역행렬을 계산하지 말라"는 격언의 근거입니다. A−1bA^{-1}\mathbf b를 구하려고 역행렬을 만들면 분해만 할 때의 세 배를 쓰고, 정확도도 대개 더 나쁩니다. 우변이 mm개 있으면 분해는 한 번만 하고 대입을 mm번 하면 됩니다(23n3+2mn2\tfrac23n^3 + 2mn^2).

피벗팅: 작은 피벗과 성장 인자

정확히 풀리는 2×2가 틀린다

0.0001x+y=10.0001x + y = 1, x+y=2x + y = 2의 해는 x=1.0001x = 1.0001, y=0.9999y = 0.9999쯤입니다. 소수 세 자리 유효 숫자로 계산하는 기계(매 연산마다 유효 숫자 3개로 반올림)로 첫 식을 피벗으로 소거하면 x=0x = 0이 나옵니다. 배정밀도에서도 피벗이 10−1710^{-17}이면 같은 일이 생깁니다(LinearBook 3장의 시뮬레이터).

예제 12.1 (유효 숫자 3자리 소거) 위 계를 매 연산 뒤 유효 숫자 3자리로 반올림하며 풀어라.
  1. 피벗팅 없이: 승수 ℓ=1/0.0001=104\ell = 1/0.0001 = 10^4. 2행: 1−104⋅1=−9999→−1.00×1041 - 10^4\cdot 1 = -9999 \to -1.00\times10^4, 우변 2−104=−9998→−1.00×1042 - 10^4 = -9998 \to -1.00\times10^4. 그러면 y=1.00y = 1.00, x=(1−1.00)/0.0001=0x = (1 - 1.00)/0.0001 = 0. x가 완전히 틀렸다. 2행의 원래 정보 "1"과 "2"가 10410^4에 묻혀 사라졌다.
  2. 부분 피벗팅: 절댓값이 큰 1을 피벗으로 행을 바꾼다. ℓ=0.0001\ell = 0.0001, 2행: 1−0.0001=0.9999→1.001 - 0.0001 = 0.9999 \to 1.00, 우변 1−0.0002=0.9998→1.001 - 0.0002 = 0.9998 \to 1.00. y=1.00y = 1.00, x=2−1.00=1.00x = 2 - 1.00 = 1.00. 3자리 기계가 낼 수 있는 최선의 답이다.

부분 피벗팅은 승수를 ∣ℓik∣≤1|\ell_{ik}| \le 1로 묶습니다. 그런데 행 하나에 큰 수를 곱해 두면 이 장치가 속습니다. 10x+105y=10510x + 10^5y = 10^5, x+y=2x + y = 2(첫 식에 10510^5를 곱한 것과 같은 계)에서 부분 피벗팅은 10을 피벗으로 골라 3자리 계산에서 다시 x=0x = 0을 냅니다. 행마다 가장 큰 원소 si=max⁡j∣aij∣s_i = \max_j|a_{ij}|로 나눈 상대 크기 ∣aik∣/si|a_{ik}|/s_i로 피벗을 고르면(10/10510/10^5 대 1/11/1) 둘째 행이 선택되어 x=y=1.00x = y = 1.00이 나옵니다. 이것이 척도 부분 피벗팅(scaled partial pivoting)입니다. 실무에서는 행렬을 미리 평형화(행·열 척도 조정)하고 부분 피벗팅을 씁니다.

정의 12.2 (피벗팅 전략과 성장 인자) kk번째 단계에서 부분 피벗팅은 kk열의 kk행 이하에서 절댓값 최대인 원소를, 완전 피벗팅은 남은 부분 행렬 전체에서 절댓값 최대인 원소를 골라 행(과 열)을 바꾼다. 소거 중 나타나는 모든 중간 원소 aij(k)a_{ij}^{(k)}에 대해
ρn=max⁡i,j,k∣aij(k)∣max⁡i,j∣aij∣\rho_n = \frac{\max_{i,j,k}|a_{ij}^{(k)}|}{\max_{i,j}|a_{ij}|}
를 성장 인자(growth factor)라 한다. 완전 피벗팅은 PAQ=LUPAQ = LU를 만들며, 원소 비교가 단계마다 O((n−k)2)O((n-k)^2)이라 전체 O(n3)O(n^3)번의 비교가 더 든다.
정리 12.3 (소거의 후방 오차, 윌킨슨) 부동소수점에서 피벗팅을 쓴 가우스 소거로 얻은 해 x^\hat{\mathbf x}는 약간 흔들린 계 (A+ΔA)x^=b(A + \Delta A)\hat{\mathbf x} = \mathbf b의 정확한 해이고,
∥ΔA∥∞∥A∥∞≤c n3ρn u\frac{\|\Delta A\|_\infty}{\|A\|_\infty} \le c\,n^3\rho_n\,u
가 성립한다(uu는 단위 반올림, cc는 크지 않은 상수; 실제 오차는 이 상한보다 훨씬 작다). 부분 피벗팅의 성장 인자는 ρn≤2n−1\rho_n \le 2^{n-1}이고, 이 상한에 도달하는 행렬이 있다.

요지. ρn\rho_n이 작으면 소거는 후방 안정하다(2장). 부분 피벗팅에서는 ∣ℓik∣≤1|\ell_{ik}| \le 1이라 한 단계에 원소가 많아야 두 배가 되어 2n−12^{n-1}이 나온다. 피벗팅이 없으면 ρn\rho_n에 상한이 없다.

상한에 닿는 예가 윌킨슨의 행렬입니다. 대각이 1, 대각 아래가 모두 −1-1, 마지막 열이 모두 1인 행렬은 부분 피벗팅이 행을 바꾸지 않고(첫 열의 최댓값이 이미 대각에 있음), 마지막 열이 단계마다 두 배가 되어 unn=2n−1u_{nn} = 2^{n-1}입니다. 조건수는 nn 정도로 작으니 문제는 전혀 예민하지 않은데, 알고리즘이 답을 망칩니다.

윌킨슨 행렬, 배정밀도n = 30n = 40n = 50n = 55n = 60
부분 피벗팅 성장 인자 ρₙ5.4×10⁸5.5×10¹¹5.6×10¹⁴1.8×10¹⁶5.8×10¹⁷
부분 피벗팅 상대 오차9.4×10⁻⁹8.2×10⁻⁶1.4×10⁻²1.5×10⁻¹1.6
완전 피벗팅 ρₙ / 상대 오차2 / 10⁻¹⁶ 이하2 / 10⁻¹⁶ 이하2 / 10⁻¹⁶ 이하2 / 10⁻¹⁶ 이하2 / 10⁻¹⁶ 이하

표는 참해를 무작위로 정하고 b=Ax\mathbf b = A\mathbf x로 만든 실험입니다. 그런데 이런 행렬은 실제 응용에서 거의 나오지 않습니다. 무작위 50×50 행렬 200개에 부분 피벗팅을 쓰면 성장 인자의 중앙값은 7.5, 최댓값은 15.8이었습니다. 이 경험적 사실 때문에 LAPACK의 일반 풀이기는 부분 피벗팅을 기본으로 쓰고, 완전 피벗팅은 거의 쓰지 않습니다.

SIMULATOR

피벗팅 전략 비교: 유효 숫자 d자리 기계의 소거

피벗팅 없음부분척도 부분완전
참해 x—
없음 · 부분—
척도 · 완전—
성장 인자 (없음 / 부분)—
해볼 것: ① '작은 피벗'에서 d = 3, ε = 10⁻⁴는 예제 12.1입니다. 막대(상대 오차, 로그)가 피벗팅 없음만 10⁰ 근처입니다. ② '행 척도 차이'로 바꾸면 부분 피벗팅도 속고, 척도 부분과 완전 피벗팅만 맞습니다. ③ d를 16으로 올리면 거의 모두 맞지만, ε를 10⁻¹²로 내리면 d = 10에서 피벗팅 없음이 다시 틀립니다. '윌킨슨 24×24'에서는 d = 6이면 부분 피벗팅도 틀리고 완전 피벗팅만 맞습니다(성장 2²³ ≈ 8×10⁶). 모델: 매 사칙연산 결과를 유효 숫자 d자리로 반올림(입력도 반올림). 오차는 ‖x̂ − x‖∞/‖x‖∞, 0은 10−17로 표시.
SIMULATOR

성장 인자: 윌킨슨 행렬과 무작위 행렬

성장 인자 ρₙ와 상대 오차 vs n (로그 눈금)
부분 피벗팅 후 |U|의 히트맵 (로그 색)
행렬
부분 피벗팅 ρₙ완전 피벗팅 ρₙ부분 피벗팅 상대 오차2ⁿ⁻¹
ρₙ 부분 · 완전—
상대 오차 부분 · 완전—
max |uᵢⱼ| 위치—
해볼 것: ① 윌킨슨 행렬에서 부분 피벗팅 ρₙ(주황)이 2ⁿ⁻¹ 직선에 정확히 붙어 있고, n ≈ 50부터 오차(빨강)가 10⁻²를 넘습니다. ② 히트맵에서 큰 값은 U의 마지막 열에만 모입니다. ③ '무작위'로 바꾸면 ρₙ가 n에 따라 아주 천천히 자랍니다. 같은 알고리즘인데 최악과 평균이 이렇게 다릅니다. 모델: 참해는 시드 고정 무작위 벡터, 배정밀도, 무작위 행렬은 n마다 하나.

PA = LU와 여러 우변

부분 피벗팅을 쓴 소거는 행 교환을 기록하는 치환 행렬 PP와 함께 PA=LUPA = LU를 만듭니다(LinearBook 4장의 정리 4.3). 구현에서는 PP를 행렬로 저장하지 않고 정수 배열 piv로 두며, 승수 ℓik\ell_{ik}를 소거로 0이 된 칸에 덮어써서 LL과 UU를 원래 배열 하나에 담습니다. 행을 바꿀 때는 이미 저장한 승수도 함께 바뀐다는 것이 손계산의 함정입니다.

정리 12.4 (PA = LU의 존재와 사용) 가역 행렬 AA에 대해 PA=LUPA = LU(LL은 대각이 1이고 ∣ℓij∣≤1|\ell_{ij}| \le 1인 하삼각, UU는 상삼각)인 치환 행렬 PP가 언제나 존재한다. 이 분해로
  • Ax=bA\mathbf x = \mathbf b: Ly=PbL\mathbf y = P\mathbf b를 전진 대입, Ux=yU\mathbf x = \mathbf y를 후진 대입(2n22n^2).
  • 행렬식: det⁡A=(−1)s∏uii\det A = (-1)^{s}\prod u_{ii}(ss는 행 교환 횟수). 공식 전개(n!n!항) 대신 O(n3)O(n^3).
  • 전치 계 ATx=cA^{\mathsf T}\mathbf x = \mathbf c: UTz=cU^{\mathsf T}\mathbf z = \mathbf c, LTw=zL^{\mathsf T}\mathbf w = \mathbf z, x=PTw\mathbf x = P^{\mathsf T}\mathbf w. 같은 분해를 재사용한다.
예제 12.2 (부분 피벗팅 PA = LU 손계산) A=[12−1431223]A = \begin{bmatrix}1 & 2 & -1\\ 4 & 3 & 1\\ 2 & 2 & 3\end{bmatrix}, b=(2,8,7)\mathbf b = (2, 8, 7)를 풀어라.
  1. 1열의 최댓값은 4(2행). 1·2행을 바꾼다: piv = (2, 1, 3). 승수 ℓ21=1/4=0.25\ell_{21} = 1/4 = 0.25, ℓ31=2/4=0.5\ell_{31} = 2/4 = 0.5. 남은 부분: 2행 (2−0.75, −1−0.25)=(1.25,−1.25)(2 - 0.75,\ -1 - 0.25) = (1.25, -1.25), 3행 (2−1.5, 3−0.5)=(0.5,2.5)(2 - 1.5,\ 3 - 0.5) = (0.5, 2.5).
  2. 2열의 아래쪽 ∣1.25∣>∣0.5∣|1.25| > |0.5|이라 교환 없음. ℓ32=0.5/1.25=0.4\ell_{32} = 0.5/1.25 = 0.4, u33=2.5−0.4(−1.25)=3u_{33} = 2.5 - 0.4(-1.25) = 3.
  3. L=[10.2510.50.41]L = \begin{bmatrix}1 & & \\ 0.25 & 1 & \\ 0.5 & 0.4 & 1\end{bmatrix}, U=[4311.25−1.253]U = \begin{bmatrix}4 & 3 & 1\\ & 1.25 & -1.25\\ & & 3\end{bmatrix}. 확인: det⁡A=−(4⋅1.25⋅3)=−15\det A = -(4\cdot 1.25\cdot 3) = -15(교환 1번).
  4. Pb=(8,2,7)P\mathbf b = (8, 2, 7). 전진: y1=8y_1 = 8, y2=2−0.25⋅8=0y_2 = 2 - 0.25\cdot 8 = 0, y3=7−0.5⋅8−0.4⋅0=3y_3 = 7 - 0.5\cdot 8 - 0.4\cdot 0 = 3.
  5. 후진: x3=3/3=1x_3 = 3/3 = 1, x2=(0+1.25⋅1)/1.25=1x_2 = (0 + 1.25\cdot 1)/1.25 = 1, x1=(8−3−1)/4=1x_1 = (8 - 3 - 1)/4 = 1. 해 x=(1,1,1)\mathbf x = (1, 1, 1).
SIMULATOR

분해 한 단계씩: PA = LU · 촐레스키 A = LLᵀ

분해
단계—
이번 단계 연산 수 · 누계—
piv (행 순서)—
‖PA − LU‖ (또는 ‖A − LLᵀ‖)—
해볼 것: ① 예제 12.2를 'PA = LU'로 한 단계씩 넘기며 피벗(초록 칸)과 새로 바뀐 칸(보라 바탕), 저장된 승수(보라 글씨)를 확인하세요. 1단계의 행 교환 때 이미 저장한 승수가 없으니 L은 그대로입니다. ② 'LU (교환 없음)'으로 같은 행렬을 분해하면 승수 4, 2가 1보다 큽니다. ③ SPD 행렬을 촐레스키로 분해하면 L의 대각이 모두 양수이고 연산 수가 LU의 약 절반입니다. '대칭 부정치'에서는 촐레스키가 음수의 제곱근에서 멈춥니다. 모델: 배정밀도, 표시는 소수 넷째 자리.

촐레스키 분해: 대칭 양정치 행렬

강성 행렬은 대칭이고 양정치다

스프링과 막대로 이루어진 구조물의 강성 행렬 KK는 대칭이고, 변위 u≠0\mathbf u \ne 0이면 탄성 에너지 12uTKu\tfrac12\mathbf u^{\mathsf T}K\mathbf u가 양수입니다. 이 성질을 쓰면 피벗팅 없이도 안정하고, 연산과 메모리를 절반으로 줄일 수 있습니다.

정리 12.5 (촐레스키 분해) 실대칭 행렬 AA가 양정치(positive definite)(모든 x≠0\mathbf x \ne 0에 대해 xTAx>0\mathbf x^{\mathsf T}A\mathbf x \gt 0)일 필요충분조건은 대각 원소가 양수인 하삼각 행렬 LL로 A=LLTA = LL^{\mathsf T}라 쓸 수 있는 것이다. 이 LL은 유일하며, 원소는 열 순서로
ℓjj=ajj−∑k<jℓjk2,ℓij=1ℓjj(aij−∑k<jℓikℓjk)(i>j).\ell_{jj} = \sqrt{a_{jj} - \sum_{k \lt j}\ell_{jk}^2},\qquad \ell_{ij} = \frac{1}{\ell_{jj}}\Bigl(a_{ij} - \sum_{k \lt j}\ell_{ik}\ell_{jk}\Bigr)\quad (i \gt j).
연산 수는 약 13n3\tfrac13n^3(LU의 절반)과 제곱근 nn개, 저장은 아래 삼각만 필요하다. 피벗팅 없이 후방 안정하다.

왜 피벗팅이 필요 없나. aija_{ij}를 LL의 ii행·jj행의 내적으로 보면 aii=∑kℓik2a_{ii} = \sum_k\ell_{ik}^2이므로 ∣ℓik∣≤aii|\ell_{ik}| \le \sqrt{a_{ii}}. LL의 원소가 AA의 대각으로 묶이니 성장이 일어나지 않는다. 또한 제곱근 안이 음수나 0이 되면 AA가 양정치가 아니라는 증거다. 그래서 촐레스키 분해는 양정치성의 가장 값싼 판정법으로도 쓰인다. ∎

예제 12.3 (3×3 촐레스키) A=[422253236]A = \begin{bmatrix}4 & 2 & 2\\ 2 & 5 & 3\\ 2 & 3 & 6\end{bmatrix}을 분해하라.
  1. 1열: ℓ11=4=2\ell_{11} = \sqrt4 = 2, ℓ21=2/2=1\ell_{21} = 2/2 = 1, ℓ31=2/2=1\ell_{31} = 2/2 = 1.
  2. 2열: ℓ22=5−12=2\ell_{22} = \sqrt{5 - 1^2} = 2, ℓ32=(3−1⋅1)/2=1\ell_{32} = (3 - 1\cdot 1)/2 = 1.
  3. 3열: ℓ33=6−12−12=2\ell_{33} = \sqrt{6 - 1^2 - 1^2} = 2.
  4. L=[212112]L = \begin{bmatrix}2 & & \\ 1 & 2 & \\ 1 & 1 & 2\end{bmatrix}. 확인: LLTLL^{\mathsf T}의 (3, 3) 성분은 1+1+4=61 + 1 + 4 = 6, (2, 3) 성분은 1+2=31 + 2 = 3. det⁡A=(2⋅2⋅2)2=64\det A = (2\cdot 2\cdot 2)^2 = 64.

대칭이지만 양정치가 아닌 행렬(구조물의 좌굴 해석, 제약 조건이 있는 최적화의 KKT 행렬)에는 대칭성을 살리면서 1×1과 2×2 블록 피벗을 쓰는 PAPT=LDLTPAP^{\mathsf T} = LDL^{\mathsf T} 분해(번치–카우프만 피벗팅)를 씁니다. LinearBook 4장의 LDLTLDL^{\mathsf T}에 피벗팅을 더한 것입니다.

띠 행렬과 토머스 알고리즘

백만 개의 격자점을 1초 안에

1차원 열전도·확산 문제, 3차 스플라인(6장), 크랭크–니콜슨 시간 걸음(16장), 경계값 문제의 유한 차분(11장)은 모두 삼중대각계를 냅니다. n=106n = 10^6이면 꽉 찬 LU는 7×10177\times10^{17}번의 연산이지만, 삼중대각 구조를 쓰면 8×1068\times10^6번입니다.

삼중대각계 aixi−1+bixi+cixi+1=dia_ix_{i-1} + b_ix_i + c_ix_{i+1} = d_i(a1=cn=0a_1 = c_n = 0)에 피벗팅 없는 소거를 쓰면 LL과 UU도 두 줄짜리 띠로 남습니다. 행마다 위쪽 행을 한 번 빼서 정규화한 계수 ci′c_i', di′d_i'를 만들고(전진 소거), 아래에서 위로 대입합니다.

function thomas(a, b, c, d)        // 길이 n, a[1] = c[n] = 0
  c'[1] ← c[1] / b[1];   d'[1] ← d[1] / b[1]
  for i = 2 … n                     // 전진 소거: 행마다 상수 번
    m ← b[i] − a[i]·c'[i−1]           // 이번 행의 피벗
    c'[i] ← c[i] / m
    d'[i] ← (d[i] − a[i]·d'[i−1]) / m
  x[n] ← d'[n]
  for i = n−1 … 1                   // 후진 대입
    x[i] ← d'[i] − c'[i]·x[i+1]
  return x                          // 총 약 8n 연산, 메모리 O(n)
정리 12.6 (토머스 알고리즘의 안정 조건) 행렬이 대각 우세(diagonally dominant)이면, 즉 모든 ii에서 ∣bi∣≥∣ai∣+∣ci∣|b_i| \ge |a_i| + |c_i|이고 적어도 한 행에서 부등호가 엄격하면(그리고 기약이면), 토머스 알고리즘의 모든 피벗 mim_i가 0이 아니고 ∣ci′∣≤1|c_i'| \le 1이다. 따라서 피벗팅 없이 안정하다. 대칭 양정치 삼중대각 행렬에서도 같은 결론이 성립한다.

귀납. ∣ci−1′∣≤1|c_{i-1}'| \le 1이면 ∣mi∣≥∣bi∣−∣ai∣∣ci−1′∣≥∣bi∣−∣ai∣≥∣ci∣|m_i| \ge |b_i| - |a_i||c_{i-1}'| \ge |b_i| - |a_i| \ge |c_i|이므로 ∣ci′∣=∣ci∣/∣mi∣≤1|c_i'| = |c_i|/|m_i| \le 1. 엄격한 행에서 ∣mi∣>0|m_i| \gt 0이 보장된다. 그래서 오차가 후진 대입에서 ∣ci′∣|c_i'|배 이상 커지지 않는다. ∎

예제 12.4 (4×4 토머스) bi=2b_i = 2, ai=ci=−1a_i = c_i = -1, d=(1,0,0,1)\mathbf d = (1, 0, 0, 1)(양 끝 온도가 1인 막대의 정상 상태).
i피벗 mᵢc′ᵢd′ᵢxᵢ
12−1/21/21
22 − 1/2 = 3/2−2/3(0 + 1/2)/(3/2) = 1/31
32 − 2/3 = 4/3−3/4(1/3)/(4/3) = 1/41
42 − 3/4 = 5/40(1 + 1/4)/(5/4) = 11
피벗은 (i+1)/i(i + 1)/i로 1보다 크고, ∣ci′∣=i/(i+1)<1|c_i'| = i/(i + 1) \lt 1이다. 후진 대입: x4=1x_4 = 1, x3=1/4+3/4=1x_3 = 1/4 + 3/4 = 1, … 모두 1. 막대 전체가 1도가 된다(정상 상태 온도는 양 끝 사이의 직선).

반띠폭이 ww인 띠 행렬로 일반화하면 연산 O(nw2)O(nw^2), 저장 O(nw)O(nw)입니다(LinearBook 정리 4.5). 부분 피벗팅을 쓰면 UU의 위쪽 띠가 2w2w까지 넓어질 수 있으므로 LAPACK의 띠 풀이기(dgbsv)는 그만큼 여분의 자리를 마련합니다.

SIMULATOR

토머스 알고리즘 한 행씩, 그리고 실제 걸리는 시간

c′ᵢ(막대)와 해 xᵢ(점): 전진 소거 → 후진 대입
이 브라우저에서 잰 시간 (로그–로그)
c′ᵢxᵢ꽉 찬 LU 시간토머스 시간
단계—
피벗 mᵢ · c′ᵢ—
max |c′ᵢ|—
잰 기울기 LU · 토머스—
해볼 것: ① '다음 행'으로 전진 소거를 진행하면 c′ᵢ 막대가 하나씩 생기고, 끝에 닿으면 후진 대입이 오른쪽에서 왼쪽으로 xᵢ를 채웁니다. ② bᵢ = 2(대각 우세의 경계)에서 |c′ᵢ| = i/(i + 1)이 1에 다가가고, bᵢ를 키우면 빨리 수렴합니다. bᵢ < 2로 내리면 대각 우세가 깨지고 피벗이 0을 지나며 |c′ᵢ|가 커질 수 있습니다(bᵢ = 1.2 근처). ③ '시간 재기'는 꽉 찬 LU(n = 50 … 400)와 토머스(n = 10³ … 10⁶)를 실제로 돌려 기울기 3과 1을 측정합니다. 모델: n = 24 (단계 보기), 시간은 같은 n을 여러 번 반복한 평균.

노름, 조건수, 그리고 오차 한계

답이 몇 자리까지 맞는가

LU 분해로 얻은 해를 원래 식에 넣었더니 잔차 b−Ax^\mathbf b - A\hat{\mathbf x}가 10−1510^{-15}입니다. 그럼 x^\hat{\mathbf x}도 15자리까지 맞을까요? 그렇지 않을 수 있습니다. 잔차는 후방 오차를, 우리가 알고 싶은 것은 전방 오차를 재고, 두 오차 사이의 환율이 조건수입니다(2장).

정의 12.7 (벡터 노름과 유도 행렬 노름) ∥x∥1=∑∣xi∣\|\mathbf x\|_1 = \sum|x_i|, ∥x∥2=∑xi2\|\mathbf x\|_2 = \sqrt{\sum x_i^2}, ∥x∥∞=max⁡∣xi∣\|\mathbf x\|_\infty = \max|x_i|. 각 벡터 노름이 유도하는 행렬 노름 ∥A∥=max⁡x≠0∥Ax∥/∥x∥\|A\| = \max_{\mathbf x \ne 0}\|A\mathbf x\|/\|\mathbf x\|는
∥A∥1=max⁡j∑i∣aij∣ (열 합),∥A∥∞=max⁡i∑j∣aij∣ (행 합),∥A∥2=σmax⁡(A).\|A\|_1 = \max_j\sum_i|a_{ij}|\ (\text{열 합}),\qquad \|A\|_\infty = \max_i\sum_j|a_{ij}|\ (\text{행 합}),\qquad \|A\|_2 = \sigma_{\max}(A).
가역 행렬의 조건수(condition number)는 κ(A)=∥A∥ ∥A−1∥\kappa(A) = \|A\|\,\|A^{-1}\|이고, 2-노름에서 κ2=σmax⁡/σmin⁡\kappa_2 = \sigma_{\max}/\sigma_{\min}이다.
예제 12.5 (세 노름의 조건수) A=[1234]A = \begin{bmatrix}1 & 2\\ 3 & 4\end{bmatrix}, A−1=[−211.5−0.5]A^{-1} = \begin{bmatrix}-2 & 1\\ 1.5 & -0.5\end{bmatrix}.
  1. ∥A∥1=max⁡(4,6)=6\|A\|_1 = \max(4, 6) = 6, ∥A−1∥1=max⁡(3.5,1.5)=3.5\|A^{-1}\|_1 = \max(3.5, 1.5) = 3.5, κ1=21\kappa_1 = 21.
  2. ∥A∥∞=max⁡(3,7)=7\|A\|_\infty = \max(3, 7) = 7, ∥A−1∥∞=max⁡(3,2)=3\|A^{-1}\|_\infty = \max(3, 2) = 3, κ∞=21\kappa_\infty = 21.
  3. ATA=[10141420]A^{\mathsf T}A = \begin{bmatrix}10 & 14\\ 14 & 20\end{bmatrix}의 고윳값의 제곱근이 σ1=5.4650\sigma_1 = 5.4650, σ2=0.36597\sigma_2 = 0.36597이므로 κ2=14.93\kappa_2 = 14.93. 노름에 따라 값은 다르지만 크기 정도(자릿수)는 같다. 모든 노름은 nn에 의존하는 상수배 안에서 동등하다.
정리 12.8 (오차 한계와 잔차) Ax=bA\mathbf x = \mathbf b의 근사해 x^\hat{\mathbf x}의 잔차를 r=b−Ax^\mathbf r = \mathbf b - A\hat{\mathbf x}라 하면
1κ(A)∥r∥∥b∥  ≤  ∥x−x^∥∥x∥  ≤  κ(A)∥r∥∥b∥.\frac{1}{\kappa(A)}\frac{\|\mathbf r\|}{\|\mathbf b\|} \;\le\; \frac{\|\mathbf x - \hat{\mathbf x}\|}{\|\mathbf x\|} \;\le\; \kappa(A)\frac{\|\mathbf r\|}{\|\mathbf b\|}.
우변 섭동 δb\delta\mathbf b에 대해 ∥δx∥/∥x∥≤κ ∥δb∥/∥b∥\|\delta\mathbf x\|/\|\mathbf x\| \le \kappa\,\|\delta\mathbf b\|/\|\mathbf b\|, 행렬 섭동 δA\delta A에 대해(κ∥δA∥/∥A∥<1\kappa\|\delta A\|/\|A\| \lt 1이면) ∥δx∥∥x∥≤κ ∥δA∥/∥A∥1−κ ∥δA∥/∥A∥\dfrac{\|\delta\mathbf x\|}{\|\mathbf x\|} \le \dfrac{\kappa\,\|\delta A\|/\|A\|}{1 - \kappa\,\|\delta A\|/\|A\|}.

증명의 핵심. x−x^=A−1r\mathbf x - \hat{\mathbf x} = A^{-1}\mathbf r이므로 ∥x−x^∥≤∥A−1∥∥r∥\|\mathbf x - \hat{\mathbf x}\| \le \|A^{-1}\|\|\mathbf r\|, 한편 ∥b∥≤∥A∥∥x∥\|\mathbf b\| \le \|A\|\|\mathbf x\|. 두 식을 곱하면 오른쪽 부등식. 왼쪽은 ∥r∥≤∥A∥∥x−x^∥\|\mathbf r\| \le \|A\|\|\mathbf x - \hat{\mathbf x}\|, ∥x∥≤∥A−1∥∥b∥\|\mathbf x\| \le \|A^{-1}\|\|\mathbf b\|에서 나온다. ∎

정리 12.3과 합치면 실용적인 경험 법칙이 나옵니다. 후방 안정한 풀이기는 ∥δA∥/∥A∥≈u≈10−16\|\delta A\|/\|A\| \approx u \approx 10^{-16}인 문제를 정확히 푸는 셈이므로, 상대 오차 ≈ κ·u, 즉 대략 log⁡10κ\log_{10}\kappa자리를 잃는다. κ = 10⁶이면 16자리 중 약 10자리가 남습니다. LAPACK은 κ를 직접 계산하지 않고(A−1A^{-1}이 필요하므로) LU 분해를 재사용해 O(n2)O(n^2)에 ∥A−1∥1\|A^{-1}\|_1을 추정합니다(dgecon).

작은 잔차 ≠ 작은 오차 A=[1111.0001]A = \begin{bmatrix}1 & 1\\ 1 & 1.0001\end{bmatrix}, b=(2,2.0001)\mathbf b = (2, 2.0001), 참해 (1,1)(1, 1), κ∞=4.0×104\kappa_\infty = 4.0\times10^4. 근사해 (2,0)(2, 0)은 잔차 (0,10−4)(0, 10^{-4})이지만 오차가 1(100%)이다. 근사해 (1.0001,1.0001)(1.0001, 1.0001)은 잔차 (−2×10−4,−2×10−4)(-2\times10^{-4}, -2\times10^{-4})로 두 배 크지만 오차는 10−410^{-4}이다. 잔차로 해를 고르면 나쁜 쪽을 고른다.
SIMULATOR

두 직선의 교점: 조건수가 측정 오차를 키우는 모습

두 직선의 방향 손잡이를 끌기
직선 1직선 2흔들린 b의 해 (구름)상한 κ‖δb‖/‖b‖의 상자
κ∞(A)—
κ₂(A)—
관찰한 최대 증폭률—
잃는 자릿수 ≈ log₁₀ κ—
해볼 것: ① 두 직선을 거의 평행하게 돌리면 해의 구름이 직선 방향으로 길게 늘어나고 κ가 수백으로 커집니다. 관찰한 증폭률(‖δx‖/‖x‖ ÷ ‖δb‖/‖b‖)은 언제나 κ∞ 이하입니다. ② '척도 ×1000'은 직선은 그대로인데 한 식에 1000을 곱한 것입니다. 해의 구름은 변하지 않는 방향도 있는데 κ는 1000배 가까이 커집니다. 조건수는 행렬의 척도에 민감하고, 평형화가 필요한 이유입니다. 모델: A의 각 행은 직선의 법선 벡터, 참해 x = (1, 1), δb는 ∞-노름 상자 안의 균등 난수(시드 고정).

힐베르트 행렬: 깔끔한 분수, 사라지는 자릿수

Hij=1/(i+j−1)H_{ij} = 1/(i + j - 1)인 힐베르트 행렬(Hilbert matrix)은 구간 [0,1][0, 1]에서 단항식 1,x,…,xn−11, x, \dots, x^{n-1}으로 최소제곱 근사를 할 때 나오는 그람 행렬입니다(7장). 단항식들이 [0,1][0, 1]에서 서로 거의 같은 모양이라(높은 차수일수록 xkx^k과 xk+1x^{k+1}은 구별하기 어렵다) 열벡터들이 거의 일차 종속이 됩니다. 역행렬은 정수 원소를 가지는 공식이 알려져 있어 조건수를 정확히 계산할 수 있습니다.

n46810111213
κ∞(Hₙ)2.8×10⁴2.9×10⁷3.4×10¹⁰3.5×10¹³1.2×10¹⁵4.1×10¹⁶1.3×10¹⁸
부분 피벗팅 해의 오차 ‖x̂ − 1‖∞6.1×10⁻¹³5.3×10⁻¹⁰4.2×10⁻⁷3.2×10⁻⁴9.7×10⁻³0.364.2
상대 잔차 ‖b − Hx̂‖∞/‖b‖∞5×10⁻¹⁷02×10⁻¹⁶8×10⁻¹⁷1.5×10⁻¹⁶2.9×10⁻¹⁶2.8×10⁻¹⁶

표가 정리 12.8을 그대로 보여 줍니다. 잔차는 n과 무관하게 반올림 수준(후방 안정)인데, 오차는 κ·u를 따라 커져 n = 12에서 한 자리도 남지 않습니다. 단, 표의 b=H1\mathbf b = H\mathbf 1 자체도 반올림된 값이고 HH의 원소(1/31/3 등)도 정확히 저장되지 않으므로, 이 오차의 상당 부분은 풀이기 이전에 이미 입력 단계에서 생긴 것입니다. 어떤 알고리즘도 되돌릴 수 없는 몫입니다.

SIMULATOR

힐베르트 행렬 κ의 증가와 잃는 자릿수

κ∞(Hₙ), 오차, 잔차, κ·u (로그 눈금)
계산한 해 x̂ᵢ (참해는 모두 1)
계산 정밀도
κ∞(Hₙ)‖x̂ − x‖∞/‖x‖∞상대 잔차κ·u
κ∞(Hₙ)—
상대 오차—
남은 자릿수 −log₁₀(오차)—
예측: 16 − log₁₀ κ (단정밀도 7.2 − …)—
해볼 것: ① n을 하나 늘릴 때마다 κ가 약 30배(1.5자리) 커지고 오차 곡선이 κ·u 선을 따라 올라가는 것을 보세요. ② 잔차(초록)는 끝까지 바닥에 붙어 있습니다. 후방 안정성은 지켜지지만 답은 틀립니다. ③ 단정밀도로 바꾸면 n = 6에서 이미 자릿수가 거의 남지 않습니다. 모델: b = Hₙ·1을 같은 정밀도로 계산, 부분 피벗팅 LU, κ∞는 정수 원소 역행렬 공식으로 정확히 계산.

반복 개선: 싼 분해로 비싼 정확도를

GPU는 단정밀도가 몇 배 빠르다

많은 가속기에서 단정밀도(유효 숫자 약 7자리) 연산이 배정밀도보다 몇 배 빠르고 메모리도 절반입니다. 그런데 공학 계산은 배정밀도의 답을 원합니다. 23n3\tfrac23n^3의 분해는 싸게 단정밀도로 하고, 답은 배정밀도로 받을 수 있을까요?

근사해 x^\hat{\mathbf x}의 오차 e=x−x^\mathbf e = \mathbf x - \hat{\mathbf x}는 정확히 Ae=rA\mathbf e = \mathbf r을 만족합니다. 이 보정 방정식을 이미 있는 (부정확한) LU로 풀어 더하면, 보정값의 상대 오차가 처음 해와 같은 수준이어도 보정 자체가 작으므로 해는 한 단계 더 정확해집니다. 핵심은 잔차 r=b−Ax^\mathbf r = \mathbf b - A\hat{\mathbf x}를 높은 정밀도로 계산하는 것입니다. 거의 같은 두 수의 뺄셈이라 여기서 정밀도를 아끼면 자릿수 상쇄(1장)로 정보가 사라집니다.

function mixed_refine(A, b)
  (L, U, P) ← lu(single(A))              // O(n³): 단정밀도, 싸다
  x ← solve_single(L, U, P, b)            // O(n²)
  repeat
    r ← b − A·x                           // O(n²): 배정밀도 (원래 A로)
    d ← solve_single(L, U, P, r)          // 같은 분해 재사용
    x ← x + d                             // 배정밀도로 더하기
  until ‖d‖ ≤ 작은 수·‖x‖
  return x
정리 12.9 (반복 개선의 수렴) 분해의 정밀도를 ufu_f, 잔차와 갱신의 정밀도를 uu라 하자. 대략 κ(A) uf<1\kappa(A)\,u_f \lt 1이면 반복마다 오차가 κuf\kappa u_f 정도의 비율로 줄어, 몇 번 만에 ∥x−x^∥/∥x∥≈κ(A) u\|\mathbf x - \hat{\mathbf x}\|/\|\mathbf x\| \approx \kappa(A)\,u(배정밀도 풀이기와 같은 수준)에 도달한다. κuf≥1\kappa u_f \ge 1이면 수렴이 보장되지 않는다.
n = 40, 단정밀도 LU + 배정밀도 잔차처음1회2회3회6회
κ = 10²2.5×10⁻⁶1.1×10⁻¹²6.8×10⁻¹⁵4.9×10⁻¹⁵6.3×10⁻¹⁵
κ = 10⁴6.8×10⁻⁵8.3×10⁻¹⁰3.6×10⁻¹³4.2×10⁻¹³4.0×10⁻¹³
κ = 10⁶3.7×10⁻³2.1×10⁻⁶5.7×10⁻⁹6.8×10⁻¹¹3.4×10⁻¹¹
κ = 10⁸2.2×10⁻¹1.2×10⁻²1.0×10⁻³9.5×10⁻⁵8.5×10⁻⁸

표는 특이값이 11부터 1/κ1/\kappa까지 등비로 퍼진 행렬로 만든 실험입니다(상대 오차, ∞-노름). κ = 10⁴에서는 단 두 번 만에 오차가 6.8×10−56.8\times10^{-5}에서 배정밀도 바닥 κu≈10−12\kappa u \approx 10^{-12} 근처로 떨어집니다. 단정밀도의 uf≈6×10−8u_f \approx 6\times10^{-8}이므로 κ = 10⁸은 κuf≈6\kappa u_f \approx 6으로 정리의 조건 밖입니다. 이 실험에서는 반복마다 약 한 자리씩 느리게 줄었지만, 다른 행렬에서는 정체하거나 발산할 수 있습니다. 최근의 혼합 정밀도 풀이기는 보정 방정식을 GMRES(13장)로 풀어 이 한계를 넓힙니다.

SIMULATOR

혼합 정밀도 반복 개선: 단정밀도 LU에서 배정밀도 답까지

잔차 계산 정밀도
상대 오차상대 잔차κ·u₆₄, κ·u₃₂
반복—
상대 오차—
줄어든 비율 (이번 / 직전)—
κ·u₃₂—
해볼 것: ① κ = 10⁴에서 '개선 한 번'을 두세 번 누르면 오차가 단정밀도 수준(κ·u₃₂ 선 부근)에서 배정밀도 바닥(κ·u₆₄)까지 내려옵니다. ② 잔차를 단정밀도로 계산하면 오차가 κ·u₃₂ 근처에서 멈춥니다. 잔차의 정밀도가 최종 정확도를 정합니다. ③ κ를 10⁸ 이상으로 올리면 수렴이 느려지거나 멈춥니다(κ·u₃₂ > 1). 모델: A = U Σ Vᵀ, U·V는 하우스홀더 반사 3개의 곱(시드 고정), 특이값은 1 … 1/κ 등비. 단정밀도는 Math.fround로 매 연산을 반올림.

희소 행렬과 채움, 재배열

400개짜리 격자, 저장은 어디까지 커지나

20×20 격자의 푸아송 방정식(16장)은 미지수 400개, 행마다 0이 아닌 원소가 많아야 5개입니다. 대칭이니 아래 삼각만 세면 0 아닌 칸이 1,160개입니다. 촐레스키 분해의 LL은 몇 칸을 차지할까요? 꽉 찬 하삼각이면 80,200칸입니다.

희소 행렬은 0 아닌 원소만 저장합니다. 가장 흔한 형식 CSR(compressed sparse row)은 값 배열, 열 번호 배열, 각 행의 시작 위치 배열 세 개로 행렬을 담아 저장량이 원소 수 nnz\mathrm{nnz}에 비례합니다. 문제는 분해입니다. 소거 중 aij←aij−ℓikukja_{ij} \leftarrow a_{ij} - \ell_{ik}u_{kj}에서 aij=0a_{ij} = 0이어도 ℓik\ell_{ik}와 ukju_{kj}가 둘 다 0이 아니면 새 원소가 생깁니다.

정의 12.10 (채움과 소거 그래프) 분해 LL(또는 L+UL + U)에는 0이 아닌데 AA에서는 0인 원소를 채움(fill-in)이라 한다. 대칭 행렬을 그래프(정점 = 미지수, 변 = 0 아닌 aija_{ij})로 보면, 정점 kk를 소거하는 것은 kk의 아직 소거되지 않은 이웃들을 모두 서로 잇는 것(클리크 만들기)과 같다. 새로 생긴 변이 채움이다. 채움의 양은 소거 순서, 곧 행렬의 재배열(reordering) PAPTPAP^{\mathsf T}에 따라 크게 달라진다.
k 소거 전: k의 이웃 4개 k를 소거한 뒤: 이웃끼리 6개의 변(빨강 = 채움) →
그림 12-1. 소거 그래프. 정점 kk를 소거하면 kk와 이어져 있던 정점들이 모두 서로 이어진다. 차수가 큰 정점을 일찍 소거하면 큰 클리크가 생기고, 차수가 작은 정점부터 소거하면 채움이 적다. 이것이 최소 차수 재배열의 아이디어다.

대표적인 재배열은 셋입니다. 역 커트힐–맥키(reverse Cuthill–McKee, RCM)는 너비 우선 탐색으로 번호를 매겨 띠폭을 줄입니다. 최소 차수(minimum degree)는 매 단계 소거 그래프에서 차수가 가장 작은 정점을 고릅니다(실무에서는 근사 최소 차수 AMD). 중첩 분할(nested dissection)은 격자를 분리자(separator) 한 줄로 반씩 나누고, 분리자를 맨 마지막에 번호 매기는 일을 재귀적으로 반복합니다. 2차원 k×kk\times k 격자에서 중첩 분할의 채움은 O(nlog⁡n)O(n\log n), 연산은 O(n3/2)O(n^{3/2})(n=k2n = k^2)로 점근적으로 최적이라는 것이 알려져 있습니다.

k × k 격자 푸아송, nnz(L) (대각 포함)k = 10 (n = 100)k = 20 (n = 400)k = 30 (n = 900)
A의 아래 삼각2801,1602,640
자연 순서 (행 단위 번호)1,0098,01927,029
RCM8055,91019,315
중첩 분할 (단순 구현)7814,86713,874
최소 차수 (탐욕)6563,72910,351
꽉 찬 하삼각 n(n+1)/25,05080,200405,450

표는 소거 그래프로 기호적 채움을 센 값입니다(숫자 상쇄는 무시). 문제 상자의 답은 자연 순서 8,019칸, 최소 차수 3,729칸입니다. 이 크기에서는 탐욕적 최소 차수가 가장 적지만, 격자가 커질수록 중첩 분할의 점근적 우위가 드러나고 병렬화에도 유리해 대규모 FEM 풀이기(MUMPS, PARDISO 등)는 두 방법을 섞어 씁니다. 채움을 아무리 줄여도 3차원 문제에서는 LL이 너무 커지는 경우가 많아, 그때는 반복 해법(13장)으로 넘어갑니다.

SIMULATOR

희소 채움 시각화: 같은 격자, 다른 번호 매기기

왼쪽: PAPᵀ의 0 아닌 칸 · 오른쪽: L (빨강 = 채움)
격자 위의 번호 순서 (밝을수록 나중)
재배열
n · nnz(A 아래 삼각)—
nnz(L) · 채움—
촐레스키 연산 수 ∑ (열 길이)²—
꽉 찬 경우 대비—
해볼 것: ① '자연' 순서에서 채움(빨강)이 띠 안을 가득 채우는 것을 보세요. 띠폭이 k입니다. ② 'RCM'은 띠를 조금 좁히고, '중첩 분할'은 분리자(가운데 줄)를 마지막에 두어 오른쪽 아래 블록에 채움을 모읍니다. ③ '최소 차수'는 구조가 무질서해 보이지만 채움이 가장 적습니다. '소거 진행'을 움직이면 소거 그래프에서 채움이 생기는 순서를 따라갈 수 있습니다. 모델: 5점 스텐실 격자 라플라시안, 기호적 촐레스키(숫자 상쇄 무시), 연산 수는 열마다 (그 열의 0 아닌 원소 수)²의 합.

이 도구가 쓰이는 곳

분야행렬의 성격쓰이는 직접 해법
회로망 해석(수정 노드 해석)희소, 비대칭(전원·제어 소스), 시간 걸음마다 같은 구조희소 LU + 재배열, 기호 분해를 한 번만 하고 수치 분해를 반복
구조 해석(트러스·골조)대칭 양정치 강성 행렬 KK희소 촐레스키(스카이라인·다중 전면 방식)
유한 요소 강성 행렬대칭 양정치, 2·3차원 격자 구조중첩 분할 + 촐레스키, 3차원 대형은 반복 해법과 전처리
1차원 확산·스플라인·크랭크–니콜슨삼중대각, 대각 우세토머스 알고리즘 O(n)O(n)
강성 ODE 풀이기·뉴턴 반복I−γhJI - \gamma hJ, 걸음마다 비슷한 행렬LU 분해를 여러 걸음 재사용(11장)

핵심 정리

  1. LU 분해는 23n3\tfrac23n^3 연산, 대입은 2n22n^2이다. 분해 한 번으로 여러 우변·행렬식·전치 계를 푼다. 역행렬은 2n32n^3이고 덜 정확하므로 계산하지 않는다.
  2. 작은 피벗은 큰 승수를 만들어 정보를 지운다. 부분 피벗팅은 ∣ℓ∣≤1|\ell| \le 1을 보장하지만 행 척도에 속을 수 있고(척도 부분 피벗팅·평형화), 완전 피벗팅은 더 안전하지만 비싸다.
  3. 소거의 후방 오차는 성장 인자 ρn\rho_n에 비례한다. 부분 피벗팅의 최악은 2n−12^{n-1}(윌킨슨 행렬)이지만 실제 행렬에서는 작아서 표준이 되었다.
  4. 대칭 양정치 행렬은 촐레스키 A=LLTA = LL^{\mathsf T}로 피벗팅 없이 안정하게 절반 비용(13n3\tfrac13n^3)에 분해되고, 분해의 성공 여부가 양정치 판정이 된다.
  5. 삼중대각계는 토머스 알고리즘으로 8n8n 연산에 풀리고, 대각 우세이면 ∣ci′∣≤1|c_i'| \le 1이라 안정하다. 띠 행렬은 O(nw2)O(nw^2).
  6. κ(A)=∥A∥∥A−1∥\kappa(A) = \|A\|\|A^{-1}\|. 상대 오차 ≤ κ × 상대 잔차, 후방 안정한 풀이기의 오차 ≈ κu이므로 약 log⁡10κ\log_{10}\kappa자리를 잃는다. 작은 잔차가 작은 오차를 뜻하지 않는다.
  7. 힐베르트 행렬은 κ가 n마다 약 30배 커져 n = 12에서 배정밀도의 자릿수를 모두 잃는다. 잔차는 끝까지 작다.
  8. 반복 개선은 잔차를 높은 정밀도로 계산해 같은 분해로 보정한다. κuf<1\kappa u_f \lt 1이면 단정밀도 분해로 배정밀도 정확도를 얻는다.
  9. 희소 분해의 채움은 소거 순서로 정해진다. RCM(띠 줄이기), 최소 차수, 중첩 분할이 메모리와 연산을 몇 배에서 몇 자릿수까지 줄인다.

확인 퀴즈

Q1. n = 2000인 꽉 찬 행렬의 LU 분해가 2초 걸렸다. 같은 분해로 우변 100개를 더 푸는 데 드는 시간은 대략?

분해 23n3\tfrac23n^3 대 대입 2n22n^2의 비는 n/3 ≈ 667. 우변 하나는 2초/667 ≈ 0.003초, 100개면 약 0.3초. (대입은 캐시 재사용이 적어 실제로는 몇 배 더 걸릴 수 있지만 분해보다 훨씬 싸다.)

Q2. 부분 피벗팅이 보장하는 것은?

부분 피벗팅은 열의 최댓값을 피벗으로 써서 승수를 1 이하로 묶는다. 그래도 성장 인자는 최대 2ⁿ⁻¹까지 갈 수 있고(윌킨슨 행렬), 조건수는 문제의 성질이라 알고리즘이 바꾸지 못한다.

Q3. A=[9335]A = \begin{bmatrix}9 & 3\\ 3 & 5\end{bmatrix}의 촐레스키 인자 LL의 ℓ22\ell_{22}는?

ℓ11=3\ell_{11} = 3, ℓ21=3/3=1\ell_{21} = 3/3 = 1, ℓ22=5−12=2\ell_{22} = \sqrt{5 - 1^2} = 2. 확인: det⁡A=45−9=36=(3⋅2)2\det A = 45 - 9 = 36 = (3\cdot 2)^2.

Q4. 삼중대각계에서 토머스 알고리즘을 피벗팅 없이 안전하게 쓸 수 있는 충분조건은?

|bᵢ| ≥ |aᵢ| + |cᵢ|(한 행 이상 엄격)이면 귀납적으로 |c′ᵢ| ≤ 1이고 피벗이 0이 아니다. 대칭 양정치여도 안전하다. 대칭이거나 대각이 양수인 것만으로는 부족하다.

Q5. κ∞(A) = 10⁹인 계를 배정밀도(u ≈ 10⁻¹⁶)의 후방 안정한 풀이기로 풀었다. 해는 대략 몇 자리 맞는가?

상대 오차 ≈ κu = 10⁹ × 10⁻¹⁶ = 10⁻⁷. 16자리 중 log₁₀ κ = 9자리를 잃어 약 7자리가 남는다.

Q6. 근사해 x̂의 상대 잔차 ‖b − Ax̂‖/‖b‖가 10⁻¹⁴이고 κ(A) = 10⁶이다. 상대 오차에 대해 확실히 말할 수 있는 것은?

정리 12.8: 상대 오차 ≤ κ·상대 잔차 = 10⁶ × 10⁻¹⁴ = 10⁻⁸. 아래쪽 한계는 잔차/κ = 10⁻²⁰이라 '이상'이 맞지만 의미 있는 정보는 상한 쪽이다. 실제 오차는 이 사이 어디든 될 수 있다.

Q7. 반복 개선에서 잔차 r = b − Ax를 분해와 같은 단정밀도로 계산하면 어떻게 되는가?

r은 거의 같은 두 벡터의 차라 자릿수 상쇄가 일어난다. 단정밀도로 계산하면 r 자체가 단정밀도 수준의 정보만 담아, 보정해도 단정밀도 풀이기 이상의 정확도를 얻지 못한다. 최종 정확도는 잔차의 정밀도가 정한다.

Q8. '허브' 정점 하나가 다른 모든 정점과 연결된 화살표 모양 희소 행렬을 촐레스키 분해할 때 채움을 0으로 만드는 순서는?

허브를 먼저 소거하면 그 이웃(나머지 전부)이 서로 이어져 L이 꽉 찬다. 다른 정점은 이웃이 허브 하나뿐이라 먼저 소거해도 새 변이 생기지 않는다. 최소 차수 재배열이 정확히 이렇게 고른다.