注意:
三种分解方法求解过程都会用到三角矩阵的回代法。小编之前已经写过三角矩阵回代法程序!!关于代码可参考:https://blog.csdn.net/m0_46498899/article/details/109223781
n阶线性方程组系数矩阵A可以分解成单位下三角矩阵L和上三角矩阵R,即
function [L,R,X]=Doolittle(A,B)
%%%输入n*n的方阵A,
%%%通过Doolittle分解;
%%%输出单位下三角矩阵L和上三角矩阵R。
[n,~]=size(A);
L=eye(n);
R=zeros(n);
for k=1:n
for j=k:n
R(k,j)=A(k,j)-L(k,1:k-1)*R(1:k-1,j);
end
for i=k+1:n
L(i,k)=(A(i,k)-L(i,1:k-1)*R(1:k-1,k))/R(k,k);
end
end
y=b_Back_subtitution(L,B); %下三角回代法函数;
X=a_Back_subtitution(R,y); %上三角回代法函数;
Doolittle分解是将矩阵A分解为单位下三角矩阵L和上三角矩阵R的乘积;而Crout分解则是将矩阵A分解为下三角矩阵L和单位上三角矩阵的乘积。具体方法与Doolittle分解类似,这里不加赘述,不明白的可以自行百度。下面直接给出matlab代码。
function [L,R,X]=Crout(A,B)
%%%输入n*n的方阵A,
%%%通过Crout分解;
%%%输出下三角矩阵L和单位上三角矩阵R。
Y=A\B;
[n,~]=size(A);
L=zeros(n);
R=eye(n);
for k=1:n
for i=k:n
L(i,k)=A(i,k)-L(i,1:k-1)*R(1:k-1,k);
end
for j=k+1:n
R(k,j)=(A(k,j)-L(k,1:k-1)*R(1:k-1,j))/L(k,k);
end
end
y=b_Back_subtitution(L,B); %%调用下三角回代法;
X=a_Back_subtitution(R,y); %%调用上三角回代法;
function [L,X]=Cholesky(A,B)
%%%输入n*n的正定矩阵A和常数项列向量B,
%%%通过Cholesky分解;
%%%输出下三角矩阵L,和方程的解X。
[n,~]=size(A);
L=zeros(n);
for j=1:n
for i=j:n
if i==j
L(j,j)=(A(j,j)-L(j,1:j-1)*(L(j,1:j-1))')^(1/2);
elseif i>j
L(i,j)=(A(i,j)-L(i,1:j-1)*(L(j,1:j-1))')/L(j,j);
end
end
end
y=b_Back_subtitution(L,B); %%调用下三角回代法函数;
X=a_Back_subtitution(L',y); %%调用上三角回代法函数。
function [L,D0,X]=Cholesky_ed(A,B)
%%%输入n*n的正定矩阵A和常数项列向量B,
%%%通过Cholesky分解;
%%%输出下三角矩阵L,和方程的解X。
%%%{diag(A,k)函数:如果A是列向量,就将列向量放在矩阵的第K条对角线上;
...如果A是矩阵,则将矩阵的第K条对角线是的元素提取并按列输出,
...K=0表示主对角线}
[n,~]=size(A);
L=eye(n);
S=zeros(n);
for j=1:n
S(j,j)=A(j,j)-S(j,1:j-1)*L(j,1:j-1)';
for i=j+1:n
S(i,j)=A(i,j)-S(i,1:j-1)*L(j,1:j-1)';
L(i,j)=S(i,j)/S(j,j);
end
end
D0=diag(S);
y=b_Back_subtitution(L,B);
y=y./D0;
X=a_Back_subtitution(L',y);