接着LU分解继续往下,就会发展出很多相关但是并不完全一样的矩阵分解,最后对于对称正定矩阵,我们则可以给出非常有用的cholesky分解。这些分解的来源就在于矩阵本身存在的特殊的

结构。对于矩阵A,如果没有任何的特殊结构,那么可以给出A=L*U分解,其中L是下三角矩阵且对角线全部为1,U是上三角矩阵但是对角线的值任意,将U正规化成对角线为1的矩阵,产生分解A = L*D*U, D为对角矩阵。如果A为对称矩阵,那么会产生A=L*D*L分解。如果A为正定对称矩阵,那么就会产生A=G*G,可以这么理解G=L*sqrt(D)。

A=L*D*U分解对应的Matlab代码如下:

function[L, D, U] =zldu(A)

%LDU decomposition of square matrix A. The first step for Cholesky

%decomposition

 

[m, n] = size(A);

if m ~= n

    error('support square matrix only')

end

 

L = eye(n);

U = eye(n);

d = zeros(n,1);

 

for k=1:n

    

    v = zeros(n, 1);

    if k == 1

        v(k:end) = A(k:end, k);

    else

        m = L(1:k-1, 1:k-1) \ A(1:k-1, k);

        for j = 1:k-1

            U(j, k) = m(j) / d(j);

        end

        

        v(k:end) = A(k:end, k) - L(k:end, 1:k-1)*m(:);

    end

    

    d(k) = v(k);

    

    if k < n

        L(k+1:end, k) = v(k+1:end)/v(k);

    end

    

end

 

D = diag(d);

分解的稳定性和精度结果如下:

mean of my lu     : 9.0307e-15

variance of my lu : 4.17441e-27

mean of matlab lu     : 3.70519e-16

variance of matlab lu : 2.07393e-32

这里的计算是基于Gaxpy,所以稳定性和精确度相当之好。

 

A=L*D*L分解对应代码如下,这里要求A必须为对称矩阵:

function[D, L] =zldl(A)

%A = L*D*L' another version of LU decomposition for matrix A

 

[m, n] = size(A);

 

if m ~= n

    error('support square matrix only')

end

 

L = eye(n);

d = zeros(n,1);

 

for k=1:n

    v = zeros(n,1);

    

    for j=1:k-1

        v(j) = L(k, j)*d(j);

    end

    

    v(k) = A(k,k) - L(k, 1:k-1)*v(1:k-1);

    

    d(k) = v(k);

    

    L(k+1:end, k) = (A(k+1:end,k) - A(k+1:end, 1:k-1)*v(1:k-1)) / v(k);

end

 

D = diag(d);

对应分解的精确度和稳定度如下:

mean of my lu : 35.264
variance of my lu : 29011.2
mean of matlab lu : 5.88824e-16
variance of matlab lu : 8.40037e-32

使用如下的代码做测试:

n = 1500;

my_error = zeros(1, n);

sys_error = zeros(1, n);

 

