MathGroup Archive 1995

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Sorting eigenvectors by eigenvalue

In article <DF36JK.603 at> valentin at (William F. Campbell) writes:
>  I'm trying to use Sort to sort eigenvectors by eigenvalue.  The eignevectors
>are in a list of lists called vecs, and the eigenvalues in vals after the 
>following function call on matrix aa:  
>  {vals,vecs}=Eigensystem[aa]
>  Then I want to define an ordering function p so I can use Sort[vecs,p].  
>I tried the following: 
>  p[vecs[[i_]],vecs[[j_]]]:=Greater[Abs[vals[[i]],Abs[vals[[j]]]]
>  Mathematica wont parse vecs[[i_]] saying that i is neither an integer nor
>a list of integers.  How can I accomplish what I want to do?
>|                                                                            |
>|                When endeavoring to explain human behaviour,                |
>|                never discount the possibility of stupidity.                |
>|                                                                            |
>|                        Never ascribe to malfeasance                        |
>|                  that which can be explained as stupidity.                 |
>|                                                                            |
>|  Bill Campbell                                                             |

I presume you are referring to the messages from

  In[1]:= p[vecs[[i_]],vecs[[j_]]]:=Greater[Abs[vals[[i]]],Abs[vals[[j]]]]

  Part::pspec: Part specification i_
       is neither an integer nor a list of non-zero integers.

  Part::pspec: Part specification j_
       is neither an integer nor a list of non-zero integers.

which come up because the elements on the left-hand side of the
assignment are evaluated before the assignment is completed.  You
can avoid these messages by enclosing the left-hand side of the
assignment in Literal, but there are two important remarks to
be made about that.  First of all, precisely *because* the part
extractions failed, the assignment constructed the rule that was

  In[2]:= ?p

  p[vecs[[i_]], vecs[[j_]]] := Abs[vals[[i]]] > Abs[vals[[j]]]

and more importantly, this rule won't do what you want.

The comparison function (the second argument) in Sort is expected to
be a function that compares pairs of elements.  Those elements will
be delivered to the comparison function by Sort.  The indices of
those elements will not be delivered to the comparison function,
so i and j in this definition will never have values.

A common way to do what you want is to transpose the result from
Eigensystem to get a list {{val1, vec1}, {val2, vec2}, ...}, sort
on the first part of each element in this list, and transpose back.
This approach is used at several places in the standard Mathematica

  In[1]:= {vals, vecs} = Eigensystem[DiagonalMatrix[{2, 1, 3}]]

  Out[1]= {{1, 2, 3}, {{0, 1, 0}, {1, 0, 0}, {0, 0, 1}}}

  In[2]:= p[v1_, v2_] := Abs[v1[[1]]] > Abs[v2[[1]]]

  In[3]:= {vals, vecs} = Transpose[Sort[Transpose[{vals, vecs}], p]]

  Out[3]= {{3, 2, 1}, {{0, 0, 1}, {1, 0, 0}, {0, 1, 0}}}

There are several other ways to do this that may be useful
in special situations.

Dave Withoff
Research and Development
Wolfram Research

  • Prev by Date: Re: Mathematica and NetScape
  • Next by Date: MmaToHTML_for_Macs
  • Previous by thread: Re: Sorting eigenvectors by eigenvalue
  • Next by thread: New user question?