MathGroup Archive 2008

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

Search the Archive

Re: question about sorting lists

  • To: mathgroup at smc.vnet.net
  • Subject: [mg90882] Re: question about sorting lists
  • From: Jean-Marc Gulliet <jeanmarc.gulliet at gmail.com>
  • Date: Mon, 28 Jul 2008 07:51:41 -0400 (EDT)
  • Organization: The Open University, Milton Keynes, UK
  • References: <g6h5ec$h1f$1@smc.vnet.net>

Tatyana Polenova wrote:

> Jean-Marc,
> thank you very much for the tip.
> 
> Indeed, I forgot to specify that the eigenvalues have to also be arranged in order of increasing or decreasing their values depending on what the distance is between the adjacent two. Say, the eigenvalues list is {-2, 1, -3}. The way this list needs to be ordered is {-3, -2, 1}. If the list is {1, 2, -3} then it needs to be ordered as {2, 1, -3}. So that the middle element in the list has an intermediate absolute value, and the distance between the second and the third elements in the list is the largest.
> 
> The way I used to do the ordering before is in two steps:
> first, the regular Sort operation to arrange the eigenvalues in order. Then, reassign the order if necessary according to the distance criterion. Something like:
> 
> CS={1,2,-3}
> Eigensort = Sort[Eigenvalues[CS]];
> If[Abs[Eigensort[[1]] - Eigensort[[2]]] > Abs[Eigensort[[3]] - Eigensort[[2]]], Vxx = Eigensort[[3]]; Vyy = Eigensort[[2]]; Vzz = Eigensort[[1]], Vxx = Eigensort[[1]]; Vyy = Eigensort[[2]]; Vzz = Eigensort[[3]]];
> 
> But then the problem arises when I need to pull out the corresponding eigenvectors, in some instances the Vxx, Vyy, and Vzz are not recognized by Mathematica as identical numbers to the original values stored in the list.
> 
> Is this a precision problem?
> 
> But in any event, I thought it may be a more concise way to do the sorting using a one-line expression, like you suggested.
> What would you recommend? Thanks for your time!
> 
> With best regards
> Tatyana

Hi Tatyana,

I believe the following function is doing what you wish in an elegant 
and concise way (of course, elegance is in the eye of the beholder :).

First, we sort the eigenvalues and their corresponding eigenvectors 
according to increasing values of the eigenvalues.

Second, we swap the third and first columns of the eigenvalue and 
eigenvector arrays if and only if the distance between the first and 
second eigenvalues is greater than the distance between the second and 
third eigenvalues.

