## Exploring Python Complex Numbers

Have you ever come across mathematical equations that involve the square root of a negative number? Do you remember being told in school that this is impossible in the world of real numbers?

Well, not anymore! Welcome to the fascinating world of complex numbers. In Python, complex numbers are a fundamental data type that represents a number in the form a + bj, where a and b are real numbers, and j is the imaginary unit.

In this article, we will explore how to create complex numbers, access their real and imaginary parts, calculate their conjugate, and more.

## Creating Complex Numbers in Python

There are two ways to create complex numbers in Python. The first is by using the complex number literal.

You can simply write a complex number in the algebraic form a + bj and assign it to a variable. Here’s an example:

`z = 2 + 3j`

In this example, z is a complex number with a real part of 2 and an imaginary part of 3.

The second way to create complex numbers in Python is by using the complex() factory function. This function takes two numeric parameters, a and b, representing the real and imaginary parts, respectively.

Here’s an example:

`z = complex(2, 3)`

In this example, z is also a complex number with a real part of 2 and an imaginary part of 3. Note that the complex() function automatically type-casts its arguments to the appropriate data type.

## Getting to Know Python Complex Numbers

Now that we know how to create complex numbers, let’s explore some of their properties.

### Accessing Real and Imaginary Parts

To access the real and imaginary parts of a complex number, we can use the attribute notation z.real and z.imag, respectively. Here’s an example:

```
z = complex(2, 3)
print(z.real) # Output: 2.0
print(z.imag) # Output: 3.0
```

As you can see, z.real returns the real part of z, which is 2.0, and z.imag returns the imaginary part of z, which is 3.0.

### Calculating the Conjugate of a Complex Number

The conjugate of a complex number is obtained by changing the sign of its imaginary part. In Python, we can calculate the conjugate of a complex number z using the conjugate() method.

Here’s an example:

```
z = complex(2, 3)
z_conj = z.conjugate()
print(z_conj) # Output: (2-3j)
```

As you can see, the conjugate() method returns a new complex number with the same real part as z and the opposite sign of the imaginary part.

## Conclusion

In this article, we explored the fundamentals of complex numbers in Python. We learned how to create complex numbers using both literal notation and the complex() factory function.

Additionally, we looked at some of the properties of complex numbers such as how to access their real and imaginary parts and how to calculate their conjugate. With this knowledge, you can now start exploring more advanced topics in mathematics and programming.

Happy coding!

## Complex Numbers Arithmetic

Now that we know how to create and access complex numbers, let’s explore how to perform arithmetic operations on them. In Python, complex numbers behave like any other number type, and so we can use the familiar mathematical operators such as +, -, *, / and ** to manipulate them.

### Addition

To add two complex numbers, we simply add their real parts and imaginary parts separately. Here’s an example:

```
z1 = complex(2, 3)
z2 = complex(4, 5)
z_sum = z1 + z2
print(z_sum) # Output: (6+8j)
```

As you can see, the resulting complex number is the sum of its real and imaginary parts.

### Subtraction

Subtracting two complex numbers follows the same pattern as addition, but we subtract the real and imaginary parts separately. Here’s an example:

```
z1 = complex(2, 3)
z2 = complex(4, 5)
z_diff = z1 - z2
print(z_diff) # Output: (-2-2j)
```

As you can see, the resulting complex number is the difference between the real and imaginary parts separately.

### Multiplication

To multiply two complex numbers, we use the complex multiplication formula:

`(a + bj) * (c + dj) = (ac - bd) + (ad + bc)j`

Here’s an example of how to multiply two complex numbers in Python:

```
z1 = complex(2, 3)
z2 = complex(4, 5)
z_prod = z1 * z2
print(z_prod) # Output: (-7+22j)
```

As you can see, the resulting complex number is calculated using the formula above.

### Division

Dividing two complex numbers is also possible in Python. However, we cannot divide by zero, since that results in a mathematical error.

Here’s an example:

```
z1 = complex(2, 3)
z2 = complex(4, 5)
z_quot = z1 / z2
print(z_quot) # Output: (0.5609756097560976+0.0487804878048781j)
```

