Search code examples
matlabperformanceeigenvector

MATLAB: efficient way to flip the sign of eigenvectors


[V D] = eig(A)

gives eigenvectors with non-consistent sign, sometimes the first entry is positive, sometimes negative. It's OK for general purpose, but unfortunately for my job I need the signs to be consistent. For example in a series of such evaluations for different A. For example, I hope the first entries of all eigenvectors to be positive. What are some efficient ways to achieve this?

Here is what I think: An if-else statement to flip the sign (if 1st entry is negative, flip). But it seems not efficient as I have to evaluate eigenvectors many times.


Solution

  • First of all, in general eigenvalues and eigenvectors can be complex. This should be taken into account when we talk about sign. Here I assume you want the first element of all the eigenvectors to be real and positive.

    This could be vectorized using bsxfun in this way:

    [V, D] = eig(A);
    % get the sign of the first row:
    signs = sign(V(1, :));
    % multiply all columns by the complex conjugate of sign of the first element:
    V = bsxfun(@times, V, conj(signs));
    

    Benchmarking:

    If you compare the speed of this method with a loop of if statement, you will see that my suggestion is a bit slower. But to be fare, this method should be compared with an equivalent loop which is capable of processing complex values. This is the results of my test:

    % the loop solution:
    for ii = 1:size(V, 2)
            V(:, ii) = V(:, ii) * conj(sign(V(1, ii)));
    end
    
    % A = rand(2);
    ------------------- With BSXFUN
    Elapsed time is 0.744195 seconds.
    ------------------- With LOOP
    Elapsed time is 0.500803 seconds.
    
    % A = rand(10);
    ------------------- With BSXFUN
    Elapsed time is 0.828464 seconds.
    ------------------- With LOOP
    Elapsed time is 0.835429 seconds.
    
    % A = rand(100);
    ------------------- With BSXFUN
    Elapsed time is 1.421716 seconds.
    ------------------- With LOOP
    Elapsed time is 4.286256 seconds.
    

    As you see, it depends on your application. If you have many many small matrices, the loop solution looks more convenient. On the other hand, if you are dealing with bigger matrices, definitely a vectorized solution does the job more efficiently.