部分旋转的LU分解如何工作?

时间:2016-12-12 13:01:02

标签: numerical-methods matrix-decomposition

我使用的方法最初将L的主对角线上的元素设置为1(认为这是Doolittle的方法,但不确定,因为我看到它以不同的方式命名)。我知道有大量的文件,论文和书籍,但我找不到使用高斯消除法找到L的简单例子。

1 个答案:

答案 0 :(得分:0)

与完全旋转相比,部分旋转仅使用行互换而不是完全旋转,这也使列成为枢轴。部分旋转的主要目的如下图所示,代码是交换行以找到最大的u,以避免在for循环中除以非常小的一个,这将导致一个大的条件数。

如果你试图实现LU分解和一些病态矩阵,如某些任意对角占优矩阵,它应该爆炸。

enter image description here

function [L,U,P] = my_lu_piv(A)
n = size(A,1);
I = eye(n);
O = zeros(n);
L = I;
U = O;
P = I;
    function change_rows(k,p)
        x = P(k,:); P(k,:) = P(p,:); P(p,:) = x;
        x = A(k,:); A(k,:) = A(p,:); A(p,:) = x;
        x = v(k); v(k) = v(p); v(p) = x;
    end

    function change_L(k,p)
        x = L(k,1:k-1); L(k,1:k-1) = L(p,1:k-1);
        L(p,1:k-1) = x;
    end
for k = 1:n
    if k == 1, v(k:n) = A(k:n,k);
    else
        z = L(1:k-1,1:k -1)\ A(1:k-1,k);
        U(1:k-1,k) = z;
        v(k:n) = A(k:n,k)-L(k:n,1:k-1)*z;
    end
    if k<n
        x = v(k:n); p = (k-1)+find(abs(x) == max(abs(x))); % find index p
        change_rows(k,p);
        L(k+1:n,k) = v(k+1:n)/v(k);
        if k > 1, change_L(k,p); end
    end
    U(k,k) = v(k);
end
end