【问题标题】:LU decomposing a square matrix matlab gauss eliminationLU分解方阵matlab高斯消除
【发布时间】:2016-02-11 22:12:51
【问题描述】:

我正在尝试创建一个程序,该程序将一个方形(n×n)矩阵作为输入,如果它是可逆的,LU 将使用高斯消元法分解矩阵。

这是我的问题:在课堂上,我们了解到最好更改行,以便您的枢轴始终是其列中的最大数字(绝对值)。例如,如果矩阵是A = [1,2;3,4],那么切换行是[3,4;1,2],然后我们可以继续进行高斯消元。

我的代码适用于不需要行更改的矩阵,但对于需要更改行的矩阵,则不需要。这是我的代码:

function newgauss(A)
    [rows,columns]=size(A);
    P=eye(rows,columns); %P is permutation matrix
    if(det(A)==0) %% determinante is 0 means no single solution
        disp('No solutions or infinite number of solutions')
        return;
    end
    U=A;
    L=eye(rows,columns);
    pivot=1;
    while(pivot<rows)
        max=abs(U(pivot,pivot));
        maxi=0;%%find maximum abs value in column pivot
        for i=pivot+1:rows
            if(abs(U(i,pivot))>max)
                max=abs(U(i,pivot));
                maxi=i;
            end
        end %%if needed then switch
        if(maxi~=0)
            temp=U(pivot,:);
            U(pivot,:)=U(maxi,:);
            U(maxi,:)=temp;
            temp=P(pivot,:);
            P(pivot,:)=P(maxi,:);
            P(maxi,:)=temp;
        end %%Grade the column pivot using gauss elimination
        for i=pivot+1:rows
            num=U(i,pivot)/U(pivot,pivot);
            U(i,:)=U(i,:)-num*U(pivot,:);
            L(i,pivot)=num;
        end
        pivot=pivot+1;
    end
    disp('PA is:');
    disp(P*A);
    disp('LU is:');
    disp(L*U);
end

澄清:由于我们正在切换行,我们希望分解P(置换矩阵)乘以A,而不是我们作为输入的原始A

代码说明:

  1. 首先我检查矩阵是否可逆,如果不是,停止。如果是,则枢轴为 (1,1)
  2. 我在第 1 列中找到最大的数字,并切换行
  3. 使用高斯消元法对第 1 列进行评分,将除点 (1,1) 以外的所有部分都归零
  4. 枢轴现在是 (2,2),在第 2 列中找到最大的数字...冲洗,重复

【问题讨论】:

  • 类似地,使用阈值代替比较maxi~=0。还要避免使用也是内置函数名称的变量名(max),这只会让人困惑

标签: algorithm matlab linear-algebra matrix-decomposition


【解决方案1】:

据我所知,您的代码似乎运行良好,至少对于基本示例A=[1,2;3,4]A=[3,4;1,2]。将您的函数定义更改为:

function [L,U,P] = newgauss(A)

这样您就可以输出您的计算值(比使用disp 好得多,但这也显示了正确的结果)。然后你会看到P*A = L*U。也许您期望L*U 直接等于A?你也可以通过Matlab的lu函数确认你是正确的:

[L,U,P] = lu(A);
L*U
P*A

Permutation matrices 是正交矩阵,所以 P-1 = PT。如果你想在你的代码中找回A,你可以这样做:

P'*L*U

同样,使用 Matlab 的 lu 与置换矩阵输出,你可以这样做:

[L,U,P] = lu(A);
P'*L*U

(在检查行列式时,您还应该使用errorwarning,而不是使用disp,但他们可能不会这么教。)

【讨论】:

  • 我会尝试更改定义,但我真的认为代码有问题。对于矩阵 A=[1,2,3;4,5,6;7,8,9] PA 是 [7,8,9;1,2,3;4,5,6] 并且 LU 是 [7 ,8,9;4,5.4286,6.8571;1,1.5714,2.1429]...未关闭
  • 也许这是您应该在问题中使用的示例矩阵,而不是适用于所有情况的矩阵。您没有正确执行高斯消除 -U 在这种情况下不是上三角形。
  • 对不起。我想我应该用那个例子。你能准确指出我进行高斯消除的方式有什么问题吗?
  • 没关系,你给出的那个例子实际上是一个奇异矩阵。执行det(A) 并查看值-它接近eps。您需要改进检查奇异矩阵的方式(非常简单),或者不使用它们测试您的代码。尝试另一个 3×3 示例,看看它是否有效,但我认为您仍然有问题。
  • 您先生完全正确。非常感谢。它适用于其他 3x3 矩阵,甚至是需要多次切换行的矩阵。只是不是行列式接近于零的那些
【解决方案2】:

请注意,det 函数是使用 LU 分解本身来实现的,以计算行列式...递归任何人:)

除此之外,页面末尾有一个提醒,建议使用cond 而不是det 来测试矩阵奇点:

使用abs(det(X)) &lt;= tolerance 测试奇点不是 推荐,因为很难选择正确的公差。这 函数cond(X) 可以检查单数和近单数 矩阵。

COND 使用奇异值分解(参见其实现:edit cond.m

【讨论】:

    【解决方案3】:

    对于将来发现此问题并需要有效解决方案的任何人:

    在创建置换矩阵P 时,OP 的代码不包含在L 中切换元素的逻辑。与 Matlab 的lu(A) 函数给出相同输出的调整后的代码是:

    function [L,U,P] = newgauss(A)
        [rows,columns]=size(A);
        P=eye(rows,columns); %P is permutation matrix
        tol = 1E-16; % I believe this is what matlab uses as a warning level
        if( rcond(A) <= tol) %% bad condition number
            error('Matrix is nearly singular')
        end
        U=A;
        L=eye(rows,columns);
        pivot=1;
        while(pivot<rows)
            max=abs(U(pivot,pivot));
            maxi=0;%%find maximum abs value in column pivot
            for i=pivot+1:rows
                if(abs(U(i,pivot))>max)
                    max=abs(U(i,pivot));
                    maxi=i;
                end
            end %%if needed then switch
            if(maxi~=0)
                temp=U(pivot,:);
                U(pivot,:)=U(maxi,:);
                U(maxi,:)=temp;
                temp=P(pivot,:);
                P(pivot,:)=P(maxi,:);
                P(maxi,:)=temp;
    
                % change elements in L-----
                if pivot >= 2
                    temp=L(pivot,1:pivot-1);
                    L(pivot,1:pivot-1)=L(maxi,1:pivot-1);
                    L(maxi,1:pivot-1)=temp;
                end
            end %%Grade the column pivot using gauss elimination
            for i=pivot+1:rows
                num=U(i,pivot)/U(pivot,pivot);
                U(i,:)=U(i,:)-num*U(pivot,:);
                L(i,pivot)=num;
            end
            pivot=pivot+1;
        end
    end
    

    希望这对将来遇到此问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      相关资源
      最近更新 更多