20

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?

nbro
  • 15,395
  • 32
  • 113
  • 196
nikos
  • 2,893
  • 11
  • 30
  • 39

4 Answers4

17

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.

See the conv and filter documentation for details.

mtrw
  • 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
  • 2
    Consider 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
  • 8
    Actually `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
14

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!

Flexo
  • 87,323
  • 22
  • 191
  • 272
dernib
  • 141
  • 1
  • 2
0

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.

Triceratops
  • 741
  • 1
  • 6
  • 15
0

If filter is applied, result would have same dimensions with applied filter. While applying convolution, would decrease the dimensions of input with filter applied.

rohan goli
  • 116
  • 4