コンテンツにスキップ

Gauss 消去と LU 分解:ピボット選択・成長因子・後退誤差解析

対象読者: 学部の線形代数(ガウスの消去法・行列式)と、本テーマ第 1 章の行列ノルム・条件数、浮動小数点数の丸め誤差の標準モデルを学んだ人。LU 分解の知識は仮定しません。

前提となる記事:行列のノルムと線形方程式の条件数:誘導ノルム・後退誤差・特異行列までの距離、浮動小数点数と丸め誤差:IEEE 754・標準モデル・和と Horner 法の誤差解析

生 Markdown

連立一次方程式をコンピュータで解くとき、答えは丸め誤差のせいで少しずれます。その「少し」がどれくらいなのか、問題が難しいせいなのか、解き方が悪いせいなのかを、きちんと見分けるのがこの記事の話です。Gauss の消去法を「行列を 2 つの三角形の積に分ける」手順として読み直し、行の入れ替え(ピボット選択)がなぜ必要か、入れ替えても数値が極端に膨らむ例があるか、を順に調べます。読み終えると、numpy.linalg.solve が返す解をどこまで信頼してよいかを、式を使って説明できるようになります。

  • 先頭の主小行列式がすべて 00 でないことと、A=LUA=LU(LL は対角が 11 の下三角、UU は正則な上三角)と一意に書けることは同値です。部分ピボット選択を使えば、どんな正方行列も PA=LUPA=LU, ∣lij∣≤1|l_{ij}|\le1 と分解できます。演算量は 23n3+O(n2)\tfrac23n^3+O(n^2) です。
  • 浮動小数点数で計算した因子は L^U^=A+ΔA\hat L\hat U=A+\Delta A, ∣ΔA∣≤γn∣L^∣∣U^∣|\Delta A|\le\gamma_n|\hat L||\hat U| を満たし、前進代入・後退代入と合わせた解は (A+ΔA)x^=b(A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b}, ∣ΔA∣≤γ3n∣L^∣∣U^∣|\Delta A|\le\gamma_{3n}|\hat L||\hat U| を満たします。丸めの基本は既存の「1 ステップの丸め誤差」の補題に帰着します。
  • 後退誤差を ∣A∣|A| の尺度で小さくできるかは ∣L^∣∣U^∣|\hat L||\hat U| の大きさ、つまり成長因子 ρn\rho_n で決まります。部分ピボット選択では ρn≤2n−1\rho_n\le2^{n-1} で、この上界に達する行列(Wilkinson の例)があります。ただし乱数行列では ρn\rho_n はずっと小さく、実用上は後退安定とみなされます。
  • 列対角優位な行列はピボット選択なしで消去でき、ρn≤2\rho_n\le2 です。Schur 補行列が列対角優位を保つからです。
  • 反復改良: 補正方程式を誤差 EkE_k のある分解で解いても、∥A−1Ek∥≤θ<1/2\|A^{-1}E_k\|\le\theta\lt1/2 なら誤差は 1 回ごとに θ/(1−θ)\theta/(1-\theta) 倍以下に縮みます。binary32 の LU と binary64 の残差を組み合わせた混合精度の解法の根拠です。

連立一次方程式 Ax=bA\boldsymbol{x}=\boldsymbol{b} を解く標準的な方法は、高校以来の掃き出し法(Gauss の消去法)です。数値計算では、これを「AA を下三角 LL と上三角 UU の積に分解し、Ly=bL\boldsymbol{y}=\boldsymbol{b}, Ux=yU\boldsymbol{x}=\boldsymbol{y} を順に解く」と読み直します。分解は O(n3)O(n^3)、三角方程式は O(n2)O(n^2) なので、同じ AA で右辺を何本も解くときに分解を使い回せます。SciPy の scipy.linalg.solve、NumPy の numpy.linalg.solve の中身は LAPACK の getrf(部分ピボット選択つき LU 分解)と getrs(三角方程式)です。

この章の問いは、浮動小数点数で計算した解がどれだけ信頼できるかです。行列のノルムと線形方程式の条件数の章で、前進誤差は条件数 × 後退誤差で抑えられることを見ました(系 7.3[行列のノルムと線形方程式の条件数])。したがって示すべきは、Gauss 消去の後退誤差が小さいことです。答えは「ピボット選択をすれば、ほとんどの場合に小さい」で、その「ほとんど」の中身が成長因子です。

2.1. ピボット選択なしの LU 分解

Section titled “2.1. ピボット選択なしの LU 分解”

A∈Mn(K)A\in M_n(\mathbb{K}) の左上の kk 次の正方部分行列を AkA_k と書き、先頭主小行列と呼びます。

定義 2.1(LU 分解)↗

A∈Mn(K)A\in M_n(\mathbb{K}) について、対角成分がすべて 11 の下三角行列 LL(単位下三角行列)と上三角行列 UU で A=LUA=LU と書くことを、AA の LU 分解という。置換行列 PP を使って PA=LUPA=LU と書くことをピボット選択つき LU 分解という。

三角行列について、次の 2 つの事実を何度も使います。

  • 三角行列の行列式は対角成分の積です。nn についての帰納法で、ブロック三角行列の行列式の公式(補題 4.1[行列の固有値評価と不等式])を 1+(n−1)1+(n-1) の分割に使えば出ます。
  • 単位下三角行列 LL は正則で、L−1L^{-1} も単位下三角です。LX=ILX=I の第 jj 列を前進代入で解くと、第 11〜j−1j-1 成分は 00、第 jj 成分は 11 になるからです。単位下三角行列どうしの積も単位下三角です(積の (i,j)(i,j) 成分 ∑klikmkj\sum_kl_{ik}m_{kj} は i<ji\lt j なら k≤i<jk\le i\lt j の項しか残らず 00)。上三角についても同様です。

定理 2.2(LU 分解の存在と一意性)✓

A∈Mn(K)A\in M_n(\mathbb{K}) について、次は同値である。

  1. 先頭主小行列式がすべて 00 でない: det⁡Ak≠0\det A_k\ne0(k=1,…,nk=1,\ldots,n)。
  2. 単位下三角行列 LL と、対角成分がすべて 00 でない上三角行列 UU で A=LUA=LU と書ける。

さらにこのとき、2 の LL, UU は一意で、u11⋯ukk=det⁡Aku_{11}\cdots u_{kk}=\det A_k である。

証明(定理 2.2)

2 ⇒ 1. A=LUA=LU をブロックに分けると、LL が下三角、UU が上三角なので左上のブロックについて Ak=LkUkA_k=L_kU_k です((LU)ij=∑mlimumj(LU)_{ij}=\sum_ml_{im}u_{mj} で、i,j≤ki,j\le k なら lim≠0l_{im}\ne0 には m≤i≤km\le i\le k が必要)。積の定理(定理 6.1[行列式とその性質])と三角行列の行列式から det⁡Ak=det⁡Lkdet⁡Uk=u11⋯ukk≠0\det A_k=\det L_k\det U_k=u_{11}\cdots u_{kk}\ne0 です。

1 ⇒ 2. nn についての帰納法です。n=1n=1 は L=(1)L=(1), U=(a11)U=(a_{11}) です。n−1n-1 で正しいとし、

