TransWikia.com

Sorting Eigensystem According to Complicated Rule

Mathematica Asked on August 2, 2021

I have looked for an answer to this but the near duplicates I could find seemed slightly distinct.

I have a matrix $A$ which has eigenvalues in pairs $lambda_1,-lambda_1,lambda_2,-lambda_2,dots$. I would like to sort the eigensystem such that the eigenvectors are in this order, with the eigenvalues having descending real parts. That is, I want to sort in descending order of the function $f=|Re(cdot)|$ and break ties by $g=Re(cdot)$.

What I was hoping for was something like:

f[z_] := Abs[Re[z]];
g[z_] := Re[z];
{eval,evec} = SortBy[Eigensystem[N[A]][Transpose],{f,z}][Transpose];

but this doesn’t work. Replacing {f,g} with Abs@*Re does work but not for the tiebreak (neither does {Abs@*Re,Re}).

An example matrix that is $8times 8$ is the following (although any anti-symmetric matrix has plus/minus pairs of eigenvalues):

A = {{0, 0, -1, -4*I, 0, 0, 0, 0}, 
    {0, 0, 0, -1, 0, 0, 0, 0}, {1, 0, 0, 0, -1, -4*I, 
      0, 0}, {4*I, 1, 0, 0, 0, -1, 0, 0}, 
    {0, 0, 1, 0, 0, 0, -1, -4*I}, {0, 0, 4*I, 1, 0, 0, 
      0, -1}, {0, 0, 0, 0, 1, 0, 0, 0}, 
    {0, 0, 0, 0, 4*I, 1, 0, 0}}

Edit:
Additionally, I have realised since writing this that for my application I probably want to organise the sorting differently than I’ve asked for. In particular I want to order first by f[z_] :=Abs[Re[z]], then break ties first by g[z_]:=Re[z]*Im[z] and second by h[z_]:=Re[z]. So a solution that enables me to simply list three functions f,g,h which I’ve defined elsewhere in my code would be preferable.

One Answer

New Edition

A = {{0, 0, 1, -I}, {0, 0, 0, 1}, {-1, 0, 0, 0}, {I, -1, 0, 0}};
result = Rule @@ Reverse@(A // N // Eigensystem) // Thread // 
  Association
SortBy[result, Re, Abs[#1] > Abs[#2] &]

Old Editon

We need a large A to test the code.

A = {{0, 0, 1, -I}, {0, 0, 0, 1}, {-1, 0, 0, 0}, {I, -1, 0, 0}};
result = Rule @@ Reverse@(A // N // Eigensystem) // Thread // 
  Association
ReverseSortBy[result, {Abs@*Re[#] &, Re[#] &}]

Original

What is your A?

use Association can keep the tie. Since we don't know A,here we set

eval=A//N//Eigensystem//First;
evac=A//N//Eigensystem//Last;
eval = {1 + 3 I, -(1 + 3 I), 2 - I, -(2 - I), 5 + I, -(5 + I), 
   3 - 8 I, -(3 - 8 I), 0.1 - 8 I, -(0.1 - 8 I)};
evac = Array[v, Length@eval];
result = ReverseSortBy[
  Association[Thread[evac -> eval]], {Abs[Re[#]] &, Re[#] &}]
{neweval, newevec} = {Values[result], Keys[result]};
<|v[5] -> 5 + I, v[6] -> -5 - I, v[7] -> 3 - 8 I, v[8] -> -3 + 8 I, 
 v[3] -> 2 - I, v[4] -> -2 + I, v[1] -> 1 + 3 I, v[2] -> -1 - 3 I, 
 v[9] -> 0.1 - 8. I, v[10] -> -0.1 + 8. I|>

{{5 + I, -5 - I, 3 - 8 I, -3 + 8 I, 2 - I, -2 + I, 1 + 3 I, -1 - 3 I, 
  0.1 - 8. I, -0.1 + 8. I}, {v[5], v[6], v[7], v[8], v[3], v[4], v[1],
   v[2], v[9], v[10]}}

Answered by cvgmt on August 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP