Clear Filters
Clear Filters

atan2 does not accept complex numbers as input

164 views (last 30 days)
M A
M A on 12 Sep 2024 at 11:16
Edited: John D'Errico on 14 Sep 2024 at 0:38
Good Morning
If I'm not mistaken I think that there is a definition of the atan2() function also in the complex field.
If so , It is possible to implement a complex version of the atan2() function ?
i mean in a way that i can compute atan2(a+i*b , c+i*d) , where a,b,c,d are real and i =sqrt(-1) ,
this both numerically and symbolically
thankyou :-)
Kind regards
Manu1965@wail.ch
  4 Comments
Stephen23
Stephen23 on 13 Sep 2024 at 7:32
Edited: Stephen23 on 13 Sep 2024 at 9:23
I am not sure what the meaning or expected output for complex inputs might be, but for real inputs at least the formula seems to give the same output as ATAN2:
v = 1;
u = 3;
atan2(v,u)
ans = 0.3218
-1i*log((u+1i*v)./sqrt(u.^2+v.^2))
ans = 0.3218 + 0.0000i
V = -10:10;
U = V(:);
A = atan2(V,U);
B = -1i*log((U+1i*V)./sqrt(U.^2+V.^2));
surf(A)
max(abs(imag(B(:)))) % only floating point noise
ans = 1.5266e-16
surf(real(B))
Do you have any complex test values with known outputs?
If that formula works for you, then perhaps you can save it in a function and use it.
M A
M A on 13 Sep 2024 at 19:11
Dear Stephen23
many thanks for the interest

Sign in to comment.

Accepted Answer

John D'Errico
John D'Errico on 13 Sep 2024 at 12:25
Edited: John D'Errico on 13 Sep 2024 at 13:00
It seems the answers provided so far are missing the point. If we want to see a 4 quadrant atan2 version, that works for complex X and Y, can we use what Alpha suggests? Thus
atan2(U,V) = -i*log(U+i*V)./sqrt(U.^2 + V.^2)
I'll modify what @Stephen23 did to see what happens, for complex U and V. A serious problem is I would need to have a hyper-dimensional monitor to show the complete behavior. (My own personal holodeck is broken, awaiting parts. But shipping is very slow, coming from the future.) I would need to display essentially 6 dimensional behavior, and a regular monitor is just not up to snuff there. Nor are my eyes or my brain. So I can only do my best to look at what happens.
fun = @(V,U) -1i*log((U+1i*V)./sqrt(U.^2+V.^2));
First, what happens for real U and V?
utest = randn(3);vtest = randn(3);
fun(vtest,utest)
ans =
1.8569 - 0.0000i 1.0516 + 0.0000i 1.4416 - 0.0000i -0.0848 + 0.0000i -2.1910 + 0.0000i 2.0958 + 0.0000i -2.7649 - 0.0000i 1.7415 + 0.0000i 1.0877 - 0.0000i
And that is clearly a problem, since for real U and V, we want the result to return a purely real result. We need to patch it for that case.
function Z = atan2alt(V,U)
% extension of atan2(V,U) into the complex plane
Z = -1i*log((U+1i*V)./sqrt(U.^2+V.^2));
% check for purely real input. if so, zero out the imaginary part.
realInputs = (imag(U) == 0) & (imag(V) == 0);
Z(realInputs) = real(Z(realInputs));
end
atan2alt(vtest,utest)
ans = 3×3
1.8569 1.0516 1.4416 -0.0848 -2.1910 2.0958 -2.7649 1.7415 1.0877
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
so atan2alt now returns purely real output for purely real inputs. Next, is it consistent with atan2?
norm(atan2(vtest,utest) - atan2alt(vtest,utest))
ans = 2.2204e-16
And that is (as we sometimes said in the deep past) good enough for government work. The difference is down into the realm of floating point trash. Now I am at least a little happy, since the two are consistent for real input.
Next is this a 4 quadrant result? Again, that will be difficult to show in detail. But perhaps we can do a little, by plotting the result along a simple path in the complex plane.
V = (-10:10);
U = V(:);
v = V - 0.1i;
u = U + 0.2i;
So u and v both now each live along lines in the complex plane, where the imaginary part is constant, and non-zero.
Z = atan2alt(v,u);
And of course, since atan2alt will now return a complex result, we need to look at both the real and imaginary part.
surf(U,V,real(Z))
xlabel "Real(U)"
ylabel "Real(V)"
zlabel "Real(Z)"
surf(U,V,imag(Z))
xlabel "Real(U)"
ylabel "Real(V)"
zlabel "imag(Z)"
The result is a 4 quadrant version. Here we see the imaginary component is indeed non-zero.
surf(U,V,abs(Z))
xlabel "Real(U)"
ylabel "Real(V)"
zlabel "abs(Z)"
Of course, this would need a great deal more thought, to see if there were additional problems other than the need for a real result. What happens when one or both of the arguments are zero? Again, unless the two are consistent, we have a problem.
atan2([0 1],[0;1])
ans = 2×2
0 1.5708 0 0.7854
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
atan2alt([0 1],[0;1])
ans = 2×2
0 1.5708 0 0.7854
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Hey, that worked. I was actually just a little surprised. I was going to guess the code would fail when U==V==0, and perhaps return a NaN. But as it turns out, the result from the formula is then 0+infi, with an infinite imaginary part. But since it has a zero real part, the check at the end of atan2alt saved me.
I noticed that @M A wanted to see it work also for symbolic inputs. Again, I was wondering for just a second if it would survive here, but it did.
syms u v
atan2alt(v,u)
Some might suggest plots I generated do not form a very strong test, since they presumed constant imaginary part. And, while it is not too difficult to conjure up a pair of paths for U and V that are more complicated, this seems a good point to stop. 'nuff said.
  5 Comments
M A
M A on 13 Sep 2024 at 19:37
⇧ (ok, I supose the proper term is forward-order?) ⇧ :-)
John D'Errico
John D'Errico on 14 Sep 2024 at 0:36
Edited: John D'Errico on 14 Sep 2024 at 0:38
Lol. That was pretty bad, I agree. But, you know how it is, Sometimes I just can't resist. :)
Anyway, I'm happy to have been of help.

Sign in to comment.

More Answers (1)

nick
nick on 12 Sep 2024 at 11:26
Hi MA,
I see you're interested in working with complex numbers and calculating angles using MATLAB. You can use 'atan2' in conjunction with the 'imag' and 'real' functions to extract the imaginary and real parts of the complex number.
Here's a simple MATLAB script to demonstrate how you can do this:
z = 4 + 3i;%example complex number
theta = atan2(imag(z),real(z));
This script calculates the angle theta of the complex number z, where 'imag(z)' gives the imaginary part and 'real(z)' gives the real part.
You can refer to the following documentation to learn more about the functions 'imag' and 'real':
  7 Comments
nick
nick on 13 Sep 2024 at 5:26
Thank you @Stephen23
"If I'm not mistaken I think that there is a definition of the atan2() function also in the complex field." I misunderstood the OP's statement that the user wanted to use complex number as input to the function and obtain the angle as a real valued output.
M A
M A on 13 Sep 2024 at 6:30
Thankyou nick for your interest
"complex number as input to the function and obtain the angle as a real valued output. "
Not really , the output should also be a complex number in general.
Although I am not clear on the physical meaning, complex angles exist in the context of 3D Clifford algebra

Sign in to comment.

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!