进行LU分解时,如何提高MATLAB中矩阵乘法代码的效率?

时间:2018-10-06 15:35:30

标签: matlab matrix-multiplication

我尝试从本文档的第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

0 个答案:

没有答案