Different complex log values displayed for a "single" input

Hello fellow MATLAB experts.
I'm here to question the following MATLAB behaviour: we do know, thanks to Euler's identity, that . Now, since complex exponential is a periodic function we do know that giving in input values that differ by an integer multiple of the period gives us in output the same value, which is, in this specific case, -1.
So it is true that
But it's also true that
And so on. So, natural logarithm of this function could give us any of these arguments as solution because it is true that for every argument in such form the complex exp's result is always -1.
This is kinda the problem: sometimes MATLAB's result of complex log is , sometimes is . From what I've seen, an example of this problem is:
So based on the argument being positive or negative i get two different, correct, results. Is there anything i can do to only get just one, say, the first one?

 Akzeptierte Antwort

James Tursa
James Tursa am 24 Okt. 2019
This is simply the result of floating point calculation artifacts ... not a bug. For instance, your assertion that all of your inputs lead to log(-1) is incorrect. E.g.,
>> m=@(x) log(exp(pi*1i+2*pi*1i*x));
>> e=@(x) exp(pi*1i+2*pi*1i*x);
>> format longg
>> e(20)
ans =
-1 + 1.56791929129057e-14i
>> e(-20)
ans =
-1 - 8.32883619547518e-15i
>> e(10)
ans =
-1 - 9.80955400591059e-16i
>> e(-10)
ans =
-1 - 5.87954259718047e-15i
So, in all cases you have a small but non-zero imaginary part as a result of doing the exp( ) calculation. In one case it happens to be slightly positive and in the three other cases it happens to be slightly negative. This leads to your downstream differences. But the root cause of all of this is that pi cannot be represented exactly in floating point, and floating point calculations involving pi will not always give you exactly what you might expect from an analytical/symbolic perspective. E.g.,
>> spi = sym('pi');
>> se=@(x) exp(spi*1i+2*spi*1i*x);
>> se(20)
ans =
-1
>> se(-20)
ans =
-1
>> se(10)
ans =
-1
>> se(-10)
ans =
-1
Bottom Line: You should not expect floating point calculations to be precise enough to always get your "expected" results from these edge cases. You need to have more reasonable expectations when working with floating point calculations. If these edge cases matter to your application, then you need to really understand what each and every calculation is doing and write your code differently to account for the floating point artifacts.

1 Kommentar

I fully understand what you're saying right here. Thanks for the answer. Unfortunately these edge cases do matter to my application and thankfully i think i might have found a workaround, but, if you were asked, what would you suggest to do?

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Steven Lord
Steven Lord am 23 Okt. 2019

0 Stimmen

Which release of MATLAB are you using? If you're using a release prior to release R2017b, try upgrading to that release or later to see if the fix for Bug Report 1653779 resolves the issue.

6 Kommentare

Alessandro Buldini
Alessandro Buldini am 24 Okt. 2019
Bearbeitet: Alessandro Buldini am 24 Okt. 2019
Unfortunately, I'm using MATLAB release 2019a. :(
In that case can you show the exact code you're running where you see this difference? Include if possible the code you use to generate the inputs to the log function. If that code is too long or complicated, instead display the inputs you pass into the log function using the longg display format (format longg) or even better the hex display format (format hex) and paste that display into your response.
Sure! I'll give you the very simplest example i can. The further we discuss the more convinced i am this might be a bug.
m=@(x) log(exp(pi*1i+2*pi*1i*x));
m1=m(20); % = 0.000000000000000 + 3.141592653589778i
m2=m(-20); % = 0.000000000000000 - 3.141592653589785i
And this is what i was talking about: despite both inputs lead to
log(-1);
the two ansers i get are different. But, for some unknown reason, even this behaviour is not consistent:
m=@(x)log(exp(pi*1i+2*pi*1i*x));
m1=m(10); % = 0.000000000000000 - 3.141592653589792i
m2=m(-10); % = 0.000000000000000 - 3.141592653589787i
Notice how both of the results now display .
I've just noticed R2019a Update 6 is available, I'll try to install it and see if the problem is somehow solved. Thank you anyway for your attention.
Unfortunately Update 6 didn't fix the problem
Let's break your m function into two pieces.
f = @(x) exp(pi*1i+2*pi*1i*x);
m = @(x) log(f(x));
When you evaluate m(20) and m(-20) the sign of the imaginary part is different. Let's see the numbers that got passed into log in those two calls.
x20 = f(20)
xm20 = f(-20)
x20 has an imaginary part that's just barely positive (around 1.6e-14.) xm20 has an imaginary part that's just barely negative (around -8.3e-15.) Since one way to define the principal value of the logarithm involves computing the atan2 of the imaginary part and the real part, that difference in sign of the imaginary part means the atan2 of one is just less than pi while the other is just greater than -pi. You're seeing the "jump" behavior described at the end of the "Definition of principal value" section on that Wikipedia page.
Why do x20 and xm20 have nonzero imaginary parts? Aren't those just the sin of integer multiples of π by Euler's formula? No. They're the sin of integer multiples of pi. pi is close to, but not exactly equal to, π. While the sine of π is exactly 0, the sin of pi is not exactly 0. You might find this Cleve's Corner article interesting, especially the last screen or so.
That's a great answer too. If you were asked too, what would you do to prevent this from happening?
Thanks anyway :)

Melden Sie sich an, um zu kommentieren.

Kategorien

Community Treasure Hunt

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

Start Hunting!

Translated by