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 Comments

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.
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
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 ?
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)
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)
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,:)));

Sign in to comment.

 Accepted Answer

MM
MM on 3 Feb 2020
A bit late but I fixed it, I could do it without filtering the pairs

More Answers (0)

Categories

Find more on Linear Algebra in Help Center and File Exchange

Products

Release

R2018b

Asked:

MM
on 17 Dec 2019

Answered:

MM
on 3 Feb 2020

Community Treasure Hunt

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

Start Hunting!