REMEZ

The Remez exchange algorithm is used to design minimax optimal FIR filters. A minimax filter is optimal in the sense that the maximum error between the desired frequency response and the actual frequency response is minimized over the specified frequency bands.

This technique is also known as equiripple filter design because the error oscillations in the passband and stopband are of equal magnitude.

Excel Usage

=REMEZ(numtaps, bands, desired, weight, filter_type, maxiter, grid_density, fs)
  • numtaps (int, required): The desired number of taps in the filter.
  • bands (list[list], required): A monotonic sequence containing the band edges.
  • desired (list[list], required): A sequence half the size of bands containing the desired gain in each band.
  • weight (list[list], optional, default: null): Relative weighting for each band region.
  • filter_type (str, optional, default: “bandpass”): The type of filter.
  • maxiter (int, optional, default: 25): Maximum number of iterations.
  • grid_density (int, optional, default: 16): Grid density.
  • fs (float, optional, default: null): The sampling frequency of the signal.

Returns (list[list]): Coefficients of the optimal FIR filter as a 2D array.

Example 1: Simple low-pass

Inputs:

numtaps bands desired
3 0 0.1 0.2 0.5 1 0

Excel formula:

=REMEZ(3, {0,0.1,0.2,0.5}, {1,0})

Expected output:

Result
0.276393 0.190983 0.276393
Example 2: Band-pass

Inputs:

numtaps bands desired
11 0 0.1 0.2 0.3 0.4 0.5 0 1 0

Excel formula:

=REMEZ(11, {0,0.1,0.2,0.3,0.4,0.5}, {0,1,0})

Expected output:

Result
-4.2895e-17 0.0599308 -3.53253e-17 -0.299285 1.26162e-18 0.380323 1.26162e-18 -0.299285 -3.53253e-17 0.0599308 -4.2895e-17

Python Code

Show Code
import numpy as np
from scipy.signal import remez as scipy_remez

def remez(numtaps, bands, desired, weight=None, filter_type='bandpass', maxiter=25, grid_density=16, fs=None):
    """
    Calculate the minimax optimal filter using the Remez exchange algorithm.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.remez.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        numtaps (int): The desired number of taps in the filter.
        bands (list[list]): A monotonic sequence containing the band edges.
        desired (list[list]): A sequence half the size of bands containing the desired gain in each band.
        weight (list[list], optional): Relative weighting for each band region. Default is None.
        filter_type (str, optional): The type of filter. Valid options: Bandpass, Differentiator, Hilbert. Default is 'bandpass'.
        maxiter (int, optional): Maximum number of iterations. Default is 25.
        grid_density (int, optional): Grid density. Default is 16.
        fs (float, optional): The sampling frequency of the signal. Default is None.

    Returns:
        list[list]: Coefficients of the optimal FIR filter as a 2D array.
    """
    try:
        def to_flat_list(val):
            if val is None: return None
            if isinstance(val, list):
                return [float(v) for row in val for v in row]
            return [float(val)]

        bands_flat = to_flat_list(bands)
        desired_flat = to_flat_list(desired)
        weight_flat = to_flat_list(weight)

        result = scipy_remez(
            int(numtaps), 
            bands_flat, 
            desired_flat, 
            weight=weight_flat, 
            type=filter_type, 
            maxiter=int(maxiter), 
            grid_density=int(grid_density), 
            fs=float(fs) if fs is not None else None
        )

        return [result.tolist()]
    except Exception as e:
        return f"Error: {str(e)}"

Online Calculator

The desired number of taps in the filter.
A monotonic sequence containing the band edges.
A sequence half the size of bands containing the desired gain in each band.
Relative weighting for each band region.
The type of filter.
Maximum number of iterations.
Grid density.
The sampling frequency of the signal.