Switching between rectangular and polar representations in Python
# A complex number can be represented in either
# rectangular or polar form.
#
# In rectangular form, we write
#
# z = a + bj,
#
# where
#
# a = Re(z)
#
# and
#
# b = Im(z).
#
# In polar form, we write
#
# z = r phase theta,
#
# where
#
# r = |z|
#
# is the magnitude and theta is the argument,
# or phase, of z.
#
# We will see how to mechanically convert
# between these two representations.
import cmath
import math
# First, suppose that a complex number is given
# in rectangular form:
#
# z = a + bj.
z = 3.2 - 4.7j
print( "\nThe complex number z:" )
print( z )
# Extract the real and imaginary components.
a = z.real
b = z.imag
print( "\nThe real component a:" )
print( a )
print( "\nThe imaginary component b:" )
print( b )
# To convert from rectangular form to polar
# form, first calculate the magnitude.
#
# From the Pythagorean theorem,
#
# __________
# / 2 2
# r = |z| = / a + b .
# V
r = math.sqrt(a**2 + b**2)
print( "\nThe magnitude calculated manually:" )
print( r )
# Python can calculate the same value directly
# using abs(...).
print( "\nThe magnitude using abs(z):" )
print( abs(z) )
# Next, calculate the argument theta.
#
# Geometrically,
#
# b
# tan(theta) = -.
# a
#
# It may therefore be tempting to calculate
#
# atan(b/a).
#
# This is not reliable because the quotient b/a
# does not contain enough information to
# determine the quadrant.
#
# Instead, use
#
# math.atan2(b, a).
#
# The function atan2(...) considers the signs
# of both a and b and therefore determines the
# correct quadrant.
theta = math.atan2(b, a)
print( "\nThe argument calculated using atan2:" )
print( theta )
# Python can calculate the principal argument
# of a complex number directly using
# cmath.phase(...).
print( "\nThe argument using cmath.phase(z):" )
print( cmath.phase(z) )
# These angles are measured in radians.
#
# We can convert the argument to degrees using
# math.degrees(...).
print( "\nThe argument in degrees:" )
print( math.degrees(theta) )
# We have therefore mechanically converted
#
# z = a + bj
#
# into
#
# z = r phase theta.
#
# The conversion formulas are
#
# __________
# / 2 2
# r = |z| = / a + b
# V
#
# and
#
# theta = atan2(b, a).
#
# In Python, these can be calculated more
# directly as
#
# r = abs(z)
#
# theta = cmath.phase(z).
# Now suppose instead that we are given a
# complex number in polar form:
#
# z = r phase theta.
#
# For example, suppose
r = 5
theta = math.pi/3
print( "\nMagnitude r:" )
print( r )
print( "\nArgument theta in radians:" )
print( theta )
print( "\nArgument theta in degrees:" )
print( math.degrees(theta) )
# To convert from polar form to rectangular
# form, use
#
# a = r*cos(theta)
#
# and
#
# b = r*sin(theta).
a = r*math.cos(theta)
b = r*math.sin(theta)
print( "\nThe real component a:" )
print( a )
print( "\nThe imaginary component b:" )
print( b )
# The rectangular representation is therefore
#
# a + bj.
z = a + 1j*b
print( "\nThe rectangular representation:" )
print( z )
# Thus, the mechanical conversion from polar to
# rectangular form is
#
# a = r*cos(theta)
#
# b = r*sin(theta)
#
# followed by
#
# z = a + bj.
#
# Equivalently, we can write this directly as
#
# z = r*cos(theta) + j*r*sin(theta)
#
# = r*(cos(theta) + j*sin(theta)).
z_trig = r*(
math.cos(theta) + 1j*math.sin(theta)
)
print( "\nUsing the trigonometric form:" )
print( z_trig )
# Recall Euler's formula:
#
# exp(j*theta)
#
# = cos(theta) + j*sin(theta).
#
# Therefore,
#
# r*(cos(theta) + j*sin(theta))
#
# = r*exp(j*theta).
#
# Consequently, our notation
#
# r phase theta
#
# represents exactly the same complex number as
#
# r*exp(j*theta).
#
# Thus,
#
# r phase theta
#
# = r*(cos(theta) + j*sin(theta))
#
# = r*exp(j*theta).
z_exp = r*cmath.exp(1j*theta)
print( "\nUsing r*exp(j*theta):" )
print( z_exp )
# The rectangular, trigonometric, exponential,
# and phase representations all describe the
# same complex number:
#
# a + bj
#
# r*(cos(theta) + j*sin(theta))
#
# r*exp(j*theta)
#
# r phase theta.
# Let us verify that converting from rectangular
# to polar and then back to rectangular returns
# the original complex number.
z = -2.5 + 6.3j
print( "\nOriginal rectangular value:" )
print( z )
# Rectangular to polar:
r = abs(z)
theta = cmath.phase(z)
print( "\nMagnitude:" )
print( r )
print( "\nArgument in radians:" )
print( theta )
print( "\nArgument in degrees:" )
print( math.degrees(theta) )
# Polar back to rectangular:
a = r*math.cos(theta)
b = r*math.sin(theta)
z_reconstructed = a + 1j*b
print( "\nReconstructed rectangular value:" )
print( z_reconstructed )
# We can also reconstruct the number directly
# from the exponential representation.
z_reconstructed_exp = r*cmath.exp(1j*theta)
print( "\nReconstructed using r*exp(j*theta):" )
print( z_reconstructed_exp )
# Apart from possible floating-point rounding,
# both reconstructed values equal the original
# complex number.
# Python's 'cmath' library also provides a
# function that performs the polar-to-
# rectangular conversion directly:
#
# cmath.rect(r, theta).
#
# It returns
#
# r*(cos(theta) + j*sin(theta)).
z_rect = cmath.rect(r, theta)
print( "\nUsing cmath.rect(r, theta):" )
print( z_rect )
# Similarly, cmath.polar(z) returns both the
# magnitude and principal argument:
#
# (r, theta).
polar = cmath.polar(z)
print( "\nUsing cmath.polar(z):" )
print( polar )
# The first value is the magnitude and the
# second is the principal argument.
print( "\nMagnitude from cmath.polar(z):" )
print( polar[0] )
print( "\nArgument from cmath.polar(z):" )
print( polar[1] )
# There is one important special case.
#
# If
#
# z = 0,
#
# then
#
# r = |z| = 0.
#
# However, the argument of zero is not
# mathematically defined.
#
# Python returns
print( "\ncmath.phase(0):" )
print( cmath.phase(0) )
# as a computational convention, but
# mathematically
#
# arg(0)
#
# is undefined because the zero vector has no
# direction.
# Finally, remember that arguments are not
# unique.
#
# If theta is an argument of a nonzero complex
# number, then
#
# theta + 2*k*pi
#
# is also an argument for every integer k.
#
# This follows because
#
# exp(j*(theta + 2*k*pi))
#
# = exp(j*theta)*exp(j*2*k*pi)
#
# = exp(j*theta).
#
# Python's cmath.phase(z) returns the principal
# argument.
#
# Thus, the central conversion formulas are:
#
# RECTANGULAR TO POLAR
#
# z = a + bj
#
# __________
# / 2 2
# r = |z| = / a + b
# V
#
# theta = atan2(b, a)
#
# or, directly in Python,
#
# r = abs(z)
# theta = cmath.phase(z)
#
# or
#
# r, theta = cmath.polar(z)
#
#
# POLAR TO RECTANGULAR
#
# z = r phase theta
#
# a = r*cos(theta)
# b = r*sin(theta)
#
# z = a + bj
#
# = r*(cos(theta) + j*sin(theta))
#
# = r*exp(j*theta)
#
# or, directly in Python,
#
# z = cmath.rect(r, theta).