Welcome, guest | Sign In | My Account | Store | Cart

Python offers a powerful data type for complex numbers in Cartesian form. Unfortunately, python does not offer support for complex numbers in polar form. This recipe contains a class that supports complex numbers in both Cartesian and polar form, and allows for arithmetic that mixes both forms.

Python, 83 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import math as m
import cmath as c

class Complex:
    """
      Author: César Otero
      Description: A complex number class which can do complex arithmetic
                   in both Cartesian and polar coordinates, or a mix of the two
    """
  
    def __init__(self, num=0, phase=0):
        if type(num) == complex:
            # cnum is in Cartesian form
            self.cnum      = num
            self.magnitude = abs(num)
            phaseRad = m.atan2(num.imag, num.real)
            self.phase     = m.degrees(phaseRad)
            
        else:
            # cnum is in polar form
            self.cnum      = m.cos(phase) + complex(0,m.sin(phase))
            self.magnitude = num
            self.phase     = phase

    def __str__(self):
        return str(self.magnitude) + " /_ (" + str(self.phase) + ") deg"

    def __add__(self,n):
        if type(n) == int:
            re = self.cnum.real + n
            im = self.cnum.imag
        elif type(n) == float:
            re = self.cnum.real + n
            im = self.cnum.imag
        else:
            re = self.cnum.real + n.cnum.real
            im = self.cnum.imag + n.cnum.imag
            
        z = re+complex(0,im)
        return Complex(z)
    
    def __radd__(self,n):
        if type(n) == int:
            re = self.cnum.real + n
            im = self.cnum.imag
        elif type(n) == float:
            re = self.cnum.real + n
            im = self.cnum.imag
        else:
            re = self.cnum.real + n.cnum.real
            im = self.cnum.imag + n.cnum.imag
            
        z = re+complex(0,im)
        return Complex(z)

    def __div__(self,n):
        magnitude = self.magnitude / n.magnitude
        phase = self.phase - n.phase
        return Complex(magnitude, phase)

    def __rdiv__(self,n):
        magnitude = n.magnitude / self.magnitude
        phase = n.phase - self.phase 
        return Complex(magnitude, phase)

if __name__=="__main__":
        ----------r=90 Ohms--------L = 160j Ohms ----------|        
        |                                                                            
      pSource = 750 /_ 30 deg                             C = -40j Ohms
        |                     |                                                                                                                                                                   
        |--------------------------------------------------|                
    
    pSource = Complex(750,30) # power source, in polar form 
                              # with a magnitude of 750 volts, and angle of 30 
                              # degrees.
    r = 90                    # Ohms ( real part only )
    L = Complex(0+160j)       # Ohms ( Cartesian form )
    C = Complex(0-40j)        # Ohms ( Cartesian form )
    Z = r+L+C                 # total impedance    
    print "Impedance is ", Z
    
    I = pSource / Z
    print "Phase current is ", I
    

In some engineering and scientific applications it is useful to represent complex numbers in polar form, or mix polar form complex numbers with Cartesian form without having to worry about the details of converting from one type to the other before doing any arithmetic. This ability is inherit in other languages such as Matlab or IDL. This recipe is useful for extending python to be able to handle these types of calculations.

A better implementation could be achieved by inheriting directly from the python complex type.

1 comment

Akira Fora 16 years, 3 months ago  # | flag

Lots of code for nothing. A common (the most common, as far as I know) way to write complex numbers in polar form is:

mag*pow(e,j*phase)                    (MathML support would be nice here)

were mag is the magnitude, e is the Neperian constant, phase is the phase in radian. This writing is allowed in Python. See the following code:

def mainWithNativeComplex():
    pSource = 750*e**(1j*pi/6)# power source, in polar form
                              # with a magnitude of 750 volts, and angle of 30
                              # degrees (pi/6 radians).
    r = 90                    # Ohms ( real part only )
    L = 0+160j                # Ohms ( Cartesian form )
    C = 0-40j                 # Ohms ( Cartesian form )
    Z = r+L+C                 # total impedance
    print "Impedance is ", Z, "(mag=", abs(Z), "; phase=", m.degrees(m.atan2(Z.imag, Z.real)), ")"

    I = pSource / Z
    print "Phase current is ", I, "(mag=", abs(I), "; phase=", m.degrees(m.atan2(I.imag, I.real)), ")"

The only lack in the native type is that you have to compute the phase by yourself. You may want to write a 1 line function for this, but certainly not a 50 lines class.

Created by cesar otero on Sat, 5 Jan 2008 (PSF)
Python recipes (4591)
cesar otero's recipes (2)

Required Modules

  • (none specified)

Other Information and Tasks