Re: question about sorting lists

*To*: mathgroup at smc.vnet.net*Subject*: [mg90884] Re: question about sorting lists*From*: Tatyana Polenova <tpolenov at mail.chem.udel.edu>*Date*: Mon, 28 Jul 2008 07:52:04 -0400 (EDT)

Jean-Marc, thanks so much! This is indeed quite an elegant way. With best regards Tatyana ----- 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: Sunday, July 27, 2008 2:24:34 PM (GMT-0500) America/New_York Subject: [mg90884] Re: question about sorting lists 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 > >