NumPy – Using conj() and conjugate() functions (4 examples)

Updated: February 28, 2024 By: Guest Contributor Post a comment

Understanding complex numbers and operations on them is crucial in various scientific and engineering applications. NumPy, a fundamental package for numerical computing in Python, offers a straightforward and efficient way to work with complex numbers, among other functionalities. This guide delves into the usage of conj() and conjugate() functions in NumPy, elucidating their applications with four practical examples, ranging from basic to advanced.

Introduction to Complex Numbers in NumPy

Before diving into the conj() and conjugate() functions, it’s essential to understand what complex numbers are. A complex number consists of a real part and an imaginary part. It is usually expressed as a + bj, where a is the real part, b is the imaginary part, and j (or i in mathematics) is the square root of -1. In NumPy, complex numbers are supported natively, and you can create a complex array as follows:

import numpy as np

a = np.array([1+2j, 3+4j, 5+6j])
print(a)

The output will be something like:

[1.+2.j 3.+4.j 5.+6.j]

Basic Usage of conj() and conjugate()

Both conj() and conjugate() functions are used to calculate the complex conjugate of complex numbers in a NumPy array. The complex conjugate of a complex number is obtained by changing the sign of its imaginary part. The syntax for these functions is identical:

import numpy as np

# Using conj()
a = np.array([1+2j, 3+4j])
print(np.conj(a))

# Using conjugate()
b = np.array([1-2j, 3-4j])
print(np.conjugate(b))

The output for both commands will display the complex conjugates:

[1.-2.j  3.-4.j]
[1.+2.j  3.+4.j]

Example 1: Using conj() in a Vectorized Manner

NumPy allows for vectorization, which means operations can be broadcast across all elements of an array without the need for explicit loops. This makes NumPy highly efficient, especially for large datasets. Let’s apply the conj() function on a 2D array to illustrate this concept:

import numpy as np

matrix = np.array([[1+2j, 3 + 4j], [5+6j, 7+8j]])
conjugate_matrix = np.conj(matrix)
print(conjugate_matrix)

The output will be:

[[1.-2.j  3.-4.j]
 [5.-6.j  7.-8.j]]

Example 2: Complex Conjugation in Mathematical Operations

Applying the complex conjugate can be particularly useful in mathematical operations involving complex numbers, such as vector dot products and calculating magnitudes. Here’s how to use it in a dot product calculation:

import numpy as np

v1 = np.array([1+2j, 3+4j])
v2 = np.array([5+6j, 7+8j])
dot_product = np.vdot(v1, np.conj(v2))
print(dot_product)

The output reveals the dot product considering the complex conjugates of the second vector:

100.0+20.0j

Example 3: Using conj() With Linear Algebra

NumPy’s conj() function can also support various linear algebra applications. For instance, when you’re dealing with Hermitian matrices (a matrix that is equal to its complex conjugate transpose), calculating the matrix’s determinant or eigenvalues can require the use of the complex conjugate:

import numpy as np

matrix = np.array([[1+2j, 3+4j], [3-4j, 1-2j]])
det = np.linalg.det(np.conj(matrix))
eigenvalues, eigenvectors = np.linalg.eig(np.conj(matrix))

print("Determinant: ", det)
print("Eigenvalues: ", eigenvalues)


This code snippet prints the determinant and eigenvalues considering the conjugated matrix, demonstrating how conj() can be seamlessly integrated into linear algebra operations.

Output:

Determinant:  (-19.999999999999996+0j)
Eigenvalues:  [ 5.58257569+1.17543480e-16j -3.58257569+2.12343977e-17j]

Example 4: Conjugate and Fourier Transforms

Complex conjugation plays an important role in signal processing, particularly in the context of Fourier transforms. When applied, the conj() function can help in computing the inverse Fourier transform implicitly. Here is an example of how it is applied in the calculation of a Fourier transform and its inverse:

import numpy as np

signal = np.array([1+0j, 0+1j, -1+0j, 0-1j])
fft = np.fft.fft(signal)
inverse_fft = np.fft.ifft(np.conj(fft))

print("FFT:", fft)
print("Inverse FFT:", inverse_fft)

Output:

FFT: [0.+0.j 4.+0.j 0.+0.j 0.+0.j]
Inverse FFT: [ 1.-0.j  0.+1.j -1.+0.j  0.-1.j]

Note, however, that this method might return complex values due to numerical inaccuracies, which are typical in floating-point computations.

Conclusion

The conj() and conjugate() functions in NumPy offer powerful tools to manipulate complex numbers, especially beneficial in fields like engineering, physics, and mathematics. Through the examples demonstrated, one can appreciate these functions’ versatility in vectorized operations, mathematical operations, linear algebra, and signal processing. Grasping these concepts allows for more efficient and scalable data analysis and scientific computing endeavors.