Complex number operation does not make sense

3 views (last 30 days)
Luigi
Luigi on 23 Dec 2021
Commented: John D'Errico on 23 Dec 2021
How is it possible that the second operation below gives a complex number, when all I am doing is multiplying exp(1i)*exp(-1i) to a scalar?
-0.9*exp(-1i*1.1)*exp(1i*1.1)
ans = -0.9000
-0.98*exp(-1i*1.1)*exp(1i*1.1)
ans = -0.9800 + 0.0000i
also using format long
format long
-0.98*exp(-1i*1.1)*exp(1i*1.1)
ans =
-0.980000000000000 + 0.000000000000000i
the imaginary part is there, but it is equal to zero?!
  2 Comments
Torsten
Torsten on 23 Dec 2021
Edited: Torsten on 23 Dec 2021
The second gives in floating point arithmetic
ans = -9.8000e-01 + 5.5511e-17i
So it's a question of precision again.
Paul
Paul on 23 Dec 2021
Order of operations also affects the apparent precision.
-0.9 * (exp(-1i*1.1)*exp(1i*1.1))
ans = -0.9000
-0.98* (exp(-1i*1.1)*exp(1i*1.1))
ans = -0.9800

Sign in to comment.

Answers (1)

John D'Errico
John D'Errico on 23 Dec 2021
Edited: John D'Errico on 23 Dec 2021
Welcome to the wonderful wacky world of floating point arithmetic.
imag(-0.98*exp(-1i*1.1)*exp(1i*1.1))
ans = 5.5511e-17
When MATLAB reports a number using format long, it does not tell you EVERY single bit of that result. In fact, down in the least significant bits of the result, we had some floating point trash.
A common signal that there is indeed SOMETHING there is the 0.0000i imaginary part as it was displayed. That is a hint that there is something down there, just too small to fit even into format long.
Is that value truly 5.5511e-17? Of course exact mathematics would produce zero. But floating point arithmetic is NOT exact mathematics, only an approximation to it. A very good approximation most of the time. But here we see there were numerical issues that returned just a tiny amount of floating point trash. Again, when you see that 0.0000 value, you should assume it was not truly zero, just rounded to 4 significant digits as zero.
  2 Comments
Luigi
Luigi on 23 Dec 2021
thanks a lot for your detailed answer. So, in practice, how should I handle these occurrences when doing computations? I assume that I should just impose real() on my result, so as to sideline the approximation issue that is produced.
John D'Errico
John D'Errico on 23 Dec 2021
If you are dealing with complex numbers, but a truly non-zero imaginary part is not mathematically possible, then just using real is the right thing. Unless that tiny imaginary part will not be relevant in future computations. Then you could just leave it alone and not worry. Since you posted this as an apparent problem, then the complex part was a surprise, and apparently an issue.
In this case, simple mathematics could have solved your problem. Since
exp(-a*i)*exp(a*i) == exp(-a*i + a*i) == exp(0) == 1
then without any need to use real, you could have resolved the issue. But of course I have no idea how the problem surfaced into your code, so I cannot really say. You might decide to ignore the complex part that arises until it could be a problem in some future computation. Then test to see if any imaginary part is significant before you discard it. Or, if you know some specific operation, like the one here, will generate sometimes arbitrary bits of imaginary trash, then just discard the trash using real. I honestly don't see it as something to worry about.
How do you deal with floating point trash in general? Careful mathematics, numerical analysis, and the use of tolerances where necessary are always valuable. Each has its place and there is no simple general rule.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!