graph TD
A[Start: What is your primary objective?] --> B{Need to design a filter?}
B -- Yes --> C{Specs are in pass/stop constraints?}
C -- Yes --> D[Use IIRDESIGN]
C -- No --> E{IIR or FIR preference?}
E -- IIR --> F{Ripple policy}
F -- Flat passband --> G[BUTTER]
F -- Passband ripple OK --> H[CHEBY1]
F -- Stopband ripple OK --> I[CHEBY2]
F -- Steepest transition --> J[ELLIP]
E -- FIR --> K{Design criterion}
K -- Windowed practical design --> L[FIRWIN + GET_WINDOW]
K -- Minimax equiripple --> M[REMEZ]
B -- No --> N{Need to apply existing filter or smooth data?}
N -- Zero-phase IIR/FIR apply --> O[SOSFILTFILT or FILTFILT]
N -- Preserve peaks/trends --> P[SAVGOL_FILTER]
N -- Gaussian-noise smoothing --> Q[GAUSSIAN_FILTER1D]
N -- Remove impulsive spikes --> R[MEDFILT]
A --> S[Always validate response with FREQZ]
Filtering
Overview
Introduction Filtering is the process of transforming a signal to emphasize information of interest and suppress information that interferes with analysis, control, or communication. In mathematical terms, a filter maps an input sequence x[n] (or continuous signal x(t)) to an output sequence y[n] by applying a defined frequency-selective or neighborhood-selective operation. In practical engineering and analytics work, filtering is one of the highest-leverage preprocessing steps because it improves signal-to-noise ratio, stabilizes downstream models, and makes decision thresholds more reliable. A broad conceptual reference is Digital filter.
For business and technical users, filtering matters whenever measurements are imperfect, sampled data are noisy, or downstream workflows assume smoother trends than raw sensors provide. Manufacturing QA teams filter vibration channels before predictive maintenance scoring. Energy analysts smooth telemetry before anomaly detection to avoid expensive false alarms. Product analytics teams use smoothing and median operations on event-rate series to separate structural behavior from short-lived spikes.
This category centers on the Python SciPy signal processing stack and one complementary function from SciPy ndimage. The tools in this page span three capabilities:
- Designing filters from specs or prototypes: BUTTER, CHEBY1, CHEBY2, ELLIP, IIRDESIGN, FIRWIN, REMEZ, and GET_WINDOW.
- Applying filters to data safely and with controlled edge behavior: FILTFILT, SOSFILTFILT, SAVGOL_FILTER, GAUSSIAN_FILTER1D, and MEDFILT.
- Verifying behavior before deployment: FREQZ for magnitude and phase response inspection.
These functions are not alternatives in a single linear list; they are a toolkit that supports complete workflows. A typical process is: define requirements, choose design method, generate coefficients, evaluate response, apply filtering with a numerically stable method, and validate against business tolerances (delay, overshoot, attenuation, false-positive rate, etc.). The category is therefore most useful when used as a system, not as isolated formulas.
When to Use It Filtering should be used when raw data fidelity is lower than the fidelity required by the decision being made. In real systems, this usually means one of three situations: high-frequency noise obscures a low-frequency trend, narrowband interference contaminates a measurement, or impulse artifacts distort summary metrics. The choice of function depends on what must be preserved (phase, peaks, edges, derivative shape) and what can be traded away (latency, ripple, transition sharpness, computational cost).
One common scenario is industrial monitoring and predictive maintenance. Suppose a plant tracks motor current and bearing vibration at fixed sampling rates. Analysts may use IIRDESIGN to encode passband and stopband requirements directly from reliability thresholds, then apply SOSFILTFILT for zero-phase offline cleaning before fault feature extraction. If the team needs a simpler prototype with flatter passband behavior, BUTTER is often the first baseline. If they need tighter transitions at fixed order, ELLIP may reduce leakage into stopbands, with an explicit ripple trade-off. Before deployment, FREQZ checks whether attenuation targets at known fault frequencies are actually met.
A second scenario is financial or operations time-series smoothing where shape preservation matters. Raw conversion rates, demand traces, or queue times often contain short shocks and missing-data artifacts. If analysts need trend smoothing but must preserve peak timing and curvature for downstream derivative-based alerts, SAVGOL_FILTER is frequently superior to plain moving averages because local polynomial fits preserve moments better. If the data include occasional extreme spikes (for example, one bad ingest batch), MEDFILT can remove impulses while retaining discontinuities that may be operationally meaningful. For broadly Gaussian measurement noise, GAUSSIAN_FILTER1D offers intuitive scale control through \sigma.
A third scenario is communications/audio/sensor front-end design where strict frequency-domain targets are contractually or physically required. If the requirement is “minimum order meeting passband/stopband specs,” IIRDESIGN is usually the right entry point. If linear phase is mandatory (for waveform morphology or pulse timing), teams move to FIR methods such as FIRWIN and REMEZ. REMEZ is especially useful when minimizing worst-case error over bands is the core objective, while GET_WINDOW supports practical window selection in FFT and FIR workflows. Throughout this process, FREQZ remains the validation tool for transfer-function behavior.
In short, use this category when the job is not simply “smooth a line,” but “prepare signals so decisions are robust.” The calculators are most valuable when requirements are concrete: allowable passband loss, minimum stopband attenuation, acceptable phase distortion, maximum processing delay, and tolerance for edge artifacts.
How It Works At a high level, digital filtering treats data as a discrete-time signal and applies a system with transfer function
H(z) = \frac{\sum_{m=0}^{M} b_m z^{-m}}{\sum_{n=0}^{N} a_n z^{-n}},
so that output is governed by the difference equation
y[n] = \sum_{m=0}^{M} b_m x[n-m] - \sum_{n=1}^{N} a_n y[n-n].
For FIR filters, a_n=0 for n\ge 1, producing guaranteed stability and often linear phase with symmetric coefficients. For IIR filters, feedback terms provide sharper transitions for lower order, but introduce phase nonlinearity and stronger numerical sensitivity. The functions in this category map directly to those design families.
For IIR prototype families:
- BUTTER implements the Butterworth family, with maximally flat passband magnitude and monotonic behavior.
- CHEBY1 allows passband ripple for steeper transitions.
- CHEBY2 places ripple in stopband instead, keeping passband monotonic.
- ELLIP allows ripple in both passband and stopband for the sharpest transition at a given order.
Conceptually, these families differ by where approximation error is distributed. That trade-off is why no single family dominates all use cases. In compliance-oriented applications, monotonic passband behavior from BUTTER can simplify interpretation. In bandwidth-constrained systems, ELLIP may meet attenuation with lower order, reducing compute and memory.
IIRDESIGN sits one level above family-specific design by solving for a minimum-order design that satisfies edge frequencies and gain constraints (g_{pass}, g_{stop}). This is often closer to how requirements are written in engineering specs, which is why it is a strong default for production design.
For FIR design:
- FIRWIN uses the window method: start from an ideal impulse response and taper it with a window to control sidelobes.
- REMEZ uses minimax optimization to equalize worst-case error across constrained bands.
- GET_WINDOW generates specific windows (Hann, Hamming, Blackman, Kaiser, Tukey, etc.) used in both FIR and spectral workflows.
In frequency-domain terms, window selection controls leakage and transition characteristics. Narrow main lobes improve resolution; low sidelobes improve out-of-band suppression. The choice is application-specific and often empirical.
After design, response verification is essential. FREQZ evaluates H(e^{j\omega}) on a grid and returns frequency, magnitude, and phase. Magnitude confirms attenuation and passband ripple targets. Phase (or group delay derived from it) reveals timing distortion risk. Teams that skip this step frequently ship filters that “work” numerically but violate domain tolerances.
Application functions then transform real data:
- FILTFILT applies a filter forward and backward to achieve near-zero phase distortion and effectively doubled order.
- SOSFILTFILT does the same using second-order sections for better numerical conditioning, particularly important for higher-order IIR designs.
- SAVGOL_FILTER performs local polynomial smoothing (or derivative estimation), preserving local structure better than boxcar averages.
- GAUSSIAN_FILTER1D convolves with a Gaussian kernel
G(x) = \frac{1}{\sqrt{2\pi}\sigma} e^{-x^2/(2\sigma^2)},
which suppresses high-frequency components with tunable scale. - MEDFILT replaces each sample with the neighborhood median, a nonlinear approach robust to impulsive outliers.
Two assumptions recur across this category. First, stationarity assumptions are often implicit: many frequency-domain interpretations are most meaningful when local signal characteristics are not drifting too fast relative to filter support. Second, edge handling matters: padding mode and window length can dominate behavior near boundaries, especially on short records. In business pipelines with daily or hourly batch sizes, edge artifacts can materially affect KPI calculations if not explicitly tested.
From a tooling standpoint, these calculators are wrappers around SciPy’s battle-tested implementations in scipy.signal and scipy.ndimage, which means users gain mature numerical methods while staying in an Excel-accessible or calculator-friendly environment. Upstream references: SciPy signal docs, SciPy window functions, and SciPy ndimage docs.
Practical Example Consider a reliability analyst responsible for detecting bearing wear from a vibration channel sampled at 2 kHz. The raw signal contains broadband noise, line-frequency interference, and occasional impulsive spikes from instrumentation glitches. The analyst needs features that are stable enough for weekly trend dashboards and sensitive enough for early-fault detection.
Step 1 is requirement framing. The analyst defines: passband preserving fault-related energy between 40–300 Hz, stopband suppression below 20 Hz and above 450 Hz, passband loss under 1 dB, and stopband attenuation over 50 dB. Because requirements are stated as performance targets (not order), IIRDESIGN is the most direct starting point.
Step 2 is candidate design generation. The analyst builds an IIR with IIRDESIGN, then also creates a baseline BUTTER design and a sharper ELLIP alternative for comparison. If review requires explicit passband-ripple governance, CHEBY1 and CHEBY2 provide additional controlled trade-offs.
Step 3 is response verification. Using FREQZ, the analyst checks three curves per candidate: magnitude, phase, and practical transition behavior near cutoffs. The design is accepted only if attenuation and ripple constraints are met with margin under expected sampling variability. This validation step is where many theoretical designs are rejected before any production use.
Step 4 is numerically stable deployment choice. Even if the design is first generated in transfer-function form (b,a), the analyst stores and applies it in SOS form and runs SOSFILTFILT on historical batches to avoid phase shift and reduce round-off risk. FILTFILT remains useful for low-order or educational cases, but SOS is preferred in production-grade pipelines.
Step 5 is artifact cleanup and feature-preserving smoothing. After band filtering, isolated spikes still appear due to occasional sensor faults. A short-window MEDFILT removes these impulses with minimal smearing. If feature extraction relies on smooth derivatives (e.g., slope of RMS envelope), SAVGOL_FILTER is applied to the derived sequence with a window/polyorder pair tuned to preserve peak width. For channels dominated by Gaussian-like measurement noise, GAUSSIAN_FILTER1D may replace Savitzky–Golay as a simpler smoother.
Step 6 is FIR cross-check for governance. Some teams require linear-phase auditability. The analyst designs a comparable FIR using FIRWIN with candidate windows from GET_WINDOW, then a tighter equiripple design using REMEZ. The FIR alternatives may require more taps (higher compute), but provide transparent linear-phase behavior that can simplify stakeholder review.
Step 7 is operationalization in Boardflare. The final workflow becomes repeatable: design parameters are versioned, FREQZ acceptance plots are documented, and filtering calls are embedded in scheduled calculators. Compared with manually chained Excel formulas, this approach reduces copy/paste risk, makes design assumptions explicit, and keeps methods consistent across analysts.
Outcome: fewer false maintenance alarms, more stable trend metrics, and a documented signal-conditioning path that can be audited and tuned without rewriting the whole model.
How to Choose Use this category by deciding first on objective, then on constraints. The most common mistake is selecting by familiarity (for example, always using Butterworth) rather than by problem structure.
The table below summarizes function selection in practical terms.
| Function | Best used for | Strengths | Trade-offs / cautions |
|---|---|---|---|
| IIRDESIGN | Designing from pass/stop specs | Directly maps to engineering requirements; minimum-order workflow | Requires clear spec definition; may choose family characteristics you need to review |
| BUTTER | Smooth monotonic IIR baseline | Flat passband, simple interpretation | Slower transition than ripple-allowing families for same order |
| CHEBY1 | Sharper IIR with passband ripple tolerance | Better roll-off than Butterworth at similar order | Passband ripple can affect amplitude-sensitive metrics |
| CHEBY2 | Flat passband with stopband ripple | Useful when passband smoothness is critical | Transition behavior can be less convenient near cutoff |
| ELLIP | Maximum transition sharpness per order | Efficient where order/computation is constrained | Ripple in both bands; interpretation and tuning complexity |
| FIRWIN | Practical linear-phase FIR design | Stable FIR coefficients; intuitive with windows | More taps often required for sharp transitions |
| REMEZ | Minimax/equiripple FIR design | Controls worst-case error over bands | Setup is more sensitive (bands, weights, density) |
| GET_WINDOW | Choosing spectral/FIR windows | Fast comparison of window families | Wrong window choice can mask leakage or broaden transitions |
| FILTFILT | Zero-phase filtering in (b,a) form | No phase delay; easy with existing coefficients | Less numerically robust than SOS at high orders |
| SOSFILTFILT | Production zero-phase filtering with IIR | Better numerical stability; preferred for high order | Requires SOS coefficients and section management |
| SAVGOL_FILTER | Smoothing while preserving local shape | Retains peaks/widths better than moving average; supports derivatives | Window and polynomial must be tuned to sampling density |
| GAUSSIAN_FILTER1D | Scale-controlled Gaussian smoothing | Intuitive \sigma control; effective high-frequency suppression | Can blur sharp events if \sigma is too large |
| MEDFILT | Impulse/no-spike cleanup | Robust to outliers; edge-preserving for discontinuities | Nonlinear behavior may distort fine oscillatory content |
| FREQZ | Verifying digital filter response | Immediate magnitude/phase diagnostics | Only diagnostic; does not design or apply filters itself |
A practical decision sequence is:
- Translate business tolerance into signal specs (allowed attenuation, ripple, delay, and artifact risk).
- Choose design family: IIRDESIGN for spec-driven IIR, or FIRWIN/REMEZ for linear-phase FIR.
- Validate with FREQZ before touching production data.
- Apply with SOSFILTFILT when possible; reserve FILTFILT for simpler/legacy (b,a) paths.
- Add targeted post-processing only when needed: MEDFILT, SAVGOL_FILTER, or GAUSSIAN_FILTER1D.
This choice framework keeps the category coherent: design functions shape the transfer function, application functions transform the data, and diagnostics verify that engineering intent matches actual behavior.
BUTTER
The Butterworth filter is a type of signal processing filter designed to have a frequency response as flat as possible in the passband. It is also referred to as a maximally flat magnitude filter.
For an Nth-order Butterworth low-pass filter, the magnitude squared of the frequency response is:
|H(j\omega)|^2 = \frac{1}{1 + (\frac{\omega}{\omega_c})^{2N}}
where N is the filter order and \omega_c is the cutoff frequency.
Excel Usage
=BUTTER(N, Wn, btype, filter_output_form, analog, fs)
N(int, required): The order of the filter.Wn(list[list], required): Critical frequency or frequencies.btype(str, optional, default: “lowpass”): The type of filter.filter_output_form(str, optional, default: “ba”): Type of output representation.analog(bool, optional, default: false): When True, return an analog filter.fs(float, optional, default: null): The sampling frequency of the digital system.
Returns (list[list]): Filter coefficients or representation.
Example 1: Low-pass (b, a)
Inputs:
| N | Wn | btype |
|---|---|---|
| 2 | 0.1 | lowpass |
Excel formula:
=BUTTER(2, 0.1, "lowpass")
Expected output:
| Result | ||
|---|---|---|
| 0.0200834 | 0.0401667 | 0.0200834 |
| 1 | -1.56102 | 0.641352 |
Example 2: High-pass (SOS)
Inputs:
| N | Wn | btype | fs | filter_output_form |
|---|---|---|---|---|
| 4 | 100 | highpass | 1000 | sos |
Excel formula:
=BUTTER(4, 100, "highpass", 1000, "sos")
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 0.432847 | -0.865693 | 0.432847 | 1 | -1.0486 | 0.29614 |
| 1 | -2 | 1 | 1 | -1.32091 | 0.632739 |
Python Code
Show Code
import numpy as np
from scipy.signal import butter as scipy_butter
def butter(N, Wn, btype='lowpass', filter_output_form='ba', analog=False, fs=None):
"""
Butterworth digital and analog filter design.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.butter.html
This example function is provided as-is without any representation of accuracy.
Args:
N (int): The order of the filter.
Wn (list[list]): Critical frequency or frequencies.
btype (str, optional): The type of filter. Valid options: Lowpass, Highpass, Bandpass, Bandstop. Default is 'lowpass'.
filter_output_form (str, optional): Type of output representation. Valid options: Numerator/Denominator, Pole-Zero, Second-Order Sections. Default is 'ba'.
analog (bool, optional): When True, return an analog filter. Default is False.
fs (float, optional): The sampling frequency of the digital system. Default is None.
Returns:
list[list]: Filter coefficients or representation.
"""
try:
if isinstance(Wn, list):
wn_flat = [float(v) for row in Wn for v in row]
wn_val = wn_flat[0] if len(wn_flat) == 1 else wn_flat
else:
wn_val = float(Wn)
result = scipy_butter(
int(N),
wn_val,
btype=btype,
analog=bool(analog),
output=filter_output_form,
fs=float(fs) if fs is not None else None
)
if filter_output_form == 'ba':
b, a = result
max_len = max(len(b), len(a))
return [b.tolist() + [""] * (max_len - len(b)), a.tolist() + [""] * (max_len - len(a))]
elif filter_output_form == 'zpk':
z, p, k = result
max_len = max(len(z), len(p), 1)
return [z.tolist() + [""] * (max_len - len(z)), p.tolist() + [""] * (max_len - len(p)), [float(k)] + [""] * (max_len - 1)]
else: # sos
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
CHEBY1
The Chebyshev Type I filter is designed to have a steeper roll-off than the Butterworth filter. This is achieved at the expense of allowing ripple in the passband.
These filters have the property that they minimize the peak error over the passband by allowing an equiripple response.
|H(j\omega)|^2 = \frac{1}{1 + \epsilon^2 T_n^2(\frac{\omega}{\omega_c})}
where T_n is the n-th order Chebyshev polynomial.
Excel Usage
=CHEBY1(N, rp, Wn, btype, filter_output_form, analog, fs)
N(int, required): The order of the filter.rp(float, required): The maximum ripple allowed below unity gain in the passband (dB).Wn(list[list], required): Critical frequency or frequencies.btype(str, optional, default: “lowpass”): The type of filter.filter_output_form(str, optional, default: “ba”): Type of output representation.analog(bool, optional, default: false): When True, return an analog filter.fs(float, optional, default: null): The sampling frequency of the digital system.
Returns (list[list]): Filter coefficients or representation as a 2D array.
Example 1: Low-pass (b, a)
Inputs:
| N | rp | Wn | btype |
|---|---|---|---|
| 2 | 1 | 0.1 | lowpass |
Excel formula:
=CHEBY1(2, 1, 0.1, "lowpass")
Expected output:
| Result | ||
|---|---|---|
| 0.0205152 | 0.0410304 | 0.0205152 |
| 1 | -1.61852 | 0.710593 |
Example 2: Band-pass (SOS)
Inputs:
| N | rp | Wn | btype | filter_output_form | |
|---|---|---|---|---|---|
| 2 | 0.5 | 0.2 | 0.4 | bandpass | sos |
Excel formula:
=CHEBY1(2, 0.5, {0.2,0.4}, "bandpass", "sos")
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 0.0930926 | 0.186185 | 0.0930926 | 1 | -0.467443 | 0.589099 |
| 1 | -2 | 1 | 1 | -1.4082 | 0.72872 |
Python Code
Show Code
import numpy as np
from scipy.signal import cheby1 as scipy_cheby1
def cheby1(N, rp, Wn, btype='lowpass', filter_output_form='ba', analog=False, fs=None):
"""
Chebyshev Type I digital and analog filter design (passband ripple).
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.cheby1.html
This example function is provided as-is without any representation of accuracy.
Args:
N (int): The order of the filter.
rp (float): The maximum ripple allowed below unity gain in the passband (dB).
Wn (list[list]): Critical frequency or frequencies.
btype (str, optional): The type of filter. Valid options: Lowpass, Highpass, Bandpass, Bandstop. Default is 'lowpass'.
filter_output_form (str, optional): Type of output representation. Valid options: Numerator/Denominator, Pole-Zero, Second-Order Sections. Default is 'ba'.
analog (bool, optional): When True, return an analog filter. Default is False.
fs (float, optional): The sampling frequency of the digital system. Default is None.
Returns:
list[list]: Filter coefficients or representation as a 2D array.
"""
try:
if isinstance(Wn, list):
wn_flat = [float(v) for row in Wn for v in row]
wn_val = wn_flat[0] if len(wn_flat) == 1 else wn_flat
else:
wn_val = float(Wn)
result = scipy_cheby1(
int(N),
float(rp),
wn_val,
btype=btype,
analog=bool(analog),
output=filter_output_form,
fs=float(fs) if fs is not None else None
)
if filter_output_form == 'ba':
b, a = result
max_len = max(len(b), len(a))
return [b.tolist() + [""] * (max_len - len(b)), a.tolist() + [""] * (max_len - len(a))]
elif filter_output_form == 'zpk':
z, p, k = result
max_len = max(len(z), len(p), 1)
return [z.tolist() + [""] * (max_len - len(z)), p.tolist() + [""] * (max_len - len(p)), [float(k)] + [""] * (max_len - 1)]
else: # sos
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
CHEBY2
The Chebyshev Type II filter, also known as the inverse Chebyshev filter, is designed to have a flat response in the passband and ripple in the stopband.
Compared to Type I, Type II filters have no ripple in the passband and a slower roll-off near the cutoff frequency, but they provide better attenuation further into the stopband for a given order.
Excel Usage
=CHEBY2(N, rs, Wn, btype, filter_output_form, analog, fs)
N(int, required): The order of the filter.rs(float, required): The minimum attenuation required in the stop band (dB).Wn(list[list], required): Critical frequency or frequencies.btype(str, optional, default: “lowpass”): The type of filter.filter_output_form(str, optional, default: “ba”): Type of output representation.analog(bool, optional, default: false): When True, return an analog filter.fs(float, optional, default: null): The sampling frequency of the digital system.
Returns (list[list]): Filter coefficients or representation as a 2D array.
Example 1: Low-pass (b, a)
Inputs:
| N | rs | Wn | btype |
|---|---|---|---|
| 2 | 40 | 0.1 | lowpass |
Excel formula:
=CHEBY2(2, 40, 0.1, "lowpass")
Expected output:
| Result | ||
|---|---|---|
| 0.0101759 | -0.0184072 | 0.0101759 |
| 1 | -1.93697 | 0.93892 |
Example 2: Band-stop (SOS)
Inputs:
| N | rs | Wn | btype | filter_output_form | |
|---|---|---|---|---|---|
| 2 | 20 | 0.2 | 0.4 | bandstop | sos |
Excel formula:
=CHEBY2(2, 20, {0.2,0.4}, "bandstop", "sos")
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 0.420673 | -0.343526 | 0.420673 | 1 | -0.00116017 | 0.344412 |
| 1 | -1.53157 | 1 | 1 | -1.4681 | 0.641703 |
Python Code
Show Code
import numpy as np
from scipy.signal import cheby2 as scipy_cheby2
def cheby2(N, rs, Wn, btype='lowpass', filter_output_form='ba', analog=False, fs=None):
"""
Chebyshev Type II digital and analog filter design (stopband ripple).
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.cheby2.html
This example function is provided as-is without any representation of accuracy.
Args:
N (int): The order of the filter.
rs (float): The minimum attenuation required in the stop band (dB).
Wn (list[list]): Critical frequency or frequencies.
btype (str, optional): The type of filter. Valid options: Lowpass, Highpass, Bandpass, Bandstop. Default is 'lowpass'.
filter_output_form (str, optional): Type of output representation. Valid options: Numerator/Denominator, Pole-Zero, Second-Order Sections. Default is 'ba'.
analog (bool, optional): When True, return an analog filter. Default is False.
fs (float, optional): The sampling frequency of the digital system. Default is None.
Returns:
list[list]: Filter coefficients or representation as a 2D array.
"""
try:
if isinstance(Wn, list):
wn_flat = [float(v) for row in Wn for v in row]
wn_val = wn_flat[0] if len(wn_flat) == 1 else wn_flat
else:
wn_val = float(Wn)
result = scipy_cheby2(
int(N),
float(rs),
wn_val,
btype=btype,
analog=bool(analog),
output=filter_output_form,
fs=float(fs) if fs is not None else None
)
if filter_output_form == 'ba':
b, a = result
max_len = max(len(b), len(a))
return [b.tolist() + [""] * (max_len - len(b)), a.tolist() + [""] * (max_len - len(a))]
elif filter_output_form == 'zpk':
z, p, k = result
max_len = max(len(z), len(p), 1)
return [z.tolist() + [""] * (max_len - len(z)), p.tolist() + [""] * (max_len - len(p)), [float(k)] + [""] * (max_len - 1)]
else: # sos
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
ELLIP
Elliptic filters, also known as Cauer filters, are designed to have ripple in both the passband and the stopband.
For a given order and given maximum passband ripple and minimum stopband attenuation, elliptic filters provide the steepest roll-off of all the standard filter types (Butterworth, Chebyshev Type I and II).
Excel Usage
=ELLIP(N, rp, rs, Wn, btype, filter_output_form, analog, fs)
N(int, required): The order of the filter.rp(float, required): The maximum ripple allowed below unity gain in the passband (dB).rs(float, required): The minimum attenuation required in the stop band (dB).Wn(list[list], required): Critical frequency or frequencies.btype(str, optional, default: “lowpass”): The type of filter.filter_output_form(str, optional, default: “ba”): Type of output representation.analog(bool, optional, default: false): When True, return an analog filter.fs(float, optional, default: null): The sampling frequency of the digital system.
Returns (list[list]): Filter coefficients or representation as a 2D array.
Example 1: Low-pass (b, a)
Inputs:
| N | rp | rs | Wn | btype |
|---|---|---|---|---|
| 2 | 1 | 40 | 0.1 | lowpass |
Excel formula:
=ELLIP(2, 1, 40, 0.1, "lowpass")
Expected output:
| Result | ||
|---|---|---|
| 0.0289618 | 0.024609 | 0.0289618 |
| 1 | -1.61943 | 0.712032 |
Example 2: High-pass (b, a)
Inputs:
| N | rp | rs | Wn | fs | btype |
|---|---|---|---|---|---|
| 4 | 0.5 | 60 | 100 | 1000 | highpass |
Excel formula:
=ELLIP(4, 0.5, 60, 100, 1000, "highpass")
Expected output:
| Result | ||||
|---|---|---|---|---|
| 0.39801 | -1.56852 | 2.3412 | -1.56852 | 0.39801 |
| 1 | -2.22489 | 2.18891 | -1.00736 | 0.224874 |
Python Code
Show Code
import numpy as np
from scipy.signal import ellip as scipy_ellip
def ellip(N, rp, rs, Wn, btype='lowpass', filter_output_form='ba', analog=False, fs=None):
"""
Elliptic (Cauer) digital and analog filter design.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.ellip.html
This example function is provided as-is without any representation of accuracy.
Args:
N (int): The order of the filter.
rp (float): The maximum ripple allowed below unity gain in the passband (dB).
rs (float): The minimum attenuation required in the stop band (dB).
Wn (list[list]): Critical frequency or frequencies.
btype (str, optional): The type of filter. Valid options: Lowpass, Highpass, Bandpass, Bandstop. Default is 'lowpass'.
filter_output_form (str, optional): Type of output representation. Valid options: Numerator/Denominator, Pole-Zero, Second-Order Sections. Default is 'ba'.
analog (bool, optional): When True, return an analog filter. Default is False.
fs (float, optional): The sampling frequency of the digital system. Default is None.
Returns:
list[list]: Filter coefficients or representation as a 2D array.
"""
try:
if isinstance(Wn, list):
wn_flat = [float(v) for row in Wn for v in row]
wn_val = wn_flat[0] if len(wn_flat) == 1 else wn_flat
else:
wn_val = float(Wn)
result = scipy_ellip(
int(N),
float(rp),
float(rs),
wn_val,
btype=btype,
analog=bool(analog),
output=filter_output_form,
fs=float(fs) if fs is not None else None
)
if filter_output_form == 'ba':
b, a = result
max_len = max(len(b), len(a))
return [b.tolist() + [""] * (max_len - len(b)), a.tolist() + [""] * (max_len - len(a))]
elif filter_output_form == 'zpk':
z, p, k = result
max_len = max(len(z), len(p), 1)
return [z.tolist() + [""] * (max_len - len(z)), p.tolist() + [""] * (max_len - len(p)), [float(k)] + [""] * (max_len - 1)]
else: # sos
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
FILTFILT
The filtfilt function applies a linear digital filter twice, once forward and once backwards. The combined filter has zero phase distortion and a filter order twice that of the original.
This technique is primarily used when it is important to preserve the timing of features in the signal (i.e., zero phase shift), at the cost of being an offline/non-real-time process.
Excel Usage
=FILTFILT(x, b, a, axis, padtype, padlen, filtfilt_method, irlen)
x(list[list], required): The input array of data to be filtered.b(list[list], required): The numerator coefficient vector of the filter (1D array in Excel).a(list[list], required): The denominator coefficient vector of the filter (1D array in Excel).axis(int, optional, default: -1): The axis along which the filter is applied.padtype(str, optional, default: “odd”): Extension mode for padding at edges.padlen(int, optional, default: null): Number of elements to extend x by at both ends.filtfilt_method(str, optional, default: “pad”): Method for handling edges.irlen(int, optional, default: null): Impulse response length for Gustafsson’s method.
Returns (list[list]): The filtered signal as a 2D array.
Example 1: Zero-phase filtering
Inputs:
| x | b | a | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 4 | 3 | 2 | 1 | 0.02008337 | 0.04016673 | 0.02008337 | 1 | -1.56101808 | 0.64135154 |
Excel formula:
=FILTFILT({1,2,3,4,5,4,3,2,1}, {0.02008337,0.04016673,0.02008337}, {1,-1.56101808,0.64135154})
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 1.04833 | 1.45384 | 1.79308 | 2.02166 | 2.1079 | 2.0395 | 1.82648 | 1.49805 | 1.09582 |
Example 2: Gustafsson’s method
Inputs:
| x | b | a | filtfilt_method | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 4 | 3 | 2 | 1 | 0.02008337 | 0.04016673 | 0.02008337 | 1 | -1.56101808 | 0.64135154 | gust |
Excel formula:
=FILTFILT({1,2,3,4,5,4,3,2,1}, {0.02008337,0.04016673,0.02008337}, {1,-1.56101808,0.64135154}, "gust")
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 2.85538 | 2.9054 | 2.95971 | 3.00267 | 3.01908 | 3.00267 | 2.95971 | 2.9054 | 2.85538 |
Python Code
Show Code
import numpy as np
from scipy.signal import filtfilt as scipy_filtfilt
def filtfilt(x, b, a, axis=-1, padtype='odd', padlen=None, filtfilt_method='pad', irlen=None):
"""
Apply a digital filter forward and backward to a signal for zero phase distortion.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.filtfilt.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): The input array of data to be filtered.
b (list[list]): The numerator coefficient vector of the filter (1D array in Excel).
a (list[list]): The denominator coefficient vector of the filter (1D array in Excel).
axis (int, optional): The axis along which the filter is applied. Default is -1.
padtype (str, optional): Extension mode for padding at edges. Valid options: Odd, Even, Constant. Default is 'odd'.
padlen (int, optional): Number of elements to extend x by at both ends. Default is None.
filtfilt_method (str, optional): Method for handling edges. Valid options: Pad, Gustafsson. Default is 'pad'.
irlen (int, optional): Impulse response length for Gustafsson's method. Default is None.
Returns:
list[list]: The filtered signal as a 2D array.
"""
try:
def to_1d(v):
if isinstance(v, list):
return np.array([float(x) for row in v for x in row])
return np.array([float(v)])
def to2d(x):
return [[x]] if not isinstance(x, list) else x
x_arr = np.array(to2d(x))
b_arr = to_1d(b)
a_arr = to_1d(a)
# SciPy's filtfilt requires len(x) > padlen. If no padlen is provided, it
# defaults to 3*max(len(a), len(b)), which can be too large for short inputs.
# In that case, shrink padlen to len(x)-1 so the call succeeds.
padlen_arg = int(padlen) if padlen is not None else None
if padlen is None:
axis_int = int(axis)
if axis_int < 0:
axis_int = x_arr.ndim + axis_int
x_len = x_arr.shape[axis_int]
default_padlen = 3 * max(b_arr.size, a_arr.size)
if x_len <= default_padlen:
padlen_arg = max(0, x_len - 1)
result = scipy_filtfilt(
b_arr,
a_arr,
x_arr,
axis=int(axis),
padtype=padtype if padtype != "None" else None,
padlen=padlen_arg,
method=filtfilt_method,
irlen=int(irlen) if irlen is not None else None
)
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
FIRWIN
The window method of FIR filter design involves multiplying an ideal impulse response by a window function to produce a practical finite impulse response filter.
This function computes the coefficients of a finite impulse response filter with linear phase. These filters are stable and have a predictable phase response.
Excel Usage
=FIRWIN(numtaps, cutoff, window, pass_zero, scale, fs)
numtaps(int, required): Length of the filter (number of coefficients).cutoff(list[list], required): Cutoff frequency or frequencies (expressed in same units as fs).window(str, optional, default: “hamming”): Desired window to use (e.g., ‘hamming’, ‘hann’, ‘blackman’).pass_zero(bool, optional, default: true): If True, the gain at frequency 0 is 1.scale(bool, optional, default: true): Set to True to scale the coefficients for unity gain.fs(float, optional, default: null): The sampling frequency of the signal.
Returns (list[list]): Coefficients of the FIR filter as a 2D array.
Example 1: Simple low-pass
Inputs:
| numtaps | cutoff |
|---|---|
| 3 | 0.1 |
Excel formula:
=FIRWIN(3, 0.1)
Expected output:
| Result | ||
|---|---|---|
| 0.0679902 | 0.86402 | 0.0679902 |
Example 2: Band-pass
Inputs:
| numtaps | cutoff | pass_zero | |
|---|---|---|---|
| 11 | 0.2 | 0.4 | false |
Excel formula:
=FIRWIN(11, {0.2,0.4}, FALSE)
Expected output:
| Result | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| -3.70383e-18 | -0.0406874 | -0.128586 | -0.0780689 | 0.208783 | 0.395894 | 0.208783 | -0.0780689 | -0.128586 | -0.0406874 | -3.70383e-18 |
Python Code
Show Code
import numpy as np
from scipy.signal import firwin as scipy_firwin
def firwin(numtaps, cutoff, window='hamming', pass_zero=True, scale=True, fs=None):
"""
FIR filter design using the window method.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.firwin.html
This example function is provided as-is without any representation of accuracy.
Args:
numtaps (int): Length of the filter (number of coefficients).
cutoff (list[list]): Cutoff frequency or frequencies (expressed in same units as fs).
window (str, optional): Desired window to use (e.g., 'hamming', 'hann', 'blackman'). Default is 'hamming'.
pass_zero (bool, optional): If True, the gain at frequency 0 is 1. Default is True.
scale (bool, optional): Set to True to scale the coefficients for unity gain. Default is True.
fs (float, optional): The sampling frequency of the signal. Default is None.
Returns:
list[list]: Coefficients of the FIR filter as a 2D array.
"""
try:
if isinstance(cutoff, list):
cutoff_flat = [float(v) for row in cutoff for v in row]
cutoff_val = cutoff_flat[0] if len(cutoff_flat) == 1 else cutoff_flat
else:
cutoff_val = float(cutoff)
result = scipy_firwin(
int(numtaps),
cutoff_val,
window=window,
pass_zero=bool(pass_zero),
scale=bool(scale),
fs=float(fs) if fs is not None else None
)
# Return as a 2D list (single row)
return [result.tolist()]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
FREQZ
This function computes the complex frequency response of a digital filter defined by numerator and denominator coefficients.
For filter transfer function
H(z) = \frac{\sum_{m=0}^{M} b_m z^{-m}}{\sum_{n=0}^{N} a_n z^{-n}}
it evaluates H(e^{j\omega}) on a frequency grid and returns frequency, magnitude, and phase so response behavior can be analyzed directly in Excel.
Excel Usage
=FREQZ(b, a, wor_n, whole, fs, include_nyquist)
b(list[list], required): Numerator (feed-forward) filter coefficients.a(list[list], optional, default: [[1]]): Denominator (feedback) filter coefficients.wor_n(int, optional, default: 512): Number of frequency points to evaluate.whole(bool, optional, default: false): If True, compute response over the whole unit circle.fs(float, optional, default: 6.283185307179586): Sampling frequency in frequency units (radians per sample by default).include_nyquist(bool, optional, default: false): If True and wor_n is an integer, include the Nyquist frequency endpoint.
Returns (list[list]): A 2D array with rows for frequency, magnitude response, and phase response.
Example 1: Frequency response for a simple low-pass filter on default grid
Inputs:
| b | a | wor_n | ||
|---|---|---|---|---|
| 1 | 1 | 1 | -0.5 | 16 |
Excel formula:
=FREQZ({1,1}, {1,-0.5}, 16)
Expected output:
| Result | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.19635 | 0.392699 | 0.589049 | 0.785398 | 0.981748 | 1.1781 | 1.37445 | 1.5708 | 1.76715 | 1.9635 | 2.15984 | 2.35619 | 2.55254 | 2.74889 | 2.94524 |
| 4 | 3.83605 | 3.43491 | 2.95836 | 2.50777 | 2.11663 | 1.78561 | 1.50525 | 1.26491 | 1.05546 | 0.869597 | 0.701632 | 0.547095 | 0.40241 | 0.264635 | 0.131251 |
| 0 | -0.2873 | -0.538017 | -0.738334 | -0.893173 | -1.01319 | -1.10805 | -1.18498 | -1.24905 | -1.30377 | -1.35165 | -1.39448 | -1.43359 | -1.47002 | -1.50459 | -1.53798 |
Example 2: Frequency response with custom number of points
Inputs:
| b | a | wor_n | ||
|---|---|---|---|---|
| 1 | 0 | -1 | 1 | 16 |
Excel formula:
=FREQZ({1,0,-1}, {1}, 16)
Expected output:
| Result | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.19635 | 0.392699 | 0.589049 | 0.785398 | 0.981748 | 1.1781 | 1.37445 | 1.5708 | 1.76715 | 1.9635 | 2.15984 | 2.35619 | 2.55254 | 2.74889 | 2.94524 |
| 0 | 0.390181 | 0.765367 | 1.11114 | 1.41421 | 1.66294 | 1.84776 | 1.96157 | 2 | 1.96157 | 1.84776 | 1.66294 | 1.41421 | 1.11114 | 0.765367 | 0.390181 |
| 0 | 1.37445 | 1.1781 | 0.981748 | 0.785398 | 0.589049 | 0.392699 | 0.19635 | 0 | -0.19635 | -0.392699 | -0.589049 | -0.785398 | -0.981748 | -1.1781 | -1.37445 |
Example 3: Frequency response over full unit circle
Inputs:
| b | a | whole | wor_n | ||||
|---|---|---|---|---|---|---|---|
| 0.2 | 0.2 | 0.2 | 0.2 | 0.2 | 1 | true | 16 |
Excel formula:
=FREQZ({0.2,0.2,0.2,0.2,0.2}, {1}, TRUE, 16)
Expected output:
| Result | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.392699 | 0.785398 | 1.1781 | 1.5708 | 1.9635 | 2.35619 | 2.74889 | 3.14159 | 3.53429 | 3.92699 | 4.31969 | 4.71239 | 5.10509 | 5.49779 | 5.89049 |
| 1 | 0.852395 | 0.482843 | 0.0702307 | 0.2 | 0.235916 | 0.0828427 | 0.113291 | 0.2 | 0.113291 | 0.0828427 | 0.235916 | 0.2 | 0.0702307 | 0.482843 | 0.852395 |
| 0 | -0.785398 | -1.5708 | -2.35619 | 0 | -0.785398 | -1.5708 | 0.785398 | 0 | -0.785398 | 1.5708 | 0.785398 | 0 | 2.35619 | 1.5708 | 0.785398 |
Example 4: Frequency response including Nyquist endpoint
Inputs:
| b | a | wor_n | include_nyquist | |
|---|---|---|---|---|
| 1 | -1 | 1 | 16 | true |
Excel formula:
=FREQZ({1,-1}, {1}, 16, TRUE)
Expected output:
| Result | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.20944 | 0.418879 | 0.628319 | 0.837758 | 1.0472 | 1.25664 | 1.46608 | 1.67552 | 1.88496 | 2.0944 | 2.30383 | 2.51327 | 2.72271 | 2.93215 | 3.14159 |
| 0 | 0.209057 | 0.415823 | 0.618034 | 0.813473 | 1 | 1.17557 | 1.33826 | 1.48629 | 1.61803 | 1.73205 | 1.82709 | 1.90211 | 1.9563 | 1.98904 | 2 |
| 0 | 1.46608 | 1.36136 | 1.25664 | 1.15192 | 1.0472 | 0.942478 | 0.837758 | 0.733038 | 0.628319 | 0.523599 | 0.418879 | 0.314159 | 0.20944 | 0.10472 | 0 |
Python Code
Show Code
import numpy as np
from scipy.signal import freqz as scipy_freqz
def freqz(b, a=[[1]], wor_n=512, whole=False, fs=6.283185307179586, include_nyquist=False):
"""
Compute the frequency response of a digital filter.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.freqz.html
This example function is provided as-is without any representation of accuracy.
Args:
b (list[list]): Numerator (feed-forward) filter coefficients.
a (list[list], optional): Denominator (feedback) filter coefficients. Default is [[1]].
wor_n (int, optional): Number of frequency points to evaluate. Default is 512.
whole (bool, optional): If True, compute response over the whole unit circle. Default is False.
fs (float, optional): Sampling frequency in frequency units (radians per sample by default). Default is 6.283185307179586.
include_nyquist (bool, optional): If True and wor_n is an integer, include the Nyquist frequency endpoint. Default is False.
Returns:
list[list]: A 2D array with rows for frequency, magnitude response, and phase response.
"""
try:
def flatten_numeric(x):
if not isinstance(x, list):
return [float(x)]
values = []
for row in x:
if isinstance(row, list):
for v in row:
values.append(float(v))
else:
values.append(float(row))
return values
b_vals = flatten_numeric(b)
a_vals = flatten_numeric(a)
if len(b_vals) == 0:
return "Error: b must contain at least one numeric coefficient"
if len(a_vals) == 0:
return "Error: a must contain at least one numeric coefficient"
w, h = scipy_freqz(
b_vals,
a_vals,
worN=int(wor_n),
whole=bool(whole),
fs=float(fs),
include_nyquist=bool(include_nyquist)
)
return [
w.tolist(),
np.abs(h).tolist(),
np.angle(h).tolist()
]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
GAUSSIAN_FILTER1D
The 1-D Gaussian filter is a linear filter that smoothes a signal by convolving it with a Gaussian function. This process effectively removes high-frequency noise from the signal while preserving its overall shape and characteristics.
The Gaussian kernel is defined as:
G(x) = \frac{1}{\sqrt{2\pi}\sigma} e^{-\frac{x^2}{2\sigma^2}}
where \sigma is the standard deviation that determines the width of the filter. Larger \sigma values result in more smoothing.
Excel Usage
=GAUSSIAN_FILTER1D(input_data, sigma, axis, order, gaussian_mode, cval, truncate)
input_data(list[list], required): The input array (Excel range).sigma(float, required): Standard deviation for Gaussian kernel (determines smoothing width).axis(int, optional, default: -1): The axis along which to calculate.order(int, optional, default: 0): Order of the derivative (0 for smoothing).gaussian_mode(str, optional, default: “reflect”): Extension mode for padded signal.cval(float, optional, default: 0): Value to fill past edges if mode is ‘constant’.truncate(float, optional, default: 4): Truncate the filter at this many standard deviations.
Returns (list[list]): The smoothed signal as a 2D array.
Example 1: Simple smoothing
Inputs:
| input_data | sigma | ||||
|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 1 |
Excel formula:
=GAUSSIAN_FILTER1D({1,2,3,4,5}, 1)
Expected output:
| Result | ||||
|---|---|---|---|---|
| 1.42704 | 2.06782 | 3 | 3.93218 | 4.57296 |
Example 2: Higher sigma smoothing
Inputs:
| input_data | sigma | ||||
|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 4 |
Excel formula:
=GAUSSIAN_FILTER1D({1,2,3,4,5}, 4)
Expected output:
| Result | ||||
|---|---|---|---|---|
| 2.91948 | 2.95024 | 3 | 3.04976 | 3.08052 |
Python Code
Show Code
import numpy as np
from scipy.ndimage import gaussian_filter1d as scipy_gaussian
def gaussian_filter1d(input_data, sigma, axis=-1, order=0, gaussian_mode='reflect', cval=0, truncate=4):
"""
1-D Gaussian filter for signal denoising and smoothing.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.gaussian_filter1d.html
This example function is provided as-is without any representation of accuracy.
Args:
input_data (list[list]): The input array (Excel range).
sigma (float): Standard deviation for Gaussian kernel (determines smoothing width).
axis (int, optional): The axis along which to calculate. Default is -1.
order (int, optional): Order of the derivative (0 for smoothing). Default is 0.
gaussian_mode (str, optional): Extension mode for padded signal. Valid options: Reflect, Constant, Nearest, Mirror, Wrap. Default is 'reflect'.
cval (float, optional): Value to fill past edges if mode is 'constant'. Default is 0.
truncate (float, optional): Truncate the filter at this many standard deviations. Default is 4.
Returns:
list[list]: The smoothed signal as a 2D array.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
data = np.array(to2d(input_data), dtype=float)
result = scipy_gaussian(
data,
sigma=float(sigma),
axis=int(axis),
order=int(order),
mode=gaussian_mode,
cval=float(cval),
truncate=float(truncate)
)
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
GET_WINDOW
Window functions are weighting sequences used in spectral analysis and filter design to control sidelobes and leakage.
This function returns a one-dimensional window of length N that can be used in FFT and filtering workflows. Different window families trade off main-lobe width and sidelobe attenuation.
Excel Usage
=GET_WINDOW(window, nx, fftbins, shape)
window(str, required): Window family name.nx(int, required): Number of samples in the output window.fftbins(bool, optional, default: true): If True, create a periodic window for FFT use; otherwise symmetric.shape(float, optional, default: null): Optional shape parameter for parameterized windows.
Returns (list[list]): Window coefficients as a single-row 2D array.
Example 1: Periodic Hann window
Inputs:
| window | nx |
|---|---|
| hann | 8 |
Excel formula:
=GET_WINDOW("hann", 8)
Expected output:
| Result | |||||||
|---|---|---|---|---|---|---|---|
| 0 | 0.146447 | 0.5 | 0.853553 | 1 | 0.853553 | 0.5 | 0.146447 |
Example 2: Symmetric Hamming window
Inputs:
| window | nx | fftbins |
|---|---|---|
| hamming | 9 | false |
Excel formula:
=GET_WINDOW("hamming", 9, FALSE)
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 0.08 | 0.214731 | 0.54 | 0.865269 | 1 | 0.865269 | 0.54 | 0.214731 | 0.08 |
Example 3: Tukey window with shape parameter
Inputs:
| window | nx | shape |
|---|---|---|
| tukey | 16 | 0.25 |
Excel formula:
=GET_WINDOW("tukey", 16, 0.25)
Expected output:
| Result | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0.5 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0.5 |
Example 4: Boxcar window for basic weighting
Inputs:
| window | nx |
|---|---|
| boxcar | 6 |
Excel formula:
=GET_WINDOW("boxcar", 6)
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 1 | 1 |
Python Code
Show Code
from scipy.signal import get_window as scipy_get_window
def get_window(window, nx, fftbins=True, shape=None):
"""
Generate a window function vector for signal processing.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.get_window.html
This example function is provided as-is without any representation of accuracy.
Args:
window (str): Window family name.
nx (int): Number of samples in the output window.
fftbins (bool, optional): If True, create a periodic window for FFT use; otherwise symmetric. Default is True.
shape (float, optional): Optional shape parameter for parameterized windows. Default is None.
Returns:
list[list]: Window coefficients as a single-row 2D array.
"""
try:
if int(nx) <= 0:
return "Error: nx must be a positive integer"
if shape is None:
win_spec = window
else:
win_spec = (window, float(shape))
result = scipy_get_window(win_spec, int(nx), fftbins=bool(fftbins))
return [result.tolist()]
except Exception as e:
return f"Error: {str(e)}"Online Calculator
IIRDESIGN
The iirdesign function provides a high-level interface to design IIR filters by specifying the desired passband and stopband characteristics, rather than the filter order directly.
It constructs an analog or digital IIR filter of minimum order for a given basic type (Butterworth, Chebyshev I, Chebyshev II, or Elliptic).
Excel Usage
=IIRDESIGN(wp, ws, gpass, gstop, analog, ftype, filter_output_form, fs)
wp(list[list], required): Passband edge frequencies.ws(list[list], required): Stopband edge frequencies.gpass(float, required): The maximum loss in the passband (dB).gstop(float, required): The minimum attenuation in the stopband (dB).analog(bool, optional, default: false): When True, return an analog filter.ftype(str, optional, default: “ellip”): The type of IIR filter.filter_output_form(str, optional, default: “ba”): Type of output representation.fs(float, optional, default: null): The sampling frequency of the digital system.
Returns (list[list]): Filter coefficients or representation as a 2D array.
Example 1: Low-pass (b, a)
Inputs:
| wp | ws | gpass | gstop |
|---|---|---|---|
| 0.2 | 0.3 | 1 | 40 |
Excel formula:
=IIRDESIGN(0.2, 0.3, 1, 40)
Expected output:
| Result | ||||
|---|---|---|---|---|
| 0.0196744 | -0.017137 | 0.0332899 | -0.017137 | 0.0196744 |
| 1 | -3.03301 | 3.8118 | -2.2911 | 0.555357 |
Example 2: Band-pass (SOS)
Inputs:
| wp | ws | gpass | gstop | filter_output_form | ||
|---|---|---|---|---|---|---|
| 0.2 | 0.4 | 0.1 | 0.5 | 1 | 60 | sos |
Excel formula:
=IIRDESIGN({0.2,0.4}, {0.1,0.5}, 1, 60, "sos")
Expected output:
| Result | |||||
|---|---|---|---|---|---|
| 0.00366595 | 0 | -0.00366595 | 1 | -1.11784 | 0.808699 |
| 1 | 0.44536 | 1 | 1 | -0.77776 | 0.846087 |
| 1 | -1.86313 | 1 | 1 | -1.43271 | 0.887093 |
| 1 | -0.106599 | 1 | 1 | -0.605994 | 0.9492 |
| 1 | -1.76647 | 1 | 1 | -1.59091 | 0.968224 |
Python Code
Show Code
import numpy as np
from scipy.signal import iirdesign as scipy_iirdesign
def iirdesign(wp, ws, gpass, gstop, analog=False, ftype='ellip', filter_output_form='ba', fs=None):
"""
Complete IIR digital and analog filter design from passband and stopband specs.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.iirdesign.html
This example function is provided as-is without any representation of accuracy.
Args:
wp (list[list]): Passband edge frequencies.
ws (list[list]): Stopband edge frequencies.
gpass (float): The maximum loss in the passband (dB).
gstop (float): The minimum attenuation in the stopband (dB).
analog (bool, optional): When True, return an analog filter. Default is False.
ftype (str, optional): The type of IIR filter. Valid options: Butterworth, Chebyshev I, Chebyshev II, Cauer/Elliptic. Default is 'ellip'.
filter_output_form (str, optional): Type of output representation. Valid options: Numerator/Denominator, Pole-Zero, Second-Order Sections. Default is 'ba'.
fs (float, optional): The sampling frequency of the digital system. Default is None.
Returns:
list[list]: Filter coefficients or representation as a 2D array.
"""
try:
def to_val(v):
if isinstance(v, list):
flat = [float(x) for row in v for x in row]
return flat[0] if len(flat) == 1 else flat
return float(v)
wp_val = to_val(wp)
ws_val = to_val(ws)
result = scipy_iirdesign(
wp_val,
ws_val,
float(gpass),
float(gstop),
analog=bool(analog),
ftype=ftype,
output=filter_output_form,
fs=float(fs) if fs is not None else None
)
if filter_output_form == 'ba':
b, a = result
max_len = max(len(b), len(a))
return [b.tolist() + [""] * (max_len - len(b)), a.tolist() + [""] * (max_len - len(a))]
elif filter_output_form == 'zpk':
z, p, k = result
max_len = max(len(z), len(p), 1)
return [z.tolist() + [""] * (max_len - len(z)), p.tolist() + [""] * (max_len - len(p)), [float(k)] + [""] * (max_len - 1)]
else: # sos
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
MEDFILT
The median filter is a non-linear digital filtering technique, often used to remove noise from an image or signal. Such noise reduction is a typical pre-processing step to improve the results of later processing. Median filtering is very widely used in digital signal processing because, under certain conditions, it preserves edges while removing noise.
The main idea of the median filter is to run through the signal entry by entry, replacing each entry with the median of neighboring entries. The pattern of neighbors is called the “window”, which slides, entry by entry, over the entire signal.
Excel Usage
=MEDFILT(volume, kernel_size)
volume(list[list], required): Input array (Excel range).kernel_size(int, optional, default: 3): Size of the median filter window (should be odd).
Returns (list[list]): The median filtered signal as a 2D array.
Example 1: Spike removal
Inputs:
| volume | kernel_size | ||||
|---|---|---|---|---|---|
| 1 | 2 | 100 | 4 | 5 | 3 |
Excel formula:
=MEDFILT({1,2,100,4,5}, 3)
Expected output:
| Result | ||||
|---|---|---|---|---|
| 1 | 2 | 4 | 5 | 4 |
Example 2: Larger window
Inputs:
| volume | kernel_size | ||||
|---|---|---|---|---|---|
| 1 | 2 | 100 | 4 | 5 | 5 |
Excel formula:
=MEDFILT({1,2,100,4,5}, 5)
Expected output:
| Result | ||||
|---|---|---|---|---|
| 1 | 2 | 4 | 4 | 4 |
Python Code
Show Code
import numpy as np
from scipy.signal import medfilt as scipy_medfilt
def medfilt(volume, kernel_size=3):
"""
Perform a median filter on a signal array to remove spike noise.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.medfilt.html
This example function is provided as-is without any representation of accuracy.
Args:
volume (list[list]): Input array (Excel range).
kernel_size (int, optional): Size of the median filter window (should be odd). Default is 3.
Returns:
list[list]: The median filtered signal as a 2D array.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
data = np.array(to2d(volume), dtype=float)
kernel = int(kernel_size)
if kernel <= 0 or kernel % 2 == 0:
return "Error: kernel_size must be a positive odd integer"
if data.ndim == 2 and data.shape[0] == 1:
kernel_spec = [1, kernel]
elif data.ndim == 2 and data.shape[1] == 1:
kernel_spec = [kernel, 1]
else:
kernel_spec = kernel
result = scipy_medfilt(data, kernel_size=kernel_spec)
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
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
SAVGOL_FILTER
The Savitzky-Golay filter is a digital filter that can be applied to a set of digital data points for the purpose of smoothing the data—that is, to increase the precision of the data without distorting the signal tendency. This is achieved, in a process known as convolution, by fitting successive sub-sets of adjacent data points with a low-degree polynomial by the method of linear least squares.
The filter is particularly effective at preserving higher moments of the signal, such as peak heights and widths, which might be flattened by other smoothing techniques like moving averages.
y_i = \sum_{j=-k}^k C_j x_{i+j}
where C_j are the filter coefficients derived from the polynomial fit.
Excel Usage
=SAVGOL_FILTER(x, window_length, polyorder, deriv, delta, axis, savgol_mode, cval)
x(list[list], required): The data to be filtered (Excel range).window_length(int, required): The length of the filter window (must be positive and odd).polyorder(int, required): The order of the polynomial used to fit the samples.deriv(int, optional, default: 0): The order of the derivative to compute.delta(float, optional, default: 1): The spacing of the samples (used if deriv > 0).axis(int, optional, default: -1): The axis along which the filter is applied.savgol_mode(str, optional, default: “interp”): Extension mode for padded signal.cval(float, optional, default: 0): Value to fill past edges if mode is ‘constant’.
Returns (list[list]): The filtered data as a 2D array.
Example 1: Basic smoothing
Inputs:
| x | window_length | polyorder | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 2 | 5 | 2 | 1 | 0 | 1 | 4 | 9 | 5 | 2 |
Excel formula:
=SAVGOL_FILTER({2,2,5,2,1,0,1,4,9}, 5, 2)
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 1.65714 | 3.17143 | 3.54286 | 2.85714 | 0.657143 | 0.171429 | 1 | 4 | 9 |
Example 2: Nearest mode
Inputs:
| x | window_length | polyorder | savgol_mode | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 2 | 5 | 2 | 1 | 0 | 1 | 4 | 9 | 5 | 2 | nearest |
Excel formula:
=SAVGOL_FILTER({2,2,5,2,1,0,1,4,9}, 5, 2, "nearest")
Expected output:
| Result | ||||||||
|---|---|---|---|---|---|---|---|---|
| 1.74286 | 3.02857 | 3.54286 | 2.85714 | 0.657143 | 0.171429 | 1 | 4.6 | 7.97143 |
Example 3: First derivative
Inputs:
| x | window_length | polyorder | deriv | ||||
|---|---|---|---|---|---|---|---|
| 0 | 1 | 4 | 9 | 16 | 5 | 2 | 1 |
Excel formula:
=SAVGOL_FILTER({0,1,4,9,16}, 5, 2, 1)
Expected output:
| Result | ||||
|---|---|---|---|---|
| -4.4406e-15 | 2 | 4 | 6 | 8 |
Python Code
Show Code
import numpy as np
from scipy.signal import savgol_filter as scipy_savgol
def savgol_filter(x, window_length, polyorder, deriv=0, delta=1, axis=-1, savgol_mode='interp', cval=0):
"""
Apply a Savitzky-Golay filter to a signal array for smoothing.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.savgol_filter.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): The data to be filtered (Excel range).
window_length (int): The length of the filter window (must be positive and odd).
polyorder (int): The order of the polynomial used to fit the samples.
deriv (int, optional): The order of the derivative to compute. Default is 0.
delta (float, optional): The spacing of the samples (used if deriv > 0). Default is 1.
axis (int, optional): The axis along which the filter is applied. Default is -1.
savgol_mode (str, optional): Extension mode for padded signal. Valid options: Mirror, Constant, Nearest, Wrap, Interp. Default is 'interp'.
cval (float, optional): Value to fill past edges if mode is 'constant'. Default is 0.
Returns:
list[list]: The filtered data as a 2D array.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
x_arr = np.array(to2d(x))
# Handle potential conversion issues
if x_arr.dtype.kind not in 'iuf':
# Try to convert to float, ignoring non-numeric
x_flat = x_arr.flatten()
cleaned = []
for val in x_flat:
try:
cleaned.append(float(val))
except (TypeError, ValueError):
cleaned.append(0.0) # Or should we use nan? filter usually fails on nan.
x_arr = np.array(cleaned).reshape(x_arr.shape)
result = scipy_savgol(
x_arr,
window_length=int(window_length),
polyorder=int(polyorder),
deriv=int(deriv),
delta=float(delta),
axis=int(axis),
mode=savgol_mode,
cval=float(cval)
)
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator
SOSFILTFILT
The sosfiltfilt function applies a digital filter using cascaded second-order sections (SOS) both forwards and backwards. This results in zero phase distortion and is numerically much more stable than using numerator/denominator (b, a) coefficients, especially for higher-order filters.
SOS representation is generally recommended for all filtering tasks in digital signal processing to avoid precision issues.
Excel Usage
=SOSFILTFILT(x, sos, axis, padtype, padlen)
x(list[list], required): The input array of data to be filtered.sos(list[list], required): Array of second-order sections filter coefficients (n_sections by 6).axis(int, optional, default: -1): The axis along which the filter is applied.padtype(str, optional, default: “odd”): Extension mode for padding at edges.padlen(int, optional, default: null): Number of elements to extend x by at both ends.
Returns (list[list]): The filtered signal as a 2D array.
Example 1: SOS zero-phase filtering
Inputs:
| x | sos | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 4 | 3 | 2 | 1 | 2 | 3 | 4 | 0.02008337 | 0.04016673 | 0.02008337 | 1 | -1.56101808 | 0.64135154 |
Excel formula:
=SOSFILTFILT({1,2,3,4,5,4,3,2,1,2,3,4}, {0.02008337,0.04016673,0.02008337,1,-1.56101808,0.64135154})
Expected output:
| Result | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.891233 | 1.36469 | 1.81575 | 2.21546 | 2.54703 | 2.81074 | 3.02431 | 3.21646 | 3.41574 | 3.6397 | 3.889 | 4.14893 |
Example 2: Even padding extension
Inputs:
| x | sos | padtype | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 4 | 3 | 2 | 1 | 2 | 3 | 4 | 0.02008337 | 0.04016673 | 0.02008337 | 1 | -1.56101808 | 0.64135154 | even |
Excel formula:
=SOSFILTFILT({1,2,3,4,5,4,3,2,1,2,3,4}, {0.02008337,0.04016673,0.02008337,1,-1.56101808,0.64135154}, "even")
Expected output:
| Result | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 3.00993 | 3.0197 | 3.03295 | 3.03579 | 3.01407 | 2.96221 | 2.88721 | 2.80537 | 2.73416 | 2.68416 | 2.65592 | 2.64429 |
Python Code
Show Code
import numpy as np
from scipy.signal import sosfiltfilt as scipy_sosfiltfilt
def sosfiltfilt(x, sos, axis=-1, padtype='odd', padlen=None):
"""
Forward-backward digital filter using cascaded second-order sections.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.sosfiltfilt.html
This example function is provided as-is without any representation of accuracy.
Args:
x (list[list]): The input array of data to be filtered.
sos (list[list]): Array of second-order sections filter coefficients (n_sections by 6).
axis (int, optional): The axis along which the filter is applied. Default is -1.
padtype (str, optional): Extension mode for padding at edges. Valid options: Odd, Even, Constant. Default is 'odd'.
padlen (int, optional): Number of elements to extend x by at both ends. Default is None.
Returns:
list[list]: The filtered signal as a 2D array.
"""
try:
def to2d(x):
return [[x]] if not isinstance(x, list) else x
x_arr = np.array(to2d(x))
sos_arr = np.array(to2d(sos))
result = scipy_sosfiltfilt(
sos_arr,
x_arr,
axis=int(axis),
padtype=padtype,
padlen=int(padlen) if padlen is not None else None
)
return result.tolist()
except Exception as e:
return f"Error: {str(e)}"Online Calculator