Qu

filtfilt

Builtin index · Signal processing

result = filtfilt(filt, x)

Input: filt, x · Output: result

What it is

filt: a Model (kind "filter"); x: a length-N vector or Signal.

Overloads

One call shape — this function is not overloaded.

CodeInputOutputDescription
result = filtfilt(filt, x)
filt Modelfilt: a Model (kind "filter").
x vector or Signalx: a length-N vector or Signal.
result vector or Signal
Returns a same-length vector or Signal, same Fs-preserving convention as sosfilt. Zero-phase filtering (forward, then backward): doubles the effective order but cancels phase distortion entirely — the standard offline-analysis choice.

Examples

From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.

  filtered = sosfilt(lp, signal)
  zero_phase = filtfilt(lp, signal)

from numerics-dsp

lp       = butter(4, "low", 120, fs)          # 4th order, cut at 120 Hz

smoothed = filtfilt(lp, y)                    # zero-phase, forward and back

print("noise removed: rms {rms(y - x):.4f} -> {rms(smoothed - x):.4f}")
output
noise removed: rms 0.2010 -> 0.0978

from from-zero

fs = 1000
n = 0 to 999
t = n / fs
clean = sin(2 * pi * 5 * t)
noisy = clean + sin(2 * pi * 120 * t)

lp = butter(4, "low", 30, fs)
filtered = filtfilt(lp, noisy)

err_noisy = rms(noisy - clean)
err_filtered = rms(filtered - clean)
print("rms error before filtering = {err_noisy:.4f}")
print("rms error after filtering  = {err_filtered:.4f}")
output
rms error before filtering = 0.7071
rms error after filtering  = 0.0266

from quickstart

Fs = 2000
fc = 60
lp = butter(4, "low", fc, Fs)
print("Butterworth order 4, cutoff {fc} Hz @ Fs={Fs} Hz -- sos shape: {rows(lp.sos)}x{cols(lp.sos)}")

N = 1000
t = (0 to N - 1) / Fs
low_tone = sin(2*pi*20*t)
high_tone = sin(2*pi*400*t)
mix = low_tone + high_tone

causal = sosfilt(lp, mix)
zerophase = filtfilt(lp, mix)

err_low_causal = rms(causal[100:N-1] - low_tone[100:N-1])
err_low_zp = rms(zerophase[100:N-1] - low_tone[100:N-1])
print("20 Hz tone RMS recovery error: causal={err_low_causal:.4f}, zero-phase={err_low_zp:.4f}")
print("High tone (400 Hz) amplitude in raw mix: {rms(high_tone):.4f}")
print("High tone leakage after zero-phase LP: {rms(zerophase - low_tone):.4f}")

from tour

How it works

filtfilt(filt, x) — zero-phase filtering (forward, then backward): doubles the effective order but cancels phase distortion entirely, the standard offline-analysis choice. Same Signal-Fs-preserving convention as sosfilt above.

From the note above this builtin in the interpreter, where the reasoning was written down as it was built.