A=(An−1bcTann)A=\begin{pmatrix}A_{n-1}&\boldsymbol{b}\\\boldsymbol{c}^{\mathsf{T}}&a_{nn}\end{pmatrix}

と分けます。An−1A_{n-1} の先頭主小行列は A1,…,An−1A_1,\ldots,A_{n-1} なので、帰納法の仮定から An−1=L′U′A_{n-1}=L'U'(L′L' は単位下三角、U′U' は対角が 00 でない上三角)です。U′U', L′L' は正則なので

L=(L′0cTU′−11),U=(U′L′−1b0Tδ),δ=ann−cTAn−1−1bL=\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}

とおくと、ブロックの積を計算して LU=ALU=A です(右下は cTU′−1L′−1b+δ=cTAn−1−1b+δ=ann\boldsymbol{c}^{\mathsf{T}}U'^{-1}L'^{-1}\boldsymbol{b}+\delta=\boldsymbol{c}^{\mathsf{T}}A_{n-1}^{-1}\boldsymbol{b}+\delta=a_{nn})。積の定理とブロック三角行列の行列式(補題 4.1[行列の固有値評価と不等式])から det⁡A=det⁡Ldet⁡U=det⁡U′⋅δ\det A=\det L\det U=\det U'\cdot\delta で、det⁡A=det⁡An≠0\det A=\det A_n\ne0 なので δ≠0\delta\ne0 です。

一意性. L1U1=L2U2L_1U_1=L_2U_2 なら L2−1L1=U2U1−1L_2^{-1}L_1=U_2U_1^{-1} です。左辺は単位下三角、右辺は上三角なので、両辺は対角行列で、しかも対角が 11、すなわち II です。よって L1=L2L_1=L_2, U1=U2U_1=U_2。最後の等式は 2 ⇒ 1 の計算です。

構成から、UU の対角成分 ukk=det⁡Ak/det⁡Ak−1u_{kk}=\det A_k/\det A_{k-1} は消去の kk 段目のピボットです。δ\delta は AA の An−1A_{n-1} に関する Schur 補行列(定理 4.2[行列の固有値評価と不等式])で、消去の各段で残る右下のブロックは、すべて Schur 補行列です(左上のブロックを消去したあとに右下に残る、「B−lwTB-\boldsymbol{l}\boldsymbol{w}^{\mathsf{T}}」の形の小さい行列のことです)。

det⁡A1=a11=0\det A_1=a_{11}=0 なら、正則な A=(0110)A=\begin{pmatrix}0&1\\1&0\end{pmatrix} でも LU 分解はありません。行を入れ替えれば解決します。数値計算では、さらにピボットの絶対値が最大になるように行を入れ替えます。

定理 2.3(部分ピボット選択つき LU 分解)✓

任意の A∈Mn(K)A\in M_n(\mathbb{K}) に対し、置換行列 PP、単位下三角行列 LL、上三角行列 UU があって

PA=LU,∣lij∣≤1(i>j)PA=LU,\qquad|l_{ij}|\le1\quad(i\gt j)

が成り立つ。AA は特異でもよい(そのとき UU の対角に 00 が現れる)。

証明(定理 2.3)

nn についての帰納法です。n=1n=1 は P=L=(1)P=L=(1), U=AU=A です。n≥2n\ge2 とし、第 1 列で絶対値が最大の成分の行 rr を選び(部分ピボット選択)、第 1 行と第 rr 行を入れ替える置換行列を P1P_1 とします。

P1A=(αwTvB),∣vi∣≤∣α∣P_1A=\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{v}&B\end{pmatrix},\qquad|v_i|\le|\alpha|

です。α≠0\alpha\ne0 なら l=v/α\boldsymbol{l}=\boldsymbol{v}/\alpha、α=0\alpha=0 なら(第 1 列は 00 なので v=0\boldsymbol{v}=\boldsymbol{0})l=0\boldsymbol{l}=\boldsymbol{0} とおくと、∣li∣≤1|l_i|\le1 で

P1A=(10TlI)(αwT0S),S=B−lwTP_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}}

