数值计算方法(Numerical Methods)MATLAB实现(2)--choleski分解

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=A22L212 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=(A32L21L31)/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=A33L312L322 从三阶的情况可以看出, ( 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=1jLikLjk,  ij将此式与对应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=1jLikLjk,  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=1j1LikLjk+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=Ajjk=1j1Ljk2 ,          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=(Aijk=1j1LikLjk)/Ljj,     j=2,3,....,n1,     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.440.365.520.000.3610.337.780.005.527.7828.409.000.000.009.0061.00 ,   b=0.042.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

验证结果如下:
在这里插入图片描述

      结果正确。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值