Complex numbers are an extension of the real numbers, consisting of a real and an imaginary part. They are useful in many mathematical and scientific applications, including electrical engineering, physics, and signal processing. In this post, we will explore complex numbers and how to work with them in Python.

## Introduction to Complex Numbers

One area where complex numbers are particularly useful, and where learners often first encounter them, is in solving quadratic equations where the discriminant is negative.

Recall that the discriminant of a quadratic equation of the form ax^2 + bx + c = 0 is given by b^2 – 4ac. If the discriminant is negative, then the quadratic equation has no real solutions. However, by introducing complex numbers, we can still find solutions to the equation.

To illustrate this, let’s consider the quadratic equation x^2 + x + 1 = 0. The discriminant of this equation is 1 – 4(1)(1) = -3, which is negative. Therefore, the equation has no real solutions.

However, if we allow for complex solutions, we can find the solutions to this equation using the quadratic formula with complex numbers. The solutions are given by:

x = (-1 ± sqrt(3)i) / 2

where i is the imaginary unit.

A complex number is a number of the form a + bi, where a and b are real numbers and i is the imaginary unit, which is defined as the square root of -1. The real part a represents the horizontal axis of the complex plane, while the imaginary part b represents the vertical axis.

## Representing Complex Numbers with Python

In Python, we can create a complex number by using the `complex()`

function, or by expressing it directly as a literal. For example:

```
z1 = complex(2, 3)
z2 = 1 - 2j
print(z1, z2)
```

Output:

```
(2+3j) (1-2j)
```

Impressively, Python knows what `2 + 3j`

means. In Python, the imaginary unit is represented by the letter j (to avoid confusion with i, which is commonly used to represent electrical current in engineering). When you use the `j`

notation in a mathematical expression, Python interprets it as the imaginary unit and performs the appropriate calculations.

For example, in the expression `2 + 3j`

, `2`

is the real part and `3j`

is the imaginary part. Python knows how to handle the `j`

notation as the imaginary unit and can perform operations with complex numbers accordingly.

## Basic Operations with Complex Numbers in Python

We can perform basic arithmetic operations on complex numbers, such as addition, subtraction, multiplication, and division. These operations are defined element-wise, just like with real numbers. For example:

```
z1 = 2 + 3j
z2 = 1 - 2j
print(z1 + z2) # Output: (3+1j)
print(z1 - z2) # Output: (1+5j)
print(z1 * z2) # Output: (8-1j)
print(z1 / z2) # Output: (-0.4+1.6j)
```

We can also compute the conjugate of a complex number, which is obtained by changing the sign of its imaginary part. This operation is denoted by a bar above the number. For example:

```
z = 2 + 3j
print(z.conjugate()) # Output: (2-3j)
```

## Plotting Complex Numbers with Python

Complex numbers can be visualized in the complex plane, where the real part represents the x-axis and the imaginary part represents the y-axis. We can use Python to plot complex numbers and see their geometric properties.

To do this, we first need to import the matplotlib library, which provides a wide range of plotting tools. Then, we can create a scatter plot of complex numbers by passing their real and imaginary parts as the x and y coordinates, respectively. For example:

```
import numpy as np
import matplotlib.pyplot as plt
# Create an array of complex numbers
c = np.array([1+2j, 3-4j, -2+1j, 0-3j])
# Plot the real and imaginary parts of the complex numbers
plt.scatter(c.real, c.imag, color='blue')
# Set the plot title and axis labels
plt.title('Plot of Complex Numbers')
plt.xlabel('Real Part')
plt.ylabel('Imaginary Part')
# Show the plot
plt.show()
```

This will produce a scatter plot of the complex numbers `1+2j`

, `3-4j`

, `-2+1j`

, `0-3j`

, with the real part on the x-axis and the imaginary part on the y-axis.

### Python Complex Numbers with the `cmath`

Module

Suppose we want to solve the quadratic equation ax^2 + bx + c = 0, where a, b, and c are real coefficients. If the discriminant b^2 – 4ac is negative, then the roots of the equation are complex numbers.

We can use the formula for complex roots to find the two complex solutions:

x = (-b ± √(b^2 – 4ac))/(2a)

For example, let’s consider the equation x^2 + 4x + 5 = 0. Here, a = 1, b = 4, and c = 5. Plugging these values into the formula, we get:

x = (-4 ± √(4^2 – 4(1)(5)))/(2(1)) x = (-4 ± √(-4))/2

Since the discriminant is negative, we have a complex solution:

x = (-4 ± 2i)/2

Simplifying the fraction, we get:

x = -2 ± i

Therefore, the solutions to the equation x^2 + 4x + 5 = 0 are -2 + i and -2 – i.

We can also use Python’s `cmath`

module to find the solutions to quadratic equations with complex roots. Check out the code below.

```
import cmath
a = 1
b = 4
c = 5
# calculate the discriminant
discriminant = cmath.sqrt(b**2 - 4*a*c)
# calculate the two solutions
solution1 = (-b - discriminant) / (2*a)
solution2 = (-b + discriminant) / (2*a)
print("The solutions are:")
print(solution1)
print(solution2)
```

This code uses the cmath module, which provides functions for working with complex numbers. We first calculate the discriminant, which involves taking the square root of a negative number. By using `cmath.sqrt`

instead of the built-in `sqrt`

function, we are able to handle complex numbers properly.

Running this code gives us the same solutions as before:

```
(-2+1j)
(-2-1j)
```

Pretty neat huh?

This article has discussed complex numbers and how to work with them in Python. Complex numbers are a powerful mathematical tool that have many applications in science, engineering, and computer science. Python provides built-in support for working with complex numbers, making it easy to explore these concepts and solve problems involving them.

Happy computing!