矩阵对角化

numerical recipe 里一共讲了两种实数对称矩阵的对角化,

jacobi法

tred2生成上三角阵以后用tqli对角化

前者稳定但慢易并行,后者较快但疑似不稳定,串行。

花了一下午,一点点调试终于知道了第二种方法不稳定的原因在哪里

 1         SUBROUTINE tred2(a,d,e,novectors)
 2         USE nrtype; USE nrutil, ONLY : assert_eq,outerprod
 3         IMPLICIT NONE
 4         REAL(SP), DIMENSION(:,:), INTENT(INOUT) :: a
 5         REAL(SP), DIMENSION(:), INTENT(OUT) :: d,e
 6         LOGICAL(LGT), OPTIONAL, INTENT(IN) :: novectors
 7         INTEGER(I4B) :: i,j,l,n
 8         REAL(SP) :: f,g,h,hh,scale
 9         REAL(SP), DIMENSION(size(a,1)) :: gg
10         LOGICAL(LGT) :: yesvec
11         n=assert_eq(size(a,1),size(a,2),size(d),size(e),‘tred2‘)
12         if (present(novectors)) then
13                 yesvec=.not. novectors
14         else
15                 yesvec=.true.
16         end if
17         do i=n,2,-1
18                 l=i-1
19                 h=0.0
20                 if (l > 1) then
21                         scale=sum(abs(a(i,1:l)))
22                         if (scale == 0.0) then
23                                 e(i)=a(i,l)
24                         else
25                                 a(i,1:l)=a(i,1:l)/scale
26                                 h=sum(a(i,1:l)**2)
27                                 f=a(i,l)
28                                 g=-sign(sqrt(h),f)
29                                 e(i)=scale*g
30                                 h=h-f*g
31                                 a(i,l)=f-g
32                                 if (yesvec) a(1:l,i)=a(i,1:l)/h
33                                 do j=1,l
34                                         e(j)=(dot_product(a(j,1:j),a(i,1:j)) &
35                                         +dot_product(a(j+1:l,j),a(i,j+1:l)))/h
36                                 end do
37                                 f=dot_product(e(1:l),a(i,1:l))
38                                 hh=f/(h+h)
39                                 e(1:l)=e(1:l)-hh*a(i,1:l)
40                                 do j=1,l
41                                         a(j,1:j)=a(j,1:j)-a(i,j)*e(1:j)-e(j)*a(i,1:j)
42                                 end do
43                         end if
44                 else
45                         e(i)=a(i,l)
46                 end if
47                 d(i)=h
48         end do
49         if (yesvec) d(1)=0.0
50         e(1)=0.0
51         do i=1,n
52                 if (yesvec) then
53                         l=i-1
54                         if (d(i) /= 0.0) then
55                                 gg(1:l)=matmul(a(i,1:l),a(1:l,1:l))
56                                 a(1:l,1:l)=a(1:l,1:l)-outerprod(a(1:l,i),gg(1:l))
57                         end if
58                         d(i)=a(i,i)
59                         a(i,i)=1.0
60                         a(i,1:l)=0.0
61                         a(1:l,i)=0.0
62                 else
63                         d(i)=a(i,i)
64                 end if
65         end do
66         END SUBROUTINE tred2

问题出在22行,scale==0.0的判断上。稍微有点常识的人都知道,计算机里做浮点数判断不能用==,必须用abs(scale-0.0)<episilon episilon为一个很小的数。没想到numerical recipe第三版的这本书里还有这样子的代码。

鉴于scale>=0.0,所以改成scale<=episilon就行了,结果就很稳定了。

吐槽一下,怪不得我总觉得结果怎么那么随机,原来是这里出的问题,这可是真随机啊!

矩阵对角化,布布扣,bubuko.com

时间: 2024-10-05 16:03:44

矩阵对角化的相关文章

Codeforces 947E Perpetual Subtraction (线性代数、矩阵对角化、DP)

手动博客搬家: 本文发表于20181212 09:37:21, 原地址https://blog.csdn.net/suncongbo/article/details/84962727 呜啊怎么又是数学了啊...数学比例\(\frac{16}{33}=0.4848\) orz yhx-12243神仙 题目链接: https://codeforces.com/contest/947/problem/E 题意: 有一个\([0,n]\)的随机数\(x\)初始为\(i\)的概率为\(p_i\). \(m

特征值、特征向量、相似矩阵,矩阵对角化的意义

1.相似矩阵 在线性代数中,相似矩阵是指存在相似关系的矩阵.设A,B为n阶矩阵,如果有n阶可逆矩阵P存在,使得P^(-1)AP=B,则称矩阵A与B相似,记为A~B 相似矩阵有以下性质: 对于 设A,B和C是任意同阶方阵,则有: (1)反身性:A~ A (2)对称性:若A~ B,则 B~ A (3)传递性:若A~ B,B~ C,则A~ C (4)若A~ B,则r(A)=r(B),|A|=|B|,tr(A)=tr(B). (5)若A~ B,且A可逆,则B也可逆,且B~ A. (6)若A~ B,则A与

Python 之 PythonVSMATLAB 矩阵操作

一.线形代数理论基础 线形代数(linear algebra)是数学的一个分支,研究矩阵理论.向量空间.线性变换和有限维线形方程组等内容. 比较重要的思想有:1.线性代数的核心内容是研究有限维线性空间的结构和线性空间的线性变换:2.向量的线性相关性是研究线性空间结构与线性变换理论的基础:3.矩阵是有限维线性空间的线性变换的表示形式:4.线性方程组的求解问题是n维空间到m维空间线性映射求核和全体原象的问题:5.行列式是研究这些问题的一个工具. 主要内容有:1.矩阵运算:加减乘除.转置.逆矩阵.行列

numpy线性代数基础 - Python和MATLAB矩阵处理的不同

http://blog.csdn.net/pipisorry/article/details/39087583 在介绍工具之前先对理论基础进行必要的回顾是很必要的.没有理论的基础,讲再多的应用都是空中楼阁.本文主要设涉及线性代数和矩阵论的基本内容.先回顾这部分理论基础,然后给出MATLAB,继而给出Python的处理.个人感觉,因为Python是面向对象的,操纵起来会更接近人的正常思维:而MATLAB大多是以函数实现的,是向对象施加的一个操作.比如,A是一个矩阵,它有一个属性attr.用Pyth

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

I. 行列式(Determinants)和迹(Trace) 1. 行列式(Determinants) 为避免和绝对值符号混淆,本文一般使用\(det(A)\)来表示矩阵\(A\)的行列式.另外这里的\(A∈R^{n×n}\)默认是方阵,因为只有方阵才能计算行列式. 行列式如何计算的就不在这里赘述了,下面简要给出行列式的各种性质和定理. 定理1:当且仅当一个方阵的行列式不为0,则该方阵可逆. 定理2:方阵\(A\)的行列式可沿着某一行或某一列的元素展开,形式如下: 沿着第\(i\)行展开:\[de

29-相似矩阵和若尔当形

一.接着上一节说正定矩阵 所谓正定,就是$x^TAx > 0$($except \space for \space x = 0$)成立,我们通常也可以通过特征值,主元,行列式来判断 虽然我们知道了什么是正定矩阵,如何判断正定矩阵,那么正定矩阵是从何而来的呢?主要来自:最小二乘法 实际上,大量的物理问题需要用长方形矩阵来描述,我们知道最小二乘法的关键是矩阵:$A^TA$,我们希望证明这是正定矩阵 如果我们知道矩阵$A, B$都是正定的,那么矩阵$A+B$是否是正定的呢?我们只需要证明:$x^T(A

PCA原理(转)

PCA(Principal Component Analysis)是一种常用的数据分析方法.PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维.网上关于PCA的文章有很多,但是大多数只描述了PCA的分析过程,而没有讲述其中的原理.这篇文章的目的是介绍PCA的基本数学原理,帮助读者了解PCA的工作机制是什么. 当然我并不打算把文章写成纯数学文章,而是希望用直观和易懂的方式叙述PCA的数学原理,所以整个文章不会引入严格的数学推导.希望读者在

最小方差解释(线性代数看PCA)

PCA降维                         ——最小方差解释(线性代数看PCA)    注:根据网上资料整理而得,欢迎讨论 机器学习算法的复杂度和数据的维数有着密切关系,甚至与维数呈指数级关联.因此我们必须对数据进行降维. 降维当然意味着信息的丢失,不过鉴于实际数据本身常常存在的相关性,我们可以想办法在降维的同时将信息的损失尽量降低. PCA是一种具有严格数学基础并且已被广泛采用的降维方法. 协方差矩阵及优化目标 如果我们必须使用一维来表示这些数据,又希望尽量保留原始的信息,你要

协方差矩阵

原文链接 自从上次谈了协方差矩阵之后,感觉写这种科普性文章还不错,那我就再谈一把协方差矩阵吧.上次那篇文章在理论层次介绍了下协方差矩阵,没准很多人觉得这东西用处不大,其实协方差矩阵在好多学科里都有很重要的作用,比如多维的正态分布,再比如今天我们今天的主角——主成分分析(Principal Component Analysis,简称PCA).结合PCA相信能对协方差矩阵有个更深入的认识~ PCA的缘起 PCA大概是198x年提出来的吧,简单的说,它是一种通用的降维工具.在我们处理高维数据的时候,为