图示两个方形脈衝波的捲積。其中函数"g"首先对
反射,接著平移"t",成為
。那么重叠部份的面积就相当于"t"处的卷积,其中橫坐標代表待变量
以及新函數
的自變量"t"。
圖示方形脈衝波和指數衰退的脈衝波的捲積(後者可能出現於RC電路中),同樣地重疊部份面積就相當於"t"處的捲積。注意到因為"g"是對稱的,所以在這兩張圖中,反射並不會改變它的形狀。
在泛函分析中,捲積(又称疊積(convolution)、褶積或旋積),是透過两个函数 f 和 g 生成第三个函数的一种数学算子,表徵函数 f 与经过翻转和平移的 g 的乘積函數所圍成的曲邊梯形的面積。如果将参加卷积的一个函数看作区间的指示函数,卷积还可以被看作是“滑動平均”的推廣。
简单介绍
卷积是数学分析中一种重要的运算。设:
、
是
上的两个可积函数,作积分:
![{\displaystyle \int _{-\infty }^{\infty }f(\tau )g(x-\tau )\,\mathrm {d} \tau }](https://wikimedia.org/api/rest_v1/media/math/render/svg/5cf6c1df775e00688e8523f8b44ccc4633aadd13)
可以证明,关于几乎所有的
,上述积分是存在的。这样,随着
的不同取值,这个积分就定义了一个新函数
,称为函数
与
的卷积,记为
。我們可以輕易验证:
,并且
仍为可积函数。这就是说,把卷积代替乘法,
空间是一个代数,甚至是巴拿赫代数。雖然這裡為了方便我們假設
,不過捲積只是運算符號,理論上並不需要對函數
有特別的限制,雖然常常要求
至少是可測函數(measurable function)(如果不是可測函數的話,積分可能根本沒有意義),至於生成的卷積函數性質會在運算之後討論。
卷积与傅里叶变换有着密切的关系。例如两函数的傅里叶变换的乘积等于它们卷积后的傅里叶变换,利用此一性質,能簡化傅里叶分析中的许多问题。
由卷积得到的函数
一般要比
和
都光滑。特别当
为具有紧支集的光滑函数,
为局部可积时,它们的卷积
也是光滑函数。利用这一性质,对于任意的可积函数
,都可以简单地构造出一列逼近于
的光滑函数列
,这种方法称为函数的光滑化或正则化。
卷积的概念还可以推广到数列、测度以及广义函数上去。
定义
函数
是定義在
上的可測函數(measurable function),
与
的卷积记作
,它是其中一个函数翻转,並平移后,与另一个函数的乘积的积分,是一个对平移量的函数,也就是:
。
如果函數不是定義在
上,可以把函數定義域以外的值都規定成零,這樣就變成一個定義在
上的函數。
圖解摺積
|
- 已知两函数f(t)和g(t)。右图第一行两图分别为f(t)和g(t)。
- 首先將兩個函數都用
來表示,从而得到f( )和g( )。将函数g( )向左移动t个单位,得到函数g( +t)的图像。将g( +t)翻转至纵轴另一侧,得到g(t- )的图像。右图第二行两图分别为f( )和g(t- )。
- 由于t非常数(实际上是时间变量),当时间变量(以下简称“时移”)取不同值时,
能沿着 轴“滑动”。右图第三四五行可理解为“滑动”。
- 讓
從-∞滑動到+∞。兩函數交會時,計算交會範圍中兩函數乘積的積分值。換句話說,我們是在計算一個滑動的的加權總和(weighted-sum)。也就是使用 當做加權函數,來對 取加權值。
- 最後得到的波形(未包含在此圖中)就是f和g的摺積。如果f(t)是一個單位脈衝,我們得到的乘積就是g(t)本身,稱為衝激響應。
|
|
离散卷积
对于定义在整數
上的函数
,卷积定义为
![{\displaystyle =\sum _{m=-\infty }^{\infty }f[n-m]\,g[m].}](https://wikimedia.org/api/rest_v1/media/math/render/svg/f067498b1393be11cf4cecfb08f3096f14bdce59)
這裡一樣把函數定義域以外的值當成零,所以可以擴展函數到所有整數上(如果本來不是的話)。
當
的支撐集(support)為有限長度
,上式會變成有限和:
![{\displaystyle (f*g)[n]=\sum _{m=-M}^{M}f[n-m]g[m].}](https://wikimedia.org/api/rest_v1/media/math/render/svg/fddacde29cbcb3c6fca263493335c31a4d2ebce2)
計算离散卷積的方法
計算卷積
有三種主要的方法,分別為
- 直接計算(Direct Method)
- 快速傅立葉轉換(FFT)
- 分段卷積(sectioned convolution)
方法1是直接利用定義來計算卷積,而方法2和3都是用到了FFT來快速計算卷積。也有不需要用到FFT的作法,如使用數論轉換。
方法1:直接計算
![{\displaystyle y[n]=f[n]*g[n]=\sum _{m=0}^{M-1}f[n-m]g[m]}](https://wikimedia.org/api/rest_v1/media/math/render/svg/1081139aae46ebd7421e11ec20351dc12688cedd)
- 若
和
皆為實數信號,則需要
個乘法。
- 若
和
皆為更一般性的複數信號,不使用複數乘法的快速演算法,會需要
個乘法;但若使用複數乘法的快速演算法,則可簡化至
個乘法。
- 因此,使用定義直接計算卷積的複雜度為
。
方法2:快速傅立葉轉換(FFT)
- 概念:由於兩個離散信號在時域(time domain)做卷積相當於這兩個信號的離散傅立葉轉換在頻域(frequency domain)做相乘:
![{\displaystyle y[n]=f[n]*g[n]\leftrightarrow Y[f]=F[f]G[f]}](https://wikimedia.org/api/rest_v1/media/math/render/svg/27f83ca717dff1b21da43e56127c50874843b8b0)
- ,可以看出在頻域的計算較簡單。
![{\displaystyle F[f]=DFT_{P}(f[n]),G[f]=DFT_{P}(g[n])}](https://wikimedia.org/api/rest_v1/media/math/render/svg/af332366ed1070784c006329adcd40833e64c44d)
- ,於是
![{\displaystyle Y[f]=DFT_{P}(f[n])DFT_{P}(g[n])}](https://wikimedia.org/api/rest_v1/media/math/render/svg/93ec9e3130dcd720d4d6b1930bd492f29fee0faf)
- ,最後再將頻域信號轉回時域,就完成了卷積的計算:
![{\displaystyle y[n]=IDFT_{P}{DFT_{P}(f[n])DFT_{P}(g[n])}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/adc12d1e8c9712ca85bf040d7e8573842c545588)
- 總共做了2次DFT和1次IDFT。
- 特別注意DFT和IDFT的點數
要滿足
。
- 由於DFT有快速演算法FFT,所以運算量為
![{\displaystyle O(P\log _{2}P)}](https://wikimedia.org/api/rest_v1/media/math/render/svg/c74fc93c033d1c137f1f3444761adb5c57a78446)
- 假設
點DFT的乘法量為
,
和
為一般性的複數信號,並使用複數乘法的快速演算法,則共需要
個乘法。
方法3:分段卷積(sectioned convolution)
- 概念:將
切成好幾段,每一段分別和
做卷積後,再將結果相加。
- 作法:先將
切成每段長度為
的區段(
),假設共切成S段:
![{\displaystyle f[n](n=0,1,...,N-1)\to f_{1}[n],f_{2}[n],f_{3}[n],...,f_{S}[n](S=\left\lceil {\frac {N}{L}}\right\rceil )}](https://wikimedia.org/api/rest_v1/media/math/render/svg/6b2758eba65ad177619e0d9198cc913abf649b9a)
- Section 1:
![{\displaystyle f_{1}[n]=f[n],n=0,1,...,L-1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/22401ad12747eb80e3ec79d0c5b189b3c186d912)
- Section 2:
![{\displaystyle f_{2}[n]=f[n+L],n=0,1,...,L-1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ccb4f0b33490a5fc67f57cb6d353087f35c3db5d)
![{\displaystyle \vdots }](https://wikimedia.org/api/rest_v1/media/math/render/svg/f8039d9feb6596ae092e5305108722975060c083)
- Section r:
![{\displaystyle f_{r}[n]=f[n+(r-1)L],n=0,1,...,L-1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/f0d987ef3bab08edc0d97642435c8f97a1383304)
![{\displaystyle \vdots }](https://wikimedia.org/api/rest_v1/media/math/render/svg/f8039d9feb6596ae092e5305108722975060c083)
- Section S:
![{\displaystyle f_{S}[n]=f[n+(S-1)L],n=0,1,...,L-1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/b30b353213c930583b0b65c5598ea334fdfee777)
- ,
為各個section的和
。
- 因此,
,
- 每一小段作卷積則是採用方法2,先將時域信號轉到頻域相乘,再轉回時域:
。
- 總共只需要做
點FFT
次,因為
只需要做一次FFT。
- 假設
點DFT的乘法量為
,
和
為一般性的複數信號,並使用複數乘法的快速演算法,則共需要
個乘法。
- 運算量:
![{\displaystyle {\frac {N}{L}}3(L+M-1)[\log _{2}(L+M-1)+1]}](https://wikimedia.org/api/rest_v1/media/math/render/svg/e4b5d72adc35b450cfcc40c0d13720fa6d6bd070)
- 運算複雜度:
,和
呈線性,較方法2小。
- 分為 Overlap-Add 和 Overlap-Save 兩種方法。
分段卷積: Overlap-Add
欲做
的分段卷積分,
長度為
,
長度為
,
Step 1: 將
每
分成一段
Step 2: 再每段
點後面添加
個零,變成長度
Step 3: 把
添加
個零,變成長度
的
Step 4: 把每個
的小段和
做快速卷積,也就是
,每小段會得到長度
的時域訊號
Step 5: 放置第
個小段的起點在位置
上,
Step 6: 會發現在每一段的後面
點有重疊,將所有點都相加起來,顧名思義 Overlap-Add,最後得到結果
舉例來說:
, 長度
, 長度
令
令
切成三段,分別為
, 每段填
個零,並將
填零至長度 ![{\displaystyle L+M-1}](https://wikimedia.org/api/rest_v1/media/math/render/svg/85e33f15990cd14d3bf8a47611f4e5e0bafe4173)
將每一段做![{\displaystyle IDFT_{L+M-1}\{{DFT_{L+M-1}(x[n])DFT_{L+M-1}(h'[n])}\}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/71884e63653a1501f77c376b182141bd9d8e86ce)
若將每小段擺在一起,可以注意到第一段的範圍是
,第二段的範圍是
,第三段的範圍是
,三段的範圍是有重疊的
最後將三小段加在一起,並將結果和未分段的卷積做比較,上圖是分段的結果,下圖是沒有分段並利用快速卷積所算出的結果,驗證兩者運算結果相同。
分段卷積: Overlap-Save
欲做
的分段卷積分,
長度為
,
長度為
,
Step 1: 將
前面填
個零
Step 2: 第一段
, 從新的
中
取到
總共
點當做一段,因此每小段會重複取到前一小段的
點,取到新的一段全為零為止
Step 3: 把
添加
個零,變成長度
的
Step 4: 把每個
的小段和
做快速卷積,也就是
,每小段會得到長度
的時域訊號
Step 5: 對於每個
小段,只會保留末端的
點,因此得名 Overlap-Save
Step 6: 將所有保留的點合再一起,得到最後結果
舉例來說:
, 長度
, 長度
令
將
前面填
個零以後,按照 Step 2 的方式分段,可以看到每一段都重複上一段的
點
再將每一段做
以後可以得到
保留每一段末端的
點,擺在一起以後,可以注意到第一段的範圍是
,第二段的範圍是
,第三段的範圍是
,第四段的範圍是
,四段的範圍是沒有重疊的
將結果和未分段的卷積做比較,下圖是分段的結果,上圖是沒有分段並利用快速卷積所算出的結果,驗證兩者運算結果相同。
至於為什麼要把前面
丟掉?
以下以一例子來闡述:
, 長度
,
, 長度
,
第一條藍線代表
軸,而兩條藍線之間代表長度
,是在做快速摺積時的週期
當在做快速摺積時
,是把訊號視為週期
,在時域上為循環摺積分,
而在一開始前
點所得到的值,是
和
內積的值,
然而
這
個值應該要為零,以往在做快速摺積時長度為
時不會遇到這些問題,
而今天因為在做快速摺積時長度為
才會把這
點算進來,因此我們要丟棄這
點內積的結果
為了要丟棄這
點內積的結果,位移
點,並把位移以後內積合的值才算有效。
應用時機
以上三種方法皆可用來計算卷積,其差別在於所需總體乘法量不同。基於運算量以及效率的考量,在計算卷積時,通常會選擇所需總體乘法量較少的方法。
以下根據
和
的長度(
)分成5類,並列出適合使用的方法:
為一非常小的整數 - 直接計算
- 分段卷积
- 快速傅里叶变换
- 分段卷积
為一非常小的整數 - 直接計算
基本上,以上只是粗略的分類。在實際應用時,最好還是算出三種方法所需的總乘法量,再選擇其中最有效率的方法來計算卷積。
例子
Q1:當
,適合用哪種方法計算卷積?
Ans:
- 方法1:所需乘法量為
![{\displaystyle 3MN=102000}](https://wikimedia.org/api/rest_v1/media/math/render/svg/176f76ca3518d89f694c6c0830be780083947e96)
- 方法2:
,而2016點的DFT最少乘法數
,所以總乘法量為![{\displaystyle 3(a+P)=44232}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ed765f9deb33d69a263ab630ad2d2961a902b732)
- 方法3:
- 若切成8塊(
),則
。選
,則總乘法量為
,比方法1和2少了很多。
- 但是若要找到最少的乘法量,必須依照以下步驟
- (1)先找出
:解
: ![{\displaystyle {\frac {\partial {{\frac {N}{L}}3(L+M-1)[\log _{2}(L+M-1)+1]}}{\partial L}}=0}](https://wikimedia.org/api/rest_v1/media/math/render/svg/5212be896bcbc7febbe5e992d9650c2b0ea09c6a)
- (2)由
算出點數在
附近的DFT所需最少的乘法量,選擇DFT的點數
- (3)最後由
算出![{\displaystyle L_{opt}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/251f8d17fb14ec764eb37937a75c9ea07333ed12)
- 因此,
- (1)由運算量對
的偏微分為0而求出![{\displaystyle L=85}](https://wikimedia.org/api/rest_v1/media/math/render/svg/915cf63e7c6ca7d395868ebfedf0b4f4c0b79b18)
- (2)
,所以選擇101點DFT附近點數乘法量最少的點數
或
。
- (3-1)當
,總乘法量為
。
- (3-2)當
,總乘法量為
。
- 由此可知,切成20塊會有較好的效率,而所需總乘法量為21480。
- 因此,當
,所需總乘法量:分段卷積<快速傅立葉轉換<直接計算。故,此時選擇使用分段卷積來計算卷積最適合。
Q2:當
,適合用哪種方法計算卷積?
Ans:
- 方法1:所需乘法量為
![{\displaystyle 3MN=9216}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ecf603bb99b5d764d4aec0c0e634833257533d9c)
- 方法2:
,選擇1026點DFT附近點數乘法量最少的點數,
。
- 因此,所需乘法量為
![{\displaystyle 3(a+P)=24342}](https://wikimedia.org/api/rest_v1/media/math/render/svg/a994d5254d9022c33244969331dc7c38c0ddc94c)
- 方法3:
- (1)由運算量對
的偏微分為0而求出![{\displaystyle L=5}](https://wikimedia.org/api/rest_v1/media/math/render/svg/2f0a13e71c8b4a72c47192e0197ae0faaa78240a)
- (2)
,所以選擇7點DFT附近點數乘法量最少的點數
或
或
。
- (3-1)當
,總乘法量為
。
- (3-2)當
,總乘法量為
。
- (3-3)當
,總乘法量為
。
- 由此可知,切成171塊會有較好的效率,而所需總乘法量為5476。
- 因此,當
,所需總乘法量:分段卷積<直接計算<快速傅立葉轉換。故,此時選擇使用分段卷積來計算卷積最適合。
- 雖然當
是個很小的正整數時,大致上適合使用直接計算。但實際上還是將3個方法所需的乘法量都算出來,才能知道用哪種方法可以達到最高的效率。
Q3:當
,適合用哪種方法計算卷積?
Ans:
- 方法1:所需乘法量為
![{\displaystyle 3MN=1843200}](https://wikimedia.org/api/rest_v1/media/math/render/svg/55d14707009359954f78aaf073f6511619f9ad5f)
- 方法2:
,選擇1026點DFT附近點數乘法量最少的點數,
。
- 因此,所需乘法量為
![{\displaystyle 3(a+P)=44232}](https://wikimedia.org/api/rest_v1/media/math/render/svg/ed765f9deb33d69a263ab630ad2d2961a902b732)
- 方法3:
- (1)由運算量對
的偏微分為0而求出![{\displaystyle L=1024}](https://wikimedia.org/api/rest_v1/media/math/render/svg/8b1dea891d99d45646054fa5a0b58b3e5dce6f25)
- (2)
,所以選擇1623點DFT附近點數乘法量最少的點數
。
- (3)當
,總乘法量為
。
- 由此可知,此時切成一段,就跟方法2一樣,所需總乘法量為44232。
- 因此,當
,所需總乘法量:快速傅立葉轉換 = 分段卷積<直接計算。故,此時選擇使用分段卷積來計算卷積最適合。
多元函数卷积
按照翻转、平移、积分的定义,还可以类似的定义多元函数上的积分:
![{\displaystyle (f*g)(t_{1},t_{2},\cdots ,t_{n})=\int \int \cdots \int f(\tau _{1},\tau _{2},\cdots ,\tau _{n})g(t_{1}-\tau _{1},t_{2}-\tau _{2},\cdots ,t_{n}-\tau _{n},)\,d\tau _{1}d\tau _{2}\cdots d\tau _{n}}](https://wikimedia.org/api/rest_v1/media/math/render/svg/65b19570fbf4403e3c20c92732786ade6061accd)
性质
各种卷积算子都满足下列性质:
- 交换律
![{\displaystyle f*g=g*f\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/e0702c60de9cfe34bad273e611a5f2503f521961)
- 结合律
![{\displaystyle f*(g*h)=(f*g)*h\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/1f91da320ed0154cf328e6777c90f3c55b87d177)
- 分配律
![{\displaystyle f*(g+h)=(f*g)+(f*h)\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/2796399c899a369d328478676837f13a05beb7d9)
- 数乘结合律
![{\displaystyle a(f*g)=(af)*g=f*(ag)\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/15bcb3b0cc4a54bcc9028ebdd4071274628af33b)
其中
为任意实数(或复数)。
- 微分定理
![{\displaystyle {\mathcal {D}}(f*g)={\mathcal {D}}f*g=f*{\mathcal {D}}g\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/dec8cf62e81d524bc2d8fea74ed8d83e9b15004c)
其中Df表示f的微分,如果在离散域中则是指差分算子,包括前向差分与后向差分两种:
- 前向差分:
![{\displaystyle {\mathcal {D}}^{+}f(n)=f(n+1)-f(n)}](https://wikimedia.org/api/rest_v1/media/math/render/svg/0a2f5a64aad71a726e2e100b69e3140c74804b15)
- 后向差分:
![{\displaystyle {\mathcal {D}}^{-}f(n)=f(n)-f(n-1)}](https://wikimedia.org/api/rest_v1/media/math/render/svg/63f0e6b5d51f0d049f94d6e03306cfc34d529843)
卷积定理
卷积定理指出,函数卷积的傅里叶变换是函数傅里叶变换的乘积。即,一个域中的卷积相当于另一个域中的乘积,例如时域中的卷积就对应于频域中的乘积。
![{\displaystyle {\mathcal {F}}(f*g)={\mathcal {F}}(f)\cdot {\mathcal {F}}(g)}](https://wikimedia.org/api/rest_v1/media/math/render/svg/a5fc5cf43e4eb888bd49dc6c7aa20e2f7a20ff10)
其中
表示f的傅里叶变换。
这一定理对拉普拉斯变换、双边拉普拉斯变换、Z变换、Mellin变换和Hartley变换(参见Mellin inversion theorem)等各种傅里叶变换的变体同样成立。在调和分析中还可以推广到在局部紧致的阿贝尔群上定义的傅里叶变换。
利用卷积定理可以简化卷积的运算量。对于长度为
的序列,按照卷积的定义进行计算,需要做
组对位乘法,其计算复杂度为
;而利用傅里叶变换将序列变换到频域上后,只需要一组对位乘法,利用傅里叶变换的快速算法之后,总的计算复杂度为
。这一结果可以在快速乘法计算中得到应用。
在群上的卷积
若G是有某m 测度的群(例如豪斯多夫空间上哈尔测度下局部紧致的拓扑群),对于G上m-勒贝格可积的实数或复数函数f和g,可定义它们的卷积:
![{\displaystyle (f*g)(x)=\int _{G}f(y)g(xy^{-1})\,dm(y)\,}](https://wikimedia.org/api/rest_v1/media/math/render/svg/8cec355c5ad869ef4f885be24d690d057d56c589)
对于这些群上定义的卷积同样可以给出诸如卷积定理等性质,但是这需要对这些群的表示理论以及调和分析的彼得-外尔定理。
应用
卷积在科学、工程和数学上都有很多应用:
- 代数中,整数乘法和多项式乘法都是卷积。
- 图像处理中,用作图像模糊、锐化、边缘检测。
- 统计学中,加权的滑动平均是一种卷积。
- 概率论中,两个统计独立变量X与Y的和的概率密度函数是X与Y的概率密度函数的卷积。
- 声学中,回声可以用源声与一个反映各种反射效应的函数的卷积表示。
- 电子工程与信号处理中,任一个线性系统的输出都可以通过将输入信号与系统函数(系统的冲激响应)做卷积获得。
- 物理学中,任何一个线性系统(符合叠加原理)都存在卷积。
参见
外部链接