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 $8\times 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.
A
? $\endgroup$A = {{0,0,1,-I},{0,0,0,1},{-1,0,0,0},{I,-1,0,0}}
. $\endgroup$