前面已经说过LU,Cholesky和QR分解,这次介绍的是实Schur分解。对这个分解的定义是任意一个矩阵A,可有如下形式的分解:

              U*A*U’ = B;其中B是拟上三角矩阵,拟上三角矩阵的定义是在矩阵的对角线上存在2x2大小的矩阵,而且矩阵U是正交矩阵,因为矩阵A的特征值和B的特征值相同。而且A的特征值出现在B的对角线上。计算特征值分解和SVD都依靠这个算法做最基本的处理,然后根据不同的任务有不同的处理。

计算schur分解的方法是是QR算法,这个算法的原理相当的简单,可以用如下的伪代码表示:

for i = 1 … 

  A(i-1)= QR

  A(i) = R*Q

end

这段代码所做的变化类似于A(i) = R*Q = (Q’)*Q*R*Q = (Q’)*A(i-1)*Q;因此这段代码的基本思想就是使用正交矩阵Q不停的对矩阵A做相似变化。在这样的变化中将矩阵A的下半三角矩阵中的数全部消去。但是在实际中使用这样的算法是不现实的,因为每一次QR分解都需要大量的计算,同时完全的矩阵相乘R*Q也需要大量的计算。对这种方法的改进是首先将矩阵A化为Hessenberg型,然后对Hessenbert计算QR分解,对应的code如下:

function [H, U] = zhess(A)

%for any matrix A, turn it into a upper hessenberg matrix by orthogonal 

%transformation

 

[m, n] = size(A);

 

if m ~= n

    error('support square matrix only')

end

 

H = A;

U = eye(n);

 

for k=1:n-2

    

    %compute the householder matrix

    [v, beta] = zhouse(H(k+1:end, k));

    temp_U = eye(n);

    

    temp_U(k+1:n,k+1:n) = eye(n-k) - beta*v*(v');

    

    H = temp_U*H;

    U = U * temp_U;

    

    %fprintf('after %d iteration\n', k);

    %disp(H);

end

 

这段代码将矩阵A转换成上hessenberg矩阵。

function [NH] = zhessqr(H)

% perform QR algorithm on upper hessenberg matrix

% firstly, we need to verity this is a hessberg matrix

 

 

[m, n] = size(H);

 

if m ~= n

    error('error, support square matrix only')

end

 

NH = H;

 

c = zeros(1, n-1);

s = zeros(1, n-1);

 

for k=1:n-1

    %compute gives rotation at first

    [c(k), s(k)] = zgivens(NH(k, k), NH(k+1, k));

    p = [c(k) s(k); -s(k) c(k)];

    NH(k:k+1, k:n) = (p')*NH(k:k+1, k:n);

    %fprintf('after %d iteration\n', k);

    %disp(NH);

end

 

for k=1:n-1

    p = [c(k) s(k); -s(k) c(k)];

    NH(1:k+1, k:k+1) = NH(1:k+1,k:k+1)*p;

end

 

这段代码计算Hessenberg型矩阵A的一个QR step,在这里使用givens旋转来获得矩阵的QR分解提高了效率。

 

在QR算法中最主要的步骤就是QR step,首先做QR分解,然后R*Q,为了加快算法收敛的速度,使用了基于位移的QR算法,基本的伪代码如下:

for i=1 ...

    A - a*I = QR

    R*Q + a*I = A

end

使用这个方法可以加快QR算法的收敛速度。在这个算法的基础上有隐式双位移算法,称为Francis QR。首先给出显式的双位移算法:

 

for i=1:infinite

    H(0) - a1*I = Q(1)*R(1)

    H(1) = R(1)*Q(1) + a1*I

    H(1) - a2*I = Q(2)*R(2)

    H(2) = R(2)*Q(2) + a2*I

end

 

略加推倒可以获得如下的公式:

>> H(2) = (Z’)*H*Z; M = Z*R; M = (H-a1*I)(H-a2*I);

Francis QR可以在不显式的构造矩阵M的情况下,完成H2=Z’ * H * Z;

Francis QR算法可以使用依赖于隐式Q定理,对应的Matlab代码如下:

function [H, U] = zfrancisqr(A)

%compute one of the step by implicitly shifted QR step

 

[m, n] = size(A);

 

if m ~= n

    error('support square matrix only')

end

 

m = n-1;

 

s = A(m, m) + A(n, n);

t = A(m, m)*A(n, n) - A(m, n)*A(n, m);

 

x = A(1,1)*A(1,1) + A(1,2)*A(2,1) - s*A(1,1) + t;

y = A(2,1)*(A(1,1) + A(2,2) - s);

z = A(2,1)*A(3,2);

 

for k=0:n-3

    

    [v, beta] = zhouse([x y z]');

    

    q = max([1 k]);

    

    %orthogonal transformation

    ot = (eye(3) - beta*v*(v'));

    

    A(k+1:k+3,q:n) = ot*A(k+1:k+3, q:n);

    

    r = min([k+4 n]);

    A(1:r, k+1:k+3) = A(1:r, k+1:k+3)*(ot');

    

    x = A(k+2, k+1);

    y = A(k+3, k+1);

    if k < n-3

        z = A(k+4, k+1);

    end

end

 

[v, beta] = zhouse([x y]');

ot = eye(2) - beta*v*(v');

A(n-1:n, n-2:n) = ot*A(n-1:n, n-2:n);

A(1:n, n-1:n) = A(1:n, n-1:n)*(ot');

 

H = A;

U = eye(n);

 

隐式Q定理的基本内容如下:对于矩阵A,存在两个不同的相似变换Q’*A*Q = H, V’*A*V=G,H和G是上Hessenberg矩阵,如果Q和V的第一列相同,那么这两个不同的相似变换就是等价的。因此Francis QR的第一步就是计算矩阵M的第一列,然后使用householder reflector将之变成e1,然后将变换后的矩阵转换成上Hessenberg矩阵,这个时候就完成了一步Francis QR。这个方式之所以可以使用隐式Q定理是因为第一个householder reflector是针对M的第一列计算的,而且后来的householder reflector的第一列都是e1,因为最后计算出的变换矩阵的第一列和直接在M上计算QR分解是相同的。

这就是QR算法涉及的主要内容,事实上QR算法的研究很多,但是这里这是给出基本的,而且没有给出完成的计算程序,是因为我现在还不能完全理解整个过程。下面对于Spectral Decomposition和Singular Value Decompositon介绍也要搁置一段时间,第一是因为两个算法很复杂,需要一段时间来理解;第二个原因是因为现在没有很强的需求去研究到这样的细节。目前依靠LAPACK和Matlab足以解决我大部分的任务,慢慢来吧。

实Schur分解的更多相关文章

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

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

  2. QR分解

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

  3. GNU scientific library

    GNU scientific library 是一个强大的C,C++数学库.它涉及的面很广,并且代码效率高,接口丰富.正好最近做的一个项目中用到多元高斯分布,就找到了这个库. GNU scientif ...

  4. MATLAB命令大全和矩阵操作大全

    转载自: http://blog.csdn.net/dengjianqiang2011/article/details/8753807 MATLAB矩阵操作大全 一.矩阵的表示在MATLAB中创建矩阵 ...

  5. MATLAB矩阵操作大全

    转载自:http://blog.csdn.net/dengjianqiang2011/article/details/8753807 MATLAB矩阵操作大全 一.矩阵的表示 在MATLAB中创建矩阵 ...

  6. Matlab学习笔记(五)

    三.矩阵运算 (一)矩阵函数和特殊矩阵 常见的矩阵处理函数 表3-1    常见的矩阵函数 函数 说明 /或\ 矩阵除法中的左除或右除,可以用于求解线性方程组 accumarray(ind,val) ...

  7. 三维重建面试13X:一些算法试题-今日头条AI-Lab

             被人牵着鼻子走,到了地方还墨明棋妙地吃一顿砖头.今日头条AI-Lab,其实我一直发现,最擅长的还是点云图像处理,且只是点云处理. 一.C++题目   New 与Malloc的区别: ...

  8. GSL--GNU Scientific Library 小记

    摘自http://qianjigui.iteye.com/blog/847612 GSL(GNU Scientific Library)是一个 C 写成的用于科学计算的库,下面是一些相关的包 Desi ...

  9. scipy线性模块liner(linalg)

    #liner import numpy as np from scipy import linalg as lg arr=np.array([[1,1],[0,1]]) matr=np.mat('[1 ...

随机推荐

  1. Visual C++内存泄露检测—VLD工具使用说明

    一.        VLD工具概述 Visual Leak Detector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.他的特点有:可以得到内存泄漏点的调用堆栈,如果可以的话,还 ...

  2. YYCache 源码分析(一)

    iOS 开发中总会用到各种缓存,YYCache或许是你最好的选择.性能上有优势,用法也很简单.作者ibireme曾经对比过同类轮子:http://blog.ibireme.com/2015/10/26 ...

  3. 如何解决eclipse上的Android程序“Please ensure that adb is correctly located at 'D:\eclipse\sdk\platform-tools\adb.exe' and can be executed.”小问题?

    首先,把运行的Android模拟器和eclipse一块儿关了, 然后win+R,cmd, 下面输入adb kill_server 再输入adb start_server 之后重新运行项目,不出意外的话 ...

  4. Android Xutils 框架

    XUtils是git上比较活跃 功能比较完善的一个框架,是基于afinal开发的,比afinal稳定性提高了不少,下面是介绍: 鉴于大家的热情,我又写了一篇Android 最火框架XUtils之注解机 ...

  5. 当ViewPager嵌套在ScrollView/ListView里时,手势冲突如何处理?

    有时我们需要将ViewPager嵌套在其他已经含有手势动作的ViewGroup里,如ScrollView,ListView时,会造成手势冲突,如表现为ViewPager向左划时,不小心向上移动了一点距 ...

  6. XML在JAVA项目中的作用

    java项目中,xml文件一般都是用来存储一些配置信息 一般的编程, 多数用来存储配置信息 . 拿JDBC来说,可以把数据库连接字符串写到xml,如果要修改数据源,只需要改xml就可以了,没必要再去重 ...

  7. target,currentTarget,delegateTarget,srcElement

    第一种情况:就是IE9+和其他现代浏览器,支持addEventListener方法.其结果是: this总是等于currentTarget currentTarget总是事件监听者 target总是事 ...

  8. JSON.parse和JSON.stringify 参数详解

    JSON.parse和JSON.stringify这两个浏览器自带(IE6/7除外)的方法平常我们经常用到,但是一般都只是用到了他们的第一个参数,比如字符串转对象:JSON.parse('{}')   ...

  9. POJ 1240 Pre-Post-erous! 解题报告

    题意: 给出一个m叉树的前,后序遍历求这样的树有多少种. Solution: 我们知道前序遍历的第一个点一定是根节点,后序遍历的最后一个点一定是根节点. 由此,我们只一要确定对于每一个节点,它有多少个 ...

  10. 关于highcharts(功能强大、开源、美观、图表丰富、兼容绝大多数浏览器的纯js图表库)

    官网http://www.hcharts.cn/ 引入下列文件 <script type="text/javascript" src="http://cdn.hch ...