一、功能
用快速傅里葉變換計算兩個有限長序列的快速卷積。
二、方法簡介
設序列\(x(n)\)的長度為\(M\),序列\(y(n)\)的長度為\(N\),序列\(x(n)\)與\(y(n)\)的線性卷積定義為
\[z(n)=\sum_{i=0}^{M-1}x(i)y(n-i) \ , \ n=0,1,...,M+N-2 \]
用快速傅里葉變換計算線性卷積的算法如下
1、選擇\(L\)滿足下述條件
\[\left\{\begin{matrix}\begin{align*}L &\geqslant M + N - 1\\ L &= 2^{\gamma }, \ \gamma \ is \ a \ positive \ integer\end{align*}\end{matrix}\right. \]
2、將序列\(x(n)\)與\(y(n)\)按如下方式補零,形成長為\(L = 2^{\gamma }\)的序列
\[\begin{matrix}x(n)=\left\{\begin{matrix}\begin{align*}x(n) &, n=0,1,...,M-1 \\ 0 &, n=M,M+1,...,L-1\end{align*}\end{matrix}\right.\\ \end{matrix} \]
\[\begin{matrix}y(n)=\left\{\begin{matrix}\begin{align*}y(n) &, n=0,1,...,N-1 \\ 0 &, n=N,N+1,...,L-1\end{align*}\end{matrix}\right.\\ \end{matrix} \]
3、用FFT算法分別計算\(x(n)\)與\(y(n)\)的離散傅里葉變換\(X(k)\)與\(Y(k)\)
\[\begin{matrix}X(k)=\sum_{n=0}^{L-1}x(n)e^{-j2\pi nk/L}\\ Y(k)=\sum_{n=0}^{L-1}y(n)e^{-j2\pi nk/L}\end{matrix} \]
4、計算\(X(k)\)與\(Y(k)\)的乘積
\[Z(k)=X(k)Y(K) \]
5、用FFT算法計算\(Z(k)\)的離散傅里葉反變換,得到卷積\(z(n)\)
\[z(n)=\frac{1}{L}\sum_{k=0}^{L-1}Z(k)e^{j2\pi nk/L}, \ n=0,1,...,L-1 \]
序列\(z(n)\)的前\(M+N-1\)點的值就是序列\(x(n)\)與\(y(n)\)的線性卷積。
三、使用說明
快速卷積的C語言實現方式如下
/************************************
x ----雙精度一維數組,長度為len。開始時存放實序列x(i),最后存放線性卷積的值。
y ----雙精度一維數組,長度為n。開始時存放實序列y(i)。
m ----數據長度,序列x(i)的長度。
n ----數據長度,序列y(i)的長度。
len ----線性卷積長度,len≥m+n-1,且必須是2的整數次冪,即len=2^gamma。
************************************/
#include "rfft.c"
#include "irfft.c"
void convol(double *x, double *y, int m, int n, int len)
{
int i, len2;
double t;
for(i = m; i < len; i++)
x[i] = 0.0;
for(i = n; i < len; i++)
y[i] = 0.0;
rfft(x, len);
irfft(y, len);
len2 = len / 2;
x[0] = x[0] * y[0];
x[len2] = x[len2] * y[len2];
for( i = 1; i < len2; i++){
t = x[i] * y[i] - x[len - i] * y[len - i];
x[len - i] = x[i] * y[len - i] + x[len - i] * y[i];
x[i] = t;
}
irfft(x, len);
}
其中rfft.c文件請參考實序列快速傅里葉變換(一)
irfft.c在rfft.c的基礎上添加系數長度的倒數。