Note that the second column of each array always stay in place since it 
is already at the right place after the initial sort.

     mySort[eigsys_] := Module[{es = eigsys},
       es = {eigsys[[1, #]], eigsys[[2, #]]} &[Ordering[eigsys[[1]]]];
       If[Abs[es[[1, 1]] - es[[1, 2]]] > Abs[es[[1, 3]] - es[[1, 2]]],
        {es[[1, 1]], es[[1, 3]]} = {es[[1, 3]], es[[1, 1]]};
        {es[[2, 1]], es[[2, 3]]} = {es[[2, 3]], es[[2, 1]]}];
       es]

     eigs = Eigensystem[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}] // N
     mySort[eigs]

     {{16.1168, -1.11684, 0.}, {{0.283349, 0.641675, 1.},
                                {-1.28335, -0.141675, 1.},
                                {1., -2., 1.}}}

     {{-1.11684, 0., 16.1168}, {{-1.28335, -0.141675, 1.},
                                {1., -2., 1.},
                                {0.283349, 0.641675, 1.}}}

     eigs = Eigensystem[N[{{1, 2, 3}, {1, 4, 9}, {1, 8, 27}}]]
     mySort[eigs]

     {{29.9428, 1.83935, 0.217884}, {{-0.119842, -0.329513, -0.936514},
                                     {-0.716252, -0.656311, 0.237146},
                                     {-0.848423, 0.515028, -0.122164}}}

     {{0.217884, 1.83935, 29.9428}, {{-0.848423, 0.515028, -0.122164},
                                     {-0.716252, -0.656311, 0.237146},
                                     {-0.119842, -0.329513, -0.936514}}}

     mySort[{{30, 1, 5}, {{1, 2, 3}, {1, 4, 9}, {1, 8, 27}}}]

         (* {{1, 5, 30}, {{1, 4, 9}, {1, 8, 27}, {1, 2, 3}}} *)

     mySort[{{-2, 1, -3}, {{1, 2, 3}, {1, 4, 9}, {1, 8, 27}}}]

         (* {{-3, -2, 1}, {{1, 8, 27}, {1, 2, 3}, {1, 4, 9}}} *)

     mySort[{{1, 2, -3}, {{1, 2, 3}, {1, 4, 9}, {1, 8, 27}}}]

         (* {{2, 1, -3}, {{1, 4, 9}, {1, 2, 3}, {1, 8, 27}}} *)

     mySort[{{1, -1, 0}, {{1, 2, 3}, {1, 4, 9}, {1, 8, 27}}}]

         (* {{-1, 0, 1}, {{1, 4, 9}, {1, 8, 27}, {1, 2, 3}}} *)


Best regards,
- Jean-Marc

> ----- Original Message -----
> From: "Jean-Marc Gulliet" <jeanmarc.gulliet at gmail.com>
> To: "Tatyana Polenova" <tpolenov at mail.chem.udel.edu>, mathgroup at smc.vnet.net
> Sent: Saturday, July 26, 2008 12:29:32 PM (GMT-0500) America/New_York
> Subject: Re: question about sorting lists
> 
> Tatyana Polenova wrote:
> 
>> I have the following numerical list:
>>
>> {{{x1, x2, x3}, {{x11, x12, x13}, {x21, x22, x23}, {x31, x32, x33}}}
>>
>> where x1, x2, and x3 are some eigenvalues, and {x11, x12, x13}, {x21,  
>> x22, x23}, and {x31, x32, x33} are their corresponding eigenvectors.
>>
>> I need to sort the list so that the eigenvalues are arranged in the  
>> order of decreasing the absolute value of the difference between any  
>> of the two eigenvalues. (and that the eigenvectors still correspond to  
>> the original eigenvalues).
>>
>> What would be the correct syntax for this operation in Mathematica 5.2?
> 
> First the easy part of your question. Say we want to sort the 
> eigenvalues in increasing order and keep their respective eigenvector in 
> order. One possible way of doing that is as follows:
> 
>      eigsys = Eigensystem[{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}] // N
>      {eigsys[[1, #]], eigsys[[2, #]]} &[Ordering[eigsys[[1]]]]
> 
> 
>      {{16.1168, -1.11684, 0.}, {{0.283349, 0.641675, 1.},
>                                 {-1.28335, -0.141675, 1.},
>                                 {1., -2., 1.}}}
> 
>      {{-1.11684, 0., 16.1168}, {{-1.28335, -0.141675, 1.},
>                                 {1., -2., 1.},
>                                 {0.283349, 0.641675, 1.}}}
> 
> 
> (Note that functions such as Sort, Ordering, etc., all have a second or 
> third optional argument that specifies the sort function -- relation -- 
> to use.)
> 
> Although I might have missed the obvious when reading your 
> specifications, your criterion is not strong enough to define an order 
> relation (among other things, it is not antisymmetric).
> 
> For instance, say we have the eigenvalues {-1, 0, 1}. How would you 
> ordered them? You might say (-1, 1, 0) for the distances among adjacent 
> pairs are 2 (Abs[(-1) - 1]) and 1 (Abs[1 - 0]). Now the triple (1, -1, 
> 0) also matches the same "order". So which one to choose?
> 
> Regards,
> -- Jean-Marc
> 
> 



  • Prev by Date: Re: Function Programming Problems
  • Next by Date: Re: Export into Excel Worksheets
  • Previous by thread: Re: question about sorting lists
  • Next by thread: Re: question about sorting lists