Understand how to pass the correct input(s), e.g. for atan (atan2)

Hi there, I am newbie to Julia.

I am learning Julia, and so I want to create a simple function to convert a set of coordinates from cartesian to polar, and backwards. This is a trivial task, but I am stuck on the correct syntaxis for the atan function to be general to accept a value, and an array.

I run easily atan with two float numbers (e.g., atan(2.,4.)). However, I want to be able to pass also a vector (Array{Float64,1}), matrix of complex numbers, etc. It could be broadcasting but I do not get the right syntax.

function cart2pol(x,y,z)
  theta = atan(y,x)
  rho   = sqrt(x*x + y*y)
  return theta, rho, z
end

x = [1,2.1213,0,-5]
y = [0,2.1213,4,0]
z = [7.,8,9,10]

theta,rho,z = cart2pol(x,y,z)

However, I get the following error.

MethodError: no method matching atan(::Array{Float64,1}, ::Array{Float64,1})

Stacktrace:
 [1] cart2pol(::Array{Float64,1}, ::Array{Float64,1}, ::Array{Float64,1}) at .\In[24]:4
 [2] top-level scope at In[26]:1

Any help will be appreaciated (solution or point to the right section in the manual to understand it)

You want cart2pol.(x,y,z). See this section of the manual.

However, note that pol = cart2pol.(x,y,z) returns an array of tuples, not a tuple of arrays. (This is usually a better data structure for working with coordinate vectors anyway because it will have better locality for most operations that you want to do with the coordinates. StaticArrays may be an even nicer option than tuples.)

(In general, if you are coming from another language, I would re-think a focus on vectorized operations involving multiple passes doing simple operations on arrays of numbers. You can do this in Julia, too, but there are often better approaches since performance in Julia does not impose vectorization on you.)

You could also do atan.(x,y) and hypot.(x,y) in your cart2pol function, which would allow you to return a tuple of arrays as desired in your original code, but this is sticking with a suboptimal vectorized style.

PS. I would also recommend using hypot(x, y) instead of sqrt(x*x + y*y), as the latter can suffer from overflow or underflow for very large or small x and y, e.g. x=1e200.

PPS. In Julia you can have variables θ = atan(y,x) and ρ = hypot(x,y), you know. Try typing \theta followed by the tab character at the interactive prompt.

4 Likes

Thank you for taking the time to give us a lot of suggestions to learn by doing.

1 Like