# Partitioned Convolution
{cite}`partitioned_convolution`
Partitioned covolution is a technique that breaks up the input sequence and/or the filter impulse response into *blocks* to increase the efficency of convolution computations.
## Input Partitioning
Input partitioning involves splitting up an input sequence of potentially indefinte length into blocks of length $B$. The following function below can be used to partition an input sequence of arbitrary size.
## Filter Partitioning
Filter partitioning involves splitting up a FIR filters impulse response into sections. There are several methods that can be used to partition a filters impulse response. The method that is selected defines the different classes of convolution algorithms that can be used.
Partitioning a filter with an impulse response of length-$N$ involves splitting up the impulse response into $P$ sub filters of length $N_0, ..., N_{P-1}$ such that:
$$\sum_{i = 0}^{P-1} N_i = N$$
Or in cases where the subfilters are zero-padded, the following realtionship holds true:
$$\sum_{i = 0}^{P-1} N_i \ge N$$
Each sub filter impulse response $h_i(n)$ relates to a connected interval $n_i^{first} \le n \le n_i^{last}$ in the original filter impulse response $h(n)$, and all sub filters are adjoining, such that $n_{i+1}^{first} = n_i^{last} + 1$.
The *sub filter length* $N_i$ is defined as:
$$N_i = n_i^{last} - n_i^{first} + 1$$
The position of the sub filter within the original impulse response is:
$$n_i^{first} = \sum_{j
## Filter Structure
Inserting the partitioned filter into the linear convolution equation gives us:
$$\begin{aligned}
y(n) \quad &= \quad x(n) * h(n) \\
&= \quad x(n) * \left[ \sum_{i=0}^{P-1} h_i(n - n_i^{first}) \right]
\end{aligned}$$
And then converting the delays to time-shifted unit impulses gives us the following two equations:
$$\begin{aligned}
y(n) \quad &= \quad \sum_{i=0}^{P-1} \left[ \left[ x(n) * \delta(n - n_i^{first}) \right] * h_i(n) \right] \\
&= \quad \sum_{i=0}^{P-1} \left[ \left[ x(n) * h_i(n) \right] * \delta(n - n_i^{first}) \right]
\end{aligned}$$
Both of these equations are equivalent since convolution is commutative. This illustrates that the delays can be moved around when performing the convolution.
## Classification of Partitioned Convolution Algorithms
The image below illustrates different classes of convolution algorithms based on the partitioning of the input sequence and the filter. Only *uniformly partitioned* input sequences are considered for real-time processing, although the other categories can be useful for offline processing.

*Classes of Convolution Algorithms: {cite}`partitioned_convolution`*
*Classes of Convolution Algorithms: {cite}`partitioned_convolution`*
## Running Convolutions
Linear convolution of a partitioned input sequence with an unpartitioned filter can be performed using the *Overlap-Add* method or the *Overlap-save* method described below.
### Overlap-Add
The overlap-add partitioned convolution method involves the following operations:
* Zero-pad a block of $B$ input samples to a length of $K$ and take the $K$-point FFT.
* Zero-pad the filters $N$-point impulse response to a length of $K$ and take the $K$-point FFT.
* Perform an element-wise complex multiplication between the input and the filters DFT coefficients.
* Transform the results of the FFT back to the time-domain using a $K$-point IFFT and buffer the partial convolution result of $B+N-1$ samples.
* Sum up $B$ samples from the overlapping partial convolution results to get the filtered output.
In order to avoid time-aliasing, the transform size $K$ must be chosen such that the following holds true:
$$K \ge B + N - 1$$
Illustrated below is a block diagram of the overlap-add method, and below that is an implementation in code.

*Overlap-Add Running Convolution: {cite}`partitioned_convolution`*
*Overlap-Add Running Convolution: {cite}`partitioned_convolution`*
### Overlap-Save
The overlap-save partitioned convolution method is very similar to the overlap-add method, but with the following differences:
* The input FFT is computed from a $K$-point sliding window of input data, where the data is shifted from the right to the left in the window.
* The $K-B$ leftmost samples in the result of the IFFT are time-aliased, so they are discarded. The rightmost $B$ samples are the ones that get saved into the output blocks.
Because of the periodic nature of the transform, the overlap-save algorithm can be modified such that the input and filter buffers are circularly shifted, altering the position that the data is written to the input and filter buffers and read from the output buffer. By circular shifting, it is possible to move the valid output block from the rightmost position of the output buffer to the leftmost position, which can be advantageous when computing partial inverse transforms.
In order to avoid time-aliasing, the transform size $K$ must be chosen such that the following holds true:
$$K \ge B + N - 1$$
Illustrated below is a block diagram of the overlap-save method, and below that is an implementation in code.

*Overlap-Save Running Convolution: {cite}`partitioned_convolution`*
*Overlap-Save Running Convolution: {cite}`partitioned_convolution`*