Code covered by the BSD License  

Highlights from


4.8 | 5 ratings Rate this file 59 Downloads (last 30 days) File Size: 19.9 KB File ID: #32261
image thumbnail




A faster FILTER and FILTFILT: Speedup factor 2.5 to 25

| Watch this File

File Information

FilterM, FiltFiltM: Fast digital filter

These functions are compatible to MATLAB's FILTER and FILTFILT commands,
but they are faster (see screenshot):
  FilterM: 30%-40% of FILTER runtime
  FiltFiltM: 4%-20% of FILTFILT runtime

- The dimension to operate on can be specified for FiltFiltM.
- FilterM can process the signal in backward direction. (This is the
  main part of the acceleration of FiltFiltM, because it avoids to
  reverse the signal two times.)
- For signals of type SINGLE, the intermediate values are stored in
  DOUBLE precision to increase the accuracy. The output is converted
  to SINGLE again.
- The Signal Processing Toolbox is *not* needed.

  Y = FiltFiltM(b, a, X, Dim)
  [Y, Zf] = FilterM(b, a, X, Zi, Dim, Reverse)

  b, a: Filter parameters as DOUBLE vectors.
  X: Signal as DOUBLE or SINGLE vector or array.
  Zi, Zf: Initial and final conditions as DOUBLE or SINGLE array.
        Optional, default: Zeros.
  Dim: Dimension to operate on. Optional, default: 1st non-singelton.
  Reverse: Flag to process the signal in reverse direction.
        Optional, default: FALSE.
  Y: Filtered signal, same size and type as X.
        While FilterM filters in forward direction, FiltFiltM processes
        the signal forward and reverse direction for a zero phase

To accelerate my FEX submission FiltFiltM, I've implemented a filter as
C-Mex, which works in reverse order. To my surprise this was faster than
running Matlab's FILTER forward, e.g. 3.7 times for a [10000 x 1] vector,
5th order Butterworth filter (Matlab 2009a, WinXP 32 bit, single core).
Therefore I've expanded the Mex such that the direction can be defined
as input. The algorithm is a direct form II transposed structure.
A future version will be mutli-threaded.

Setup the compiler if not done before: mex -setup.
Auto-compilation: Call FilterM without inputs to start the compilation.
A pre-compiled Mex can be downloaded:
Run the unit-tests uTest_FilterM and uTest_FiltFiltM to check validity and speed.

Tested: Matlab 6.5, 7.7, 7.8, WinXP, 32bit
        Compiler: LCC2.4/3.8, BCC5.5, OWC1.8, MSVC2008
Assumed Compatibility: higher Matlab versions, Mac, Linux, 64bit

This is faster and more powerful than my former submission "FiltFiltM", which will be removed soon.

MATLAB release MATLAB 7.8 (R2009a)
Other requirements For full speed, the C-Mex function must be compiled: Call "FilterM" without inputs.
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (14)
25 May 2014 Yerlan Aitzhan  
06 Mar 2014 Yair Altman

Still 20-30% faster than Matlab's built-in, even after the performance boost to the built-in filter function in R2014a.

Nice documentation, unit-tests and optimization for good performance.

Suggestion: rename the functions filterm, filterx etc. (without capitals). The current FilterM file breaks because it refers to filterX instead of FilterX for example. Now that Matlab is case-sensitive, better make all functions lowercase, as is the Matlab convention.

Aside from this minor issue, a very useful utility. Well done!

Any progress with the promised multi-threaded version?

24 Feb 2014 Dr. Rami Khushaba  
16 Dec 2013 Carlo E.D. Riboldi

Thanks for these great functions. Besides an improvement in speed, they apparently solve some instability of default filtfilt function causing NaN in the output on a randomic basis.

28 Dec 2011 Royi Avital

@Jan, try even longer filters. I'd be happy if you could release an update for long FIR's even before the threaded version.
It would be great!

Thank you for this great function.

27 Dec 2011 Jan Simon

@Royi Avital: The currently published version does not consider the reduced calculations for FIR filters. I get these measurements for 2011b/64 under Windows, MSVC 2008:
x=rand(1e5, 1); B=repmat(1/21, 1, 21);
tic; for i=1:100, y=filter(B,1,x); clear('y'); end, toc
>> 0.56 sec
tic; for i=1:100, y=FilterX(B,1,x); clear('y'); end, toc
>> 0.42 sec (still faster)
The new version of FilterX considers A=1 explicitely and requires 0.27 sec only. It will be included in the next version, which is multi-threaded also. See:

27 Dec 2011 Royi Avital

@Jan, for FIR Filters with more than 20 coefficients FilterM lags behind MATLAB's implementation.
Do you think you could optimize for longer filters as well?
Thank you.

20 Dec 2011 Jan Simon

Sorry, currently only real values are considered. The implementation of a complex parameters is not trivial in C. It is planned later.

20 Dec 2011 Royi Avital

Jan, there's an issue with complex coefficients, Could you check that?

I'm using the MEX file directly (For "Classic" use as Filter).

Thank you.

20 Dec 2011 Jan Simon

@Royi: I'm working on a multi-threaded version at the moment. Unfortunately this will work under Windows only, because I cannot test the pthread libs under Linux and MacOS.

20 Dec 2011 Royi Avital

Thank you, this is great!
Do you think further optimization could be made?
Do you intentions to do so?

07 Nov 2011 Jan Simon

@Vassilis: I do not get the point. FilterM produces exactly the same results as Matlab's FILTER (except for the higher accuracy for SINGLE), therefore it leads to the same phase shift. FiltFiltM (from this submission) produces the same results as Matlab's FILTFILT. The former submission 25337 "Patch FiltFilt" is slower, depends on the SPT and does not work with modern Matlab versions - but it creates the same results as FiltFiltM.

If you get different results between FilterM and FILTER or between FiltFiltM and FILTFILT, please send me the output of unit-test functions by mail.

07 Nov 2011 Vassilis Kehayas

Very good addition Jan. I observed however that, as you might know, it produces different results than your FiltFiltM as well as from the built-in filtfilt function. I think this is because of the zero-padding you apply, while in the previous version you were using Gustafsson's method -- am I right? The most prominent difference is a time-lag to the signal, plus some minor distortions in the signal.

07 Nov 2011 Vassilis Kehayas  

Contact us