I am trying to calculate the output of a LTI system. I came across two different Matlab functions that are supposed to be appropriate for the job: filter
and conv
. What is the difference between the two of them?
4 Answers
filter
can handle FIR and IIR systems, while conv
takes two inputs and returns their convolution. So conv(h,x)
and filter(h,1,x)
would give the same result. The 1 in filter indicates that the recursive coefficients of the filter are just [1]
. But if you have an IIR filter, you can't use conv
. filter
can also return the filter states, so that it can be used in subsequent calls without incurring filter transients.

- 34,200
- 7
- 63
- 71
-
so as far as i got it from what i read, if it's an IIR system and i use `conv`, i will get the right output only for an amount of samples equals to the length of `h`. Is that correct? – nikos Dec 06 '11 at 17:21
-
2Consider the filter `H(z) = [1 - 2z^-1 + z^-2]/[1 - z^-1]`. If you set the input to `x = [1 0 0 0]`, you'll get the results `[1 -2 1 0]` with `conv([1,-2,1],x)` and `[1 -1 0 0]` with `filter([1,-2,1],[1,-1],x)`. – mtrw Dec 06 '11 at 18:47
-
8Actually `conv(b,x)` and `filter(b,1,x)` are not **exactly** the same. `filter` will give you an output with same length as `x`, while `conv` will give an output with length of `length(x)+length(b)-1`. – LWZ Nov 13 '15 at 16:36
conv(x,b)
performs the complete convolution. The length of the result is length(x)+ length(b)-1
.
filter(b,[1],x)
gives an output of the same length than x
. It doesn’t flush the delay line of the filter.
Assume x
is a row vector. Make x0 = [x zeros(1,length(b)-1)]
; now filter(b,[1],x0)
is the same as conv(x,b)
. This is because the additional 0’s are used to flush the delay line.
Which one is more reasonable? It depends of what you need!
A related answer is the situation in Python. As mentioned above, for FIR filters the functions scipy.signal.lfilter
and numpy.convolve
do the same operation up to boundary effects.
Assume len(x) > len(h)
. When using numpy.convolve(h,x,mode='same')
one gets a vector of len(x)
but padded with zeros symmetrically.
However, when using `scipy.signal.lfilter the zero padding is not symmetrical but one-sided!
One can check that
import numpy as np
from scipy.signal import lfilter
h = np.array([1, 2, 1])
x = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
fx = lfilter(h, 1, x)
cx = np.convolve(h, x, mode='full')[0:len(x)]
print(fx == cx)
gives all "True".
The idea is that the mode full pads maximally with zeros on both sides, giving a vector of size len(x) + len(h) - 1
(see Numpy documentation) and what you need to do is trim the redundant elements in the end.

- 741
- 1
- 6
- 15
If filter is applied, result would have same dimensions with applied filter. While applying convolution, would decrease the dimensions of input with filter applied.

- 116
- 4