Crate pm_remez

Crate pm_remez 

Source
Expand description

§Parks-McClellan Remez FIR design algorithm

The pm_remez crate is a modern implementation of the Parks-McClellan Remez exchange algorithm. It supports the design of FIR filters with even symmetry and odd symmetry, and with an even number of taps and an odd number of taps, by reducing all these cases to the even symmetry odd number of taps case. The desired frequency response in each band, as well as the weights, can be defined as arbitrary functions. The crate supports using num-bigfloat, or any other high precision floating point package that implements the Float trait for the calculations. This can be used to solve numerically challenging problems that are difficult to solve using f64 arithmetic.

The implementation draws ideas from [2] to make the algorithm robust against numerical errors. These ideas include the use of Chebyshev proxy root finding to find the extrema of the weighted error function in the Remez exchange step.

§Examples

The main function of this crate is pm_remez, which takes a DesignParameters object defining the filter to be constructed and returns a PMDesign struct containing the filter taps and other information. There are two coding styles in which this function can be used.

The first style uses BandSetting to define each band, setting the desired response and weight separately on each band. The following constructs a lowpass filter by setting the desired response to a constant of one in the passband and a constant of zero in the stopband. Other kinds of reponses can be specified with linear (linear slope interpolating two values) and function (arbitrary function). A weight different from the default of constant(1.0) can be provided with BandSetting::with_weight. The weight can be defined using constant, linear or function.

use pm_remez::{
    constant, pm_parameters, pm_remez,
    BandSetting, PMParameters, ParametersBuilder,
};
let bands = [
    BandSetting::new(0.0, 0.2, constant(1.0))?,
    BandSetting::new(0.3, 0.5, constant(0.0))?,
];
let num_taps = 35;
let parameters = pm_parameters(num_taps, &bands)?;
let design = pm_remez(&parameters)?;

The second style is closer to how the pm_remez function is implemented. It uses the PMParameters struct to define a list of Bands and the desired response and weight as single functions for all the bands. The pm_remez function is generic in the types of the desired response and weight functions, so this style can enable more compile time optimizations by using monomorphization.

This designs the same lowpass filter using this second coding style.

use pm_remez::{pm_remez, Band, BandSetting, PMParameters};
let num_taps = 35;
let parameters = PMParameters::new(
    num_taps,
    vec![Band::new(0.0, 0.2)?, Band::new(0.3, 0.5)?],
    |f| if f < 0.25 { 1.0 } else { 0.0 },
    |_| 1.0,
)?;
let design = pm_remez(&parameters)?;

The documentation of the Python bindings contains a series of examples that show how to use pm-remez to design commonly used types of FIR filters. These examples are also useful to understand how the Rust pm_remez function can be used.

§Building

The pm_remez crate supports different backends to solve eigenvalue problems. These are selected with feature flags. See EigenvalueBackend for more details. By default, only the faer backend is enabled, which is a pure Rust implementation.

Another supported backend uses ndarray_linalg to solve eigenvalue problems with LAPACK. It is enabled with the lapack-backend feature flag. The pm_remez crate has several feature flags that are used to select the LAPACK backend. Exactly one of these features needs to be enabled to build pm_remez with the lapack-backend flag. The feature flags are openblas-static, openblas-system, netlib-static, netlib-system, intel-mkl-static and intel-mkl-system. The -static versions of each flag build the LAPACK backend and link statically against it. The -system versions link against a system-installed library (linking can be dynamic or static depending on which type of library is installed).

§References

[1] M. Ahsan and T. Saramaki, “Two Novel Implementations of the Remez Multiple Exchange Algorithm for Optimum FIR Filter Design”, MATLAB - A Fundamental Tool for Scientific Computing and Engineering Applications - Volume 2. InTech, Sep. 26, 2012.

[2] S.I. Filip. “A Robust and Scalable Implementation of the Parks-McClellan Algorithm for Designing FIR Filters,” in ACM Trans. Math. Softw. 43, 1, Article 7, March 2017.

[3] J. McClellan, T. Parks and L. Rabiner, “A computer program for designing optimum FIR linear phase digital filters,” in IEEE Transactions on Audio and Electroacoustics, vol. 21, no. 6, pp. 506-526, December 1973

[4] T. Parks and J. McClellan, “Chebyshev Approximation for Nonrecursive Digital Filters with Linear Phase,” in IEEE Transactions on Circuit Theory, vol. 19, no. 2, pp. 189-194, March 1972.

[5] B.N. Parlett and C. Reinsch, “Balancing a matrix for calculation of eigenvalues and eigenvectors”. Numer. Math. 13, 293–304 (1969).

Modules§

error
Error types used by pm_remez.
order_estimates
FIR filter order estimates.

Structs§

Band
Band.
BandSetting
Band with desired response and weight Settings.
FaerBackend
faer eigenvalue backend.
LapackBackend
LAPACK eigenvalue backend.
NalgebraBackend
nalgebra eigenvalue backend.
PMDesign
A FIR filter design produced by the pm_remez function.
PMParameters
Parks-McClellan design parameters struct.
Setting
Desired response or weight setting.

Enums§

Symmetry
Symmetry of the FIR filter taps.

Traits§

Convf64
Conversion between a type and f64.
DesignParameters
Parks-McClellan design parameters trait.
EigenvalueBackend
Eigenvalue backend.
IsLapack
Marker trait used to mark for which types that have the trait Lapack, the trait ToLapack should be implemented as a no-op conversion.
ParametersBuilder
Parks-McClellan design parameters setter trait.
ToLapack
Conversion to a LAPACK-compatible scalar.

Functions§

constant
Creates a Setting that represents a constant function.
function
Creates a Setting that represents an arbitrary function.
linear
Creates a Setting that represents a linear function.
pm_parameters
Creates parameters for the Parks-McClellan algorithm in terms of a list of BandSettings.
pm_remez
Parks-McClellan Remez exchange algorithm.
pm_remez_with_backend
Parks-McClellan Remez exchange algorithm with eigenvalue backend.

Type Aliases§

DefaultEigenvalueBackend
Default eigenvalue backend.