我正在使用 MATLAB 的
eig
函数。
我定义
Sxx
和 Sxx2
是完全相同的,但是使用函数 eig
来获取特征值 D
和 D2
它们是不同的。
xt=Xnor';
Sxx=xt*Xnor/6299;
Sxx2=Xnor'*Xnor/6299;
D = eig(Sxx);
D2 = eig(Sxx2);
我检查了矩阵
Sxx
和Sxx2
,值都是一样的D
和 D2
的值似乎包含一个巨大的错误
我错过了什么吗?
@克里斯·卢恩戈
“...奇怪的是 MATLAB 在某种情况下会选择不同的算法...”
这一点也不奇怪。在一种情况下,代码强制 MATLAB 执行通用矩阵乘法(不保证结果严格对称/厄米特):
xt=Xnor';
Sxx=xt*Xnor/6299; % symmetry not recognized, generic DGEMM() or ZGEMM() BLAS routine called.
在另一种情况下,MATLAB 解析器识别对称性并调用对称 BLAS() 矩阵乘法例程,这是一个完全不同的例程(保证结果严格对称/厄米特)。
Sxx2=Xnor'*Xnor/6299; % symmetry recognized by parser, DSYRK() or ZSYRK() BLAS routine called
因此,在对称情况下,操作和计算的背景顺序发生了变化。人们应该预料到结果可能会略有不同。
“...这个矩阵被秘密标记为对称...”
MATLAB 变量中没有这样的背景标记。 eig() 函数本身在决定调用哪个后台例程之前显式检查输入参数的对称性。只是 DGEMM() 或 ZGEMM() 结果通常会略有偏差,并且不严格对称/厄米式直至最后一位,而 DSYRK() 或 ZSYRK() 结果保证严格对称/厄米式直至最后一位最后一位(它们仅返回三角形结果...MATLAB 复制背景中的非对角线元素以获得完整结果,因此保留了精确的对称性)。
对结果进行排序应该会发现答案非常接近。
一般来说,我建议不要明确地形成转置。让 MATLAB 尽可能保持严格的对称性。
例如,取一个随机矩阵,看看会发生什么
>> a = rand(100);
>> b1 = a'*a; % faster and strictly symmetric/Hermitian result
>> at = a';
>> b2 = at*a; % slower and no guarantee of symmetric/Hermitian result
>> isequal(b1,b2)
ans =
logical
0
>> isequal(b1',b1)
ans =
logical
1
>> isequal(b2',b2)
ans =
logical
0
>> max(abs(b1(:)-b2(:))./b1(:))
ans =
1.0307e-15
不完全一样,但非常接近。 b1 中保留了严格对称性,但 b2 中没有。