Complex Numbers in Python – An Introduction

The Python language provides comprehensive support for complex numbers, with basic functionality being included with the core language and more advanced features included in the cmath module.

This article will demonstrate the basic operations such as arithmetic which does not require any additional modules. I will also go a bit further than that by writing code to carry out these operations without using the Python operators; of course you wouldn't do this in production code but it does provide an insight into how these operations and complex numbers in general work.

In this article I am assuming you know what a complex number is - if not please read the first few paragraphs of the Wikipedia article.

Python provides a complex type and the first bit of code shows how to create such a number. I'll then show how to perform arithmetic on these with the usual operators +, -, * and /. However, the underlying processes involved are not immediately obvious so we need to untangle them to gain a full understanding. Before starting to code I will show the actual formulae for addition, subtraction, multiplication and division. In each of these we have two complex numbers on the left of the = sign, with the +, -, * and / operations applied to them. The real and imaginary parts of each are labelled with subscript 1 and 2 so they can be identified in the part to the right of the = sign.

Addition and Subtraction

(a1 + bi1) + (a2 + bi2) = (a1 + a2) + (bi1 + bi2)
(a1 - bi1) + (a2 - bi2) = (a1 + a2) - (bi1 + bi2)

Multiplication

(a1 + bi1)(a2 + bi2) = (a1a2 - b1b2) + (a1b2 + b1a2)i

Division

(a1 + bi1) / (a2 + bi2) = ((a1 + b1)(a2 - bi2)) / ((a2 - bi2)(a2 + bi2))

Take a look at the boxes above to get a flavour of how the operators work but don't bother trying to memorize them as we'll see them implemented in code in a moment.

Coding

Create a new file called complexnumbersintro.py somewhere convenient. You can download the code from the Downloads page or clone/download from Github if you prefer. Open the file and type or paste the following:

complexnumbersintro.py

def main():

    """
    Call a few functions to demonstrate basic complex number handling.
    """

    print("---------------------------------\n| code-in-python.com            |\n| Complex Numbers: Introduction |\n---------------------------------")

    ccreation()

    caddition()
    csubtraction()
    cmultiplication()
    cdivision()

    cconjugate()
    cmagnitude()

#-----------------------------------------------------

def ccreation():

    """
    Demonstrate ways of creating complex numbers, also print the type.
    """

    print("\nCreation\n--------")

    z1 = 7 + 12j
    z2 = complex(14, 24)

    print(z1)
    print(z2)

    print(type(z1))

#-----------------------------------------------------

def caddition():

    """
    Demonstrate addition of complex numbers.
    """

    print("\nAddition\n--------")

    z1 = 7 + 12j
    z2 = 14 + 24j

    print("{} + {} = {}".format(z1, z2, z1+z2))

    print("({:g}+{:g}) + ({:g}j+{:g}j) = {}".format(z1.real, z2.real, z1.imag, z2.imag, complex(z1.real+z2.real, z1.imag+z2.imag)))

#-----------------------------------------------------

def csubtraction():

    """
    Demonstrate subtraction of complex numbers.
    """

    print("\nSubtraction\n----------")

    z1 = 10 + 6j
    z2 = 5 + 3j

    print("{} - {} = {}".format(z1, z2, z1-z2))

    print("({:g}-{:g}) + ({:g}j-{:g}j) = {}".format(z1.real, z2.real, z1.imag, z2.imag, complex(z1.real-z2.real, z1.imag-z2.imag)))

#-----------------------------------------------------

def cmultiplication():

    """
    Demonstrate multiplication of complex numbers.
    """

    print("\nMultiplication\n--------------")

    z1 = 3 + 2j
    z2 = 4 + 5j

    print("{} * {} = {}".format(z1, z2, z1*z2))

    print("({:g}*{:g} - {:g}*{:g}) + ({:g}*{:g} + {:g}*{:g})j = {}".format(z1.real, z2.real, z1.imag, z2.imag,
                                                                   z1.real, z2.imag, z1.imag, z2.real,
                                                                   complex(z1.real *z2.real - z1.imag * z2.imag, z1.real * z2.imag + z1.imag * z2.real)))

#-----------------------------------------------------

def cdivision():

    """
    Demonstrate division of complex numbers.
    """

    print("\nDivision\n--------")

    z1 = 4 + 7j
    z2 = 1 - 3j

    print("{} / {} = {}".format(z1, z2, z1/z2))

    numerator = z1*z2.conjugate()
    denominator = z2*z2.conjugate()
    quotientreal = numerator.real / denominator.real
    quotientimag = numerator.imag / denominator.real
    quotient = complex(quotientreal, quotientimag)

    print("({}{}) / ({}{})".format(z1, z2.conjugate(), z2, z2.conjugate()), end="")
    print(" = ({}/{}) + ({}/{})j".format(numerator.real, denominator.real, numerator.imag, denominator.real), end="")
    print(" = {}".format(quotient))