です(右辺の左下は αl=v\alpha\boldsymbol{l}=\boldsymbol{v}、右下は lwT+S=B\boldsymbol{l}\boldsymbol{w}^{\mathsf{T}}+S=B)。帰納法の仮定から P′S=L′U′P'S=L'U', ∣lij′∣≤1|l'_{ij}|\le1 です。P=diag⁡(1,P′)P1P=\operatorname{diag}(1,P')P_1 とすると

PA=(10TP′lP′)(αwT0S)=(αwTαP′lP′lwT+P′S)=(10TP′lL′)(αwT0U′)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′S=L′U′P'S=L'U' を使いました)。右辺の左の因子は単位下三角で、成分は P′lP'\boldsymbol{l}(l\boldsymbol{l} の並べ替え)と L′L' の成分なので絶対値は 11 以下です。

証明の手順がそのまま算法です。kk 段目では、残っている右下のブロック A(k)A^{(k)}(A(1)=AA^{(1)}=A)の第 1 列から絶対値最大の行を選んで入れ替え、乗数 lik=aik(k)/akk(k)l_{ik}=a^{(k)}_{ik}/a^{(k)}_{kk} を作り、

aij(k+1)=aij(k)−likakj(k)(i,j>k)a^{(k+1)}_{ij}=a^{(k)}_{ij}-l_{ik}a^{(k)}_{kj}\qquad(i,j\gt k)

で次のブロックを作ります。UU の第 kk 行は akj(k)a^{(k)}_{kj}(j≥kj\ge k)です。行の入れ替えは浮動小数点数でも厳密なので、丸め誤差の解析では、最終的な PP を先に AA に施した行列をピボット選択なしで消去したと考えてかまいません。

命題 2.4(LU 分解の演算量)✓

上の算法(ピボット選択の比較を除く)の浮動小数点演算の回数は 23n3−12n2−16n\tfrac23n^3-\tfrac12n^2-\tfrac16n である。分解が済めば、Ly=PbL\boldsymbol{y}=P\boldsymbol{b} と Ux=yU\boldsymbol{x}=\boldsymbol{y} は合わせて 2n2−n2n^2-n 回で解ける。

証明(命題 2.4)

kk 段目(m=n−km=n-k とおく)は、乗数の割り算が mm 回、aij(k+1)a^{(k+1)}_{ij} の更新が m2m^2 個でそれぞれ乗算と減算の 2 回です。m=1,…,n−1m=1,\ldots,n-1 について足すと

∑m=1n−1(2m2+m)=(n−1)n(2n−1)3+n(n−1)2=23n3−12n2−16n\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

です。前進代入(対角は 11 なので割り算なし)は第 ii 行で乗算と減算が i−1i-1 回ずつで計 n2−nn^2-n 回、後退代入は第 ii 行でさらに割り算 1 回が加わって計 n2n^2 回です。

例 2.5(ピボット選択なしで壊れる 2×2 の例)

A=(ε111)A=\begin{pmatrix}\varepsilon&1\\1&1\end{pmatrix}, b=(1,2)T\boldsymbol{b}=(1,2)^{\mathsf{T}} の解は x1=1/(1−ε)x_1=1/(1-\varepsilon), x2=(1−2ε)/(1−ε)x_2=(1-2\varepsilon)/(1-\varepsilon) で、ε→0\varepsilon\to0 ではどちらも 11 に近く、κ∞(A)≈4\kappa_\infty(A)\approx4 と条件のよい問題です。binary64 で ε=10−20\varepsilon=10^{-20} としてピボット選択なしで消去すると、l21=1020l_{21}=10^{20}, u22=fl(1−1020)=−1020u_{22}=\mathrm{fl}(1-10^{20})=-10^{20} で、11 の情報が丸めで消えます。後退代入の結果は x^2=1\hat x_2=1, x^1=fl((1−1)/ε)=0\hat x_1=\mathrm{fl}((1-1)/\varepsilon)=0 で、x1x_1 がまったく違います。部分ピボット選択なら 2 行を入れ替えて l21=εl_{21}=\varepsilon となり、numpy.linalg.solve は (1,1)(1,1) を返します。L^U^\hat L\hat U の大きさを見ると、ピボット選択なしでは ∣L^∣∣U^∣|\hat L||\hat U| の成分が 102010^{20} に達し、次節の後退誤差の評価 γ∣L^∣∣U^∣\gamma|\hat L||\hat U| が ∣A∣|A| の尺度ではまったく小さくないことがわかります。

例 2.6(三重対角行列の消去)

AA が三重対角(∣i−j∣≥2|i-j|\ge2 で aij=0a_{ij}=0)で、ピボット選択なしで消去できるとします。kk 段目で第 kk 列の非零は ak+1,k(k)a^{(k)}_{k+1,k} だけで、第 kk 行の非零は ak,k+1(k)a^{(k)}_{k,k+1} だけなので、更新されるのは ak+1,k+1(k+1)a^{(k+1)}_{k+1,k+1} の 1 成分だけです。したがって LL は対角と 1 本下の副対角、UU は対角と 1 本上の副対角だけをもち、分解は割り算・乗算・減算 1 回ずつの 3(n−1)3(n-1) 回で済みます。23n3\tfrac23n^3 と比べると、比はおよそ 29n2\tfrac29n^2 で、n=106n=10^6 では約 2×10112\times10^{11} 倍の差です。一般の帯行列で帯幅が保たれることは、Cholesky 分解と帯行列の章で定理として扱います。

以下、行列は浮動小数点数を成分とし、途中でオーバーフローもアンダーフローも起きず、3nu<13nu\lt1 とします。行列やベクトルの絶対値 ∣A∣|A| と不等号 ∣E∣≤F|E|\le F は成分ごとです。丸めの記号 fl\mathrm{fl}、γk=ku/(1−ku)\gamma_k=ku/(1-ku) は浮動小数点数と丸め誤差の章のとおりです。

ピボット選択なしの消去を、浮動小数点数では次の順序で行うとします(行の入れ替えは厳密なので、部分ピボット選択の場合はあらかじめ入れ替えた PAPA に適用したと考えます)。a^ij(1)=aij\hat a^{(1)}_{ij}=a_{ij} とし、k=1,…,n−1k=1,\ldots,n-1 について

l^ik=fl(a^ik(k)/a^kk(k)),a^ij(k+1)=fl(a^ij(k)−fl(l^ika^kj(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)

を計算し、u^kj=a^kj(k)\hat u_{kj}=\hat a^{(k)}_{kj}(j≥kj\ge k)とします。成分 (i,j)(i,j) に注目すると、s0=aijs_0=a_{ij} から始めて sm=fl(sm−1−fl(l^imu^mj))s_m=\mathrm{fl}(s_{m-1}-\mathrm{fl}(\hat l_{im}\hat u_{mj})) を m=1,2,…m=1,2,\ldots と更新しており、これは既存の「1 ステップの丸め誤差」の補題(補題 4.1[行列計算の認証と最適化の証明書])の形そのものです。つまり、消去の 1 成分の計算は「引き算と掛け算を何回か繰り返し、最後に割り算をする」だけの計算で、その丸め誤差は 1 つの補題でまとめて扱えます。下の引用は、その補題の主張だけを再掲したものです。

1 ステップの丸め誤差(補題 4.1[行列計算の認証と最適化の証明書] の 1): c,ak,bk,d∈Fc,a_k,b_k,d\in\mathbb{F}、s0=cs_0=c, sk=fl(sk−1−fl(akbk))s_k=\mathrm{fl}(s_{k-1}-\mathrm{fl}(a_kb_k))(k=1,…,mk=1,\ldots,m)、y=fl(sm/d)y=\mathrm{fl}(s_m/d) なら、c=dy(1+θ(0))+∑k=1makbk(1+θ(k))c=dy(1+\theta^{(0)})+\sum_{k=1}^ma_kb_k(1+\theta^{(k)}), ∣θ(k)∣≤γm+1|\theta^{(k)}|\le\gamma_{m+1} と書ける。

補題 3.1(三角方程式の後退誤差)✓

T∈Fn×nT\in\mathbb{F}^{n\times n} を対角成分が 00 でない下三角行列、b∈Fn\boldsymbol{b}\in\mathbb{F}^n とし、前進代入

x^i=fl((bi−∑k=1i−1tikx^k)/tii)\hat x_i=\mathrm{fl}\Bigl(\bigl(b_i-\textstyle\sum_{k=1}^{i-1}t_{ik}\hat x_k\bigr)/t_{ii}\Bigr)

(和は s←fl(s−fl(tikx^k))s\leftarrow\mathrm{fl}(s-\mathrm{fl}(t_{ik}\hat x_k)) で k=1,…,i−1k=1,\ldots,i-1 の順に計算する)で x^\hat{\boldsymbol{x}} を求める。このとき

(T+ΔT)x^=b,∣ΔT∣≤γn∣T∣(T+\Delta T)\hat{\boldsymbol{x}}=\boldsymbol{b},\qquad|\Delta T|\le\gamma_n|T|

となる下三角行列 ΔT\Delta T がある。上三角行列の後退代入(kk を任意の順に計算してよい)についても同じことが成り立つ。

証明(補題 3.1)

第 ii 行に「1 ステップの丸め誤差」の補題(補題 4.1[行列計算の認証と最適化の証明書] の 1)を c=bic=b_i, m=i−1m=i-1, akbk=tikx^ka_kb_k=t_{ik}\hat x_k, d=tiid=t_{ii}, y=x^iy=\hat x_i で使うと

bi=tiix^i(1+θi(0))+∑k=1i−1tikx^k(1+θi(k)),∣θi(k)∣≤γi≤γnb_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

です(γk\gamma_k は kk について増加。補題 3.2[浮動小数点数と丸め誤差] の 1)。Δtii=tiiθi(0)\Delta t_{ii}=t_{ii}\theta^{(0)}_i, Δtik=tikθi(k)\Delta t_{ik}=t_{ik}\theta^{(k)}_i(k<ik\lt i)とおけば主張です。後退代入では和の項の番号を付け替えれば同じ議論です。

この節の流れは次のとおりです。まず分解 L^U^\hat L\hat U が元の AA から成分ごとにどれだけずれるかを示し、次に前進代入・後退代入の誤差(3.2 節)を重ねて、最終的な解が「AA を少し変えた方程式の正確な解」になっていることを示します。どちらも、各成分に入る丸めの回数を数えて γk\gamma_k で上から抑えるだけです。

定理 3.2(LU 分解の後退誤差)✓

A∈Fn×nA\in\mathbb{F}^{n\times n} の 3.1 節の消去がピボット a^kk(k)≠0\hat a^{(k)}_{kk}\ne0 のまま最後まで進み、L^\hat L(単位下三角、(i,k)(i,k) 成分 l^ik\hat l_{ik})と U^\hat 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|.
証明(定理 3.2)

(L^U^)ij=∑k≤min⁡(i,j)l^iku^kj(\hat L\hat U)_{ij}=\sum_{k\le\min(i,j)}\hat l_{ik}\hat u_{kj}(l^ii=1\hat l_{ii}=1)です。

i≤ji\le j のとき、u^ij=a^ij(i)\hat u_{ij}=\hat a^{(i)}_{ij} は s0=aijs_0=a_{ij} から sm=fl(sm−1−fl(l^imu^mj))s_m=\mathrm{fl}(s_{m-1}-\mathrm{fl}(\hat l_{im}\hat u_{mj}))(m=1,…,i−1m=1,\ldots,i-1)で得た si−1s_{i-1} です。これは d=1d=1, y=fl(si−1/1)=si−1y=\mathrm{fl}(s_{i-1}/1)=s_{i-1} とした補題(補題 4.1[行列計算の認証と最適化の証明書] の 1)の形なので

aij=u^ij(1+θ(0))+∑k=1i−1l^iku^kj(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.

i>ji\gt j のとき、l^ij=fl(sj−1/u^jj)\hat l_{ij}=\mathrm{fl}(s_{j-1}/\hat u_{jj}) で、sj−1s_{j-1} は同じ更新を m=1,…,j−1m=1,\ldots,j-1 まで行った値です。補題を d=u^jjd=\hat u_{jj}, y=l^ijy=\hat l_{ij} で使うと

aij=l^iju^jj(1+θ(0))+∑k=1j−1l^iku^kj(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.

どちらの場合も aij=∑k≤min⁡(i,j)l^iku^kj(1+θ(k))a_{ij}=\sum_{k\le\min(i,j)}\hat l_{ik}\hat u_{kj}(1+\theta^{(k)}) なので、Δaij=(L^U^)ij−aij=−∑kl^iku^kjθ(k)\Delta a_{ij}=(\hat L\hat U)_{ij}-a_{ij}=-\sum_k\hat l_{ik}\hat u_{kj}\theta^{(k)} で、∣Δaij∣≤γn∑k∣l^ik∣∣u^kj∣=γn(∣L^∣∣U^∣)ij|\Delta a_{ij}|\le\gamma_n\sum_k|\hat l_{ik}||\hat u_{kj}|=\gamma_n(|\hat L||\hat U|)_{ij} です。

定理 3.3(Gauss 消去による解の後退誤差)✓

定理 3.2 の L^\hat L, U^\hat U を使い、前進代入 L^y^=b\hat L\hat{\boldsymbol{y}}=\boldsymbol{b} と後退代入 U^x^=y^\hat U\hat{\boldsymbol{x}}=\hat{\boldsymbol{y}} を 補題 3.1 の算法で解いたとする。このとき

(A+ΔA)x^=b,∣ΔA∣≤γ3n∣L^∣∣U^∣.(A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b},\qquad|\Delta A|\le\gamma_{3n}|\hat L||\hat U|.

部分ピボット選択の場合は、L^U^\hat L\hat U が PAPA の分解で L^y^=Pb\hat L\hat{\boldsymbol{y}}=P\boldsymbol{b} を解くとして、(A+ΔA)x^=b(A+\Delta A)\hat{\boldsymbol{x}}=\boldsymbol{b}, ∣ΔA∣≤γ3nPT∣L^∣∣U^∣|\Delta A|\le\gamma_{3n}P^{\mathsf{T}}|\hat L||\hat U| である。

証明(定理 3.3)

補題 3.1 から (L^+ΔL)y^=b(\hat L+\Delta L)\hat{\boldsymbol{y}}=\boldsymbol{b}, ∣ΔL∣≤γn∣L^∣|\Delta L|\le\gamma_n|\hat L|、(U^+ΔU)x^=y^(\hat U+\Delta U)\hat{\boldsymbol{x}}=\hat{\boldsymbol{y}}, ∣ΔU∣≤γn∣U^∣|\Delta U|\le\gamma_n|\hat U| です。代入して 定理 3.2 の L^U^=A+ΔA1\hat L\hat U=A+\Delta A_1 を使うと

b=(L^+ΔL)(U^+ΔU)x^=(A+ΔA1+L^ΔU+ΔLU^+Δ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}}

なので、ΔA=ΔA1+L^ΔU+ΔLU^+ΔLΔU\Delta A=\Delta A_1+\hat L\Delta U+\Delta L\hat U+\Delta L\Delta U とおきます。成分ごとの三角不等式から

∣ΔA∣≤(γn+2γn+γn2)∣L^∣∣U^∣|\Delta A|\le(\gamma_n+2\gamma_n+\gamma_n^2)|\hat L||\hat U|

です。補題 3.2[浮動小数点数と丸め誤差] の 2 から 2γn+γn2≤γ2n2\gamma_n+\gamma_n^2\le\gamma_{2n}、同じく γ2n+γn≤γ3n\gamma_{2n}+\gamma_n\le\gamma_{3n} なので、係数は γ3n\gamma_{3n} 以下です。部分ピボット選択の場合は PAPA, PbP\boldsymbol{b} に適用して (PA+ΔA′)x^=Pb(PA+\Delta A')\hat{\boldsymbol{x}}=P\boldsymbol{b} を得、左から PTP^{\mathsf{T}} を掛けて ΔA=PTΔA′\Delta A=P^{\mathsf{T}}\Delta A' とします(置換は成分の絶対値を並べ替えるだけです)。

この定理は成分ごとの後退誤差の評価ですが、尺度は ∣A∣|A| ではなく ∣L^∣∣U^∣|\hat L||\hat U| です。∣L^∣∣U^∣|\hat L||\hat U| が ∣A∣|A| と同じ程度の大きさなら、Gauss 消去は(成分ごと・ノルムともに)後退安定です。しかし 例 2.5 のように ∣L^∣∣U^∣≫∣A∣|\hat L||\hat U|\gg|A| となることがあり、そのときは評価が役に立ちません。ピボット選択の目的は、∣L^∣∣U^∣|\hat L||\hat U| を ∣A∣|A| の尺度に抑えることです。

なお LAPACK の getrf はキャッシュを活かすためにブロック化した順序で計算し、内積の順序も上の算法と異なりますが、各成分が受ける丸めの回数は同じ程度で、同じ形の評価(定数が少し変わる)が成り立つことが知られています(Higham『Accuracy and Stability of Numerical Algorithms』第 9 章・第 13 章)。以下のコードの数値は LAPACK の結果なので、定理の評価との比較は「同じ大きさか」を見るものです。

4.1. 部分ピボット選択の成長因子

Section titled “4.1. 部分ピボット選択の成長因子”

定義 4.1(成長因子)↗

3.1 節の消去で現れるすべての中間値の絶対値の最大と、AA の成分の絶対値の最大の比

ρ^n(A)=max⁡i,j,k∣a^ij(k)∣max⁡i,j∣aij∣\hat\rho_n(A)=\frac{\max_{i,j,k}|\hat a^{(k)}_{ij}|}{\max_{i,j}|a_{ij}|}

を(計算した消去の)成長因子という。厳密な算術で行った消去の中間値 aij(k)a^{(k)}_{ij} で同じ比をとったものを ρn(A)\rho_n(A) と書く。

u^kj=a^kj(k)\hat u_{kj}=\hat a^{(k)}_{kj} なので max⁡∣u^kj∣≤ρ^nmax⁡∣aij∣\max|\hat u_{kj}|\le\hat\rho_n\max|a_{ij}| です。部分ピボット選択では ∣l^ik∣≤1|\hat l_{ik}|\le1 なので、∣L^∣∣U^∣|\hat L||\hat U| の大きさは成長因子で決まります。次の定理は、その成長因子が最悪でもどこまで大きくなりうるかを与えます。証明の方針は、各段で成分の絶対値が高々 2 倍にしかならないことを示し、それを段数だけ繰り返すことです。

定理 4.2(部分ピボット選択の成長因子)✓

部分ピボット選択を行う消去について、

  1. 厳密な算術では ρn(A)≤2n−1\rho_n(A)\le2^{n-1}。
  2. 浮動小数点数の消去(3.1 節の算法を、各段で ∣a^ik(k)∣|\hat a^{(k)}_{ik}| が最大の行を選んで行う)では ∣l^ik∣≤1|\hat l_{ik}|\le1 であり、ρ^n(A)≤(2(1+u)2)n−1\hat\rho_n(A)\le\bigl(2(1+u)^2\bigr)^{n-1}。
証明(定理 4.2)
  1. kk 段目のピボットは第 kk 列で絶対値最大なので ∣lik∣=∣aik(k)/akk(k)∣≤1|l_{ik}|=|a^{(k)}_{ik}/a^{(k)}_{kk}|\le1 です(ピボットが 00 なら列は 00 で、乗数を 00 とします)。よって ∣aij(k+1)∣≤∣aij(k)∣+∣lik∣∣akj(k)∣≤2max⁡p,q∣apq(k)∣|a^{(k+1)}_{ij}|\le|a^{(k)}_{ij}|+|l_{ik}||a^{(k)}_{kj}|\le2\max_{p,q}|a^{(k)}_{pq}| で、kk についての帰納法から max⁡∣apq(k)∣≤2k−1max⁡∣apq∣\max|a^{(k)}_{pq}|\le2^{k-1}\max|a_{pq}| です。k≤nk\le n なので主張が出ます。
  2. t=a^ik(k)/a^kk(k)t=\hat a^{(k)}_{ik}/\hat a^{(k)}_{kk} は ∣t∣≤1|t|\le1 です。l^ik=fl(t)\hat l_{ik}=\mathrm{fl}(t) が 11 より大きいとすると、1∈F1\in\mathbb{F} は tt との距離 1−t1-t が fl(t)−t\mathrm{fl}(t)-t より小さく、最も近い浮動小数点数を選ぶ丸めの定義に反します。−1-1 についても同様で、∣l^ik∣≤1|\hat l_{ik}|\le1 です。標準モデル(系 3.1[浮動小数点数と丸め誤差])から ∣a^ij(k+1)∣≤(1+u)(∣a^ij(k)∣+(1+u)∣l^ik∣∣a^kj(k)∣)≤2(1+u)2max⁡p,q∣a^pq(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}| で、1 と同じ帰納法です。

系 4.3(部分ピボット選択つき Gauss 消去のノルムによる後退誤差)✓

部分ピボット選択つき Gauss 消去で計算した解 x^\hat{\boldsymbol{x}} は

(A+ΔA)x^=b,∥ΔA∥∞≤n2γ3n ρ^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

を満たす。したがってノルムに関する後退誤差(定義 7.1[行列のノルムと線形方程式の条件数]、∞\infty ノルム)は n2γ3nρ^n(A)n^2\gamma_{3n}\hat\rho_n(A) 以下である。

証明(系 4.3)

定理 3.3 から ∣ΔA∣≤γ3nPT∣L^∣∣U^∣|\Delta A|\le\gamma_{3n}P^{\mathsf{T}}|\hat L||\hat U| です。∥⋅∥∞\|\cdot\|_\infty は行和の最大(命題 4.2[行列のノルムと線形方程式の条件数] の 2)なので、成分ごとの不等式 ∣E∣≤F|E|\le F から ∥E∥∞≤∥F∥∞\|E\|_\infty\le\|F\|_\infty が従い、行の並べ替え PTP^{\mathsf{T}} はノルムを変えません。また誘導ノルムは ∥XYz∥≤∥X∥∥Yz∥≤∥X∥∥Y∥∥z∥\|XY\boldsymbol{z}\|\le\|X\|\|Y\boldsymbol{z}\|\le\|X\|\|Y\|\|\boldsymbol{z}\| から劣乗法的です。よって

∥ΔA∥∞≤γ3n ∥∣L^∣∥∞ ∥∣U^∣∥∞\|\Delta A\|_\infty\le\gamma_{3n}\,\||\hat L|\|_\infty\,\||\hat U|\|_\infty

です。∣l^ik∣≤1|\hat l_{ik}|\le1(定理 4.2 の 2)から ∥∣L^∣∥∞≤n\||\hat L|\|_\infty\le n、∣u^kj∣≤ρ^nmax⁡∣aij∣|\hat u_{kj}|\le\hat\rho_n\max|a_{ij}| から ∥∣U^∣∥∞≤nρ^nmax⁡∣aij∣\||\hat U|\|_\infty\le n\hat\rho_n\max|a_{ij}|、そして max⁡∣aij∣≤∥A∥∞\max|a_{ij}|\le\|A\|_\infty です。後半は Δb=0\Delta\boldsymbol{b}=\boldsymbol{0} として定義に当てはめたものです。

したがって条件数との積で、前進誤差は ∥x^−x∥∞/∥x∥∞≲2κ∞(A) n2γ3nρ^n\|\hat{\boldsymbol{x}}-\boldsymbol{x}\|_\infty/\|\boldsymbol{x}\|_\infty\lesssim2\kappa_\infty(A)\,n^2\gamma_{3n}\hat\rho_n です(系 7.3[行列のノルムと線形方程式の条件数])。n2n^2 の係数は最悪の場合の数え方で、実際の誤差はずっと小さいのが普通です。問題は ρ^n\hat\rho_n です。

例 4.4(成長因子が 2ⁿ⁻¹ に達する行列)

対角成分が 11、対角より下がすべて −1-1、最後の列がすべて 11、他が 00 の行列 WnW_n を考えます。第 1 列は 1,−1,…,−11,-1,\ldots,-1 で絶対値がすべて等しく、部分ピボット選択は行を入れ替えません(同点なら上の行を選ぶ約束)。1 段目の消去で最後の列は 1,2,…,21,2,\ldots,2 になり、残りのブロックは同じ形で最後の列が 2 倍になったものです。これを繰り返すと unn=2n−1u_{nn}=2^{n-1} となり、ρn(Wn)=2n−1\rho_n(W_n)=2^{n-1} で 定理 4.2 の上界に達します。一方 κ∞(Wn)=n\kappa_\infty(W_n)=n で、問題の条件はよいのです。

次のコードは n=10,20,30,50n=10,20,30,50 について、scipy.linalg.lu の UU から測った成長因子(=2n−1=2^{n-1} かの判定とその値)、P∣L^∣∣U^∣∣x^∣P|\hat L||\hat U||\hat{\boldsymbol{x}}| を尺度とした成分ごとの後退誤差 ω=max⁡i∣ri∣/(P∣L^∣∣U^∣∣x^∣)i\omega=\max_i|r_i|/(P|\hat L||\hat U||\hat{\boldsymbol{x}}|)_i と評価 γ3n\gamma_{3n}、Rigal–Gaches の後退誤差 η=∥r∥∞/(∥A∥∞∥x^∥∞+∥b∥∞)\eta=\|\boldsymbol{r}\|_\infty/(\|A\|_\infty\|\hat{\boldsymbol{x}}\|_\infty+\|\boldsymbol{b}\|_\infty)(定理 7.2[行列のノルムと線形方程式の条件数])、κ∞\kappa_\infty、mpmath の 50 桁の解に対する前進誤差を並べます(SciPy の lu は A=PLUA=PLU の形で返すので、尺度の PP は本文の PTP^{\mathsf{T}} にあたります)。

# Python 3.12.10 / NumPy 2.5.2 / SciPy 1.18.1 / mpmath 1.3.0
# (x86-64, OpenBLAS)/乱数種 20261006
import numpy as np
import scipy.linalg as sla
import mpmath as mp
def wilkinson(n): # 対角 1, 対角より下 -1, 最後の列 1
A = np.eye(n) - np.tril(np.ones((n, n)), -1)
A[:, -1] = 1.0
return A
mp.mp.dps = 50
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):
A = wilkinson(n)
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)
r = b - A @ x
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 つの nn すべてで 2n−12^{n-1} に一致し(True)、κ∞(Wn)=n\kappa_\infty(W_n)=n も閉じた形のとおりです。(b) 別精度: 前進誤差は mpmath の 50 桁の解との比較で、系 7.3[行列のノルムと線形方程式の条件数] の評価 2κ∞η/(1−κ∞η)2\kappa_\infty\eta/(1-\kappa_\infty\eta) の内側にあります(n=50n=50 で 2.6×10−3≤9.7×10−32.6\times10^{-3}\le9.7\times10^{-3})。(c) 次数: ∣L^∣∣U^∣|\hat L||\hat U| を尺度とした後退誤差 ω\omega はどの nn でも uu 程度で 定理 3.3 の γ3n\gamma_{3n} の内側ですが、∣A∣|A| の尺度の後退誤差 η\eta は、n=10n=10 から 2020 では約 5656 倍ですが、その先は nn が 10 増えるごとにおよそ 210≈1032^{10}\approx10^3 倍に増え、成長因子の増え方 2n−12^{n-1} と同じ割合で悪化します。条件のよい問題なのに答えが 3 桁しか合わないのは、アルゴリズムの後退誤差が大きいからです。

注意 4.5(完全ピボット選択と成長因子の典型的な大きさ(文献))

残りのブロック全体から絶対値最大の成分をピボットに選ぶ(行と列を入れ替える)完全ピボット選択では、Wilkinson が Hadamard の不等式を使って ρn≤n1/2(2⋅31/2⋯n1/(n−1))1/2\rho_n\le n^{1/2}(2\cdot3^{1/2}\cdots n^{1/(n-1)})^{1/2} を示しました(Wilkinson 1961、Higham 第 2 版 §9.4)。列だけでなく行の最大でもあるピボットを探すルークピボット選択も、成長因子の上界が完全ピボット選択と同様に指数関数よりずっと遅く増えることが知られています(Foster 1997、Higham §9.1)。これらは比較の手間が増えるので、LAPACK の標準の解法は部分ピボット選択です。部分ピボット選択で成長因子が大きくなる行列は実際にはまれで、乱数行列の成長因子の分布は Trefethen–Schreiber(1990)が数値実験で調べています。この記事の証明はこれらの評価を使いません。

例 4.6(乱数行列の成長因子)

乱数種を固定した標準正規乱数の n×nn\times n 行列を各 nn で 30 本作り、scipy.linalg.lu の UU から測った max⁡∣u^kj∣/max⁡∣aij∣\max|\hat u_{kj}|/\max|a_{ij}|(成長因子の下界)の平均と最大を出します。最後の列は最後の 1 本の max⁡∣l^ik∣\max|\hat l_{ik}| です。

# Python 3.12.10 / NumPy 2.5.2 / SciPy 1.18.1(x86-64, OpenBLAS)
# 乱数種 20261006
import numpy as np
import scipy.linalg as sla
rng = np.random.default_rng(20261006)
for n in (100, 200, 400, 800):
rho = []
for _ in range(30):
A = rng.standard_normal((n, n))
P, L, U = sla.lu(A)
rho.append(np.abs(U).max() / np.abs(A).max())
rho = np.array(rho)
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^ik∣≤1|\hat l_{ik}|\le1(定理 4.2 の 2)が成り立っています。(b) 別の物差し: 成長因子は上界 2n−12^{n-1}(n=100n=100 で 6×10296\times10^{29})より 28 桁以上小さく、例 4.4 とは対照的です。(c) 増え方: この範囲では平均は n\sqrt n にほぼ比例して増えています(比が 0.530.53〜0.560.56)。ただしこれは 30 本の標本で見た経験的な傾向で、定理ではありません。UU だけから測っているので、中間値をすべて含む成長因子はこれ以上です。

ピボット選択が要らない重要な行列の族があります。狭義列対角優位とは、各列で対角成分の絶対値が、同じ列のほかの成分の絶対値の和より大きいことです。次の定理は、この性質が消去の途中で失われず、成長因子も小さく抑えられることを示します。

定理 4.7(列対角優位な行列の LU 分解)✓

A∈Mn(K)A\in M_n(\mathbb{K}) が狭義列対角優位、すなわちすべての jj で ∣ajj∣>∑i≠j∣aij∣|a_{jj}|\gt\sum_{i\ne j}|a_{ij}| とする。このとき(厳密な算術で)

  1. ピボット選択なしの消去は最後まで進み、A=LUA=LU の LU 分解がある。乗数は ∣lik∣<1|l_{ik}|\lt1 で、部分ピボット選択は行を入れ替えない。
  2. 消去の各段の残りのブロック(Schur 補行列)も狭義列対角優位である。
  3. 各列の成分の絶対値の和は消去で増えず、成長因子は ρn(A)≤2\rho_n(A)\le2 である。
証明(定理 4.7)

1 段目を考えます。A=(αwTvB)A=\begin{pmatrix}\alpha&\boldsymbol{w}^{\mathsf{T}}\\\boldsymbol{v}&B\end{pmatrix} とすると、第 1 列の狭義列対角優位から ∣α∣>∑i∣vi∣≥0|\alpha|\gt\sum_i|v_i|\ge0 なので α≠0\alpha\ne0、∣li∣=∣vi∣/∣α∣<1|l_i|=|v_i|/|\alpha|\lt1 です。Schur 補行列の分解(定理 4.2[行列の固有値評価と不等式] の 2 を 1×11\times1 の左上ブロック α\alpha で使う)から、AA は (10Tv/αI)(αwT0S)\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}, S=B−vwT/αS=B-\boldsymbol{v}\boldsymbol{w}^{\mathsf{T}}/\alpha と書けます。

2. SS の第 jj 列(AA の第 j+1j+1 列に対応。以下 bijb_{ij}, wjw_j, viv_i は対応する成分)を見ます。AA のこの列の狭義列対角優位は ∣bjj∣>∣wj∣+∑i≠j∣bij∣|b_{jj}|\gt|w_j|+\sum_{i\ne j}|b_{ij}| で、第 1 列のそれから ∑i≠j∣vi∣<∣α∣−∣vj∣\sum_{i\ne j}|v_i|\lt|\alpha|-|v_j| です。よって

∑i≠j∣sij∣≤∑i≠j∣bij∣+∣wj∣∣α∣∑i≠j∣vi∣<(∣bjj∣−∣wj∣)+∣wj∣(1−∣vj∣∣α∣)=∣bjj∣−∣wj∣∣vj∣∣α∣≤∣sjj∣\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}|

です(最後は sjj=bjj−vjwj/αs_{jj}=b_{jj}-v_jw_j/\alpha と三角不等式)。SS は狭義列対角優位なので、同じ議論を SS に繰り返せます。各段のピボットが 00 でないので消去は最後まで進み、定理 2.3 の証明と同じ組み立て(P=IP=I)で A=LUA=LU を得ます。

3. SS の第 jj 列の絶対値の和は ∑i∣sij∣≤∑i∣bij∣+∣wj∣∑i∣vi∣/∣α∣≤∑i∣bij∣+∣wj∣\sum_i|s_{ij}|\le\sum_i|b_{ij}|+|w_j|\sum_i|v_i|/|\alpha|\le\sum_i|b_{ij}|+|w_j| で、これは AA の対応する列の絶対値の和です。各段で列の絶対値の和は増えないので、kk 段目の中間値について ∣aij(k)∣≤∑p∣apj∣<2∣ajj∣≤2max⁡∣apq∣|a^{(k)}_{ij}|\le\sum_p|a_{pj}|\lt2|a_{jj}|\le2\max|a_{pq}| です(狭義列対角優位から非対角の和は ∣ajj∣|a_{jj}| 未満)。よって ρn(A)≤2\rho_n(A)\le2 です。

列対角優位な行列は、偏微分方程式の上流差分、Markov 連鎖の遷移行列から作る行列などに現れます。行対角優位な行列は転置が列対角優位なので、AT=LUA^{\mathsf{T}}=LU から A=UTLTA=U^{\mathsf{T}}L^{\mathsf{T}} の形の分解が同様に安定に作れます。

計算した解 x0\boldsymbol{x}_0 の残差 r0=b−Ax0\boldsymbol{r}_0=\boldsymbol{b}-A\boldsymbol{x}_0 を求め、補正方程式 Ad0=r0A\boldsymbol{d}_0=\boldsymbol{r}_0 を解いて x1=x0+d0\boldsymbol{x}_1=\boldsymbol{x}_0+\boldsymbol{d}_0 とする操作を繰り返すのが反復改良です。補正方程式は、手元の(誤差のある)LU 分解で解きます。その誤差を AA の摂動 EkE_k として表すと、次の定理が成り立ちます。

定理に出てくる 3 つの誤差は、それぞれ別の場所で生じるものです。gk\boldsymbol{g}_k は残差 b−Axk\boldsymbol{b}-A\boldsymbol{x}_k を計算するときの誤差、EkE_k は補正方程式を(精度の低い)LU 分解で解くことによる誤差、fk\boldsymbol{f}_k は xk+dk\boldsymbol{x}_k+\boldsymbol{d}_k の足し算の誤差です。主張は、補正方程式の誤差が十分小さければ、1 回ごとに解の誤差が一定の割合で縮む、というものです。

定理 5.1(反復改良の収束)✓

A∈Mn(K)A\in M_n(\mathbb{K}) を正則、Ax=bA\boldsymbol{x}=\boldsymbol{b} とし、ベクトルノルムとその誘導ノルムを 1 つ固定する。x0\boldsymbol{x}_0 から次のように xk\boldsymbol{x}_k を作る。

rk=b−Axk+gk,(A+Ek)dk=rk,xk+1=xk+dk+fk.\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.

ここで gk\boldsymbol{g}_k は残差の計算誤差、EkE_k は補正方程式を解く誤差、fk\boldsymbol{f}_k は足し算の誤差である。∥A−1Ek∥≤θ<1\|A^{-1}E_k\|\le\theta\lt1 がすべての kk で成り立つとき、ek=xk−x\boldsymbol{e}_k=\boldsymbol{x}_k-\boldsymbol{x} は

∥ek+1∥≤θ1−θ∥ek∥+∥A−1∥ ∥gk∥1−θ+∥fk∥\|\boldsymbol{e}_{k+1}\|\le\frac{\theta}{1-\theta}\|\boldsymbol{e}_k\|+\frac{\|A^{-1}\|\,\|\boldsymbol{g}_k\|}{1-\theta}+\|\boldsymbol{f}_k\|

を満たす。とくに gk=fk=0\boldsymbol{g}_k=\boldsymbol{f}_k=\boldsymbol{0} で θ<1/2\theta\lt1/2 なら、誤差は 1 回ごとに θ/(1−θ)<1\theta/(1-\theta)\lt1 倍以下に縮み、xk→x\boldsymbol{x}_k\to\boldsymbol{x} である。

証明(定理 5.1)

逆行列の摂動の補題(補題 6.1[行列のノルムと線形方程式の条件数])を、正則行列 II(逆行列は II)と摂動 A−1EkA^{-1}E_k に使うと、∥A−1Ek∥≤θ<1\|A^{-1}E_k\|\le\theta\lt1 から I+A−1EkI+A^{-1}E_k は正則で ∥(I+A−1Ek)−1∥≤1/(1−θ)\|(I+A^{-1}E_k)^{-1}\|\le1/(1-\theta) です。A+Ek=A(I+A−1Ek)A+E_k=A(I+A^{-1}E_k) も正則で、Mk=(A+Ek)−1=(I+A−1Ek)−1A−1M_k=(A+E_k)^{-1}=(I+A^{-1}E_k)^{-1}A^{-1} です。b−Axk=−Aek\boldsymbol{b}-A\boldsymbol{x}_k=-A\boldsymbol{e}_k なので

ek+1=ek+Mk(−Aek+gk)+fk=(I−MkA)ek+Mkgk+fk\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

です。I−MkA=Mk((A+Ek)−A)=MkEk=(I+A−1Ek)−1A−1EkI-M_kA=M_k\bigl((A+E_k)-A\bigr)=M_kE_k=(I+A^{-1}E_k)^{-1}A^{-1}E_k なので ∥I−MkA∥≤θ/(1−θ)\|I-M_kA\|\le\theta/(1-\theta)、また ∥Mk∥≤∥A−1∥/(1−θ)\|M_k\|\le\|A^{-1}\|/(1-\theta) です。三角不等式で主張の不等式を得ます。θ<1/2\theta\lt1/2 なら θ/(1−θ)<1\theta/(1-\theta)\lt1 で、∥ek∥≤(θ/(1−θ))k∥e0∥→0\|\boldsymbol{e}_k\|\le(\theta/(1-\theta))^k\|\boldsymbol{e}_0\|\to0 です。

この定理の読み方は次のとおりです。

  • 縮小率 θ/(1−θ)≈∥A−1Ek∥\theta/(1-\theta)\approx\|A^{-1}E_k\| は、補正方程式を解く精度で決まります。分解を単位丸め ufu_{\mathrm{f}} で行えば、定理 3.3 と成長因子の評価から ∥Ek∥≲cnρ^nuf∥A∥\|E_k\|\lesssim c_n\hat\rho_nu_{\mathrm{f}}\|A\| で、θ≈cnρ^nκ(A)uf\theta\approx c_n\hat\rho_n\kappa(A)u_{\mathrm{f}} です。
  • 到達できる精度は第 2 項・第 3 項、つまり残差と足し算の精度で決まります。残差を分解より高い精度 uru_{\mathrm{r}} で計算すれば、分解が低い精度でも、最終的な誤差は uru_{\mathrm{r}} の側で決まります。

これが混合精度の反復改良の考え方です。O(n3)O(n^3) の分解を速い低精度(binary32 や GPU の binary16)で行い、O(n2)O(n^2) の残差と更新だけを binary64 で行います。条件は κ(A)uf\kappa(A)u_{\mathrm{f}} が 11 より十分小さいことです。

例 5.2(binary32 の LU と binary64 の残差)

乱数種を固定した直交行列 Q1,Q2Q_1,Q_2 と、11 から 1/κ1/\kappa まで等比に並べた特異値で A=Q1ΣQ2TA=Q_1\Sigma Q_2^{\mathsf{T}}(κ2(A)=κ\kappa_2(A)=\kappa)を作り、n=50n=50 で binary32 の LU 分解と binary64 の残差による反復改良を 4 回行います。1 行目は x0\boldsymbol{x}_0(binary32 の分解で解いたもの)から x4\boldsymbol{x}_4 までの相対誤差(∞\infty ノルム、参照解は mpmath の 50 桁)、2 行目は最初の 2 回の縮小率、κu32\kappa 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 numpy as np
import scipy.linalg as sla
import mpmath as mp
mp.mp.dps = 50
rng = np.random.default_rng(20261006)
n, u32 = 50, 2.0 ** -24
Q1, _ = np.linalg.qr(rng.standard_normal((n, n)))
Q2, _ = np.linalg.qr(rng.standard_normal((n, n)))
b = rng.standard_normal(n)
for kap in (1e2, 1e4):
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 = []
for k in range(5):
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) は構成どおり 10210^2, 10410^4 で、参照解は mpmath の 50 桁で解いたものです。(b) 別精度・別手法: 2〜3 回の改良で、binary64 の分解で直接解いた解と同じかそれ以上の精度に達します。(c) 率: 縮小率は κ=104\kappa=10^4 で 3.5×10−53.5\times10^{-5}, 5.6×10−55.6\times10^{-5} と、定理 5.1 の予言する θ≈κu32=6×10−4\theta\approx\kappa u_{32}=6\times10^{-4} 以下です。κ=102\kappa=10^2 の 2 回目の比 2.7×10−42.7\times10^{-4} は、誤差がすでに binary64 の到達精度(第 2・第 3 項)に達して止まったためで、縮小率ではありません。

