Why some eigen vector signs from C++ Armadillo are different from Python and R
Question: I was wondering why the sign of the elements in the eigen vectors from
Armadillo is the opposite from other languages like Python (i.e. numpy) and R.

For example:

C++

    
    
    using namespace arma;
    
    vec eigval;
    mat eigvec;
    
    // C++11 initialization
    mat A = { 1, -1, 0, -1, 2, -1, 0, -1, 1};
    
    eig_sym(eigval, eigvec, A);
    eigvec.print("Eigen Vectors");
    

Output

    
    
    Eigen Vectors
    -5.7735e-01  -7.071068e-01  0.4082483
    -5.7735e-01  9.714451e-e17  -0.8164966
    -5.7735e-01  7.017068e-01   0.4082483
    

Python

    
    
    import numpy as np
    w,v = np.linalg.eig(np.array([[1,-1,0],[-1,2,-1],[0,-1,1]]))
    v 
    

Output

    
    
    array([[ -4.08248290e-01,  -7.07106781e-01,   5.77350269e-01],
           [  8.16496581e-01,   2.61214948e-16,   5.77350269e-01],
           [ -4.08248290e-01,   7.07106781e-01,   5.77350269e-01]])
    

R

    
    
    eigen(matrix(c(1,-1,0,-1,2,-1,0,-1,1), 3, byrow=TRUE)$vectors
    

Output

    
    
    -4.082483e-01  -7.071068e-01   5.773503e-01
     8.164966e-01   9.420555e-16   5.773503e-01
    -4.082483e-01   7.071068e-01   5.773503e-01
    

You can see that Python and R provide the same eigen vectors (excluding
rounding errors). The armadillo result does provide the same numbers (the
order is a simple fix) but the sign on the first and third columns are
opposite from the corresponding columns in Python and R. Am I overlooking
something here?


Answer: That is answered by `help(eigen)` in R:

    
    
    Value:
    
         The spectral decomposition of ‘x’ is returned as components of a
         list with components
    
      values: a vector containing the p eigenvalues of ‘x’, sorted in
              _decreasing_ order, according to ‘Mod(values)’ in the
              asymmetric case when they might be complex (even for real
              matrices).  For real asymmetric matrices the vector will be
              complex only if complex conjugate pairs of eigenvalues are
              detected.
    
     vectors: either a p * p matrix whose columns contain the eigenvectors
              of ‘x’, or ‘NULL’ if ‘only.values’ is ‘TRUE’.  The vectors
              are normalized to unit length.
    
              Recall that the eigenvectors are only defined up to a
              constant: even when the length is specified they are still
              only defined up to a scalar of modulus one (the sign for real
              matrices).
    

So the sign is a 'free' parameter, and the result is truly equivalent. If it
were me, I'd follow R and Python but Conrad generally knows what he is doing.

