butter
Builtin index · Signal processing
result = butter(order, kind, cutoff, fs)
Input: order, kind, cutoff, fs · Output: result
What it is
order: number (filter order); kind: string; cutoff: number or length-2 vector (Hz); fs: number (Hz).
Overloads
cutoff can be number or vector.
2 forms. Each carries its own inputs, outputs and worked example — pick the tab for the one you are calling.
| Code | Input | Output | Description |
result = butter(order, "low"/"high", cutoff, fs) | order numberorder: number (filter order)."low"/"high" —not documented yetcutoff number or vectorcutoff: number or length-2 vector (Hz).fs numberfs: number (Hz). | result number | A single Hz number — the low-pass or high-pass edge. |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
fs = 1000
lp = butter(4, "low", 100, fs) # 4th-order lowpass, 100 Hz cutoff
notch = butter(2, "notch", [45, 55], fs) # removes 45-55 Hz (mains hum)
from numerics-dsp
print(zeros(3)) # [0, 0, 0]
print(zeros(2, 3)) # [0, 0, 0; 0, 0, 0]
filt = butter(4, "low", 100, 1000)
print(zeros(filt)) # [-1, -1, -1, -1] -- a CVec, not a fresh zero-fill
[0, 0, 0] [0, 0, 0; 0, 0, 0] [-1, -1, -1, -1]
from core-math
fs = 1000
iir = butter(2, "low", 100, fs)
print("IIR poles: {poles(iir)}")
# IIR poles: [0.57149 + 0.293599i, 0.57149 - 0.293599i]
IIR poles: [0.57149 + 0.293599j, 0.57149 - 0.293599j]
from signal-processing
fs = 1000
lp = butter(4, "low", 100, fs)
bp = butter(4, "band", [80, 120], fs)
print("lowpass sections: {shape(lp.sos)[0]}") # lowpass sections: 2
print("bandpass sections: {shape(bp.sos)[0]}") # bandpass sections: 4
lowpass sections: 2 bandpass sections: 4
from signal-processing
| Code | Input | Output | Description |
result = butter(order, "band"/"stop", cutoff, fs) | order numberorder: number (filter order)."band"/"stop" —not documented yetcutoff number or vectorcutoff: number or length-2 vector (Hz).fs numberfs: number (Hz). | result vector | A length-2 [low, high] Hz vector — the passband/stopband edges ("stop"/"notch" cuts that band out instead of keeping it). |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
fs = 1000
lp = butter(4, "low", 100, fs) # 4th-order lowpass, 100 Hz cutoff
notch = butter(2, "notch", [45, 55], fs) # removes 45-55 Hz (mains hum)
from numerics-dsp
print(zeros(3)) # [0, 0, 0]
print(zeros(2, 3)) # [0, 0, 0; 0, 0, 0]
filt = butter(4, "low", 100, 1000)
print(zeros(filt)) # [-1, -1, -1, -1] -- a CVec, not a fresh zero-fill
[0, 0, 0] [0, 0, 0; 0, 0, 0] [-1, -1, -1, -1]
from core-math
fs = 1000
iir = butter(2, "low", 100, fs)
print("IIR poles: {poles(iir)}")
# IIR poles: [0.57149 + 0.293599i, 0.57149 - 0.293599i]
IIR poles: [0.57149 + 0.293599j, 0.57149 - 0.293599j]
from signal-processing
fs = 1000
lp = butter(4, "low", 100, fs)
bp = butter(4, "band", [80, 120], fs)
print("lowpass sections: {shape(lp.sos)[0]}") # lowpass sections: 2
print("bandpass sections: {shape(bp.sos)[0]}") # bandpass sections: 4
lowpass sections: 2 bandpass sections: 4
from signal-processing
How it works
butter(order, kind, cutoff, fs) — designs a digital Butterworth filter as a cascade of second-order sections (SOS), the numerically stable representation used no matter the order. kind is "low"/"high"/"band"/ "stop" ("bandpass"/"lowpass"/"highpass"/ "bandstop"/"notch" all accepted as more readable aliases). cutoff is one frequency in Hz for low/high, or [low, high] for band/stop. Model kind "filter", field sos (a matrix, one section per row: [b0,b1,b2,a1,a2]).
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.