離散卷積的定義:
將兩個離散序列中的數,按照規則,兩兩相乘再相加的操作。
卷積運算:
的長度是 , 的長度是 , 的長度是
計算卷積的過程:序列翻轉,移位,相乘,取和
計算舉例:
其中k等於a的長度。
翻轉移位相乘的操作如下:
代碼實現:
Matlab代碼:
a=[1,2,3];
b=[2,3,1];
y=conv(b,a);
C++代碼:
這裏實現的主要問題有幾個:
1.k的取值範圍:和a的長度相關
2.b的下標,如果按照公式來看的話比較直接,但是按照翻轉移位來寫就會比較令人迷惑
3.卷積滿足交換律
void convolution(int a[],int b[],int NA,int NB)
{
int NC=NA+NB-1;
int *c=(int *)malloc(sizeof(int)*NC);
memset(c,0,sizeof(int)*NC);
for(int n=0;n<NC;n++)
{
for(int k=0;k<NA;k++)
{
int bindex=n-k;
if(bindex>=0&&bindex<NB)
{
c[n]+=a[k]*b[bindex];
}
}
}
for(int n=0;n<NC;n++)
printf("%d ",c[n]);
}
離散卷積與傅里葉變換的關係:
圖源自:快速傅里葉變換:算法與應用
使用matlab代碼驗證
clear;
a=[1,2,3];
b=[2,3,1];
c1=conv(a,b);
na=length(a);
nb=length(b);
for i=na+1:na+nb-1
a(1,i)=0;
end
for i=nb+1:na+nb-1
b(1,i)=0;
end
FA=fft(a);
FB=fft(b);
FC=FA.*FB;
c2=ifft(FC);
這個代碼裏的pad0的長度只需要大於等於na+nb-1即可,可以設置的更大。
c1: 2 7 13 11 3
c2: 2.0000 7.0000 13.0000 11.0000 3.0000