I have assembled a little python script that displays @Marcus's solution. I wanted to share this as proof of concept on how this works for anyone that is stuck on the same problem that I was.
The reason I need to use four separate channels is because I am working on an FPGA implementation that includes an FFT. I cannot choose an implementation that processes data in parallel but the data that I get always arrives in packets of 4.
Any improvements to this method are appreciated
from numpy.fft import fft, fftshift
import numpy as np
import matplotlib.pyplot as plt
size = 2048
n = np.arange(size)
x = np.e ** (-2j * np.pi * 0.3 * n) # some arbitrary data
N = 4 # the amount of channels
x_i = [x[idx::N] for idx in range(N)] # The data, rearranged for the channels
def bf_2(even, odd):
"""
2-point butterfly implementation
"""
points = len(even) + len(odd)
def w(k):
return np.e ** (-2j * np.pi * k / points)
twiddles = w(np.arange(points/2))
odd = odd * twiddles
even_ret = even + odd
odd_ret = even - odd
return np.concatenate([even_ret, odd_ret])
def bf_4(x0, x1, x2, x3):
"""
four-point butterfly implementation
"""
res_1 = bf_2(x0, x2) # equivalent to bit-reverse ordering
res_2 = bf_2(x1, x3) # equivalent to bit-reverse ordering
return bf_2(res_1, res_2)
# Compute four separate FFT's
A_i = map(fft, x_i)
# And re-assemble them using the butterfly-structure
x_restored = bf_4(*A_i)
mag = np.abs(x_restored)
f = np.linspace(-0.5, 0.5, len(mag))
plt.plot(f, fftshift(mag))
plt.show()