I want to start with that I am quite new in this community, so if this question does not belong here, please point me to the right place. Thank you!
Background
I am learning and writing a half-band filter in C++ using the famous Remez exchange algorithm. And I am implementing the filter following A “TRICK” for the Design of FIR Half-Band Filters. I am also using this blog as a reference. This is the source remez.cpp.
In the blog, section Half-Band Filter Design with NumPy, filter coefficients are generated using the python signal package from scipy module.
g = signal.remez(N//2+1, [0., 2*Fpb/Fs, .5, .5], [1, 0], [1, 1]) # The Trick
with numbers plugged in:
g = signal.remez(6, [0., 0.4, .5, .5], [1, 0], [1, 1]) # The Trick
And it outputs
g = [ 0.10753661 -0.18306401 0.62633938 0.62633938 -0.18306401 0.10753661]
Problem
Calling remez()
in remez.cpp
using the same specs, however, does not return the same coefficients.
/********************
* remez
*=======
* Calculates the optimal (in the Chebyshev/minimax sense)
* FIR filter impulse response given a set of band edges,
* the desired response on those bands, and the weight given to
* the error in those bands.
*
* INPUT:
* ------
* int numtaps - Number of filter coefficients
* int numband - Number of bands in filter specification
* double bands[] - User-specified band edges [2 * numband]
* double des[] - User-specified band responses [numband]
* double weight[] - User-specified error weights [numband]
* int type - Type of filter
*
* OUTPUT:
* -------
* double h[] - Impulse response of final filter [numtaps]
* returns - true on success, false on failure to converge
********************/
int numOrder = 5;
std::vector<double> h(numOrder + 1);
std::vector<double> bandsEdges = {0, 0.4, 0.5, 0.5};
std::vector<double> desiredAmps = {1, 0};
std::vector<double> weights = {1, 1};
remez(h.data(),6,2,bandsEdges.data(),desiredAmps.data(),weights.data(),1,16)
// Pseudo code
// h = [0.0154523, 0.115447, 0.343533, 0.343533, 0.115447, 0.0154523];
I've also tried in Matlab using the following command, and I also couldn't get the same coefficients as Python ones.
h = firpm(5,[0 0.8 1 1],[1,1,0,0],[1,1]);
h = [0.089673, -0.176451, 0.624020, 0.624020, -0.176451, 0.089673];
Question
I am really baffled by the three completely different sets of results. Am I using the wrong specs in either Matlab or C++ remez?