#-----------------------------------------------------

def cconjugate():

    """
    Demonstrate complex conjugate using the conjugate method and by reversing imaginary part.
    """

    print("\nConjugate\n---------")

    z = 44 + 22j

    print(z)
    print(z.conjugate())
    print(complex(z.real, z.imag * -1))

#-----------------------------------------------------

def cmagnitude():

    """
    Demonstrate magnitude using abs method and by calculation.
    """

    print("\nMagnitude\n---------")

    z = 9 + 12j

    print(z)
    print(abs(z))
    print((z.real ** 2 + z.imag ** 2) ** 0.5)

#-----------------------------------------------------

main()

Main

This program consists of seven functions to demonstrate basic complex number handling, and the main function simply call each of them.

Creation

There are actually two ways to create a complex number: you can assign real + imaginary to a variable with a j* suffix or call the complex function with the real and imaginary values. With the latter you do not need to use j. Here I have done both before printing them, and finally printed the type.

* Two letters are commonly used for imaginary numbers - i is used in mathematics but j is used in engineering as i refers to electrical current. Python uses j, presumably to emphasize its practical and applied nature. (I have no idea what controversy and argument this might have caused!)

Addition

As I mentioned above I will use Python's operators for all arithmetic and other operations and also implement the processes manually just to demonstrate them.

After creating a couple of complex numbers I first print them along with their sum using the + operator. Then I carry out essentially the same process again by implementing the addition formula shown earlier.

Note here that the complex type provides the real and imag values as attributes.

Subtraction

This is almost a clone of the addition function, the only difference being the use of - instead of + for the calculations. Don't change the + signs within the complex numbers themselves!

Multiplication

Using the * operator is again straightforward, but the manual implementation of the above formula is rather more involved.

Division

This is the most complicated of the lot, so much so that I have split it out into several operations rather than cram them all into a string format statement.

Conjugate

The complex conjugate is simply a complex number with the sign of the imaginary part reversed. Python provides a conjugate method to do this, but here I have also carried out the process manually by multiplying the imaginary part by -1.

Magnitude

If you imagine a complex number as being the coordinates of a point then the magnitude of the complex number is the straight line distance from the origin 0,0 to the point. In a future post I will create an Argand Diagram which plots complex numbers in just this way.

The line from the origin to the point forms the hypotenuse of a right angled triangle and, as everyone knows, "the square on the hypotenuse is equal to the sum of the squares on the other two sides." The proper way to calculate the magnitude is with Python's abs() function but I have also done it the Pythagoras way: add the squares of the real and imaginary parts, and then take the square root.

That's the code finished so run it with this command.

Running the program

python3.6 main.py

The output is

Program Output

---------------------------------
| code-in-python.com            |
| Complex Numbers: Introduction |
---------------------------------

Creation
--------
(7+12j)
(14+24j)
<class 'complex'>

Addition
--------
(7+12j) + (14+24j) = (21+36j)
(7+14) + (12j+24j) = (21+36j)

Subtraction
----------
(10+6j) - (5+3j) = (5+3j)
(10-5) + (6j-3j) = (5+3j)

Multiplication
--------------
(3+2j) * (4+5j) = (2+23j)
(3*4 - 2*5) + (3*5 + 2*4)j = (2+23j)

Division
--------
(4+7j) / (1-3j) = (-1.7+1.9j)
((4+7j)(1+3j)) / ((1-3j)(1+3j)) = (-17.0/10.0) + (19.0/10.0)j = (-1.7+1.9j)

Conjugate
---------
(44+22j)
(44-22j)
(44-22j)

Magnitude
---------
(9+12j)
15.0
15.0

Under the Creation heading we just see the two complex numbers we created as well as their type.

The Addition, Subtraction, Multiplication and Division sections all have two lines, the first using the +, -, * and / operators and the second showing the actual arithmetic performed on the real and imaginary parts of the complex numbers to get the end result. For example, to add two complex numbers we add the real parts to get the real value of the sum, and add the imaginary parts to get the imaginary parts of the sum. Subtraction is similar but of course we subtract the relevant values. Multiplication and division are more involved and you might like to study the steps if you interested.

Under the Conjugate heading we see the original number and then its conjugate twice, firstly calculated using the conjugate() function and then calculated by multiplying the imaginary part by -1. Finally under Magnitude we see a complex number and its magnitude, firstly calculated using abs() and then using Pythagoras's Theorem.

That's the end of my introduction to complex numbers in Python but as I mentioned above I will also be writing posts on Argand diagrams which plot complex numbers, and will also write a post on the more advanced functions found in the cmath module.