演習 6.1易

A=(211433879)A=\begin{pmatrix}2&1&1\\4&3&3\\8&7&9\end{pmatrix} の LU 分解(ピボット選択なし)を求め、定理 2.2 の u11u22u33=det⁡Au_{11}u_{22}u_{33}=\det A を確かめよ。また部分ピボット選択を行うと、1 段目でどの行がピボットになるか。

解答

1 段目の乗数は l21=2l_{21}=2, l31=4l_{31}=4 で、残りは (1135)\begin{pmatrix}1&1\\3&5\end{pmatrix}。2 段目の乗数は l32=3l_{32}=3 で、u33=5−3=2u_{33}=5-3=2 です。よって

L=(100210431),U=(211011002),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},

det⁡A=2⋅1⋅2=4\det A=2\cdot1\cdot2=4 です(det⁡A1=2\det A_1=2, det⁡A2=2⋅3−1⋅4=2=u11u22\det A_2=2\cdot3-1\cdot4=2=u_{11}u_{22} も確かめられます)。部分ピボット選択では第 1 列の絶対値最大の 88 の第 3 行がピボットになり、乗数は 1/41/4, 1/21/2 です。

演習 6.2標準

部分ピボット選択で 3×33\times3 の行列の成長因子が上界 44 に達する例を作れ。例 4.4 の W3W_3 の消去を手で追ってもよい。

