27

Is there a built-in Numpy function to convert a complex number in polar form, a magnitude and an angle (degrees) to one in real and imaginary components?

Clearly I could write my own but it seems like the type of thing for which there is an optimised version included in some module?

More specifically, I have an array of magnitudes and an array of angles:

>>> a
array([1, 1, 1, 1, 1])
>>> b
array([120, 121, 120, 120, 121])

And what I would like is:

>>> c
[(-0.5+0.8660254038j),(-0.515038074+0.8571673007j),(-0.5+0.8660254038j),(-0.5+0.8660254038j),(-0.515038074+0.8571673007j)]
Lee
  • 29,398
  • 28
  • 117
  • 170
  • 1
    I doubt that there is a built in numpy function, but you could make a function that takes the two arrays and does the conversion – Ryan Saxe May 08 '13 at 15:44

5 Answers5

33

There isn't a function to do exactly what you want, but there is angle, which does the hardest part. So, for example, one could define two functions:

def P2R(radii, angles):
    return radii * exp(1j*angles)

def R2P(x):
    return abs(x), angle(x)

These functions are using radians for input and output, and for degrees, one would need to do the conversion to radians in both functions.

In the numpy reference there's a section on handling complex numbers, and this is where the function you're looking for would be listed (so since they're not there, I don't think they exist within numpy).

tom10
  • 67,082
  • 10
  • 127
  • 137
  • 1
    `angle` and `absolute` get you from rectangular to polar, but I don't know of a way to go back. – endolith Apr 18 '14 at 01:40
  • 2
    @endolith: I edited my answer to include functions to go both directions. (I didn't included these before because the OP was specifically saying he was looking for something built-in.) – tom10 Apr 18 '14 at 20:34
  • You can "get back" from polar to rectangular with `Amplitude*exp(1j*Angle_Radians)` - python will print and store this as rectangular complex, and you can use `().real/().imag`. – Demis Aug 09 '16 at 22:08
  • FYI, `radii` & `angles` must by Numpy Arrays here. So the one-liner code looks kind of ugly because of that (saving 3 polars): `a,b,c = np.array([1,2,3])*np.exp(1j*np.array([3.14,1.05,0]))` – Demis Aug 09 '16 at 22:13
  • 2
    To avoid confuzion, I would change the answer to use the explicitly functions from numpy, e.g. `np.absolute` instead of `abs`, since the latter is also a built-in function. – Bas Swinckels Mar 09 '17 at 12:40
  • 1
    @BasSwinckels: surely this is the exact reason for operator overloading, and why numpy uses the `__abs__` method. – tom10 Mar 10 '17 at 16:17
5

There's an error in the previous answer that uses numpy.vectorize - cmath.rect is not a module that can be imported. Numpy also provides the deg2rad function that provides a cleaner piece of code for the angle conversion. Another version of that code could be:

import numpy as np
from cmath import rect

nprect = np.vectorize(rect)

c = nprect(a, np.deg2rad(b))

The code uses numpy's vectorize function to return a numpy style version of the standard library's cmath.rect function that can be applied element wise across numpy arrays.

dyqik
  • 51
  • 1
  • 2
1

I used cmath with itertools:

from cmath import rect,pi
from itertools import imap
b = b*pi/180                   # convert from deg to rad
c = [x for x in imap(rect,a,b)]
Lee
  • 29,398
  • 28
  • 117
  • 170
0
import numpy as np
import cmath.rect

nprect = np.vectorize(rect)

c = nprect(a,b*np.pi/180)
Kees
  • 1
0

tom10 answer works fine... you can also expand the Euler's formula to:

def P2R(A, phi):
    return A * ( np.cos(phi) + np.sin(phi)*1j )
Thomio
  • 1,403
  • 15
  • 19