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?
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.
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)
. –
Imogene 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
. –
Adjournment 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.
If filter is applied, result would have same dimensions with applied filter. While applying convolution, would decrease the dimensions of input with filter applied.
© 2022 - 2024 — McMap. All rights reserved.
conv
, i will get the right output only for an amount of samples equals to the length ofh
. Is that correct? – Cowbind