cholrank1 更新与 LDL 分解

use*_*837 4 matlab matrix linear-algebra

我有对称正定(SPD)矩阵的cholrank1 更新程序(维基百科)。

function [L] = cholupdate(L,x)
    p = length(x);
    for k=1:p
        r = sqrt(L(k,k)^2 + x(k)^2);
        c = r / L(k, k);
        s = x(k) / L(k, k);
        L(k, k) = r;
        L(k+1:p,k) = (L(k+1:p,k) + s*x(k+1:p)) / c;
        x(k+1:p) = c*x(k+1:p) - s*L(k+1:p,k);
    end
end
Run Code Online (Sandbox Code Playgroud)

它与 LL 分解一起使用。我尝试修复处理 LDL 分解的程序(即不调用 sqrt),如下所示:

function [L] = cholupdate_ldl(L,x)
    p = length(x);
    for k=1:p
        r = L(k,k) + x(k)^2;
        c = r / L(k, k);
        s = x(k) / L(k, k);
        L(k, k) = r;
        L(k+1:p,k) = (L(k+1:p,k) + s*x(k+1:p)) / c;
        x(k+1:p) = sqrt(c)*(x(k+1:p) - x(k)*L(k+1:p,k));
    end
end
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我被迫使用 sqrt。如何在不使用 sqrt 的情况下更新 LDL 分解?

tra*_*ion 6

有很多种方法。参见Gill、Golub、Murray 和 Saunders (1974)计算数学修改矩阵分解的方法。为了正式总结你的问题,我引用论文中的内容:

在此输入图像描述

在此输入图像描述

最后我们进入算法:

在此输入图像描述

这是我在 MATLAB 中的实现:

function [L1,D1] = ldlt_update(L0,D0,z)

n = size(L0,1) ;
D1 = zeros(n,n) ;
L1 = zeros(n,n) ;

a = 1 ;
w = z ;
for jj = 1:n
    p = w(jj) ;
    D1(jj,jj) = D0(jj,jj) + a*p^2 ;
    b = p*a/D1(jj,jj) ;
    a = D0(jj,jj)*a/D1(jj,jj) ;
    for r = jj+1:n
        w(r) = w(r) - p*L0(r,jj) ;
        L1(r,jj) = L0(r,jj) + b*w(r) ;
    end
end
end
Run Code Online (Sandbox Code Playgroud)

上面引用的论文以及Gill、Murray 和 Wright (1982)中存在一种替代算法:实用优化。Brian Borchers 拥有一套完整的 MATLAB 代码,用于处理实对称正定 LDLT 分解,如Golub 和 Van Loan (2013)矩阵计算及其网站上所定义。