Note that the resulting complex number is in the form (x + yj), where x and y are real numbers and y is not zero. We can also use the modulus operator (%) to get the remainder of a complex division.

### Exponentiation

Python has a binary exponentiation operator (**) that we can use with complex numbers to raise them to a power. Here’s an example:

```
z1 = complex(2, 3)
z_pow = z1 ** 2
print(z_pow) # Output: (-5+12j)
```

Alternatively, we can use the built-in pow() function to raise a complex number to a power.

Here’s an example:

```
z1 = complex(2, 3)
z_pow = pow(z1, 2)
print(z_pow) # Output: (-5+12j)
```

## Using Python Complex Numbers as 2D Vectors

In addition to being used as mathematical objects, complex numbers can also be used to represent 2D vectors in a Cartesian coordinate system. In this context, the real and imaginary parts of the complex number represent the coordinates of the vector in the x and y axes, respectively.

Let’s explore some of the properties of complex numbers as vectors.

### Getting the Coordinates

To get the coordinates of a complex number z in a Cartesian coordinate system, we simply use its real and imaginary parts as the x and y coordinates, respectively. Here’s an example:

```
z = complex(2, 3)
x = z.real
y = z.imag
print("The coordinates of z are ({}, {})".format(x, y)) # Output: The coordinates of z are (2.0, 3.0)
```

Note that the coordinates can be fractional numbers.

### Calculating the Magnitude

The magnitude of a complex number is equivalent to the length of its corresponding vector in the Cartesian coordinate system. We can easily calculate the magnitude of a complex number using the Pythagorean theorem:

`magnitude = ((real_part ** 2) + (imag_part ** 2)) ** 0.5`

Here’s an example of how to calculate the magnitude:

```
z = complex(2, 3)
magnitude = abs(z)
print("The magnitude of z is {}".format(magnitude)) # Output: The magnitude of z is 3.605551275463989
```

### Finding the Distance Between Two Points

If we have two complex numbers z1 and z2, we can use them to represent two points in a Cartesian coordinate system and find the distance between them using the Pythagorean theorem. Here’s an example:

```
z1 = complex(2, 3)
z2 = complex(4, 6)
distance = abs(z1 - z2)
print("The distance between z1 and z2 is {}".format(distance)) # Output: The distance between z1 and z2 is 3.1622776601683795
```

Translating, Flipping, Scaling, and Rotating

We can also use the properties of complex numbers to perform transformations on vectors in a Cartesian coordinate system.

These transformations include translating (shifting), flipping, scaling, and rotating vectors. To perform these transformations, we simply manipulate the real and imaginary parts of the complex number.

### Here are some examples:

```
z = complex(2, 3)
# Translating (shifting) vector by (4, -2)
z_new = z + complex(4, -2)
print("The new vector after translation is {}".format(z_new)) # Output: The new vector after translation is (6+1j)
# Flipping vector across x-axis
z_new = complex(z.real, -z.imag)
print("The new vector after flipping across x-axis is {}".format(z_new)) # Output: The new vector after flipping across x-axis is (2-3j)
# Scaling vector by a factor of 2
z_new = z * 2
print("The new vector after scaling is {}".format(z_new)) # Output: The new vector after scaling is (4+6j)
# Rotating vector by 90 degrees counter-clockwise
z_new = complex(-z.imag, z.real)
print("The new vector after rotating is {}".format(z_new)) # Output: The new vector after rotating is (-3+2j)
```

These transformations can be combined to create more complex transformations, such as rotating and scaling a vector, and then flipping it across the x-axis.

## Conclusion

In this article, we explored the arithmetic operations on complex numbers in Python, including addition, subtraction, multiplication, division, and exponentiation. We also explored the properties of complex numbers as 2D vectors, including getting their coordinates, calculating their magnitude, finding the distance between two points, and performing transformations such as translating, flipping, scaling, and rotating.

With this knowledge, you can now start visualizing mathematical concepts and exploring a wide range of applications across multiple fields. Exploring Complex Numbers in Python: Part 2

In the previous article, we explored the fundamentals of complex numbers in Python, and how we can use them as 2D vectors in a Cartesian coordinate system.

In this article, we will explore complex numbers in more depth, starting with the math module and how we can use it with complex numbers. Exploring the Math Module for Complex Numbers: cmath

