我尝试从本文档的第3-6页实施LU协调化:
http://www4.ncsu.edu/~kksivara/ma505/handouts/lu-pivot.pdf
为简单的4x4矩阵运行以下代码的示例:
A=[2 1 1 0; 4 3 3 1; 8 7 9 5 ; 6 7 9 8];
intch=[];flag=0;
>> [Bp]=Gauss2(A,4,intch,flag);
>> B=lu(A);
>> Bp
Bp =
8.0000 7.0000 9.0000 5.0000
0.7500 1.7500 2.2500 4.2500
0.5000 -0.2857 -0.8571 -0.2857
0.2500 -0.4286 0.3333 0.6667
>> B
B =
8.0000 7.0000 9.0000 5.0000
0.7500 1.7500 2.2500 4.2500
0.5000 -0.2857 -0.8571 -0.2857
0.2500 -0.4286 0.3333 0.6667
如您所见,矩阵Bp和B是相同的,这证明我的LU分解算法对于4x4矩阵A可以正常工作。我将A修改为60x60和256x256,两者也都可以正常工作(即Bp == B)。但是,我现在在4000x4000的数据集上运行此代码。我的程序没有完成(即使连续运行了10个小时也是如此)。在MATLAB中,程序运行时,我可以单击“暂停”按钮。这会将程序置于调试模式,并告诉我程序要花费大量时间的精确代码行。事实证明,在下面的“ Gauss2”函数中,该程序在函数末尾的两个嵌套的for循环上花费了大量时间(请参见下面我在注释中标识为“ BOTTLENECK”的位置)。
如何在这里提高矩阵乘法的速度?如果您转到pg的最底部。 http://www4.ncsu.edu/~kksivara/ma505/handouts/lu-pivot.pdf中的5,您将看到等式21.6和21.7:
L_k'=P(m-1)...P(k+1)L_k*P(k+1)...*P(m+1)
和
L=inverse(L(m-1)' .... L(2)'L(1)')
这正是下面两个嵌套的for循环试图做的事情。有没有更聪明的方法来计算L_k'?
function [Bp]= Gauss2(A, n, intch, flag)
intch=zeros(n,1);
flag=0;
a=zeros(n,n);
for k=1:n-1
[amax,amax_index] = max(abs(A(k:n,k)));
amax_index=amax_index+k-1;
if (amax == 0)
flag=1; % matrix is singular
intch(k)=0;
else
intch(k)=amax_index;
if (amax_index ~= k)
% pivoting
% interchange rows k and m
A([k,amax_index],:) = A([amax_index,k],:);
end
% calculate multipliers store, and store in "a"
for i=k+1:n
a(i,k)=-A(i,k)/A(k,k);
end
% perform elimination for column "k"
for i=k+1:n
A(i,:)=A(i,:)+a(i,k)*A(k,:);
end
end
end
if (A(n,n)==0)
flag=1;
intch(n)=0;
else
intch(n)=n;
end
U=A; % this is the uppper matrix
% next, need to determine "L_k'" from algorithm
% for all k
prevX=eye(n);
for k=1:n-1
X=eye(n);
for j=(n-1):-1:(k+1)
X=X*P(j,intch(j),n); % <---- BOTTLENECK HERE
end
X=X*L(a,k,n);
for j=(k+1):(n-1)
X=X*P(j,intch(j),n); % < --- BOTTLENECK HERE
end
prevX=X*prevX;
end
Lower=inv(prevX);
Bp=U+Lower-eye(n);
end
这是我下面的下午和下午代码。这些是上面代码中用于生成置换矩阵P_1,P_2,...,P_k和L_1,L_2,.... L_k的函数。我需要对它们进行计算,以便找出L_k'矩阵,然后可以将其用于找出最终的L下层矩阵。
function [Y]=L(a,k,n)
Y=eye(n);
Y((k+1):n,k)=a(k+1:n,k);
end
function [X]=P(i,j,n)
X=eye(n);
X([i,j],:) = X([j,i],:);
end