重叠-储存之折积法

**重疊 - 儲存之摺積法** ( _Overlap-save method_, _Overlap-discard method_ ) 是一種區塊摺積 (block convolution, sectioned convolution)，可以有效的計算一個很長的訊號 _x_[_n_] 和一個 FIR 濾波器 _h_[_n_] 的離散摺積。

　
: ${\begin{aligned}y[n]=x[n]\star h[n]\ {\stackrel {\mathrm {def} }{=}}\ \sum _{m=-\infty }^{\infty }h[m]\cdot x[n-m]=\sum _{m=1}^{M}h[m]\cdot x[n-m]\end{aligned}}$

其中 _h_[_m_] 在 [1, _M_] 之外為零。

與重疊 - 相加之摺積法不同之處在於，**重疊 - 儲存之摺積法**所算出的輸出區塊並不重疊 (因此計算上少了將輸出區塊相加所需的加法)，而是每次用的輸入區塊有所重疊。因此實作時每次讀取輸入後需將和下一個輸入重疊的部分儲存起來，作為下一輸入區塊的開頭部份，因此稱為_重疊_-_儲存_之摺積法。另外重疊 - 儲存之摺積法也不需補零。

## 演算法

概念上，這個做法是選用一個較短的適當長度 _L_ 來切割 _y_[_n_] ，則因為 _h_[_n_] 是有限長度，因此在某一區塊內的 _y_[_n_] 也只被有限長的 _x_[_n_] 區塊（會比 _y_[_n_] 分割成的區塊長一點）所決定。因此只要選擇有影響的輸入區塊和 _h_[_n_] 摺積，再選擇結果中適當的部分即可得到正確的輸出區塊。

 

　
: $x_{k}[n]\ {\stackrel {\mathrm {def} }{=}}{\begin{cases}x[n+kL-M]&1\leq n\leq L+M-1\\0&{\textrm {otherwise}}.\end{cases}}$

　
: $y_{k}[n]\ {\stackrel {\mathrm {def} }{=}}\ x_{k}[n]\star h[n]\,$

 
則對於在 $[kL+1,(k+1)L]$ 內的 _n_ ， 輸出 _y_[_n_] 可寫成

　
: ${\begin{aligned}y[n]=\sum _{m=1}^{M}h[m]\cdot x[n-m]=\sum _{m=1}^{M}h[m]\cdot x_{k}[n+M-kL-m]&=x_{k}[n+M-kL]\star h[n]\\&{\stackrel {\mathrm {def} }{=}}\ y_{k}[n+M-kL].\end{aligned}}$

所以只需計算 _n_ 在 $[kL+1,(k+1)L]$ 中的 _y_k[_n_ + _M_ - _kL_] ，亦即 _n_ 在 $[M+1,L+M]$ 的 _y_k[_n_] 部份即可。因此每一段輸出區塊 _y_k[_n_] 的前 _M_-1 點可丟棄（discard）。

 
儘管一時看不出切割成區塊的好處為何，但將 _x_k[_n_] 做 $N\geq L+M-1\,$ 的週期延伸，

　
: $x_{k,N}[n]\ {\stackrel {\mathrm {def} }{=}}\ \sum _{k=-\infty }^{\infty }x_{k}[n-kN],$

則 $(x_{k,N})\star h\,$ 和 $x_{k}\star h\,$ 這兩個摺積在 $[M+1,L+M]$ 的部份相等。所以可以將線性摺積改以 $N\,$ 點圓周摺積計算，結果的 $[M+1,L+M]$ 部分作為輸出 _y_[_n_] 在 $[kL+1,(k+1)L]$ 的部份。由於每段 _x_k[_n_] 原本就有 $L+M-1\,$ 長，所以選擇 $N=L+M-1\,$ 的話輸入 _x_[_n_] 就不需補零。
改以圓周摺積計算後即可藉圓周摺積定理

　
: $y_{k}[n]={\textrm {IFFT}}\left({\textrm {FFT}}\left(x_{k}[n]\right)\cdot {\textrm {FFT}}\left(h[n]\right)\right)$

轉換成三次 $N\,$ 點快速傅立葉變換和 $N\,$ 次乘法，使原本每段 _O_(_N_2) 的運算量減少至 _O_(_N_ _logN_)，速度大幅增加。

### 準程式碼

```
   (_Overlap-save algorithm for linear convolution_)
   //////// revised by fantastic ////////
   N = length(x), M = length(h)
   O = M – 1;	// overlap length must be M-1
   L = M;	// >=1 is OK
   P = O + L;
   H = FFT(h, P);	// just calc once
   idx = - (O - 1);	// starting index which is offset M-1 in matlab
   **while** (idx <= N)
       i1 = max(1, idx);	// must be >= 1
       i2 = min(N, idx+P-1);	// must be <= N
       yt = IFFT( FFT(x(i1:i2), P).*H, P );
       y(idx:idx+P-M) = yt(M:P);	// discard first M-1 values and concatenate the remaining
       idx = idx + L;
   **end**
   y = y(1:M+N-1);	// the first M+N-1 values are the convolution result
```

## 區塊長度的選擇

當 _x_[_n_] 的長度 _N'_ 和 _h_[_n_] 的長度 _M_ 相差太大時（例如 _M_ < log2_N'_ ），直接摺積（不透過圓周摺積和 FFT ）反而最快。而當 _N'_ 和 _M_ 差不多在同一個數量級時，不用分割，也就是只有一塊長度 _L_ = _N'_ 的區塊去做 FFT 即可。而當 _N'_ 比 _M_ 大了不少，卻沒大太多時，區塊長度 _L_ 就需要選擇。除了與 _N'_ 和 _M_ 相關以外，也要考慮當兩者相除有餘數時，剩下一小段的輸入可能會造成浪費。

## 相關條目

* 離散摺積
* 圓周摺積
* 快速傅立葉變換
* 重疊 - 相加之摺積法

## 參考文獻

* Rabiner, Lawrence R.; Gold, Bernard. Theory and application of digital signal processing. Englewood Cliffs, N.J.: Prentice-Hall. 1975: pp 65–67. ISBN 0-13-914101-4.  引文格式 1 維護：冗餘文字 (link)
* Helms, H., Fast Fourier transform method of computing difference equations and simulating filters, IEEE Transactions on Audio and Electroacoustics, 1967, **15(2)**: 85–90 [2008-06-23], （原始內容存檔於 2019-06-30）

## 外部連結

* DSP class Fall 2005 Lecture08 at The University of Texas at Arlington]