The math module in Python provides an extensive range of mathematical functions that we can use with real numbers.

However, this module is not designed to work with complex numbers. To work with complex numbers in Python, we need to use the cmath module instead.

This module provides the same functions as the math module but extends them to work with complex numbers. Here are some examples of how we can use the cmath module with complex numbers.

### Extracting the Root of a Complex Number

To extract the root of a complex number, we can use the cmath.sqrt() function. This function returns the square root of a complex number, which is also a complex number.

Here’s an example:

```
import cmath
z = complex(2, 3)
z_root = cmath.sqrt(z)
print("The square root of z is {}".format(z_root)) # Output: The square root of z is (1.6741492280355401+0.8959774761298381j)
```

Note that the output is a complex number that represents the square root of the original complex number.

### Converting Between Rectangular and Polar Coordinates

We can also convert between rectangular and polar coordinates using the cmath module. To convert a complex number from rectangular coordinates to polar coordinates, we use the cmath.polar() function.

This function returns a tuple of the magnitude and phase angle of the complex number. Here’s an example:

```
z = complex(2, 3)
z_polar = cmath.polar(z)
print("The polar coordinates of z are {}".format(z_polar)) # Output: The polar coordinates of z are (3.605551275463989, 0.982793723247329)
```

To convert a complex number from polar coordinates to rectangular coordinates, we use the cmath.rect() function.

This function takes the magnitude and phase angle of the complex number as its arguments and returns a new complex number in rectangular coordinates. Here’s an example:

```
magnitude = 3.605551275463989
phase_angle = 0.982793723247329
z_rect = cmath.rect(magnitude, phase_angle)
print("The rectangular coordinates of z are {}".format(z_rect)) # Output: The rectangular coordinates of z are (2+2.9999999999999982j)
```

Note that the output is a complex number in rectangular coordinates that represents the original complex number.

### Representing Complex Numbers Differently

Complex numbers can also be represented differently using the cmath module. In addition to the algebraic form a + bj, and the polar form r(cos + jsin), we can also represent complex numbers in exponential form re^(j).

To represent a complex number in exponential form, we use the cmath.exp() function. Here’s an example:

```
z = complex(2, 3)
z_exp = cmath.exp(z)
print("The exponential form of z is {}".format(z_exp)) # Output: The exponential form of z is (-7.315110094901006+1.0427436562359042j)
```

Note that the output is a complex number in exponential form that represents the original complex number.

### Creating Your Own Complex Data Type

Python comes with a built-in complex data type, but sometimes we might need to create our own complex data types to suit our specific needs. In this section, we will explore some advanced topics related to complex numbers in Python, including the discrete Fourier transform, dissecting a complex number, testing equality of complex numbers, ordering complex numbers, and formatting complex numbers as strings.

### Calculating the Discrete Fourier Transform With Complex Numbers

The discrete Fourier transform (DFT) is a mathematical technique that transforms a finite sequence of discrete data points into a sequence of complex numbers, which represent the frequency components of the original sequence. We can use complex numbers in Python to calculate the DFT efficiently, using the fast Fourier transform (FFT) algorithm provided by the numpy module.

Here’s an example of how to calculate the DFT of a sequence of data points:

```
import numpy as np
data = [2, 3, 4, 5]
data_fft = np.fft.fft(data)
print("The DFT of the data is {}".format(data_fft)) # Output: The DFT of the data is [14.+0.j -2.+2.j -2.+0.j -2.-2.j]
```

Note that the output is a sequence of complex numbers that represents the frequency components of the original data points.

### Dissecting a Complex Number in Python

Complex numbers in Python are represented by two attributes, real and imag, which represent the real and imaginary parts of the complex number, respectively. In addition to these attributes, there are many other methods that we can use to dissect a complex number and extract useful information from it.

### Here are some examples:

```
z = complex(2, 3)
# Getting the magnitude of z
magnitude = abs(z)
print("The magnitude of z is {}".format(magnitude)) # Output: The magnitude of z is 3.605551275463989
# Getting the phase angle of z
phase_angle = cmath.phase(z)
print("The phase angle of z is {}".format(phase_angle)) # Output: The phase angle
```