x, int newSize) {
if (x.size() < newSize) {
int diff = newSize - x.size();
for (int i = 0; i < diff; i++) x.add(new FFT.Complex());
}
}
/**
* Discrete circular convolution function. It uses the convolution theorem for discrete signals:
* convolved = IDFT(DFT(a)*DFT(b)). Then we use the FFT algorithm for faster calculations of the
* two DFTs and the final IDFT.
*
* More info: https://en.wikipedia.org/wiki/Convolution_theorem
*
* @param a The first signal.
* @param b The other signal.
* @return The convolved signal.
*/
public static ArrayList fftCircularConvolution(
ArrayList a, ArrayList b) {
int convolvedSize =
Math.max(
a.size(), b.size()); // The two signals must have the same size equal to the bigger one
padding(a, convolvedSize); // Zero padding the smaller signal
padding(b, convolvedSize);
/* Find the FFTs of both signal. Here we use the Bluestein algorithm because we want the FFT to have the same length with the signal and not bigger */
FFTBluestein.fftBluestein(a, false);
FFTBluestein.fftBluestein(b, false);
ArrayList convolved = new ArrayList<>();
for (int i = 0; i < a.size(); i++) convolved.add(a.get(i).multiply(b.get(i))); // FFT(a)*FFT(b)
FFTBluestein.fftBluestein(convolved, true); // IFFT
return convolved;
}
}