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.
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP