Eigen和Matlab中的不同特征向量和特征值可能产生误差? [英] Different eigenvector and eigenvalues in Eigen and Matlab could generate errors?

查看:1474
本文介绍了Eigen和Matlab中的不同特征向量和特征值可能产生误差?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

喜欢解释这里这里特征值的(或相对特征向量和它们的符号)是库依赖和(根据第一个链接的问题)它不应该是一个问题。此外,相对于几乎为零的特征值的特征向量可以被认为是垃圾。到目前为止这么好。



现在,考虑下面的MATLAB代码,我想在C ++中使用 Eigen

 %假设K是3x3矩阵
[V_K,D_K] = eig
d_k = diag(D_K);
ind_k = find(d_k> 1e-8);
d_k(ind_k)= d_k(ind_k)。^( - 1/2);
K_half = V_K * diag(d_k)* V_K';

而我的C ++实现:

  EigenSolver< Matrix3f> es(K,true); 
auto v = es.eigenvalues();
//如果特征值太小则设置为零,否则v ^( - 1/2)
v =(v.array()。real()> 1e-8).select(v.cwiseSqrt ().cwiseInverse(),0);
auto KHalf = es.eigenvectors()* v.asDiagonal()* es.eigenvectors()。inverse();

问题是 K_half 的值不同从 KHafl ,您可以从打印结果中看到:



Matlab:

  V_K = 

0.5774 0.8428 -0.0415
0.5774 -0.3806 -0.7468
0.5774 -0.3806 0.6638


D_K =

17.0000 0 0
0 2.0000 0
0 0 -0.0000

K_half =

0.5831 -0.1460 -0.1460
-0.1460 0.1833 0.1833
-0.1460 0.1833 0.1833

eigenvalues =
(2,0)
17,0)
(0,0)
eigenvectors =
(-0.842777,0)(0.57735,0)(-0.041487,0)
(0.380609,0) 0.57735,0)(-0.746766,0)
(0.380609,0)(0.57735,0)(0.663792,0)

KHalf =
(0.0754555,-3.9918e- 310)(0.0764066,1.9959e-310)(0.0906734,1.9959e-310)
(-0.144533,0)(0.186401,0)(0.200668,0)
(-0.144533,0)(0.186401 ,0)(0.200668,0)

问题是我不知道这个差别是将是对其余算法的差异或不(我在问题的结尾是完整性)。从我的理解,没有办法保证特征向量与两个库相同(因为存在多个特征向量,并且它们是成本不变的)。我必须担心这个吗?

pre> %p和b int参数,W和H返回
%为每个散列位的t个随机点创建索引
%然后形成权重矩阵
for i = 1:b
rp = randperm(p);
I_s(i,:) = rp(1:t);
e_s = zeros(p,1);
e_s(I_s(i,:))= 1;
W(:,i)= sqrt((p-1)/ t)* K_half * e_s;
end
H =(K * W)> 0;
W = real(W);


解决方案

感谢两个回答的评论我想出了问题:

  Eigen :: MatrixXcf KHalf = es.eigenvectors()* v.asDiagonal()* es.eigenvectors()。transpose ); 

(使用 transpose() c $ c> Eigen :: MatrixXcf 起作用)


Like it's explained here and here the orde of the eigenvalues (and relative eigenvectors and their sign too) are library dependent and (according to the first linked question) it shouldn't be a problem. In addition, eigenvectors relative to almost-zero eigenvalues can be considered as garbage. So far so good.

Now, consider the MATLAB code below that I want to rewrite in C++ using Eigen library:

%supposing K is 3x3 matrix
[V_K,D_K] = eig(K);
d_k = diag(D_K);
ind_k = find(d_k > 1e-8);
d_k(ind_k) = d_k(ind_k).^(-1/2);
K_half = V_K*diag(d_k)*V_K';

And my C++ implementation:

EigenSolver<Matrix3f> es (K,true);
auto v = es.eigenvalues();
//set to zero if eigenvalues too smal, otherwise v^(-1/2)
v = (v.array().real() > 1e-8).select(v.cwiseSqrt().cwiseInverse(), 0);
auto KHalf = es.eigenvectors()*v.asDiagonal()*es.eigenvectors().inverse();

The problem is that K_half values are different from KHafl, as you can see from the printed result:

Matlab:

V_K =

    0.5774    0.8428   -0.0415
    0.5774   -0.3806   -0.7468
    0.5774   -0.3806    0.6638


D_K =

   17.0000         0         0
         0    2.0000         0
         0         0   -0.0000

K_half =

    0.5831   -0.1460   -0.1460
   -0.1460    0.1833    0.1833
   -0.1460    0.1833    0.1833

eigenvalues=
 (2,0)
(17,0)
 (0,0)
eigenvectors=
(-0.842777,0)   (0.57735,0) (-0.041487,0)
 (0.380609,0)   (0.57735,0) (-0.746766,0)
 (0.380609,0)   (0.57735,0)  (0.663792,0)

KHalf=
(0.0754555,-3.9918e-310)  (0.0764066,1.9959e-310)  (0.0906734,1.9959e-310)
           (-0.144533,0)             (0.186401,0)             (0.200668,0)
           (-0.144533,0)             (0.186401,0)             (0.200668,0)

The problem is that I don't know if this difference is going to be a difference for the rest of algorithm or not (which I post at the end of the question for completeness). From what I understand there is no way to guarantee that the eigenvectors are the same from the two libraries (since there exists multiple eigenvectors and they are costant-invariant). Do I have to worry about this? Eventually, how can I solve it?

The rest of the Matlab algorithm:

% p and b int parameters , W and H returned
%create indices for the t random points for each hash bit
%then form weight matrix
for i = 1:b
    rp = randperm(p);
    I_s(i,:) = rp(1:t);
    e_s = zeros(p,1);
    e_s(I_s(i,:)) = 1;
    W(:,i) = sqrt((p-1)/t)*K_half*e_s;
end
H = (K*W)>0;
W = real(W);

解决方案

Thanks to both answer's comments I figured out the problem:

Eigen::MatrixXcf KHalf = es.eigenvectors()*v.asDiagonal()*es.eigenvectors().transpose();

(using transpose() and Eigen::MatrixXcf made the trick)

这篇关于Eigen和Matlab中的不同特征向量和特征值可能产生误差?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