連立一次方程式をコンピュータで解くとき、答えは丸め誤差のせいで少しずれます。その「少し」がどれくらいなのか、問題が難しいせいなのか、解き方が悪いせいなのかを、きちんと見分けるのがこの記事の話です。Gauss の消去法を「行列を 2 つの三角形の積に分ける」手順として読み直し、行の入れ替え(ピボット選択)がなぜ必要か、入れ替えても数値が極端に膨らむ例があるか、を順に調べます。読み終えると、numpy.linalg.solve が返す解をどこまで信頼してよいかを、式を使って説明できるようになります。
先頭の主小行列式がすべて 0 0 0 でないことと、A = L U A=LU A = LU (L L L は対角が 1 1 1 の下三角、U U U は正則な上三角)と一意に書けることは同値です。部分ピボット選択 を使えば、どんな正方行列も P A = L U PA=LU P A = LU , ∣ l i j ∣ ≤ 1 |l_{ij}|\le1 ∣ l ij ∣ ≤ 1 と分解できます。演算量は 2 3 n 3 + O ( n 2 ) \tfrac23n^3+O(n^2) 3 2 n 3 + O ( n 2 ) です。
浮動小数点数で計算した因子は L ^ U ^ = A + Δ A \hat L\hat U=A+\Delta A L ^ U ^ = A + Δ A , ∣ Δ A ∣ ≤ γ n ∣ L ^ ∣ ∣ U ^ ∣ |\Delta A|\le\gamma_n|\hat L||\hat U| ∣Δ A ∣ ≤ γ n ∣ L ^ ∣∣ U ^ ∣ を満たし、前進代入・後退代入と合わせた解は ( A + Δ A ) x ^ = b (A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b} ( A + Δ A ) x ^ = b , ∣ Δ A ∣ ≤ γ 3 n ∣ L ^ ∣ ∣ U ^ ∣ |\Delta A|\le\gamma_{3n}|\hat L||\hat U| ∣Δ A ∣ ≤ γ 3 n ∣ L ^ ∣∣ U ^ ∣ を満たします。丸めの基本は既存の「1 ステップの丸め誤差」の補題に帰着します。
後退誤差を ∣ A ∣ |A| ∣ A ∣ の尺度で小さくできるかは ∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ の大きさ、つまり成長因子 ρ n \rho_n ρ n で決まります。部分ピボット選択では ρ n ≤ 2 n − 1 \rho_n\le2^{n-1} ρ n ≤ 2 n − 1 で、この上界に達する行列(Wilkinson の例)があります。ただし乱数行列では ρ n \rho_n ρ n はずっと小さく、実用上は後退安定とみなされます。
列対角優位な行列はピボット選択なしで消去でき、ρ n ≤ 2 \rho_n\le2 ρ n ≤ 2 です。Schur 補行列が列対角優位を保つからです。
反復改良 : 補正方程式を誤差 E k E_k E k のある分解で解いても、∥ A − 1 E k ∥ ≤ θ < 1 / 2 \|A^{-1}E_k\|\le\theta\lt1/2 ∥ A − 1 E k ∥ ≤ θ < 1/2 なら誤差は 1 回ごとに θ / ( 1 − θ ) \theta/(1-\theta) θ / ( 1 − θ ) 倍以下に縮みます。binary32 の LU と binary64 の残差を組み合わせた混合精度の解法の根拠です。
この記事で使う事前知識
後退誤差 : 計算で得た解を「元の問題を少し変えたものの正確な解」とみなしたときの、変え方の大きさ。→ ノルムに関する後退誤差
条件数 : 入力の小さな変化が解をどれだけ変えるかを表す数。前進誤差は条件数 × 後退誤差で抑えられます。→ 条件数
誘導ノルム : ベクトルのノルムから決まる行列のノルム。行列とベクトルの積の大きさを測ります。→ 誘導ノルム
単位丸め u u u と γ k \gamma_k γ k : 1 回の演算の相対誤差の上限が u u u 、k k k 回分をまとめた上限が γ k = k u / ( 1 − k u ) \gamma_k=ku/(1-ku) γ k = k u / ( 1 − k u ) 。→ 浮動小数点数と丸め誤差
成分ごとの後退誤差 : 行列の各成分ごとに相対的な変化の大きさを測る後退誤差。→ 成分ごとの後退誤差
連立一次方程式 A x = b A\boldsymbol{x}=\boldsymbol{b} A x = b を解く標準的な方法は、高校以来の掃き出し法(Gauss の消去法)です。数値計算では、これを「A A A を下三角 L L L と上三角 U U U の積に分解し、L y = b L\boldsymbol{y}=\boldsymbol{b} L y = b , U x = y U\boldsymbol{x}=\boldsymbol{y} U x = y を順に解く」と読み直します。分解は O ( n 3 ) O(n^3) O ( n 3 ) 、三角方程式は O ( n 2 ) O(n^2) O ( n 2 ) なので、同じ A A A で右辺を何本も解くときに分解を使い回せます。SciPy の scipy.linalg.solve、NumPy の numpy.linalg.solve の中身は LAPACK の getrf(部分ピボット選択つき LU 分解)と getrs(三角方程式)です。
この章の問いは、浮動小数点数で計算した解がどれだけ信頼できるかです。行列のノルムと線形方程式の条件数 の章で、前進誤差は条件数 × 後退誤差で抑えられることを見ました(系 7.3[行列のノルムと線形方程式の条件数] )。したがって示すべきは、Gauss 消去の後退誤差 が小さいことです。答えは「ピボット選択をすれば、ほとんどの場合に小さい」で、その「ほとんど」の中身が成長因子です。
A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) の左上の k k k 次の正方部分行列を A k A_k A k と書き、先頭主小行列 と呼びます。
定義 2.1 (LU 分解 ) ↗
A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) について、対角成分がすべて 1 1 1 の下三角行列 L L L (単位下三角行列 )と上三角行列 U U U で A = L U A=LU A = LU と書くことを、A A A の LU 分解 という。置換行列 P P P を使って P A = L U PA=LU P A = LU と書くことをピボット選択つき LU 分解 という。
三角行列について、次の 2 つの事実を何度も使います。
三角行列の行列式は対角成分の積です。n n n についての帰納法で、ブロック三角行列の行列式の公式(補題 4.1[行列の固有値評価と不等式] )を 1 + ( n − 1 ) 1+(n-1) 1 + ( n − 1 ) の分割に使えば出ます。
単位下三角行列 L L L は正則で、L − 1 L^{-1} L − 1 も単位下三角です。L X = I LX=I L X = I の第 j j j 列を前進代入で解くと、第 1 1 1 〜j − 1 j-1 j − 1 成分は 0 0 0 、第 j j j 成分は 1 1 1 になるからです。単位下三角行列どうしの積も単位下三角です(積の ( i , j ) (i,j) ( i , j ) 成分 ∑ k l i k m k j \sum_kl_{ik}m_{kj} ∑ k l ik m k j は i < j i\lt j i < j なら k ≤ i < j k\le i\lt j k ≤ i < j の項しか残らず 0 0 0 )。上三角についても同様です。
定理 2.2 (LU 分解の存在と一意性 ) ✓
A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) について、次は同値である。
先頭主小行列式がすべて 0 0 0 でない: det A k ≠ 0 \det A_k\ne0 det A k = 0 (k = 1 , … , n k=1,\ldots,n k = 1 , … , n )。
単位下三角行列 L L L と、対角成分がすべて 0 0 0 でない上三角行列 U U U で A = L U A=LU A = LU と書ける。
さらにこのとき、2 の L L L , U U U は一意で、u 11 ⋯ u k k = det A k u_{11}\cdots u_{kk}=\det A_k u 11 ⋯ u k k = det A k である。
証明(定理 2.2) 2 ⇒ 1. A = L U A=LU A = LU をブロックに分けると、L L L が下三角、U U U が上三角なので左上のブロックについて A k = L k U k A_k=L_kU_k A k = L k U k です(( L U ) i j = ∑ m l i m u m j (LU)_{ij}=\sum_ml_{im}u_{mj} ( LU ) ij = ∑ m l im u mj で、i , j ≤ k i,j\le k i , j ≤ k なら l i m ≠ 0 l_{im}\ne0 l im = 0 には m ≤ i ≤ k m\le i\le k m ≤ i ≤ k が必要)。積の定理(定理 6.1[行列式とその性質] )と三角行列の行列式から det A k = det L k det U k = u 11 ⋯ u k k ≠ 0 \det A_k=\det L_k\det U_k=u_{11}\cdots u_{kk}\ne0 det A k = det L k det U k = u 11 ⋯ u k k = 0 です。
1 ⇒ 2. n n n についての帰納法です。n = 1 n=1 n = 1 は L = ( 1 ) L=(1) L = ( 1 ) , U = ( a 11 ) U=(a_{11}) U = ( a 11 ) です。n − 1 n-1 n − 1 で正しいとし、
A = ( A n − 1 b c T a n n ) A=\begin{pmatrix}A_{n-1}&\boldsymbol{b}\\\boldsymbol{c}^{\mathsf{T}}&a_{nn}\end{pmatrix} A = ( A n − 1 c T b a nn ) と分けます。A n − 1 A_{n-1} A n − 1 の先頭主小行列は A 1 , … , A n − 1 A_1,\ldots,A_{n-1} A 1 , … , A n − 1 なので、帰納法の仮定から A n − 1 = L ′ U ′ A_{n-1}=L'U' A n − 1 = L ′ U ′ (L ′ L' L ′ は単位下三角、U ′ U' U ′ は対角が 0 0 0 でない上三角)です。U ′ U' U ′ , L ′ L' L ′ は正則なので
L = ( L ′ 0 c T U ′ − 1 1 ) , U = ( U ′ L ′ − 1 b 0 T δ ) , δ = a n n − c T A n − 1 − 1 b L=\begin{pmatrix}L'&\boldsymbol{0}\\\boldsymbol{c}^{\mathsf{T}}U'^{-1}&1\end{pmatrix},\qquad U=\begin{pmatrix}U'&L'^{-1}\boldsymbol{b}\\\boldsymbol{0}^{\mathsf{T}}&\delta\end{pmatrix},\qquad\delta=a_{nn}-\boldsymbol{c}^{\mathsf{T}}A_{n-1}^{-1}\boldsymbol{b} L = ( L ′ c T U ′ − 1 0 1 ) , U = ( U ′ 0 T L ′ − 1 b δ ) , δ = a nn − c T A n − 1 − 1 b とおくと、ブロックの積を計算して L U = A LU=A LU = A です(右下は c T U ′ − 1 L ′ − 1 b + δ = c T A n − 1 − 1 b + δ = a n n \boldsymbol{c}^{\mathsf{T}}U'^{-1}L'^{-1}\boldsymbol{b}+\delta=\boldsymbol{c}^{\mathsf{T}}A_{n-1}^{-1}\boldsymbol{b}+\delta=a_{nn} c T U ′ − 1 L ′ − 1 b + δ = c T A n − 1 − 1 b + δ = a nn )。積の定理とブロック三角行列の行列式(補題 4.1[行列の固有値評価と不等式] )から det A = det L det U = det U ′ ⋅ δ \det A=\det L\det U=\det U'\cdot\delta det A = det L det U = det U ′ ⋅ δ で、det A = det A n ≠ 0 \det A=\det A_n\ne0 det A = det A n = 0 なので δ ≠ 0 \delta\ne0 δ = 0 です。
一意性. L 1 U 1 = L 2 U 2 L_1U_1=L_2U_2 L 1 U 1 = L 2 U 2 なら L 2 − 1 L 1 = U 2 U 1 − 1 L_2^{-1}L_1=U_2U_1^{-1} L 2 − 1 L 1 = U 2 U 1 − 1 です。左辺は単位下三角、右辺は上三角なので、両辺は対角行列で、しかも対角が 1 1 1 、すなわち I I I です。よって L 1 = L 2 L_1=L_2 L 1 = L 2 , U 1 = U 2 U_1=U_2 U 1 = U 2 。最後の等式は 2 ⇒ 1 の計算です。
∎
構成から、U U U の対角成分 u k k = det A k / det A k − 1 u_{kk}=\det A_k/\det A_{k-1} u k k = det A k / det A k − 1 は消去の k k k 段目のピボット です。δ \delta δ は A A A の A n − 1 A_{n-1} A n − 1 に関する Schur 補行列(定理 4.2[行列の固有値評価と不等式] )で、消去の各段で残る右下のブロックは、すべて Schur 補行列です(左上のブロックを消去したあとに右下に残る、「B − l w T B-\boldsymbol{l}\boldsymbol{w}^{\mathsf{T}} B − l w T 」の形の小さい行列のことです)。
det A 1 = a 11 = 0 \det A_1=a_{11}=0 det A 1 = a 11 = 0 なら、正則な A = ( 0 1 1 0 ) A=\begin{pmatrix}0&1\\1&0\end{pmatrix} A = ( 0 1 1 0 ) でも LU 分解はありません。行を入れ替えれば解決します。数値計算では、さらにピボットの絶対値が最大になるように 行を入れ替えます。
定理 2.3 (部分ピボット選択つき LU 分解 ) ✓
任意の A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) に対し、置換行列 P P P 、単位下三角行列 L L L 、上三角行列 U U U があって
P A = L U , ∣ l i j ∣ ≤ 1 ( i > j ) PA=LU,\qquad|l_{ij}|\le1\quad(i\gt j) P A = LU , ∣ l ij ∣ ≤ 1 ( i > j ) が成り立つ。A A A は特異でもよい(そのとき U U U の対角に 0 0 0 が現れる)。
証明(定理 2.3) n n n についての帰納法です。n = 1 n=1 n = 1 は P = L = ( 1 ) P=L=(1) P = L = ( 1 ) , U = A U=A U = A です。n ≥ 2 n\ge2 n ≥ 2 とし、第 1 列で絶対値が最大の成分の行 r r r を選び(部分ピボット選択 )、第 1 行と第 r r r 行を入れ替える置換行列を P 1 P_1 P 1 とします。
P 1 A = ( α w T v B ) , ∣ v i ∣ ≤ ∣ α ∣ P_1A=\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{v}&B\end{pmatrix},\qquad|v_i|\le|\alpha| P 1 A = ( α v w T B ) , ∣ v i ∣ ≤ ∣ α ∣ です。α ≠ 0 \alpha\ne0 α = 0 なら l = v / α \boldsymbol{l}=\boldsymbol{v}/\alpha l = v / α 、α = 0 \alpha=0 α = 0 なら(第 1 列は 0 0 0 なので v = 0 \boldsymbol{v}=\boldsymbol{0} v = 0 )l = 0 \boldsymbol{l}=\boldsymbol{0} l = 0 とおくと、∣ l i ∣ ≤ 1 |l_i|\le1 ∣ l i ∣ ≤ 1 で
P 1 A = ( 1 0 T l I ) ( α w T 0 S ) , S = B − l w T P_1A=\begin{pmatrix}1&\boldsymbol{0}^{\mathsf{T}}\\\boldsymbol{l}&I\end{pmatrix}\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{0}&S\end{pmatrix},\qquad S=B-\boldsymbol{l}\boldsymbol{w}^{\mathsf{T}} P 1 A = ( 1 l 0 T I ) ( α 0 w T S ) , S = B − l w T です(右辺の左下は α l = v \alpha\boldsymbol{l}=\boldsymbol{v} α l = v 、右下は l w T + S = B \boldsymbol{l}\boldsymbol{w}^{\mathsf{T}}+S=B l w T + S = B )。帰納法の仮定から P ′ S = L ′ U ′ P'S=L'U' P ′ S = L ′ U ′ , ∣ l i j ′ ∣ ≤ 1 |l'_{ij}|\le1 ∣ l ij ′ ∣ ≤ 1 です。P = diag ( 1 , P ′ ) P 1 P=\operatorname{diag}(1,P')P_1 P = diag ( 1 , P ′ ) P 1 とすると
P A = ( 1 0 T P ′ l P ′ ) ( α w T 0 S ) = ( α w T α P ′ l P ′ l w T + P ′ S ) = ( 1 0 T P ′ l L ′ ) ( α w T 0 U ′ ) PA=\begin{pmatrix}1&\boldsymbol{0}^{\mathsf{T}}\\P'\boldsymbol{l}&P'\end{pmatrix}\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{0}&S\end{pmatrix}=\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\alpha P'\boldsymbol{l}&P'\boldsymbol{l}\boldsymbol{w}^{\mathsf{T}}+P'S\end{pmatrix}=\begin{pmatrix}1&\boldsymbol{0}^{\mathsf{T}}\\P'\boldsymbol{l}&L'\end{pmatrix}\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{0}&U'\end{pmatrix} P A = ( 1 P ′ l 0 T P ′ ) ( α 0 w T S ) = ( α α P ′ l w T P ′ l w T + P ′ S ) = ( 1 P ′ l 0 T L ′ ) ( α 0 w T U ′ ) です(最後は P ′ S = L ′ U ′ P'S=L'U' P ′ S = L ′ U ′ を使いました)。右辺の左の因子は単位下三角で、成分は P ′ l P'\boldsymbol{l} P ′ l (l \boldsymbol{l} l の並べ替え)と L ′ L' L ′ の成分なので絶対値は 1 1 1 以下です。
∎
証明の手順がそのまま算法です。k k k 段目では、残っている右下のブロック A ( k ) A^{(k)} A ( k ) (A ( 1 ) = A A^{(1)}=A A ( 1 ) = A )の第 1 列から絶対値最大の行を選んで入れ替え、乗数 l i k = a i k ( k ) / a k k ( k ) l_{ik}=a^{(k)}_{ik}/a^{(k)}_{kk} l ik = a ik ( k ) / a k k ( k ) を作り、
a i j ( k + 1 ) = a i j ( k ) − l i k a k j ( k ) ( i , j > k ) a^{(k+1)}_{ij}=a^{(k)}_{ij}-l_{ik}a^{(k)}_{kj}\qquad(i,j\gt k) a ij ( k + 1 ) = a ij ( k ) − l ik a k j ( k ) ( i , j > k )
で次のブロックを作ります。U U U の第 k k k 行は a k j ( k ) a^{(k)}_{kj} a k j ( k ) (j ≥ k j\ge k j ≥ k )です。行の入れ替えは浮動小数点数でも厳密なので、丸め誤差の解析では、最終的な P P P を先に A A A に施した行列をピボット選択なしで消去した と考えてかまいません。
命題 2.4 (LU 分解の演算量 ) ✓
上の算法(ピボット選択の比較を除く)の浮動小数点演算の回数は 2 3 n 3 − 1 2 n 2 − 1 6 n \tfrac23n^3-\tfrac12n^2-\tfrac16n 3 2 n 3 − 2 1 n 2 − 6 1 n である。分解が済めば、L y = P b L\boldsymbol{y}=P\boldsymbol{b} L y = P b と U x = y U\boldsymbol{x}=\boldsymbol{y} U x = y は合わせて 2 n 2 − n 2n^2-n 2 n 2 − n 回で解ける。
証明(命題 2.4) k k k 段目(m = n − k m=n-k m = n − k とおく)は、乗数の割り算が m m m 回、a i j ( k + 1 ) a^{(k+1)}_{ij} a ij ( k + 1 ) の更新が m 2 m^2 m 2 個でそれぞれ乗算と減算の 2 回です。m = 1 , … , n − 1 m=1,\ldots,n-1 m = 1 , … , n − 1 について足すと
∑ m = 1 n − 1 ( 2 m 2 + m ) = ( n − 1 ) n ( 2 n − 1 ) 3 + n ( n − 1 ) 2 = 2 3 n 3 − 1 2 n 2 − 1 6 n \sum_{m=1}^{n-1}(2m^2+m)=\frac{(n-1)n(2n-1)}{3}+\frac{n(n-1)}{2}=\frac23n^3-\frac12n^2-\frac16n m = 1 ∑ n − 1 ( 2 m 2 + m ) = 3 ( n − 1 ) n ( 2 n − 1 ) + 2 n ( n − 1 ) = 3 2 n 3 − 2 1 n 2 − 6 1 n です。前進代入(対角は 1 1 1 なので割り算なし)は第 i i i 行で乗算と減算が i − 1 i-1 i − 1 回ずつで計 n 2 − n n^2-n n 2 − n 回、後退代入は第 i i i 行でさらに割り算 1 回が加わって計 n 2 n^2 n 2 回です。
∎
例 2.5 (ピボット選択なしで壊れる 2×2 の例 )
A = ( ε 1 1 1 ) A=\begin{pmatrix}\varepsilon&1\\1&1\end{pmatrix} A = ( ε 1 1 1 ) , b = ( 1 , 2 ) T \boldsymbol{b}=(1,2)^{\mathsf{T}} b = ( 1 , 2 ) T の解は x 1 = 1 / ( 1 − ε ) x_1=1/(1-\varepsilon) x 1 = 1/ ( 1 − ε ) , x 2 = ( 1 − 2 ε ) / ( 1 − ε ) x_2=(1-2\varepsilon)/(1-\varepsilon) x 2 = ( 1 − 2 ε ) / ( 1 − ε ) で、ε → 0 \varepsilon\to0 ε → 0 ではどちらも 1 1 1 に近く、κ ∞ ( A ) ≈ 4 \kappa_\infty(A)\approx4 κ ∞ ( A ) ≈ 4 と条件のよい問題です。binary64 で ε = 10 − 20 \varepsilon=10^{-20} ε = 1 0 − 20 としてピボット選択なしで消去すると、l 21 = 10 20 l_{21}=10^{20} l 21 = 1 0 20 , u 22 = f l ( 1 − 10 20 ) = − 10 20 u_{22}=\mathrm{fl}(1-10^{20})=-10^{20} u 22 = fl ( 1 − 1 0 20 ) = − 1 0 20 で、1 1 1 の情報が丸めで消えます。後退代入の結果は x ^ 2 = 1 \hat x_2=1 x ^ 2 = 1 , x ^ 1 = f l ( ( 1 − 1 ) / ε ) = 0 \hat x_1=\mathrm{fl}((1-1)/\varepsilon)=0 x ^ 1 = fl (( 1 − 1 ) / ε ) = 0 で、x 1 x_1 x 1 がまったく違います。部分ピボット選択なら 2 行を入れ替えて l 21 = ε l_{21}=\varepsilon l 21 = ε となり、numpy.linalg.solve は ( 1 , 1 ) (1,1) ( 1 , 1 ) を返します。L ^ U ^ \hat L\hat U L ^ U ^ の大きさを見ると、ピボット選択なしでは ∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ の成分が 10 20 10^{20} 1 0 20 に達し、次節の後退誤差の評価 γ ∣ L ^ ∣ ∣ U ^ ∣ \gamma|\hat L||\hat U| γ ∣ L ^ ∣∣ U ^ ∣ が ∣ A ∣ |A| ∣ A ∣ の尺度ではまったく小さくないことがわかります。
例 2.6 (三重対角行列の消去 )
A A A が三重対角(∣ i − j ∣ ≥ 2 |i-j|\ge2 ∣ i − j ∣ ≥ 2 で a i j = 0 a_{ij}=0 a ij = 0 )で、ピボット選択なしで消去できるとします。k k k 段目で第 k k k 列の非零は a k + 1 , k ( k ) a^{(k)}_{k+1,k} a k + 1 , k ( k ) だけで、第 k k k 行の非零は a k , k + 1 ( k ) a^{(k)}_{k,k+1} a k , k + 1 ( k ) だけなので、更新されるのは a k + 1 , k + 1 ( k + 1 ) a^{(k+1)}_{k+1,k+1} a k + 1 , k + 1 ( k + 1 ) の 1 成分だけです。したがって L L L は対角と 1 本下の副対角、U U U は対角と 1 本上の副対角だけをもち、分解は割り算・乗算・減算 1 回ずつの 3 ( n − 1 ) 3(n-1) 3 ( n − 1 ) 回で済みます。2 3 n 3 \tfrac23n^3 3 2 n 3 と比べると、比はおよそ 2 9 n 2 \tfrac29n^2 9 2 n 2 で、n = 10 6 n=10^6 n = 1 0 6 では約 2 × 10 11 2\times10^{11} 2 × 1 0 11 倍の差です。一般の帯行列で帯幅が保たれることは、Cholesky 分解と帯行列の章で定理として扱います。
以下、行列は浮動小数点数を成分とし、途中でオーバーフローもアンダーフローも起きず、3 n u < 1 3nu\lt1 3 n u < 1 とします。行列やベクトルの絶対値 ∣ A ∣ |A| ∣ A ∣ と不等号 ∣ E ∣ ≤ F |E|\le F ∣ E ∣ ≤ F は成分ごとです。丸めの記号 f l \mathrm{fl} fl 、γ k = k u / ( 1 − k u ) \gamma_k=ku/(1-ku) γ k = k u / ( 1 − k u ) は浮動小数点数と丸め誤差 の章のとおりです。
ピボット選択なしの消去を、浮動小数点数では次の順序で行うとします(行の入れ替えは厳密なので、部分ピボット選択の場合はあらかじめ入れ替えた P A PA P A に適用したと考えます)。a ^ i j ( 1 ) = a i j \hat a^{(1)}_{ij}=a_{ij} a ^ ij ( 1 ) = a ij とし、k = 1 , … , n − 1 k=1,\ldots,n-1 k = 1 , … , n − 1 について
l ^ i k = f l ( a ^ i k ( k ) / a ^ k k ( k ) ) , a ^ i j ( k + 1 ) = f l ( a ^ i j ( k ) − f l ( l ^ i k a ^ k j ( k ) ) ) ( i , j > k ) \hat l_{ik}=\mathrm{fl}\bigl(\hat a^{(k)}_{ik}/\hat a^{(k)}_{kk}\bigr),\qquad\hat a^{(k+1)}_{ij}=\mathrm{fl}\bigl(\hat a^{(k)}_{ij}-\mathrm{fl}(\hat l_{ik}\hat a^{(k)}_{kj})\bigr)\qquad(i,j\gt k) l ^ ik = fl ( a ^ ik ( k ) / a ^ k k ( k ) ) , a ^ ij ( k + 1 ) = fl ( a ^ ij ( k ) − fl ( l ^ ik a ^ k j ( k ) ) ) ( i , j > k )
を計算し、u ^ k j = a ^ k j ( k ) \hat u_{kj}=\hat a^{(k)}_{kj} u ^ k j = a ^ k j ( k ) (j ≥ k j\ge k j ≥ k )とします。成分 ( i , j ) (i,j) ( i , j ) に注目すると、s 0 = a i j s_0=a_{ij} s 0 = a ij から始めて s m = f l ( s m − 1 − f l ( l ^ i m u ^ m j ) ) s_m=\mathrm{fl}(s_{m-1}-\mathrm{fl}(\hat l_{im}\hat u_{mj})) s m = fl ( s m − 1 − fl ( l ^ im u ^ mj )) を m = 1 , 2 , … m=1,2,\ldots m = 1 , 2 , … と更新しており、これは既存の「1 ステップの丸め誤差」の補題(補題 4.1[行列計算の認証と最適化の証明書] )の形そのものです。つまり、消去の 1 成分の計算は「引き算と掛け算を何回か繰り返し、最後に割り算をする」だけの計算で、その丸め誤差は 1 つの補題でまとめて扱えます。下の引用は、その補題の主張だけを再掲したものです。
1 ステップの丸め誤差 (補題 4.1[行列計算の認証と最適化の証明書] の 1): c , a k , b k , d ∈ F c,a_k,b_k,d\in\mathbb{F} c , a k , b k , d ∈ F 、s 0 = c s_0=c s 0 = c , s k = f l ( s k − 1 − f l ( a k b k ) ) s_k=\mathrm{fl}(s_{k-1}-\mathrm{fl}(a_kb_k)) s k = fl ( s k − 1 − fl ( a k b k )) (k = 1 , … , m k=1,\ldots,m k = 1 , … , m )、y = f l ( s m / d ) y=\mathrm{fl}(s_m/d) y = fl ( s m / d ) なら、c = d y ( 1 + θ ( 0 ) ) + ∑ k = 1 m a k b k ( 1 + θ ( k ) ) c=dy(1+\theta^{(0)})+\sum_{k=1}^ma_kb_k(1+\theta^{(k)}) c = d y ( 1 + θ ( 0 ) ) + ∑ k = 1 m a k b k ( 1 + θ ( k ) ) , ∣ θ ( k ) ∣ ≤ γ m + 1 |\theta^{(k)}|\le\gamma_{m+1} ∣ θ ( k ) ∣ ≤ γ m + 1 と書ける。
補題 3.1 (三角方程式の後退誤差 ) ✓
T ∈ F n × n T\in\mathbb{F}^{n\times n} T ∈ F n × n を対角成分が 0 0 0 でない下三角行列、b ∈ F n \boldsymbol{b}\in\mathbb{F}^n b ∈ F n とし、前進代入
x ^ i = f l ( ( b i − ∑ k = 1 i − 1 t i k x ^ k ) / t i i ) \hat x_i=\mathrm{fl}\Bigl(\bigl(b_i-\textstyle\sum_{k=1}^{i-1}t_{ik}\hat x_k\bigr)/t_{ii}\Bigr) x ^ i = fl ( ( b i − ∑ k = 1 i − 1 t ik x ^ k ) / t ii ) (和は s ← f l ( s − f l ( t i k x ^ k ) ) s\leftarrow\mathrm{fl}(s-\mathrm{fl}(t_{ik}\hat x_k)) s ← fl ( s − fl ( t ik x ^ k )) で k = 1 , … , i − 1 k=1,\ldots,i-1 k = 1 , … , i − 1 の順に計算する)で x ^ \hat{\boldsymbol{x}} x ^ を求める。このとき
( T + Δ T ) x ^ = b , ∣ Δ T ∣ ≤ γ n ∣ T ∣ (T+\Delta T)\hat{\boldsymbol{x}}=\boldsymbol{b},\qquad|\Delta T|\le\gamma_n|T| ( T + Δ T ) x ^ = b , ∣Δ T ∣ ≤ γ n ∣ T ∣ となる下三角行列 Δ T \Delta T Δ T がある。上三角行列の後退代入(k k k を任意の順に計算してよい)についても同じことが成り立つ。
証明(補題 3.1) 第 i i i 行に「1 ステップの丸め誤差」の補題(補題 4.1[行列計算の認証と最適化の証明書] の 1)を c = b i c=b_i c = b i , m = i − 1 m=i-1 m = i − 1 , a k b k = t i k x ^ k a_kb_k=t_{ik}\hat x_k a k b k = t ik x ^ k , d = t i i d=t_{ii} d = t ii , y = x ^ i y=\hat x_i y = x ^ i で使うと
b i = t i i x ^ i ( 1 + θ i ( 0 ) ) + ∑ k = 1 i − 1 t i k x ^ k ( 1 + θ i ( k ) ) , ∣ θ i ( k ) ∣ ≤ γ i ≤ γ n b_i=t_{ii}\hat x_i(1+\theta^{(0)}_i)+\sum_{k=1}^{i-1}t_{ik}\hat x_k(1+\theta^{(k)}_i),\qquad|\theta^{(k)}_i|\le\gamma_i\le\gamma_n b i = t ii x ^ i ( 1 + θ i ( 0 ) ) + k = 1 ∑ i − 1 t ik x ^ k ( 1 + θ i ( k ) ) , ∣ θ i ( k ) ∣ ≤ γ i ≤ γ n です(γ k \gamma_k γ k は k k k について増加。補題 3.2[浮動小数点数と丸め誤差] の 1)。Δ t i i = t i i θ i ( 0 ) \Delta t_{ii}=t_{ii}\theta^{(0)}_i Δ t ii = t ii θ i ( 0 ) , Δ t i k = t i k θ i ( k ) \Delta t_{ik}=t_{ik}\theta^{(k)}_i Δ t ik = t ik θ i ( k ) (k < i k\lt i k < i )とおけば主張です。後退代入では和の項の番号を付け替えれば同じ議論です。
∎
この節の流れは次のとおりです。まず分解 L ^ U ^ \hat L\hat U L ^ U ^ が元の A A A から成分ごとにどれだけずれるかを示し、次に前進代入・後退代入の誤差(3.2 節)を重ねて、最終的な解が「A A A を少し変えた方程式の正確な解」になっていることを示します。どちらも、各成分に入る丸めの回数を数えて γ k \gamma_k γ k で上から抑えるだけです。
定理 3.2 (LU 分解の後退誤差 ) ✓
A ∈ F n × n A\in\mathbb{F}^{n\times n} A ∈ F n × n の 3.1 節の消去がピボット a ^ k k ( k ) ≠ 0 \hat a^{(k)}_{kk}\ne0 a ^ k k ( k ) = 0 のまま最後まで進み、L ^ \hat L L ^ (単位下三角、( i , k ) (i,k) ( i , k ) 成分 l ^ i k \hat l_{ik} l ^ ik )と U ^ \hat U U ^ を返したとする。このとき
L ^ U ^ = A + Δ A , ∣ Δ A ∣ ≤ γ n ∣ L ^ ∣ ∣ U ^ ∣ . \hat L\hat U=A+\Delta A,\qquad|\Delta A|\le\gamma_n|\hat L||\hat U|. L ^ U ^ = A + Δ A , ∣Δ A ∣ ≤ γ n ∣ L ^ ∣∣ U ^ ∣.
証明(定理 3.2) ( L ^ U ^ ) i j = ∑ k ≤ min ( i , j ) l ^ i k u ^ k j (\hat L\hat U)_{ij}=\sum_{k\le\min(i,j)}\hat l_{ik}\hat u_{kj} ( L ^ U ^ ) ij = ∑ k ≤ m i n ( i , j ) l ^ ik u ^ k j (l ^ i i = 1 \hat l_{ii}=1 l ^ ii = 1 )です。
i ≤ j i\le j i ≤ j のとき、u ^ i j = a ^ i j ( i ) \hat u_{ij}=\hat a^{(i)}_{ij} u ^ ij = a ^ ij ( i ) は s 0 = a i j s_0=a_{ij} s 0 = a ij から s m = f l ( s m − 1 − f l ( l ^ i m u ^ m j ) ) s_m=\mathrm{fl}(s_{m-1}-\mathrm{fl}(\hat l_{im}\hat u_{mj})) s m = fl ( s m − 1 − fl ( l ^ im u ^ mj )) (m = 1 , … , i − 1 m=1,\ldots,i-1 m = 1 , … , i − 1 )で得た s i − 1 s_{i-1} s i − 1 です。これは d = 1 d=1 d = 1 , y = f l ( s i − 1 / 1 ) = s i − 1 y=\mathrm{fl}(s_{i-1}/1)=s_{i-1} y = fl ( s i − 1 /1 ) = s i − 1 とした補題(補題 4.1[行列計算の認証と最適化の証明書] の 1)の形なので
a i j = u ^ i j ( 1 + θ ( 0 ) ) + ∑ k = 1 i − 1 l ^ i k u ^ k j ( 1 + θ ( k ) ) , ∣ θ ( k ) ∣ ≤ γ i ≤ γ n . a_{ij}=\hat u_{ij}(1+\theta^{(0)})+\sum_{k=1}^{i-1}\hat l_{ik}\hat u_{kj}(1+\theta^{(k)}),\qquad|\theta^{(k)}|\le\gamma_i\le\gamma_n. a ij = u ^ ij ( 1 + θ ( 0 ) ) + k = 1 ∑ i − 1 l ^ ik u ^ k j ( 1 + θ ( k ) ) , ∣ θ ( k ) ∣ ≤ γ i ≤ γ n . i > j i\gt j i > j のとき、l ^ i j = f l ( s j − 1 / u ^ j j ) \hat l_{ij}=\mathrm{fl}(s_{j-1}/\hat u_{jj}) l ^ ij = fl ( s j − 1 / u ^ j j ) で、s j − 1 s_{j-1} s j − 1 は同じ更新を m = 1 , … , j − 1 m=1,\ldots,j-1 m = 1 , … , j − 1 まで行った値です。補題を d = u ^ j j d=\hat u_{jj} d = u ^ j j , y = l ^ i j y=\hat l_{ij} y = l ^ ij で使うと
a i j = l ^ i j u ^ j j ( 1 + θ ( 0 ) ) + ∑ k = 1 j − 1 l ^ i k u ^ k j ( 1 + θ ( k ) ) , ∣ θ ( k ) ∣ ≤ γ j ≤ γ n . a_{ij}=\hat l_{ij}\hat u_{jj}(1+\theta^{(0)})+\sum_{k=1}^{j-1}\hat l_{ik}\hat u_{kj}(1+\theta^{(k)}),\qquad|\theta^{(k)}|\le\gamma_j\le\gamma_n. a ij = l ^ ij u ^ j j ( 1 + θ ( 0 ) ) + k = 1 ∑ j − 1 l ^ ik u ^ k j ( 1 + θ ( k ) ) , ∣ θ ( k ) ∣ ≤ γ j ≤ γ n . どちらの場合も a i j = ∑ k ≤ min ( i , j ) l ^ i k u ^ k j ( 1 + θ ( k ) ) a_{ij}=\sum_{k\le\min(i,j)}\hat l_{ik}\hat u_{kj}(1+\theta^{(k)}) a ij = ∑ k ≤ m i n ( i , j ) l ^ ik u ^ k j ( 1 + θ ( k ) ) なので、Δ a i j = ( L ^ U ^ ) i j − a i j = − ∑ k l ^ i k u ^ k j θ ( k ) \Delta a_{ij}=(\hat L\hat U)_{ij}-a_{ij}=-\sum_k\hat l_{ik}\hat u_{kj}\theta^{(k)} Δ a ij = ( L ^ U ^ ) ij − a ij = − ∑ k l ^ ik u ^ k j θ ( k ) で、∣ Δ a i j ∣ ≤ γ n ∑ k ∣ l ^ i k ∣ ∣ u ^ k j ∣ = γ n ( ∣ L ^ ∣ ∣ U ^ ∣ ) i j |\Delta a_{ij}|\le\gamma_n\sum_k|\hat l_{ik}||\hat u_{kj}|=\gamma_n(|\hat L||\hat U|)_{ij} ∣Δ a ij ∣ ≤ γ n ∑ k ∣ l ^ ik ∣∣ u ^ k j ∣ = γ n ( ∣ L ^ ∣∣ U ^ ∣ ) ij です。
∎
定理 3.3 (Gauss 消去による解の後退誤差 ) ✓
定理 3.2 の L ^ \hat L L ^ , U ^ \hat U U ^ を使い、前進代入 L ^ y ^ = b \hat L\hat{\boldsymbol{y}}=\boldsymbol{b} L ^ y ^ = b と後退代入 U ^ x ^ = y ^ \hat U\hat{\boldsymbol{x}}=\hat{\boldsymbol{y}} U ^ x ^ = y ^ を 補題 3.1 の算法で解いたとする。このとき
( A + Δ A ) x ^ = b , ∣ Δ A ∣ ≤ γ 3 n ∣ L ^ ∣ ∣ U ^ ∣ . (A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b},\qquad|\Delta A|\le\gamma_{3n}|\hat L||\hat U|. ( A + Δ A ) x ^ = b , ∣Δ A ∣ ≤ γ 3 n ∣ L ^ ∣∣ U ^ ∣. 部分ピボット選択の場合は、L ^ U ^ \hat L\hat U L ^ U ^ が P A PA P A の分解で L ^ y ^ = P b \hat L\hat{\boldsymbol{y}}=P\boldsymbol{b} L ^ y ^ = P b を解くとして、( A + Δ A ) x ^ = b (A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b} ( A + Δ A ) x ^ = b , ∣ Δ A ∣ ≤ γ 3 n P T ∣ L ^ ∣ ∣ U ^ ∣ |\Delta A|\le\gamma_{3n}P^{\mathsf{T}}|\hat L||\hat U| ∣Δ A ∣ ≤ γ 3 n P T ∣ L ^ ∣∣ U ^ ∣ である。
証明(定理 3.3) 補題 3.1 から ( L ^ + Δ L ) y ^ = b (\hat L+\Delta L)\hat{\boldsymbol{y}}=\boldsymbol{b} ( L ^ + Δ L ) y ^ = b , ∣ Δ L ∣ ≤ γ n ∣ L ^ ∣ |\Delta L|\le\gamma_n|\hat L| ∣Δ L ∣ ≤ γ n ∣ L ^ ∣ 、( U ^ + Δ U ) x ^ = y ^ (\hat U+\Delta U)\hat{\boldsymbol{x}}=\hat{\boldsymbol{y}} ( U ^ + Δ U ) x ^ = y ^ , ∣ Δ U ∣ ≤ γ n ∣ U ^ ∣ |\Delta U|\le\gamma_n|\hat U| ∣Δ U ∣ ≤ γ n ∣ U ^ ∣ です。代入して 定理 3.2 の L ^ U ^ = A + Δ A 1 \hat L\hat U=A+\Delta A_1 L ^ U ^ = A + Δ A 1 を使うと
b = ( L ^ + Δ L ) ( U ^ + Δ U ) x ^ = ( A + Δ A 1 + L ^ Δ U + Δ L U ^ + Δ L Δ U ) x ^ \boldsymbol{b}=(\hat L+\Delta L)(\hat U+\Delta U)\hat{\boldsymbol{x}}=(A+\Delta A_1+\hat L\Delta U+\Delta L\hat U+\Delta L\Delta U)\hat{\boldsymbol{x}} b = ( L ^ + Δ L ) ( U ^ + Δ U ) x ^ = ( A + Δ A 1 + L ^ Δ U + Δ L U ^ + Δ L Δ U ) x ^ なので、Δ A = Δ A 1 + L ^ Δ U + Δ L U ^ + Δ L Δ U \Delta A=\Delta A_1+\hat L\Delta U+\Delta L\hat U+\Delta L\Delta U Δ A = Δ A 1 + L ^ Δ U + Δ L U ^ + Δ L Δ U とおきます。成分ごとの三角不等式から
∣ Δ A ∣ ≤ ( γ n + 2 γ n + γ n 2 ) ∣ L ^ ∣ ∣ U ^ ∣ |\Delta A|\le(\gamma_n+2\gamma_n+\gamma_n^2)|\hat L||\hat U| ∣Δ A ∣ ≤ ( γ n + 2 γ n + γ n 2 ) ∣ L ^ ∣∣ U ^ ∣ です。補題 3.2[浮動小数点数と丸め誤差] の 2 から 2 γ n + γ n 2 ≤ γ 2 n 2\gamma_n+\gamma_n^2\le\gamma_{2n} 2 γ n + γ n 2 ≤ γ 2 n 、同じく γ 2 n + γ n ≤ γ 3 n \gamma_{2n}+\gamma_n\le\gamma_{3n} γ 2 n + γ n ≤ γ 3 n なので、係数は γ 3 n \gamma_{3n} γ 3 n 以下です。部分ピボット選択の場合は P A PA P A , P b P\boldsymbol{b} P b に適用して ( P A + Δ A ′ ) x ^ = P b (PA+\Delta A')\hat{\boldsymbol{x}}=P\boldsymbol{b} ( P A + Δ A ′ ) x ^ = P b を得、左から P T P^{\mathsf{T}} P T を掛けて Δ A = P T Δ A ′ \Delta A=P^{\mathsf{T}}\Delta A' Δ A = P T Δ A ′ とします(置換は成分の絶対値を並べ替えるだけです)。
∎
この定理は成分ごと の後退誤差の評価ですが、尺度は ∣ A ∣ |A| ∣ A ∣ ではなく ∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ です。∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ が ∣ A ∣ |A| ∣ A ∣ と同じ程度の大きさなら、Gauss 消去は(成分ごと・ノルムともに)後退安定です。しかし 例 2.5 のように ∣ L ^ ∣ ∣ U ^ ∣ ≫ ∣ A ∣ |\hat L||\hat U|\gg|A| ∣ L ^ ∣∣ U ^ ∣ ≫ ∣ A ∣ となることがあり、そのときは評価が役に立ちません。ピボット選択の目的は、∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ を ∣ A ∣ |A| ∣ A ∣ の尺度に抑えることです。
なお LAPACK の getrf はキャッシュを活かすためにブロック化した順序で計算し、内積の順序も上の算法と異なりますが、各成分が受ける丸めの回数は同じ程度で、同じ形の評価(定数が少し変わる)が成り立つことが知られています(Higham『Accuracy and Stability of Numerical Algorithms』第 9 章・第 13 章)。以下のコードの数値は LAPACK の結果なので、定理の評価との比較は「同じ大きさか」を見るものです。
定義 4.1 (成長因子 ) ↗
3.1 節の消去で現れるすべての中間値の絶対値の最大と、A A A の成分の絶対値の最大の比
ρ ^ n ( A ) = max i , j , k ∣ a ^ i j ( k ) ∣ max i , j ∣ a i j ∣ \hat\rho_n(A)=\frac{\max_{i,j,k}|\hat a^{(k)}_{ij}|}{\max_{i,j}|a_{ij}|} ρ ^ n ( A ) = max i , j ∣ a ij ∣ max i , j , k ∣ a ^ ij ( k ) ∣ を(計算した消去の)成長因子 という。厳密な算術で行った消去の中間値 a i j ( k ) a^{(k)}_{ij} a ij ( k ) で同じ比をとったものを ρ n ( A ) \rho_n(A) ρ n ( A ) と書く。
u ^ k j = a ^ k j ( k ) \hat u_{kj}=\hat a^{(k)}_{kj} u ^ k j = a ^ k j ( k ) なので max ∣ u ^ k j ∣ ≤ ρ ^ n max ∣ a i j ∣ \max|\hat u_{kj}|\le\hat\rho_n\max|a_{ij}| max ∣ u ^ k j ∣ ≤ ρ ^ n max ∣ a ij ∣ です。部分ピボット選択では ∣ l ^ i k ∣ ≤ 1 |\hat l_{ik}|\le1 ∣ l ^ ik ∣ ≤ 1 なので、∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ の大きさは成長因子で決まります。次の定理は、その成長因子が最悪でもどこまで大きくなりうるかを与えます。証明の方針は、各段で成分の絶対値が高々 2 倍にしかならないことを示し、それを段数だけ繰り返すことです。
定理 4.2 (部分ピボット選択の成長因子 ) ✓
部分ピボット選択を行う消去について、
厳密な算術では ρ n ( A ) ≤ 2 n − 1 \rho_n(A)\le2^{n-1} ρ n ( A ) ≤ 2 n − 1 。
浮動小数点数の消去(3.1 節の算法を、各段で ∣ a ^ i k ( k ) ∣ |\hat a^{(k)}_{ik}| ∣ a ^ ik ( k ) ∣ が最大の行を選んで行う)では ∣ l ^ i k ∣ ≤ 1 |\hat l_{ik}|\le1 ∣ l ^ ik ∣ ≤ 1 であり、ρ ^ n ( A ) ≤ ( 2 ( 1 + u ) 2 ) n − 1 \hat\rho_n(A)\le\bigl(2(1+u)^2\bigr)^{n-1} ρ ^ n ( A ) ≤ ( 2 ( 1 + u ) 2 ) n − 1 。
証明(定理 4.2)
k k k 段目のピボットは第 k k k 列で絶対値最大なので ∣ l i k ∣ = ∣ a i k ( k ) / a k k ( k ) ∣ ≤ 1 |l_{ik}|=|a^{(k)}_{ik}/a^{(k)}_{kk}|\le1 ∣ l ik ∣ = ∣ a ik ( k ) / a k k ( k ) ∣ ≤ 1 です(ピボットが 0 0 0 なら列は 0 0 0 で、乗数を 0 0 0 とします)。よって ∣ a i j ( k + 1 ) ∣ ≤ ∣ a i j ( k ) ∣ + ∣ l i k ∣ ∣ a k j ( k ) ∣ ≤ 2 max p , q ∣ a p q ( k ) ∣ |a^{(k+1)}_{ij}|\le|a^{(k)}_{ij}|+|l_{ik}||a^{(k)}_{kj}|\le2\max_{p,q}|a^{(k)}_{pq}| ∣ a ij ( k + 1 ) ∣ ≤ ∣ a ij ( k ) ∣ + ∣ l ik ∣∣ a k j ( k ) ∣ ≤ 2 max p , q ∣ a pq ( k ) ∣ で、k k k についての帰納法から max ∣ a p q ( k ) ∣ ≤ 2 k − 1 max ∣ a p q ∣ \max|a^{(k)}_{pq}|\le2^{k-1}\max|a_{pq}| max ∣ a pq ( k ) ∣ ≤ 2 k − 1 max ∣ a pq ∣ です。k ≤ n k\le n k ≤ n なので主張が出ます。
t = a ^ i k ( k ) / a ^ k k ( k ) t=\hat a^{(k)}_{ik}/\hat a^{(k)}_{kk} t = a ^ ik ( k ) / a ^ k k ( k ) は ∣ t ∣ ≤ 1 |t|\le1 ∣ t ∣ ≤ 1 です。l ^ i k = f l ( t ) \hat l_{ik}=\mathrm{fl}(t) l ^ ik = fl ( t ) が 1 1 1 より大きいとすると、1 ∈ F 1\in\mathbb{F} 1 ∈ F は t t t との距離 1 − t 1-t 1 − t が f l ( t ) − t \mathrm{fl}(t)-t fl ( t ) − t より小さく、最も近い浮動小数点数を選ぶ丸めの定義に反します。− 1 -1 − 1 についても同様で、∣ l ^ i k ∣ ≤ 1 |\hat l_{ik}|\le1 ∣ l ^ ik ∣ ≤ 1 です。標準モデル(系 3.1[浮動小数点数と丸め誤差] )から
∣ a ^ i j ( k + 1 ) ∣ ≤ ( 1 + u ) ( ∣ a ^ i j ( k ) ∣ + ( 1 + u ) ∣ l ^ i k ∣ ∣ a ^ k j ( k ) ∣ ) ≤ 2 ( 1 + u ) 2 max p , q ∣ a ^ p q ( k ) ∣ |\hat a^{(k+1)}_{ij}|\le(1+u)\bigl(|\hat a^{(k)}_{ij}|+(1+u)|\hat l_{ik}||\hat a^{(k)}_{kj}|\bigr)\le2(1+u)^2\max_{p,q}|\hat a^{(k)}_{pq}| ∣ a ^ ij ( k + 1 ) ∣ ≤ ( 1 + u ) ( ∣ a ^ ij ( k ) ∣ + ( 1 + u ) ∣ l ^ ik ∣∣ a ^ k j ( k ) ∣ ) ≤ 2 ( 1 + u ) 2 p , q max ∣ a ^ pq ( k ) ∣
で、1 と同じ帰納法です。
∎
系 4.3 (部分ピボット選択つき Gauss 消去のノルムによる後退誤差 ) ✓
部分ピボット選択つき Gauss 消去で計算した解 x ^ \hat{\boldsymbol{x}} x ^ は
( A + Δ A ) x ^ = b , ∥ Δ A ∥ ∞ ≤ n 2 γ 3 n ρ ^ n ( A ) ∥ A ∥ ∞ (A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b},\qquad\|\Delta A\|_\infty\le n^2\gamma_{3n}\,\hat\rho_n(A)\,\|A\|_\infty ( A + Δ A ) x ^ = b , ∥Δ A ∥ ∞ ≤ n 2 γ 3 n ρ ^ n ( A ) ∥ A ∥ ∞ を満たす。したがってノルムに関する後退誤差(定義 7.1[行列のノルムと線形方程式の条件数] 、∞ \infty ∞ ノルム)は n 2 γ 3 n ρ ^ n ( A ) n^2\gamma_{3n}\hat\rho_n(A) n 2 γ 3 n ρ ^ n ( A ) 以下である。
証明(系 4.3) 定理 3.3 から ∣ Δ A ∣ ≤ γ 3 n P T ∣ L ^ ∣ ∣ U ^ ∣ |\Delta A|\le\gamma_{3n}P^{\mathsf{T}}|\hat L||\hat U| ∣Δ A ∣ ≤ γ 3 n P T ∣ L ^ ∣∣ U ^ ∣ です。∥ ⋅ ∥ ∞ \|\cdot\|_\infty ∥ ⋅ ∥ ∞ は行和の最大(命題 4.2[行列のノルムと線形方程式の条件数] の 2)なので、成分ごとの不等式 ∣ E ∣ ≤ F |E|\le F ∣ E ∣ ≤ F から ∥ E ∥ ∞ ≤ ∥ F ∥ ∞ \|E\|_\infty\le\|F\|_\infty ∥ E ∥ ∞ ≤ ∥ F ∥ ∞ が従い、行の並べ替え P T P^{\mathsf{T}} P T はノルムを変えません。また誘導ノルムは ∥ X Y z ∥ ≤ ∥ X ∥ ∥ Y z ∥ ≤ ∥ X ∥ ∥ Y ∥ ∥ z ∥ \|XY\boldsymbol{z}\|\le\|X\|\|Y\boldsymbol{z}\|\le\|X\|\|Y\|\|\boldsymbol{z}\| ∥ X Y z ∥ ≤ ∥ X ∥∥ Y z ∥ ≤ ∥ X ∥∥ Y ∥∥ z ∥ から劣乗法的です。よって
∥ Δ A ∥ ∞ ≤ γ 3 n ∥ ∣ L ^ ∣ ∥ ∞ ∥ ∣ U ^ ∣ ∥ ∞ \|\Delta A\|_\infty\le\gamma_{3n}\,\||\hat L|\|_\infty\,\||\hat U|\|_\infty ∥Δ A ∥ ∞ ≤ γ 3 n ∥∣ L ^ ∣ ∥ ∞ ∥∣ U ^ ∣ ∥ ∞ です。∣ l ^ i k ∣ ≤ 1 |\hat l_{ik}|\le1 ∣ l ^ ik ∣ ≤ 1 (定理 4.2 の 2)から ∥ ∣ L ^ ∣ ∥ ∞ ≤ n \||\hat L|\|_\infty\le n ∥∣ L ^ ∣ ∥ ∞ ≤ n 、∣ u ^ k j ∣ ≤ ρ ^ n max ∣ a i j ∣ |\hat u_{kj}|\le\hat\rho_n\max|a_{ij}| ∣ u ^ k j ∣ ≤ ρ ^ n max ∣ a ij ∣ から ∥ ∣ U ^ ∣ ∥ ∞ ≤ n ρ ^ n max ∣ a i j ∣ \||\hat U|\|_\infty\le n\hat\rho_n\max|a_{ij}| ∥∣ U ^ ∣ ∥ ∞ ≤ n ρ ^ n max ∣ a ij ∣ 、そして max ∣ a i j ∣ ≤ ∥ A ∥ ∞ \max|a_{ij}|\le\|A\|_\infty max ∣ a ij ∣ ≤ ∥ A ∥ ∞ です。後半は Δ b = 0 \Delta\boldsymbol{b}=\boldsymbol{0} Δ b = 0 として定義に当てはめたものです。
∎
したがって条件数との積で、前進誤差は ∥ x ^ − x ∥ ∞ / ∥ x ∥ ∞ ≲ 2 κ ∞ ( A ) n 2 γ 3 n ρ ^ n \|\hat{\boldsymbol{x}}-\boldsymbol{x}\|_\infty/\|\boldsymbol{x}\|_\infty\lesssim2\kappa_\infty(A)\,n^2\gamma_{3n}\hat\rho_n ∥ x ^ − x ∥ ∞ /∥ x ∥ ∞ ≲ 2 κ ∞ ( A ) n 2 γ 3 n ρ ^ n です(系 7.3[行列のノルムと線形方程式の条件数] )。n 2 n^2 n 2 の係数は最悪の場合の数え方で、実際の誤差はずっと小さいのが普通です。問題は ρ ^ n \hat\rho_n ρ ^ n です。
例 4.4 (成長因子が 2ⁿ⁻¹ に達する行列 )
対角成分が 1 1 1 、対角より下がすべて − 1 -1 − 1 、最後の列がすべて 1 1 1 、他が 0 0 0 の行列 W n W_n W n を考えます。第 1 列は 1 , − 1 , … , − 1 1,-1,\ldots,-1 1 , − 1 , … , − 1 で絶対値がすべて等しく、部分ピボット選択は行を入れ替えません(同点なら上の行を選ぶ約束)。1 段目の消去で最後の列は 1 , 2 , … , 2 1,2,\ldots,2 1 , 2 , … , 2 になり、残りのブロックは同じ形で最後の列が 2 倍になったものです。これを繰り返すと u n n = 2 n − 1 u_{nn}=2^{n-1} u nn = 2 n − 1 となり、ρ n ( W n ) = 2 n − 1 \rho_n(W_n)=2^{n-1} ρ n ( W n ) = 2 n − 1 で 定理 4.2 の上界に達します。一方 κ ∞ ( W n ) = n \kappa_\infty(W_n)=n κ ∞ ( W n ) = n で、問題の条件はよいのです。
次のコードは n = 10 , 20 , 30 , 50 n=10,20,30,50 n = 10 , 20 , 30 , 50 について、scipy.linalg.lu の U U U から測った成長因子(= 2 n − 1 =2^{n-1} = 2 n − 1 かの判定とその値)、P ∣ L ^ ∣ ∣ U ^ ∣ ∣ x ^ ∣ P|\hat L||\hat U||\hat{\boldsymbol{x}}| P ∣ L ^ ∣∣ U ^ ∣∣ x ^ ∣ を尺度とした成分ごとの後退誤差 ω = max i ∣ r i ∣ / ( P ∣ L ^ ∣ ∣ U ^ ∣ ∣ x ^ ∣ ) i \omega=\max_i|r_i|/(P|\hat L||\hat U||\hat{\boldsymbol{x}}|)_i ω = max i ∣ r i ∣/ ( P ∣ L ^ ∣∣ U ^ ∣∣ x ^ ∣ ) i と評価 γ 3 n \gamma_{3n} γ 3 n 、Rigal–Gaches の後退誤差 η = ∥ r ∥ ∞ / ( ∥ A ∥ ∞ ∥ x ^ ∥ ∞ + ∥ b ∥ ∞ ) \eta=\|\boldsymbol{r}\|_\infty/(\|A\|_\infty\|\hat{\boldsymbol{x}}\|_\infty+\|\boldsymbol{b}\|_\infty) η = ∥ r ∥ ∞ / ( ∥ A ∥ ∞ ∥ x ^ ∥ ∞ + ∥ b ∥ ∞ ) (定理 7.2[行列のノルムと線形方程式の条件数] )、κ ∞ \kappa_\infty κ ∞ 、mpmath の 50 桁の解に対する前進誤差を並べます(SciPy の lu は A = P L U A=PLU A = P LU の形で返すので、尺度の P P P は本文の P T P^{\mathsf{T}} P T にあたります)。
# Python 3.12.10 / NumPy 2.5.2 / SciPy 1.18.1 / mpmath 1.3.0
# (x86-64, OpenBLAS)/乱数種 20261006
import scipy.linalg as sla
def wilkinson ( n ) : # 対角 1, 対角より下 -1, 最後の列 1
A = np. eye ( n ) - np. tril ( np. ones ( (n, n) ) , - 1 )
rng = np.random. default_rng ( 20261006 )
g = lambda k : k * 2.0 **- 53 / ( 1 - k * 2.0 **- 53 )
for n in ( 10 , 20 , 30 , 50 ):
P, L, U = sla. lu ( A ) # A = P L U
rho = np. abs ( U ). max () / np. abs ( A ). max ()
b = rng. standard_normal ( n )
x = sla. lu_solve ( sla. lu_factor ( A ) , b )
om = np. max ( np. abs ( r ) / (P @ np. abs ( L ) @ np. abs ( U ) @ np. abs ( x ) ) )
eta = np. abs ( r ). max () / (n * np. abs ( x ). max () + np. abs ( b ). max ())
kap = np.linalg. cond ( A , np.inf )
xm = mp. lu_solve ( mp. matrix ( A. tolist ()) , mp. matrix ( b. tolist ()))
fe = max ( abs ( xm [ i ] - x [ i ]) for i in range ( n )) / mp. norm ( xm , mp.inf )
print ( f " {n :>2 } {rho == 2.0 ** (n - 1 )} {rho :.2e } {om :.1e } { g ( 3 * n ) :.1e } "
f " {eta :.2e } {kap :.0f } { float ( fe ) :.2e } " )
10 True 5.12e+02 6.9e-17 3.3e-15 6.04e-16 10 2.47e-15
20 True 5.24e+05 1.2e-16 6.7e-15 3.38e-14 20 4.91e-13
30 True 5.37e+08 8.4e-17 1.0e-14 8.78e-11 30 9.45e-10
50 True 5.63e+14 6.2e-17 1.7e-14 9.65e-05 50 2.59e-03
検算. (a) 既知値: 成長因子は 4 つの n n n すべてで 2 n − 1 2^{n-1} 2 n − 1 に一致し(True)、κ ∞ ( W n ) = n \kappa_\infty(W_n)=n κ ∞ ( W n ) = n も閉じた形のとおりです。(b) 別精度: 前進誤差は mpmath の 50 桁の解との比較で、系 7.3[行列のノルムと線形方程式の条件数] の評価 2 κ ∞ η / ( 1 − κ ∞ η ) 2\kappa_\infty\eta/(1-\kappa_\infty\eta) 2 κ ∞ η / ( 1 − κ ∞ η ) の内側にあります(n = 50 n=50 n = 50 で 2.6 × 10 − 3 ≤ 9.7 × 10 − 3 2.6\times10^{-3}\le9.7\times10^{-3} 2.6 × 1 0 − 3 ≤ 9.7 × 1 0 − 3 )。(c) 次数: ∣ L ^ ∣ ∣ U ^ ∣ |\hat L||\hat U| ∣ L ^ ∣∣ U ^ ∣ を尺度とした後退誤差 ω \omega ω はどの n n n でも u u u 程度で 定理 3.3 の γ 3 n \gamma_{3n} γ 3 n の内側ですが、∣ A ∣ |A| ∣ A ∣ の尺度の後退誤差 η \eta η は、n = 10 n=10 n = 10 から 20 20 20 では約 56 56 56 倍ですが、その先は n n n が 10 増えるごとにおよそ 2 10 ≈ 10 3 2^{10}\approx10^3 2 10 ≈ 1 0 3 倍に増え、成長因子の増え方 2 n − 1 2^{n-1} 2 n − 1 と同じ割合で悪化します。条件のよい問題なのに答えが 3 桁しか合わないのは、アルゴリズムの後退誤差が大きいからです。
例 4.6 (乱数行列の成長因子 )
乱数種を固定した標準正規乱数の n × n n\times n n × n 行列を各 n n n で 30 本作り、scipy.linalg.lu の U U U から測った max ∣ u ^ k j ∣ / max ∣ a i j ∣ \max|\hat u_{kj}|/\max|a_{ij}| max ∣ u ^ k j ∣/ max ∣ a ij ∣ (成長因子の下界)の平均と最大を出します。最後の列は最後の 1 本の max ∣ l ^ i k ∣ \max|\hat l_{ik}| max ∣ l ^ ik ∣ です。
# Python 3.12.10 / NumPy 2.5.2 / SciPy 1.18.1(x86-64, OpenBLAS)
import scipy.linalg as sla
rng = np.random. default_rng ( 20261006 )
for n in ( 100 , 200 , 400 , 800 ):
A = rng. standard_normal ( (n, n) )
rho. append ( np. abs ( U ) . max () / np. abs ( A ) . max ())
print ( f " {n :>4 } 平均 {rho. mean () :6.2f } 最大 {rho. max () :6.2f } "
f " 平均/√n {rho. mean () / n ** 0.5 :.3f } "
f " |L|最大 {np. abs ( L ) . max () :.2f } " )
100 平均 5.51 最大 10.11 平均/√n 0.551 |L|最大 1.00
200 平均 7.57 最大 12.48 平均/√n 0.535 |L|最大 1.00
400 平均 11.21 最大 14.44 平均/√n 0.560 |L|最大 1.00
800 平均 15.65 最大 24.16 平均/√n 0.553 |L|最大 1.00
検算. (a) 既知値: ∣ l ^ i k ∣ ≤ 1 |\hat l_{ik}|\le1 ∣ l ^ ik ∣ ≤ 1 (定理 4.2 の 2)が成り立っています。(b) 別の物差し: 成長因子は上界 2 n − 1 2^{n-1} 2 n − 1 (n = 100 n=100 n = 100 で 6 × 10 29 6\times10^{29} 6 × 1 0 29 )より 28 桁以上小さく、例 4.4 とは対照的です。(c) 増え方: この範囲では平均は n \sqrt n n にほぼ比例して増えています(比が 0.53 0.53 0.53 〜0.56 0.56 0.56 )。ただしこれは 30 本の標本で見た経験的な傾向で、定理ではありません。U U U だけから測っているので、中間値をすべて含む成長因子はこれ以上です。
ピボット選択が要らない重要な行列の族があります。狭義列対角優位とは、各列で対角成分の絶対値が、同じ列のほかの成分の絶対値の和より大きいことです。次の定理は、この性質が消去の途中で失われず、成長因子も小さく抑えられることを示します。
定理 4.7 (列対角優位な行列の LU 分解 ) ✓
A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) が狭義列対角優位 、すなわちすべての j j j で ∣ a j j ∣ > ∑ i ≠ j ∣ a i j ∣ |a_{jj}|\gt\sum_{i\ne j}|a_{ij}| ∣ a j j ∣ > ∑ i = j ∣ a ij ∣ とする。このとき(厳密な算術で)
ピボット選択なしの消去は最後まで進み、A = L U A=LU A = LU の LU 分解がある。乗数は ∣ l i k ∣ < 1 |l_{ik}|\lt1 ∣ l ik ∣ < 1 で、部分ピボット選択は行を入れ替えない。
消去の各段の残りのブロック(Schur 補行列)も狭義列対角優位である。
各列の成分の絶対値の和は消去で増えず、成長因子は ρ n ( A ) ≤ 2 \rho_n(A)\le2 ρ n ( A ) ≤ 2 である。
証明(定理 4.7) 1 段目を考えます。A = ( α w T v B ) A=\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{v}&B\end{pmatrix} A = ( α v w T B ) とすると、第 1 列の狭義列対角優位から ∣ α ∣ > ∑ i ∣ v i ∣ ≥ 0 |\alpha|\gt\sum_i|v_i|\ge0 ∣ α ∣ > ∑ i ∣ v i ∣ ≥ 0 なので α ≠ 0 \alpha\ne0 α = 0 、∣ l i ∣ = ∣ v i ∣ / ∣ α ∣ < 1 |l_i|=|v_i|/|\alpha|\lt1 ∣ l i ∣ = ∣ v i ∣/∣ α ∣ < 1 です。Schur 補行列の分解(定理 4.2[行列の固有値評価と不等式] の 2 を 1 × 1 1\times1 1 × 1 の左上ブロック α \alpha α で使う)から、A A A は ( 1 0 T v / α I ) ( α w T 0 S ) \begin{pmatrix}1&\boldsymbol{0}^{\mathsf{T}}\\\boldsymbol{v}/\alpha&I\end{pmatrix}\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{0}&S\end{pmatrix} ( 1 v / α 0 T I ) ( α 0 w T S ) , S = B − v w T / α S=B-\boldsymbol{v}\boldsymbol{w}^{\mathsf{T}}/\alpha S = B − v w T / α と書けます。
2. S S S の第 j j j 列(A A A の第 j + 1 j+1 j + 1 列に対応。以下 b i j b_{ij} b ij , w j w_j w j , v i v_i v i は対応する成分)を見ます。A A A のこの列の狭義列対角優位は ∣ b j j ∣ > ∣ w j ∣ + ∑ i ≠ j ∣ b i j ∣ |b_{jj}|\gt|w_j|+\sum_{i\ne j}|b_{ij}| ∣ b j j ∣ > ∣ w j ∣ + ∑ i = j ∣ b ij ∣ で、第 1 列のそれから ∑ i ≠ j ∣ v i ∣ < ∣ α ∣ − ∣ v j ∣ \sum_{i\ne j}|v_i|\lt|\alpha|-|v_j| ∑ i = j ∣ v i ∣ < ∣ α ∣ − ∣ v j ∣ です。よって
∑ i ≠ j ∣ s i j ∣ ≤ ∑ i ≠ j ∣ b i j ∣ + ∣ w j ∣ ∣ α ∣ ∑ i ≠ j ∣ v i ∣ < ( ∣ b j j ∣ − ∣ w j ∣ ) + ∣ w j ∣ ( 1 − ∣ v j ∣ ∣ α ∣ ) = ∣ b j j ∣ − ∣ w j ∣ ∣ v j ∣ ∣ α ∣ ≤ ∣ s j j ∣ \sum_{i\ne j}|s_{ij}|\le\sum_{i\ne j}|b_{ij}|+\frac{|w_j|}{|\alpha|}\sum_{i\ne j}|v_i|\lt\bigl(|b_{jj}|-|w_j|\bigr)+|w_j|\Bigl(1-\frac{|v_j|}{|\alpha|}\Bigr)=|b_{jj}|-\frac{|w_j||v_j|}{|\alpha|}\le|s_{jj}| i = j ∑ ∣ s ij ∣ ≤ i = j ∑ ∣ b ij ∣ + ∣ α ∣ ∣ w j ∣ i = j ∑ ∣ v i ∣ < ( ∣ b j j ∣ − ∣ w j ∣ ) + ∣ w j ∣ ( 1 − ∣ α ∣ ∣ v j ∣ ) = ∣ b j j ∣ − ∣ α ∣ ∣ w j ∣∣ v j ∣ ≤ ∣ s j j ∣ です(最後は s j j = b j j − v j w j / α s_{jj}=b_{jj}-v_jw_j/\alpha s j j = b j j − v j w j / α と三角不等式)。S S S は狭義列対角優位なので、同じ議論を S S S に繰り返せます。各段のピボットが 0 0 0 でないので消去は最後まで進み、定理 2.3 の証明と同じ組み立て(P = I P=I P = I )で A = L U A=LU A = LU を得ます。
3. S S S の第 j j j 列の絶対値の和は ∑ i ∣ s i j ∣ ≤ ∑ i ∣ b i j ∣ + ∣ w j ∣ ∑ i ∣ v i ∣ / ∣ α ∣ ≤ ∑ i ∣ b i j ∣ + ∣ w j ∣ \sum_i|s_{ij}|\le\sum_i|b_{ij}|+|w_j|\sum_i|v_i|/|\alpha|\le\sum_i|b_{ij}|+|w_j| ∑ i ∣ s ij ∣ ≤ ∑ i ∣ b ij ∣ + ∣ w j ∣ ∑ i ∣ v i ∣/∣ α ∣ ≤ ∑ i ∣ b ij ∣ + ∣ w j ∣ で、これは A A A の対応する列の絶対値の和です。各段で列の絶対値の和は増えないので、k k k 段目の中間値について ∣ a i j ( k ) ∣ ≤ ∑ p ∣ a p j ∣ < 2 ∣ a j j ∣ ≤ 2 max ∣ a p q ∣ |a^{(k)}_{ij}|\le\sum_p|a_{pj}|\lt2|a_{jj}|\le2\max|a_{pq}| ∣ a ij ( k ) ∣ ≤ ∑ p ∣ a p j ∣ < 2∣ a j j ∣ ≤ 2 max ∣ a pq ∣ です(狭義列対角優位から非対角の和は ∣ a j j ∣ |a_{jj}| ∣ a j j ∣ 未満)。よって ρ n ( A ) ≤ 2 \rho_n(A)\le2 ρ n ( A ) ≤ 2 です。
∎
列対角優位な行列は、偏微分方程式の上流差分、Markov 連鎖の遷移行列から作る行列などに現れます。行対角優位な行列は転置が列対角優位なので、A T = L U A^{\mathsf{T}}=LU A T = LU から A = U T L T A=U^{\mathsf{T}}L^{\mathsf{T}} A = U T L T の形の分解が同様に安定に作れます。
計算した解 x 0 \boldsymbol{x}_0 x 0 の残差 r 0 = b − A x 0 \boldsymbol{r}_0=\boldsymbol{b}-A\boldsymbol{x}_0 r 0 = b − A x 0 を求め、補正方程式 A d 0 = r 0 A\boldsymbol{d}_0=\boldsymbol{r}_0 A d 0 = r 0 を解いて x 1 = x 0 + d 0 \boldsymbol{x}_1=\boldsymbol{x}_0+\boldsymbol{d}_0 x 1 = x 0 + d 0 とする操作を繰り返すのが反復改良 です。補正方程式は、手元の(誤差のある)LU 分解で解きます。その誤差を A A A の摂動 E k E_k E k として表すと、次の定理が成り立ちます。
定理に出てくる 3 つの誤差は、それぞれ別の場所で生じるものです。g k \boldsymbol{g}_k g k は残差 b − A x k \boldsymbol{b}-A\boldsymbol{x}_k b − A x k を計算するときの誤差、E k E_k E k は補正方程式を(精度の低い)LU 分解で解くことによる誤差、f k \boldsymbol{f}_k f k は x k + d k \boldsymbol{x}_k+\boldsymbol{d}_k x k + d k の足し算の誤差です。主張は、補正方程式の誤差が十分小さければ、1 回ごとに解の誤差が一定の割合で縮む、というものです。
定理 5.1 (反復改良の収束 ) ✓
A ∈ M n ( K ) A\in M_n(\mathbb{K}) A ∈ M n ( K ) を正則、A x = b A\boldsymbol{x}=\boldsymbol{b} A x = b とし、ベクトルノルムとその誘導ノルムを 1 つ固定する。x 0 \boldsymbol{x}_0 x 0 から次のように x k \boldsymbol{x}_k x k を作る。
r k = b − A x k + g k , ( A + E k ) d k = r k , x k + 1 = x k + d k + f k . \boldsymbol{r}_k=\boldsymbol{b}-A\boldsymbol{x}_k+\boldsymbol{g}_k,\qquad(A+E_k)\boldsymbol{d}_k=\boldsymbol{r}_k,\qquad\boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\boldsymbol{d}_k+\boldsymbol{f}_k. r k = b − A x k + g k , ( A + E k ) d k = r k , x k + 1 = x k + d k + f k . ここで g k \boldsymbol{g}_k g k は残差の計算誤差、E k E_k E k は補正方程式を解く誤差、f k \boldsymbol{f}_k f k は足し算の誤差である。∥ A − 1 E k ∥ ≤ θ < 1 \|A^{-1}E_k\|\le\theta\lt1 ∥ A − 1 E k ∥ ≤ θ < 1 がすべての k k k で成り立つとき、e k = x k − x \boldsymbol{e}_k=\boldsymbol{x}_k-\boldsymbol{x} e k = x k − x は
∥ e k + 1 ∥ ≤ θ 1 − θ ∥ e k ∥ + ∥ A − 1 ∥ ∥ g k ∥ 1 − θ + ∥ f k ∥ \|\boldsymbol{e}_{k+1}\|\le\frac{\theta}{1-\theta}\|\boldsymbol{e}_k\|+\frac{\|A^{-1}\|\,\|\boldsymbol{g}_k\|}{1-\theta}+\|\boldsymbol{f}_k\| ∥ e k + 1 ∥ ≤ 1 − θ θ ∥ e k ∥ + 1 − θ ∥ A − 1 ∥ ∥ g k ∥ + ∥ f k ∥ を満たす。とくに g k = f k = 0 \boldsymbol{g}_k=\boldsymbol{f}_k=\boldsymbol{0} g k = f k = 0 で θ < 1 / 2 \theta\lt1/2 θ < 1/2 なら、誤差は 1 回ごとに θ / ( 1 − θ ) < 1 \theta/(1-\theta)\lt1 θ / ( 1 − θ ) < 1 倍以下に縮み、x k → x \boldsymbol{x}_k\to\boldsymbol{x} x k → x である。
証明(定理 5.1) 逆行列の摂動の補題(補題 6.1[行列のノルムと線形方程式の条件数] )を、正則行列 I I I (逆行列は I I I )と摂動 A − 1 E k A^{-1}E_k A − 1 E k に使うと、∥ A − 1 E k ∥ ≤ θ < 1 \|A^{-1}E_k\|\le\theta\lt1 ∥ A − 1 E k ∥ ≤ θ < 1 から I + A − 1 E k I+A^{-1}E_k I + A − 1 E k は正則で ∥ ( I + A − 1 E k ) − 1 ∥ ≤ 1 / ( 1 − θ ) \|(I+A^{-1}E_k)^{-1}\|\le1/(1-\theta) ∥ ( I + A − 1 E k ) − 1 ∥ ≤ 1/ ( 1 − θ ) です。A + E k = A ( I + A − 1 E k ) A+E_k=A(I+A^{-1}E_k) A + E k = A ( I + A − 1 E k ) も正則で、M k = ( A + E k ) − 1 = ( I + A − 1 E k ) − 1 A − 1 M_k=(A+E_k)^{-1}=(I+A^{-1}E_k)^{-1}A^{-1} M k = ( A + E k ) − 1 = ( I + A − 1 E k ) − 1 A − 1 です。b − A x k = − A e k \boldsymbol{b}-A\boldsymbol{x}_k=-A\boldsymbol{e}_k b − A x k = − A e k なので
e k + 1 = e k + M k ( − A e k + g k ) + f k = ( I − M k A ) e k + M k g k + f k \boldsymbol{e}_{k+1}=\boldsymbol{e}_k+M_k(-A\boldsymbol{e}_k+\boldsymbol{g}_k)+\boldsymbol{f}_k=(I-M_kA)\boldsymbol{e}_k+M_k\boldsymbol{g}_k+\boldsymbol{f}_k e k + 1 = e k + M k ( − A e k + g k ) + f k = ( I − M k A ) e k + M k g k + f k です。I − M k A = M k ( ( A + E k ) − A ) = M k E k = ( I + A − 1 E k ) − 1 A − 1 E k I-M_kA=M_k\bigl((A+E_k)-A\bigr)=M_kE_k=(I+A^{-1}E_k)^{-1}A^{-1}E_k I − M k A = M k ( ( A + E k ) − A ) = M k E k = ( I + A − 1 E k ) − 1 A − 1 E k なので ∥ I − M k A ∥ ≤ θ / ( 1 − θ ) \|I-M_kA\|\le\theta/(1-\theta) ∥ I − M k A ∥ ≤ θ / ( 1 − θ ) 、また ∥ M k ∥ ≤ ∥ A − 1 ∥ / ( 1 − θ ) \|M_k\|\le\|A^{-1}\|/(1-\theta) ∥ M k ∥ ≤ ∥ A − 1 ∥/ ( 1 − θ ) です。三角不等式で主張の不等式を得ます。θ < 1 / 2 \theta\lt1/2 θ < 1/2 なら θ / ( 1 − θ ) < 1 \theta/(1-\theta)\lt1 θ / ( 1 − θ ) < 1 で、∥ e k ∥ ≤ ( θ / ( 1 − θ ) ) k ∥ e 0 ∥ → 0 \|\boldsymbol{e}_k\|\le(\theta/(1-\theta))^k\|\boldsymbol{e}_0\|\to0 ∥ e k ∥ ≤ ( θ / ( 1 − θ ) ) k ∥ e 0 ∥ → 0 です。
∎
この定理の読み方は次のとおりです。
縮小率 θ / ( 1 − θ ) ≈ ∥ A − 1 E k ∥ \theta/(1-\theta)\approx\|A^{-1}E_k\| θ / ( 1 − θ ) ≈ ∥ A − 1 E k ∥ は、補正方程式を解く精度で決まります。分解を単位丸め u f u_{\mathrm{f}} u f で行えば、定理 3.3 と成長因子の評価から ∥ E k ∥ ≲ c n ρ ^ n u f ∥ A ∥ \|E_k\|\lesssim c_n\hat\rho_nu_{\mathrm{f}}\|A\| ∥ E k ∥ ≲ c n ρ ^ n u f ∥ A ∥ で、θ ≈ c n ρ ^ n κ ( A ) u f \theta\approx c_n\hat\rho_n\kappa(A)u_{\mathrm{f}} θ ≈ c n ρ ^ n κ ( A ) u f です。
到達できる精度 は第 2 項・第 3 項、つまり残差と足し算の精度で決まります。残差を分解より高い精度 u r u_{\mathrm{r}} u r で計算すれば、分解が低い精度でも、最終的な誤差は u r u_{\mathrm{r}} u r の側で決まります。
これが混合精度の反復改良 の考え方です。O ( n 3 ) O(n^3) O ( n 3 ) の分解を速い低精度(binary32 や GPU の binary16)で行い、O ( n 2 ) O(n^2) O ( n 2 ) の残差と更新だけを binary64 で行います。条件は κ ( A ) u f \kappa(A)u_{\mathrm{f}} κ ( A ) u f が 1 1 1 より十分小さいことです。
例 5.2 (binary32 の LU と binary64 の残差 )
乱数種を固定した直交行列 Q 1 , Q 2 Q_1,Q_2 Q 1 , Q 2 と、1 1 1 から 1 / κ 1/\kappa 1/ κ まで等比に並べた特異値で A = Q 1 Σ Q 2 T A=Q_1\Sigma Q_2^{\mathsf{T}} A = Q 1 Σ Q 2 T (κ 2 ( A ) = κ \kappa_2(A)=\kappa κ 2 ( A ) = κ )を作り、n = 50 n=50 n = 50 で binary32 の LU 分解と binary64 の残差による反復改良を 4 回行います。1 行目は x 0 \boldsymbol{x}_0 x 0 (binary32 の分解で解いたもの)から x 4 \boldsymbol{x}_4 x 4 までの相対誤差(∞ \infty ∞ ノルム、参照解は mpmath の 50 桁)、2 行目は最初の 2 回の縮小率、κ u 32 \kappa u_{32} κ u 32 、binary64 の solve で直接解いたときの相対誤差です。
# Python 3.12.10 / NumPy 2.5.2 / SciPy 1.18.1 / mpmath 1.3.0
# (x86-64, OpenBLAS)/乱数種 20261006
import scipy.linalg as sla
rng = np.random. default_rng ( 20261006 )
Q1, _ = np.linalg. qr ( rng. standard_normal ( (n, n) ))
Q2, _ = np.linalg. qr ( rng. standard_normal ( (n, n) ))
b = rng. standard_normal ( n )
A = Q1 @ np. diag ( np. geomspace ( 1 , 1 / kap , n )) @ Q2.T # κ2 = kap
xs = mp. lu_solve ( mp. matrix ( A. tolist ()) , mp. matrix ( b. tolist ()))
xs = np. array ( [ float ( t ) for t in xs ] ) # 参照解
f32 = sla. lu_factor ( A. astype ( np.float32 )) # binary32 の LU
x = sla. lu_solve ( f32 , b. astype ( np.float32 )). astype ( np.float64 )
errs. append ( np. abs ( x - xs ) . max () / np. abs ( xs ) . max ())
r = b - A @ x # binary64 の残差
d = sla. lu_solve ( f32 , r. astype ( np.float32 ))
x = x + d. astype ( np.float64 )
x64 = np.linalg. solve ( A , b )
e64 = np. abs ( x64 - xs ). max () / np. abs ( xs ). max ()
rate = [ errs[k + 1 ] / errs[k] for k in range ( 2 ) ]
print ( f "κ= {kap :.0e } " + " " . join ( f " {e :.2e } " for e in errs ))
print ( f " 比 {rate [ 0 ] :.1e } {rate [ 1 ] :.1e } κu32 {kap * u32 :.1e } "
f " binary64 直接 {e64 :.2e } " )
κ=1e+02 2.89e-06 3.84e-12 1.02e-15 1.59e-15 1.28e-15
比 1.3e-06 2.7e-04 κu32 6.0e-06 binary64 直接 2.39e-15
κ=1e+04 5.66e-05 1.99e-09 1.12e-13 5.25e-14 4.59e-14
比 3.5e-05 5.6e-05 κu32 6.0e-04 binary64 直接 1.55e-13
検算. (a) 既知値: 特異値を指定して作ったので κ 2 ( A ) \kappa_2(A) κ 2 ( A ) は構成どおり 10 2 10^2 1 0 2 , 10 4 10^4 1 0 4 で、参照解は mpmath の 50 桁で解いたものです。(b) 別精度・別手法: 2〜3 回の改良で、binary64 の分解で直接解いた解と同じかそれ以上の精度に達します。(c) 率: 縮小率は κ = 10 4 \kappa=10^4 κ = 1 0 4 で 3.5 × 10 − 5 3.5\times10^{-5} 3.5 × 1 0 − 5 , 5.6 × 10 − 5 5.6\times10^{-5} 5.6 × 1 0 − 5 と、定理 5.1 の予言する θ ≈ κ u 32 = 6 × 10 − 4 \theta\approx\kappa u_{32}=6\times10^{-4} θ ≈ κ u 32 = 6 × 1 0 − 4 以下です。κ = 10 2 \kappa=10^2 κ = 1 0 2 の 2 回目の比 2.7 × 10 − 4 2.7\times10^{-4} 2.7 × 1 0 − 4 は、誤差がすでに binary64 の到達精度(第 2・第 3 項)に達して止まったためで、縮小率ではありません。
演習 6.1 易
A = ( 2 1 1 4 3 3 8 7 9 ) A=\begin{pmatrix}2&1&1\\4&3&3\\8&7&9\end{pmatrix} A = 2 4 8 1 3 7 1 3 9 の LU 分解(ピボット選択なし)を求め、定理 2.2 の u 11 u 22 u 33 = det A u_{11}u_{22}u_{33}=\det A u 11 u 22 u 33 = det A を確かめよ。また部分ピボット選択を行うと、1 段目でどの行がピボットになるか。
解答 1 段目の乗数は l 21 = 2 l_{21}=2 l 21 = 2 , l 31 = 4 l_{31}=4 l 31 = 4 で、残りは ( 1 1 3 5 ) \begin{pmatrix}1&1\\3&5\end{pmatrix} ( 1 3 1 5 ) 。2 段目の乗数は l 32 = 3 l_{32}=3 l 32 = 3 で、u 33 = 5 − 3 = 2 u_{33}=5-3=2 u 33 = 5 − 3 = 2 です。よって
L = ( 1 0 0 2 1 0 4 3 1 ) , U = ( 2 1 1 0 1 1 0 0 2 ) , L=\begin{pmatrix}1&0&0\\2&1&0\\4&3&1\end{pmatrix},\qquad U=\begin{pmatrix}2&1&1\\0&1&1\\0&0&2\end{pmatrix}, L = 1 2 4 0 1 3 0 0 1 , U = 2 0 0 1 1 0 1 1 2 , det A = 2 ⋅ 1 ⋅ 2 = 4 \det A=2\cdot1\cdot2=4 det A = 2 ⋅ 1 ⋅ 2 = 4 です(det A 1 = 2 \det A_1=2 det A 1 = 2 , det A 2 = 2 ⋅ 3 − 1 ⋅ 4 = 2 = u 11 u 22 \det A_2=2\cdot3-1\cdot4=2=u_{11}u_{22} det A 2 = 2 ⋅ 3 − 1 ⋅ 4 = 2 = u 11 u 22 も確かめられます)。部分ピボット選択では第 1 列の絶対値最大の 8 8 8 の第 3 行がピボットになり、乗数は 1 / 4 1/4 1/4 , 1 / 2 1/2 1/2 です。
演習 6.2 標準
部分ピボット選択で 3 × 3 3\times3 3 × 3 の行列の成長因子が上界 4 4 4 に達する例を作れ。例 4.4 の W 3 W_3 W 3 の消去を手で追ってもよい。
解答 W 3 = ( 1 0 1 − 1 1 1 − 1 − 1 1 ) W_3=\begin{pmatrix}1&0&1\\-1&1&1\\-1&-1&1\end{pmatrix} W 3 = 1 − 1 − 1 0 1 − 1 1 1 1 です。1 段目は同点で第 1 行がピボット、乗数は − 1 , − 1 -1,-1 − 1 , − 1 で、残りのブロックは ( 1 2 − 1 2 ) \begin{pmatrix}1&2\\-1&2\end{pmatrix} ( 1 − 1 2 2 ) 。2 段目も同点で第 2 行がピボット、乗数 − 1 -1 − 1 で u 33 = 2 + 2 = 4 u_{33}=2+2=4 u 33 = 2 + 2 = 4 です。max ∣ a i j ∣ = 1 \max|a_{ij}|=1 max ∣ a ij ∣ = 1 なので成長因子は 4 = 2 3 − 1 4=2^{3-1} 4 = 2 3 − 1 です。各段で乗数の絶対値が 1 1 1 、かつ足し合わせる 2 つの成分の符号がそろうことが、上界に達する条件です。
演習 6.3 標準
κ ∞ ( A ) = 10 6 \kappa_\infty(A)=10^6 κ ∞ ( A ) = 1 0 6 の行列を binary32(u 32 ≈ 6 × 10 − 8 u_{32}\approx6\times10^{-8} u 32 ≈ 6 × 1 0 − 8 )の LU と binary64 の残差で反復改良する。定理 5.1 の縮小率を θ ≈ κ u 32 \theta\approx\kappa u_{32} θ ≈ κ u 32 と見積もり、初期誤差 10 − 1 10^{-1} 1 0 − 1 から 10 − 8 10^{-8} 1 0 − 8 に下げるのに何回の改良が要るかを見積もれ。κ = 10 8 \kappa=10^8 κ = 1 0 8 ではどうか。
解答 θ ≈ 10 6 ⋅ 6 × 10 − 8 = 0.06 \theta\approx10^6\cdot6\times10^{-8}=0.06 θ ≈ 1 0 6 ⋅ 6 × 1 0 − 8 = 0.06 で、θ / ( 1 − θ ) ≈ 0.064 \theta/(1-\theta)\approx0.064 θ / ( 1 − θ ) ≈ 0.064 、1 回でおよそ 1.2 1.2 1.2 桁縮みます。7 桁下げるには 7 / 1.2 ≈ 5.9 7/1.2\approx5.9 7/1.2 ≈ 5.9 から約 6 6 6 回です。それ以上改良しても、誤差は定理の第 2 項(binary64 の残差の誤差 ∥ A − 1 ∥ ∥ g k ∥ \|A^{-1}\|\|\boldsymbol{g}_k\| ∥ A − 1 ∥∥ g k ∥ )で止まり、最悪の場合の目安は κ u 64 ≈ 10 6 ⋅ 1.1 × 10 − 16 ≈ 10 − 10 \kappa u_{64}\approx10^6\cdot1.1\times10^{-16}\approx10^{-10} κ u 64 ≈ 1 0 6 ⋅ 1.1 × 1 0 − 16 ≈ 1 0 − 10 です。κ = 10 8 \kappa=10^8 κ = 1 0 8 では θ ≈ 6 \theta\approx6 θ ≈ 6 で θ < 1 \theta\lt1 θ < 1 の仮定が成り立たず、定理は収束を保証しません。実際、binary32 の分解は A A A を κ u 32 > 1 \kappa u_{32}\gt1 κ u 32 > 1 の相対誤差で表しており、補正の方向がほとんど情報をもたないので、反復改良は一般に収束しません。この場合は binary64 で分解します。
N. J. Higham, Accuracy and Stability of Numerical Algorithms , 2nd ed., SIAM, 2002 — 第 8 章(三角方程式)、第 9 章(LU 分解と Gauss 消去、成長因子)、第 12 章(反復改良)。
G. H. Golub, C. F. Van Loan, Matrix Computations , 4th ed., Johns Hopkins University Press, 2013 — 第 3 章(一般の線形方程式)。
L. N. Trefethen, D. Bau III, Numerical Linear Algebra , SIAM, 1997 — Lecture 20–23(Gauss 消去、ピボット選択、安定性)。
J. H. Wilkinson, “Error analysis of direct methods of matrix inversion”, Journal of the ACM 8 (1961), 281–330. doi:10.1145/321075.321076
L. N. Trefethen, R. S. Schreiber, “Average-case stability of Gaussian elimination”, SIAM Journal on Matrix Analysis and Applications 11 (1990), 335–360. doi:10.1137/0611023
L. V. Foster, “The growth factor and efficiency of Gaussian elimination with rook pivoting”, Journal of Computational and Applied Mathematics 86 (1997), 177–194.
執筆: Claude Code(Opus 5.5)、Claude Code(Sonnet 5.5)・監査 2 回(Claude Code)・最終 2026-10-12