for i = 1:n

    test = gensys(5);

    [zd, zl] = zldl(test);

    [l, d] = ldl(test);

 

    my_error(i) = norm(zl*zd*(zl') - test, 'fro');

    sys_error(i) = norm(l*d*(l') - test, 'fro');

end

 

fprintf('mean of my lu     : %g\n', mean(my_error));

fprintf('variance of my lu : %g\n', var(my_error));

 

fprintf('mean of matlab lu     : %g\n', mean(sys_error));

fprintf('variance of matlab lu : %g\n', var(sys_error));

对于运算的精度如此之低的原因并不清楚

 

A=G*G’; cholesky分解对应的代码如下:

function[G] =zgaxpychol(A)

%cholesky decomposition for symmetric positive definite matrix

%the only requirement is matrix A: symmetric positive definite

 

[m, n] = size(A);

 

if m ~= n

    error('support square matrix only')

end

 

G = eye(n);

 

for k=1:n

    

    v = A(:,k);

    

    if k > 1

        v(:) = v(:) - G(:,1:k-1)*G(k,1:k-1)';

    end

    

    G(k:end, k) = v(k:end) / sqrt(v(k));

end

对应的测试结果如下

mean of my lu : 1.10711e-15
variance of my lu : 3.04741e-31
mean of matlab lu : 5.5205e-16
variance of matlab lu : 9.64928e-32

自己代码的精确度和稳定性可以媲美Matlab的代码,产生这种结果的原因应该是positive sysmetric definite matrix的原因,这段代码基于gaxpy的结果,下面给出另外一种基于外积的运算结果。

function[G] =zopchol(A)

%cholesky decomposition based on rank-1 matrix update

 

[m, n] = size(A);

if m ~= n

    error('support square matrix only')

end

 

G = zeros(n);

 

for k=1:n

    

    G(k,k) = sqrt(A(k,k));

    G(k+1:end, k) = A(k+1:end, k) / G(k,k);

    

    %update matrix A

    for j = (k+1):n

        A(k+1:end,j) = A(k+1:end,j) - G(j,k)*G(k+1:end,k);

    end

end

 

对应的测试结果如下:

mean of my lu : 9.33114e-16
variance of my lu : 1.71179e-31
mean of matlab lu : 9.92241e-16
variance of matlab lu : 1.60667e-31

对应的测试程序如下,这里使用系统自带的chol函数完成cholesky分解。

n = 1500;

my_error = zeros(1, n);

sys_error = zeros(1, n);

 

for i = 1:n

    test = genpd(5);

    [zg] = zopchol(test);

    l = chol(test, 'lower');

 

    my_error(i) = norm(zg*(zg') - test, 'fro');

    sys_error(i) = norm(l*(l') - test, 'fro');

end

 

fprintf('mean of my lu     : %g\n', mean(my_error));

fprintf('variance of my lu : %g\n', var(my_error));

 

fprintf('mean of matlab lu     : %g\n', mean(sys_error));

fprintf('variance of matlab lu : %g\n', var(sys_error));

将两个结果想比较,可以发现两个版本的cholesky分解的精确度和稳定度差不多。

Cholesky分解的核心在于矩阵对称正定的结构,基于LU分解的再次扩展。

cholesky分解的更多相关文章

  1. 矩阵分解----Cholesky分解

    矩阵分解是将矩阵拆解成多个矩阵的乘积,常见的分解方法有 三角分解法.QR分解法.奇异值分解法.三角分解法是将原方阵分解成一个上三角矩阵和一个下三角矩阵,这种分解方法叫做LU分解法.进一步,如果待分解的 ...

  2. Cholesky分解(Cholesky decomposition / Cholesky )

    Cholesky decomposition In linear algebra, the Cholesky decomposition or Cholesky is a decomposition ...

  3. Cholesky分解 平方根法

    一种矩阵运算方法,又叫Cholesky分解.所谓平方根法,就是利用对称正定矩阵的三角分解得到的求解对称正定方程组的一种有效方法.它是把一个对称正定的矩阵表示成一个下三角矩阵L和其转置的乘积的分解.它要 ...

  4. QR分解

        从矩阵分解的角度来看,LU和Cholesky分解目标在于将矩阵转化为三角矩阵的乘积,所以在LAPACK种对应的名称是trf(Triangular Factorization).QR分解的目的在 ...

  5. 【Math for ML】矩阵分解(Matrix Decompositions) (上)

    I. 行列式(Determinants)和迹(Trace) 1. 行列式(Determinants) 为避免和绝对值符号混淆,本文一般使用\(det(A)\)来表示矩阵\(A\)的行列式.另外这里的\ ...

  6. SVD分解及线性最小二乘问题

    这部分矩阵运算的知识是三维重建的数据基础. 矩阵分解 求解线性方程组:,其解可以表示为. 为了提高运算速度,节约存储空间,通常会采用矩阵分解的方案,常见的矩阵分解有LU分解.QR分解.Cholesky ...

  7. 矩阵分解-----LDL分解

    若一个矩阵A是正定的,那么该矩阵也可以唯一分解为\[{\bf{A = LD}}{{\bf{L}}^{\bf{T}}}\] 其中L是对角元素都为1的下三角矩阵,D是对角元素都为正数的对角矩阵.还是以三维 ...

  8. QR 分解

    将学习到什么 介绍了平面旋转矩阵,Householder 矩阵和 QR 分解以入相关性质.   预备知识 平面旋转与 Householder 矩阵是特殊的酉矩阵,它们在建立某些基本的矩阵分解过程中起着 ...

  9. 【原创】开源Math.NET基础数学类库使用(01)综合介绍

                   本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新  开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...

随机推荐

  1. java.util.jar.JarFile cause native heap memory leak

    最近项目中使用了JarFile 这个类 来load jar包中的 configuration,大致的情况如下 public void processJarEntries(JarFile paramJa ...

  2. Java基础知识强化之IO流笔记08:异常的注意事项

    1. 异常注意事项: (1)子类重写父类方法时候,子类的方法必须抛出相同的异常或者父类异常的子类.(父亲坏了,儿子不能比父亲更坏) (2)如果父类抛出多个异常,子类重写父类时候,只能抛出相同的异常或者 ...

  3. Apache MINA NioSocketAcceptor类的实现

    NioSocketAcceptor 继承AbstractPollingIoAcceptor,实现SocketAcceptor接口 public final class NioSocketAccepto ...

  4. FineUI属性的简单总结

    .PageManager控件— 页面级别的控制(包括主题.语言 等等) 覆盖web.config中自定义结点的配置 EnablePageLoading:是否启用页面的第一次加载提示,默认居中显示加载图 ...

  5. Asp.Net中的session配置

    一.InProc模式(缺省模式) <sessionState mode="InProc" timeout="20"></sessionStat ...

  6. (转)php中__autoload()方法详解

    转之--http://www.php100.com/html/php/lei/2013/0905/5267.html PHP在魔术函数__autoload()方法出现以前,如果你要在一个程序文件中实例 ...

  7. 抓取锁的sql语句-第一次修改

    CREATE OR REPLACE PROCEDURE SOLVE_LOCK AS V_SQL VARCHAR2(3000); CUR_LOCK SYS_REFCURSOR; TYPE TP_LOCK ...

  8. ASP.NET菜鸟之路之Seesion小例子

    背景 我是一个ASP.NET菜鸟,暂时开始学习ASP.NET,在此记录下我个人敲的代码,没有多少参考价值,请看到的盆友们为我点个赞支持我一下,多谢了. Session介绍 Session保存特定用户相 ...

  9. cas sso单点登录系列6_cas单点登录防止登出退出后刷新后退ticket失效报500错

    转(http://blog.csdn.net/ae6623/article/details/9494601) 问题: 我登录了client2,又登录了client3,现在我把client2退出了,在c ...

  10. 你好,C++(31)我终于找到对象啦!6.1 从结构化设计到面向对象程序设计

    第6章 当C++爱上面向对象 很多第一次进入C++世界的人都会问:C++中的那两个加号到底是什么意思啊? C++是由C语言发展而来的,它比C语言多出的两个加号,实际上是C语言的自增操作符,表示C++语 ...