This is my personal implementation of the Matlab filtfilt function. I tested it with FIR and IIR filter coefficients, and this implementation gives the same results when implementing MATLAB. I used the Eigen library to calculate the initial conditions of the filter in the same way as it was done in MATLAB, but if you are ready to implement matrix multiplication and inverse operations, you can get rid of it, and the code will just depend on STL <vector> and <algorithm> .
#include <vector>
To verify this, you can use the following code:
TEST_METHOD(TestFilterAndFiltfilt) { vectord b_coeff = { }; vectord a_coeff = { }; vectord input_signal = { }; vectord y_filter_ori = { }; vectord y_filtfilt_ori = { }; vectord y_filter_out; vectord zi = { 0 }; filter(b_coeff, a_coeff, input_signal, y_filter_out, zi); Assert::IsTrue(compare(y_filter_out, y_filter_ori, 0.0001)); vectord y_filtfilt_out; filtfilt(b_coeff, a_coeff, input_signal, y_filtfilt_out); Assert::IsTrue(compare(y_filtfilt_out, y_filtfilt_ori, 0.0001)); } bool compare(const vectord &original, const vectord &expected, double tolerance = DBL_EPSILON) { if (original.size() != expected.size()) { return false; } size_t size = original.size(); for (size_t i = 0; i < size; ++i) { auto diff = abs(original[i] - expected[i]); if (diff >= tolerance) { return false; } } return true; }
source share