Has anyone tried implementing matlab's filtfilt()
function in Java (or at least in C++)? If you guys have an algorithm, that would be of great help.
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- Sorting 3 numbers without branching [closed]
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
Here is my implementation in C++ of the
filtfilt
algorithm as implemented in MATLAB. Hope this helps you.Allright, I know this question is ancient, but maybe I can be of help to someone else who winds up here wondering what
filtfilt
actually does.Although it is obvious from the docs that
filtfilt
does forward-backward (a.k.a. zero-phase) filtering, it was not so obvious to me how it deals with things like padding and initial conditions.As I couldn't find any other answers here (nor elsewhere) with sufficient information about these implementation details of
filtfilt
, I implemented a simplified version ofPython
'sscipy.signal.filtfilt
, based on its source and documentation (so, notJava
, norC++
, butPython
). I believe thescipy
version works the same way asMatlab
's.To keep things simple, the code below was written specifically for a second order IIR filter, and it assumes the coefficient vectors
a
andb
are known (e.g. obtained fromscipy.signal.butter
, or calculated by hand).It matches the
filtfilt
default behavior, usingodd
padding of length3 * max(len(a), len(b))
, which is applied before the forward pass. The initial state is found using the approach fromscipy.signal.lfilter_zi
(docs).Disclaimer: This code is only intended to provide some insight into certain implementation details of
filtfilt
, so the goal is clarity instead of computational efficiency/performance. Thescipy.signal.filtfilt
implementation is much faster (e.g. 100x faster according to a quick & dirtytimeit
test on my system).Note that this implementation does not require
scipy
. Moreover, it can easily be adapted to work in pure python, without evennumpy
, by writing out the solution forzi
and using lists instead of numpy arrays. This even comes with a substantial performance benefit, because accessing individual numpy array elements in a python loop is much slower than accessing list elements.The filter itself is implemented here in a simple
Python
loop. It uses the state space representation, because this is used anyway to determine the initial conditions (seescipy.signal.lfilter_zi
). I believe that the actualscipy
implementation of the linear filter (i.e.scipy.signal.sigtools._linear_filter
) does something similar inC
, as can be seen here (thanks to this answer).Here's some code providing a (very basic) check for equality of the
scipy
output andcustom
output:This basic comparison yields a figure like below, suggesting equality to at least 14 decimals, for this specific case (machine precision, I guess?):