Like it's explained <a href="https://stackoverflow.com/questions/28860070/why-some-eigen-vector-signs-from-c-armadillo-are-different-from-python-and-r" rel="nofollow">here</a> and <a href="https://stackoverflow.com/questions/22634638/c-linear-algebra-library-armadillo-how-to-use-eig-pair-to-get-the-same-resul" rel="nofollow">here</a> 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
%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:
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?
<strong>The rest of the Matlab algorithm:</strong>
% 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);Answer1:
Thanks to both answer's comments I figured out the problem:
Eigen::MatrixXcf KHalf = es.eigenvectors()*v.asDiagonal()*es.eigenvectors().transpose();
Eigen::MatrixXcf made the trick)