1
$\begingroup$

Here is some code that hopefully clearly illustrates what I'm doing:

>>> sp.linalg.eig(d)[0].real; sp.linalg.eigh(d)[0]; d; sp.linalg.eig(d)[1]; sp.linalg.eigh(d)[1]
array([ 1., -1.])
array([-1.,  1.])
matrix([[ 0, -1],
        [-1,  0]])
array([[ 0.70710678,  0.70710678],
       [-0.70710678,  0.70710678]])
array([[-0.70710678, -0.70710678],
       [-0.70710678,  0.70710678]])

To explain the code a little, the first two array()'s are the eigenvalues from eig() and eigh() respectively, where the latter is only for Hermitian matrices. Then I show the matrix d, and then the eigenvectors are shown as the columns of the following two matrices, in the same order as the eigenvalues.

Here, what I'm doing is taking a matrix d which in this case is simply $\sigma_x$, the Pauli x-spin matrix. I'm doing adiabatic quantum simulation, so I'm getting the ground state here of a transverse magnetic field for a 1-qubit case. Higher qubit cases have initial state vector that corresponds to the lowest energy for:

$D = -\sum_i^N I \otimes I \otimes ...\otimes ~\sigma_x^i \otimes...\otimes ~I$

So what I'm doing now is using the general LAPACK eigensolver zgeev with the eig() call and zheevd with the eigh() call, which is general and Hermitian solvers, respectively.

Why do I get the ground state eigenvector as one thing from eig(), but with eigh() I get the same thing but with an overall negative? And does it matter at all?

It's worth noting that this problem does NOT arise if I say $D$ has positive values instead of negative ones. That bit really confuses me.

$\endgroup$
  • 3
    $\begingroup$ Are you concerned that the eigenvectors returned for the same problem by two different solvers differ by a constant scalar? The eigenvalue equation is: $A\mathbf{v}=\lambda\mathbf{v}$ which is satisfied for any constant scalar multiple of $\mathbf{v}$. If you want to always guarantee uniqueness, you can post-normalize the result yourself. $\endgroup$ – Costis Apr 9 '13 at 1:06
  • $\begingroup$ @Costis You should post that as an answer. $\endgroup$ – user3224 Apr 9 '13 at 2:56
5
$\begingroup$

Eigenvector solutions to the standard eigenvalue problem formulation ($A\mathbf{v}=\lambda\mathbf{v}$) are unique up to a constant multiplier. It is clear that if there exists an eigenvector solution $\mathbf{v_a}$ which satisfies $A\mathbf{v_a}=\lambda\mathbf{v_a}$, then for any real\complex scalar $k$, $\mathbf{v_b}=k\mathbf{v_a}$ is also valid simply because $A\mathbf{v_b}=kA\mathbf{v_a}=k\lambda\mathbf{v_a}=\lambda\mathbf{v_b}$.

Therefore, it is not surprising that two different eigensolvers are returning the same eigenvector scaled differently. You must define your own renormalization procedure if you wish to completely uniquely define the eigenvectors (for instance: always force one of the components of the eigenvector to be 1 by dividing the resulting eigenvector with the value of that component.)

$\endgroup$
  • $\begingroup$ OK, that makes sense. What worries me is what I do in the rest of the code. I do an eigendecomposition at each timestep and check the overlap of the lowest eigenvector and my actual state that I'm evolving in. So what I really wonder now is if this scaling is systematic and predictable. What makes the solver give this particular scaling instead of another? $\endgroup$ – hadsed Apr 9 '13 at 12:51
  • 2
    $\begingroup$ Many eigensolver packages will automatically normalize the eigenvectors to have unit norm, which allows eigen-decompositions of vectors by just using inner products. So it might be better to force uniqueness by multiplying by -1 in the real case (or a complex number of absolute value 1 in the complex case) if necessary to make the first nonzero entry of the eigenvector positive (or some variation on this theme). $\endgroup$ – hardmath Apr 9 '13 at 12:54
1
$\begingroup$

The other answers suggest normalizing eigenvectors so that their first component is positive, but this seems bad advice to me: if the computed eigenvectors are v = (1e-17, 1) and w =(-1e-17, 1), then normalizing them to v_n = (1e-17, 1) and w_n =(1e-17, -1) and checking their distance with norm(v_n, w_n) identifies them as far apart when they are in fact very close to one another.

My advice is that you are looking at the problem at the wrong level: you don't need to normalize your output, you need to change the way in which you make comparisons between vectors. Compare two vectors $a,b$ by computing their angle, or correlation: $\frac{|a^Tb|}{\lVert a \rVert \lVert b\rVert}$. If this quantity is close to 1, then the two vectors differ only by a phase.

$\endgroup$
0
$\begingroup$

You can fix the eigenvectors to have the same sign in Python like this: eigvects = np.sign(eigvects[0,:]).transpose()*eigvects

That will fix the 1st eigenvector component to positive for all eigenvectors.

I can't figure out the LAPACK signing routine either vs ARPACK which would be nice to know so that eigh signs could be replicated, keeping your simulation predictable.

$\endgroup$
0
$\begingroup$

The above concern with a result of positive or negative 1e-17 as the first eigenvector value (which suggests a rounding error on essentially a 0 value could render your scaled eigenvector invalid) is not impacted by the ARPACK eigsh routine (Python, or eigs in MATLAB) - it consistently reproduces identical eigenvectors only differing by +/-1 scalar. If you use another method which may introduce rounding errors, I would suggest increasing precision to avoid that issue if it presents itself.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.