Let us consider a matrix of order $n \times n$ with $n/2$ positive and $n/2$ negative eigenvalues. How to collect $n/2$ eigenvectors corresponding to positive eigenvalues in a matrix of order $n \times n/2$? It can be done by arranging the eigenvalues in descending order and arranging the eigenvectors according to the new arrangement of corresponding eigenvalues. But how can one collect the eigenvectors corresponding to the positive eigenvalues without using descending order array of eigenvalues?


The method proceeds in two stages: use Eigensystem[] to compute the set of eigenvalues and eigenvectors, and then use Pick[] to retain the eigenvectors corresponding to the positive eigenvalues.

As a concrete example, take the Clement-Kac matrices:

ckmat[n_Integer?Positive] :=
SparseArray[{{i_, j_} /; Abs[i - j] == 1 :>
             With[{k = Min[i, j]}, Sqrt[k (n - k)]]}, {n, n}]

Get the eigensystem for the $8\times 8$ case:

{vals, vecs} = Eigensystem[N[ckmat[8]]];

The desired eigenvector set can then be obtained as

Pick[vecs, Positive[vals]]

You can check that the right set was picked out by comparing the result of that with vals and vecs (keeping in mind that the eigenvectors are stored by rows).

| improve this answer | |
  • $\begingroup$ Thanks for responding. I tried using the following program: "mm[x_, y_, z_] := With[{vals, vecs} = Eigensystem[M[x, y, z]], Pick[vecs, Positive[Re[vals]]]]; mm[0, 0, 0] // MatrixForm" where m[x,y,z] is 16 cross 16 matrix. But it shows an error : "With::lvlist: Local variable specification {vals,vecs}=Eigensystem[M[0,0,0]] is not a List." $\endgroup$ – atanu Sep 26 '18 at 9:06
  • 1
    $\begingroup$ You used With[] wrong. In this case, Module[] is more appropriate: mm[x_, y_, z_] := Module[{vals, vecs}, {vals, vecs} = Eigensystem[M[x, y, z]]; Pick[vecs, Positive[Re[vals]]]] $\endgroup$ – J. M.'s technical difficulties Sep 26 '18 at 9:16
  • $\begingroup$ Thanks a lot. Now it is working. $\endgroup$ – atanu Sep 26 '18 at 9:57

I believe this should work (I have not extensively tested it),

system = Eigensystem[M]
systemSorted = Transpose@Sort@Transpose@system

The idea is to take the initial list of the form

system ~ { {e1, e2,...} , {{v11, v12,...}, {v21, v22,...}, ... } }

Transpose@system ~ { {e1, {v11, v12,...}}, {e2, {v21, v22,...}}, ... }

Sort then sorts these in increasing order of the eigenvalues, then Transpose takes you back to the original form of the list but now all eigenvalues and eigenvectors are sorted in ascending order.

Now we can simply take the last n/2 eigenvectors from the list. So overall

positiveEigensystem = (Transpose@Sort@Transpose@Eigensystem[M])[[-n/2;;]]

assuming n is even (e.g. I was working on a similar problem in which I knew for certain that the eigenvalues came in $\pm$ pairs).

| improve this answer | |
  • $\begingroup$ This only orders them, it does not select positive ones. $\endgroup$ – CA Trevillian Aug 8 at 21:44
  • $\begingroup$ Nice update! You should also be able to drop the second n in your Part, such that you have (...)[[-n/2;;]]. Can you clarify how you might have this work if the Eigenvectors or Eigenvalues are Complex? $\endgroup$ – CA Trevillian Aug 9 at 13:35
  • 1
    $\begingroup$ @CATrevillian sorry I was on my phone earlier so didn't reply to your comment. From the documentation, Sort sorts complex numbers according to their real part, but can be passed a specific function for determining the sort order. Rereading the question now, I realize that it specifically asked for a non-sorting solution, but hopefully the answer is still useful to people (like myself) who found this question while trying to figure this out. $\endgroup$ – Kai Aug 9 at 14:35
  • $\begingroup$ It still works if the eigenvectors are complex, since it is only sorting according to eigenvalue. $\endgroup$ – Kai Aug 9 at 14:37

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.