解答

W3=(101−111−1−11)W_3=\begin{pmatrix}1&0&1\\-1&1&1\\-1&-1&1\end{pmatrix} です。1 段目は同点で第 1 行がピボット、乗数は −1,−1-1,-1 で、残りのブロックは (12−12)\begin{pmatrix}1&2\\-1&2\end{pmatrix}。2 段目も同点で第 2 行がピボット、乗数 −1-1 で u33=2+2=4u_{33}=2+2=4 です。max⁡∣aij∣=1\max|a_{ij}|=1 なので成長因子は 4=23−14=2^{3-1} です。各段で乗数の絶対値が 11、かつ足し合わせる 2 つの成分の符号がそろうことが、上界に達する条件です。

演習 6.3標準

κ∞(A)=106\kappa_\infty(A)=10^6 の行列を binary32(u32≈6×10−8u_{32}\approx6\times10^{-8})の LU と binary64 の残差で反復改良する。定理 5.1 の縮小率を θ≈κu32\theta\approx\kappa u_{32} と見積もり、初期誤差 10−110^{-1} から 10−810^{-8} に下げるのに何回の改良が要るかを見積もれ。κ=108\kappa=10^8 ではどうか。

解答

θ≈106⋅6×10−8=0.06\theta\approx10^6\cdot6\times10^{-8}=0.06 で、θ/(1−θ)≈0.064\theta/(1-\theta)\approx0.064、1 回でおよそ 1.21.2 桁縮みます。7 桁下げるには 7/1.2≈5.97/1.2\approx5.9 から約 66 回です。それ以上改良しても、誤差は定理の第 2 項(binary64 の残差の誤差 ∥A−1∥∥gk∥\|A^{-1}\|\|\boldsymbol{g}_k\|)で止まり、最悪の場合の目安は κu64≈106⋅1.1×10−16≈10−10\kappa u_{64}\approx10^6\cdot1.1\times10^{-16}\approx10^{-10} です。κ=108\kappa=10^8 では θ≈6\theta\approx6 で θ<1\theta\lt1 の仮定が成り立たず、定理は収束を保証しません。実際、binary32 の分解は AA を κu32>1\kappa u_{32}\gt1 の相対誤差で表しており、補正の方向がほとんど情報をもたないので、反復改良は一般に収束しません。この場合は 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.

このテーマの 100 本ノック(100 問)

執筆: Claude Code(Opus 5.5)、Claude Code(Sonnet 5.5)・監査 2 回(Claude Code)・最終 2026-10-12

この記事の誤りを報告する ・運営: 夢現技研合同会社 ・料金 ・利用条件 ・特定商取引法に基づく表記

© 2026 夢現技研合同会社 ・コード例は MIT ライセンスです。