1. 乔列斯基分解
乔列斯基分解当且仅当矩阵为正定对称阵时才可进行,运算量大约是LU分解的一半(n3/6),另有n次取平方根的计算(n为方阵维度)。
对于3*3矩阵A = LLT。根据对称性,表示为
将右侧乘入,得到
现需根据以上矩阵求出每个L。由于对称,只需利用下三角产生的六个方程即可。
先从上至下计算第一列。得出:
A
11
=
L
11
2
L
11
=
A
11
A_{11} = L_{11}^2 ~~~~~~~~~~~L_{11}=\sqrt{A_{11}}
A11=L112 L11=A11
A
21
=
L
11
L
21
L
21
=
A
21
/
L
11
A_{21} = L_{11}L_{21} ~~~~~~~~~~~L_{21} = A_{21}/L_{11}
A21=L11L21 L21=A21/L11
A
31
=
L
11
L
31
L
31
=
A
31
/
L
11
A_{31} = L_{11}L_{31} ~~~~~~~~~~~L_{31} = A_{31}/L_{11}
A31=L11L31 L31=A31/L11根据对称性,第二列只需从第二行开始计算。
A
22
=
L
21
2
+
L
22
2
L
22
=
A
22
−
L
21
2
A_{22} = L_{21}^{2}+L_{22}^{2}~~~~~~~~~L_{22}=\sqrt{A_{22}-L_{21}^2}
A22=L212+L222 L22=A22−L212
A
32
=
L
21
L
31
+
L
22
L
32
L
32
=
(
A
32
−
L
21
L
31
)
/
L
22
A_{32}=L_{21}L_{31}+L_{22}L_{32}~~~~~~L_{32}=(A_{32}-L_{21}L_{31})/L_{22}
A32=L21L31+L22L32 L32=(A32−L21L31)/L22最后从第三行求出L33即可。
A
33
=
L
31
2
+
L
32
2
+
L
33
2
L
33
=
A
33
−
L
31
2
−
L
32
2
A_{33}=L_{31}^2+L_{32}^2+L_{33}^2~~~~~~~~L_{33}=\sqrt{A_{33}-L_{31}^2-L_{32}^2}
A33=L312+L322+L332 L33=A33−L312−L322从三阶的情况可以看出,
(
L
L
T
)
i
j
=
L
i
1
L
j
1
+
L
i
2
L
j
2
+
.
.
.
+
L
i
j
L
j
j
=
∑
k
=
1
j
L
i
k
L
j
k
,
i
≥
j
(LL^T)_{ij}=L_{i1}L_{j1}+L_{i2}L_{j2}+...+L_{ij}L_{jj}=\sum_{k=1}^jL_{ik}L_{jk},~~i \ge j
(LLT)ij=Li1Lj1+Li2Lj2+...+LijLjj=k=1∑jLikLjk, i≥j将此式与对应A中的元素对应,得到
A
i
j
=
∑
k
=
1
j
L
i
k
L
j
k
,
i
=
j
,
j
+
1
,
.
.
.
,
n
,
j
=
1
,
2
,
.
.
.
,
n
A_{ij}=\sum_{k=1}^jL_{ik}L_{jk},~~i=j,j+1,...,n, j =1,2,...,n
Aij=k=1∑jLikLjk, i=j,j+1,...,n,j=1,2,...,n下标表示计算发生在下三角形矩阵。对于j=1(第一列),有
L
11
=
A
11
L
i
1
=
A
i
1
/
L
i
1
,
i
=
2
,
3
,
.
.
.
.
.
.
,
n
L_{11}=\sqrt{A_{11}}~~~~~~~L_{i1}=A_{i1}/L_{i1},~~~~i=2,3,......,n
L11=A11 Li1=Ai1/Li1, i=2,3,......,n推广可得,进行到Aij得到的代求值应该是Lij,(此时该行方程的其他需要求的L值都已求)。将含有Lij的一项从和式中取出:
A
i
j
=
∑
k
=
1
j
−
1
L
i
k
L
j
k
+
L
i
j
L
j
j
A_{ij}=\sum_{k=1}^{j-1}L_{ik}L_{jk}+L_{ij}L_{jj}
Aij=k=1∑j−1LikLjk+LijLjj如果待求L在对角线上(i=j),Ljj的解为
L
j
j
=
A
j
j
−
∑
k
=
1
j
−
1
L
j
k
2
,
j
=
2
,
3
,
.
.
.
,
n
L_{jj}=\sqrt{A_{jj}-\sum_{k=1}^{j-1}L_{jk}^2},~~~~~~~~~~j=2,3,...,n
Ljj=Ajj−k=1∑j−1Ljk2, j=2,3,...,n若不是对角线元素,那么
L
i
j
=
(
A
i
j
−
∑
k
=
1
j
−
1
L
i
k
L
j
k
)
/
L
j
j
,
j
=
2
,
3
,
.
.
.
.
,
n
−
1
,
i
=
j
+
1
,
j
+
2
,
.
.
.
.
.
,
n
L_{ij}=(A_{ij}-\sum_{k=1}^{j-1}L_{ik}L_{jk})/L_{jj},~~~~~j=2,3,....,n-1,~~~~~i=j+1,j+2,.....,n
Lij=(Aij−k=1∑j−1LikLjk)/Ljj, j=2,3,....,n−1, i=j+1,j+2,.....,n
分解阶段代码
从以上分析中看出,Aij仅在计算Lij处使用。因此,若Lij已被计算,Aij就没有用了。这样就可以在程序中用L覆盖下三角矩阵中的A值。如果遇到Ljj2取负的情况,程序报错,终止。
function L = choleski(A)
%computes L in Coleski's decomposition A = LL'
n =size(A,1);
for j = 1:n
temp = A(j,j) -dot(A(j,1:j-1),A(j,1:j-1));
if temp < 0.0
error("Matrix is not positive definite");
end
A(j,j)=sqrt(temp);
for i =j+1:n
A(i,j)=(A(i,j) - dot(A(i,1:j-1),A(j,1:j-1)))/A(j,j);
end
end
L = tril(A);
end
求解阶段代码
与上篇Doolittle分解相似的代换方式即可解出:
function x = choleskiSol(L,b)
%solves [L]{L'} = {b}
n = length(b);
if size(b,2) >1;b=b';end %{b} must be column vector
for k = 1:n %Solution of [L]{y} = {b}
b(k) = (b(k)-dot(L(k,1:k-1),b(1:k-1)'))/L(k,k);
end
for k = n:-1:1 %Solution of {L}'{x} = {y}
b(k) = (b(k) - dot(L(k+1:n,k),b(k+1:n)))/L(k,k);
end
x=b;
例如,使用乔列斯基分解法求解Ax=b并验证,其中,
A
=
(
1.44
−
0.36
5.52
0.00
−
0.36
10.33
−
7.78
0.00
5.52
−
7.78
28.40
9.00
0.00
0.00
9.00
61.00
)
,
b
=
(
0.04
−
2.15
0.00
0.88
)
\textbf{A}=\left( \begin{array}{cccc} 1.44 & -0.36 & 5.52&0.00\\ -0.36 & 10.33 & -7.78&0.00\\ 5.52&-7.78&28.40&9.00\\0.00&0.00&9.00&61.00 \end{array}\right)~,~~~\textbf{b}=\left(\begin{array}{c}0.04\\-2.15\\0.00\\0.88\end{array}\right)
A=⎝⎜⎜⎛1.44−0.365.520.00−0.3610.33−7.780.005.52−7.7828.409.000.000.009.0061.00⎠⎟⎟⎞ , b=⎝⎜⎜⎛0.04−2.150.000.88⎠⎟⎟⎞ 完整程序如下:
function L = choleski(A)
%computes L in Coleski's decomposition A = LL'
n =size(A,1);
for j = 1:n
temp = A(j,j) -dot(A(j,1:j-1),A(j,1:j-1));
if temp < 0.0
error("Matrix is not positive definite");
end
A(j,j)=sqrt(temp);
for i =j+1:n
A(i,j)=(A(i,j) - dot(A(i,1:j-1),A(j,1:j-1)))/A(j,j);
end
end
L = tril(A);
end
function x = choleskiSol(L,b)
%solves [L]{L'} = {b}
n = length(b);
if size(b,2) >1;b=b';end %{b} must be column vector
for k = 1:n %Solution of [L]{y} = {b}
b(k) = (b(k)-dot(L(k,1:k-1),b(1:k-1)'))/L(k,k);
end
for k = n:-1:1 %Solution of {L}'{x} = {y}
b(k) = (b(k) - dot(L(k+1:n,k),b(k+1:n)))/L(k,k);
end
x=b;
在命令行中输入
A = [1.44 -0.36 5.52 0.00;
-0.36 10.33 -7.78 0.00;
5.52 -7.78 28.40 9.00;
0.00 0.00 9.00 61.00];
b = [0.04 -2.15 0 0.88];
L = choleski(A);
x = choleskiSol(L,b)
Check = A*x
验证结果如下:
结果正确。