问题
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);
回答1:
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)
来源:https://stackoverflow.com/questions/38327550/different-eigenvector-and-eigenvalues-in-eigen-and-matlab-could-generate-errors