Range Compression Tutorial#
This tutorial demonstrates how to perform Fast Fourier Transform (FFT) based range compression using the sarcomp library. We will generate a 2D complex array and perform forward FFT, multiply it by a 1D vector (representing the range compression function), and then perform the inverse FFT to compress the range.
Setup#
To run this tutorial, make sure you have the sarcomp package installed along with its dependencies, such as numpy.
Example Code#
import numpy as np
from sarcomp import fft, math
def generate_data(nx, ny):
# Define the shape of the array
if nx == 1:
shape = (ny,)
else:
shape = (nx, ny)
real_part = np.random.rand(*shape).astype(np.float32)
imaginary_part = np.random.rand(*shape).astype(np.float32)
complex_array = np.complex64(real_part + 1j * imaginary_part)
return complex_array
# Generate a test signal
az_samples = 1024
rg_samples = 8192
matrix = generate_data(az_samples, rg_samples)
vector = generate_data(1, rg_samples)
# Create FFT plans
fft_plan0 = fft.fft(shape=(az_samples, rg_samples), dtype='c8', axis=1) # Forward FFT plan
fft_plan1 = fft.ifft(shape=(az_samples, rg_samples), dtype='c8', axis=1) # Backward FFT plan
### Range Compression
fft_plan0(matrix)
math.mul(matrix, vector)
fft_plan1(matrix)
print('Done...')
Explanation#
Data Generation: - The function generate_data(nx, ny) generates a complex array with the specified shape by combining random real and imaginary components. The output array is in the complex64 format.
FFT Plan Creation: - fft.fft(shape=(az_samples, rg_samples), dtype=’c8’, axis=1) creates a forward FFT plan for processing the signal along the second axis (range axis). - fft.ifft(shape=(az_samples, rg_samples), dtype=’c8’, axis=1) creates an inverse FFT plan for processing the signal.
Range Compression: - The matrix undergoes a forward FFT using fft_plan0(matrix). - It is then multiplied by the range compression vector using math.mul(matrix, vector). - Finally, the inverse FFT is applied using fft_plan1(matrix) to compress the range.
Example Code with Zero-Padding#
Zero-padding is often used to improve FFT performance by increasing the array size to the next power of two.
import numpy as np
from sarcomp import fft, math, memory
def generate_data(nx, ny):
# Define the shape of the array
if nx == 1:
shape = (ny,)
else:
shape = (nx, ny)
real_part = np.random.rand(*shape).astype(np.float32)
imaginary_part = np.random.rand(*shape).astype(np.float32)
complex_array = np.complex64(real_part + 1j * imaginary_part)
return complex_array
# Generate a test signal
az_samples = 1024
rg_samples = 8000
matrix = generate_data(az_samples, rg_samples)
vector = generate_data(1, rg_samples)
# Zero-padding the matrix and vector
matrix_zpf = memory.copy(matrix, p2=True, axis=1) # Zero-pad along the range axis (axis=1)
vector_zpf = memory.copy(vector, p2=True) # Zero-pad along the range axis
rg_samples_zpf = matrix_zpf.shape[1]
# Create FFT plans for the zero-padded data
fft_plan0 = fft.fft(shape=(az_samples, rg_samples_zpf), dtype='c8', axis=1) # Forward FFT plan
fft_plan1 = fft.ifft(shape=(az_samples, rg_samples_zpf), dtype='c8', axis=1) # Backward FFT plan
### Range Compression
fft_plan0(matrix_zpf)
math.mul(matrix_zpf, vector_zpf)
fft_plan1(matrix_zpf)
print('Done...')
Explanation for Zero-Padding#
In this example, we use zero-padding to increase the size of the range dimension (axis 1) to the next power of two, which often improves the efficiency of FFT operations. The memory.copy function is used to create zero-padded copies of the original matrix and vector. The FFT plans are then adjusted to account for the padded shape.