How to find a complex eigenvalue of a matrix

I want to find the highest complex eigenvalue of a matrix A. For example:
lambda = eig(A)
I'll get:
lambda =
2.6955 + 0.0000i
-1.1216 + 3.9723i
-1.1216 - 3.9723i
-1.7535 + 0.0000i
-0.1240 + 2.2553i
-0.1240 - 2.2553i
When I do:
[lambda_max, index_max] = max(real(lambda))
I'll get:
lambda_max =
2.6955
While I would like to have
-0.1240
How can I do this?
(sometimes the imaginairy part of complex eigenvalues can be zero)

10 comentarios

Walter Roberson
Walter Roberson el 17 de Dic. de 2019
Why would you select that one? It does not have the most positive real component; it does not have the most positive imaginary component; it does not have the greatest absolute value; it does not have the least absolute value; it does not have the most negative real component; it does not have the most negative imaginary component.
To the extent that complex numbers can be said to be ordered, you would expect to pick out -1.1216 +/- 3.9723i which has an absolute value greater than 4, whereas the one you picked out has an absolute value less than 3.
MM
MM el 17 de Dic. de 2019
I want the largest real value of complex conjugates of the eigenvalues to see if these are in the RHP and to calculate the damping and frequency (and I want to do this automated for large matrices). So in my example above that would be -0.1240±2.2553i
-0.1240 > -1.1216
Walter Roberson
Walter Roberson el 17 de Dic. de 2019
I want the largest real value of complex conjugates
Are you saying that you would discard the entries 2.6955 + 0.0000i and -1.7535 + 0.0000i because they are not part of a complex conjugate pair, and that once those are discarded, you would select -0.1240 +/- 2.2553i instead of -1.1216 +/- 3.9723i because -0.1240 > -1.1216 ?
MM
MM el 17 de Dic. de 2019
Yes, but seeing you questioning this, do you think I make some kind of mistake here?
I just want to see if the largest real part of complex comjugates is in the RHP. That's why I want to select -0.1240 in this example because this one is the closest to the RHP
Yes, but seeing you questioning this, do you think I make some kind of mistake here?
The fault with your existing code is that you are not discarding the elements that are not complex conjugates.
Hmmm... let me see...
[real(lambda(:)), abs(imag(lambda(:)))]
If you were then to uniquetol() with 'byrows' and take the third output, that would be a grouping variable. You would look for duplicated grouping variables... Mumble, mumble, splitapply(@(V) {V}, lambda(:), Grouping_Variable) then throw away the entries with length 1 ?
Yes I was hoping there was some kind of function that could do this for me, but I can't find it.
Maybe something like
if real(lambda(i)) == real(lambda(j))
with i~= j
and then check if imag(lambda(i)) == -imag(lamda(j)) for those two values
And then save this to a new matrix to do max(real(newlambda)) again
It might create double values because in this example:
lambda =
2.6955 + 0.0000i
-1.1216 + 3.9723i
-1.1216 - 3.9723i
-1.7535 + 0.0000i
-0.1240 + 2.2553i
-0.1240 - 2.2553i
real(lambda(2)) == real(lambda(3))
and
real(lambda(3)) == real(lambda(2))
But that doesn't really matter for the outcome (however I wouldn't mind to prevent this from happening if it isn't too difficult)
But I don't know how to do this the proper way (if this could work)
Walter Roberson
Walter Roberson el 17 de Dic. de 2019
You cannot use == for this purpose, as you cannot be sure that the conjugates are bitwise identical except for sign. I mentioned uniquetol() rather than unique() in order to permit "close" values.
It looks like it works when I do it like this:
lambda_conj = [];
for ii = 1:length(lambda)
for jj = 1:length(lambda)
if ii == jj
elseif uniquetol(real(lambda(ii))) == uniquetol(real(lambda(jj)))
lambda_conj = [lambda_conj; lambda(ii)];
end
end
end
lambda = lambda_conj;
but it looks like this does the same:
lambda_conj = [];
for ii = 1:length(lambda)
for jj = 1:length(lambda)
if ii == jj
elseif real(lambda(ii)) == real(lambda(jj))
lambda_conj = [lambda_conj; lambda(ii)];
end
end
end
lambda = lambda_conj;
But I think the way I used uniquetol, it doesn't really do anything. It probably only looks to that one value of lambda so it will always gave the same output as when I don't use it. I didn't test it yet but I think both methods will fail when for example the values are
-1.121600000000000 + 3.9723i
-1.121600000000001 - 3.9723i
(I don't know what the standard tolerance is, even if I say the tolerance is 0.0005. Both methods will probably still fail when the difference is as small as mentioned above)
Steven Lord
Steven Lord el 18 de Dic. de 2019
I think the cplxpair function may be of interest to you in making sure the complex conjugate pairs are grouped together.
lambda = [
2.6955 + 0.0000i
-1.1216 + 3.9723i
-1.1216 - 3.9723i
-1.7535 + 0.0000i
-0.1240 + 2.2553i
-0.1240 - 2.2553i];
[uniquegroups, ~, group] = uniquetol([real(lambda), abs(imag(lambda))], 'byrows', true);
groupcounts = accumarray(group, 1);
maxeigreal = max(real(uniquegroups(groupcounts>1,:)));

Iniciar sesión para comentar.

 Respuesta aceptada

MM
MM el 3 de Feb. de 2020

0 votos

A bit late but I fixed it, I could do it without filtering the pairs

Más respuestas (0)

Categorías

Más información sobre Linear Algebra en Centro de ayuda y File Exchange.

Productos

Versión

R2018b

Preguntada:

MM
el 17 de Dic. de 2019

Respondida:

MM
el 3 de Feb. de 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by