Search code examples
c++complex-numberspolar-coordinates

Efficiently converting complex to its polar form


It's easy to convert an std::complex c to its polar form:

magnitude = abs(c)
phase = arg(c)

However, these are two separate operations to get the magnitude and the phase. Optimizations, either algorithmic or in implementation, might be possible if there were a single method provided by the standard library to convert an std::complex to its polar form.

Does the standard library provide a more efficient way to convert a cartesian complex to its polar form? I only found the polar method which does the opposite.


Solution

  • I would be rather surprised if any part of the work could actually be shared in the computation of these two results. Note that not only different functions, but even different approaches are used calculating the amplitude and the phase. This is very different from the case of calculating, e.g., sine and cosine together, where it's virtually no harder getting both the results simultaneously and separating them than getting one or the other only.

    The form z = r e^(iφ) does not treat r and φ in any kind of symmetric manner, not giving any grounds for believing its inverse should. Actually requiring r ≥ 0 is rather arbitrary to start with; unlike the ambiguity in angle, which is defined up to an integer multiple of 2π, this is not a result of branch choice but simply of geometric intuition. In short, the polar form is not terribly mathematically interesting.

    The story changes completely if you are happy with s = log r instead of r, because then z = e^(s + iφ) and s + iφ = log z. Thus "just" generalizing logarithm for complex numbers does the trick, your two answers are stored in the real and the imaginary parts of the result. std::log is extended for complex numbers in <complex>.

    Try a little benchmarking. It might be the case that log + real + imag + exp is faster (using optimization) than abs + arg.