is_stable
Builtin index · Signal processing
result = is_stable(filt)
Input: filt · Output: result
What it is
filt: a Model (kind "filter").
Overloads
One call shape — this function is not overloaded.
Code Input Output Description
result = is_stable(filt)filt Model not documented yet
result boolean
Returns a boolean, true iff every pole lies strictly inside the unit circle โ the standard causal-LTI stability criterion. An FIR filter (poles at the origin) is always stable.
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
t = (0 to 999 ) / fs
signal = sin (2 * pi * 50 * t) + 0.5 * sin (2 * pi * 220 * t) + 0.1 * randn (1000 , seed = 2 )
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
filtered = sosfilt (lp, signal) # causal, one pass
zero_phase = filtfilt (lp, signal) # zero-phase, double effective order
print ("lp is stable: {is_stable(lp)}, notch is stable: {is_stable(notch)}" )
H = freqz (lp, 512 )
plot (linspace (0 , fs/2 , 512 ), mag2db (abs (H)))
output lp is stable: true, notch is stable: true
ยท plot: figure 3 (512 points)
-200
-100
0
100
200
300
400
500
-200
0
200
400
600
800
x=0.21, y=0
x=0.21, y=0
x=0.21, y=0
x=0.21, y=0
x=0.21, y=0
x=0.21, y=0
x=0.21, y=$10^{-9}$
x=0.21, y=$1.1\times10^{-9}$
x=0.21, y=$1.2\times10^{-9}$
x=0.21, y=$1.3\times10^{-9}$
x=0.21, y=$1.4\times10^{-9}$
x=0.21, y=$1.5\times10^{-9}$
x=0.21, y=$1.7\times10^{-9}$
x=0.21, y=$1.8\times10^{-9}$
x=0.21, y=$2\times10^{-9}$
x=0.21, y=$2.1\times10^{-9}$
x=0.21, y=$2.3\times10^{-9}$
x=0.21, y=$2.5\times10^{-9}$
x=0.21, y=$2.7\times10^{-9}$
x=0.21, y=$2.9\times10^{-9}$
x=0.21, y=$3.2\times10^{-9}$
x=0.21, y=$3.4\times10^{-9}$
x=0.21, y=$3.7\times10^{-9}$
x=0.21, y=$4\times10^{-9}$
x=0.21, y=$4.4\times10^{-9}$
x=0.21, y=$4.8\times10^{-9}$
x=0.21, y=$5.2\times10^{-9}$
x=0.21, y=$5.6\times10^{-9}$
x=0.21, y=$6.1\times10^{-9}$
x=0.21, y=$6.6\times10^{-9}$
x=0.21, y=$7.1\times10^{-9}$
x=0.21, y=$7.7\times10^{-9}$
x=0.21, y=$8.4\times10^{-9}$
x=0.21, y=$9.1\times10^{-9}$
x=0.21, y=$9.9\times10^{-9}$
x=0.21, y=$1.1\times10^{-8}$
x=0.21, y=$1.2\times10^{-8}$
x=0.21, y=$1.3\times10^{-8}$
x=0.21, y=$1.4\times10^{-8}$
x=0.21, y=$1.5\times10^{-8}$
x=0.21, y=$1.6\times10^{-8}$
x=0.21, y=$1.7\times10^{-8}$
x=0.21, y=$1.9\times10^{-8}$
x=0.21, y=$2\times10^{-8}$
x=0.21, y=$2.2\times10^{-8}$
x=0.21, y=$2.4\times10^{-8}$
x=0.21, y=$2.6\times10^{-8}$
x=0.21, y=$2.8\times10^{-8}$
x=0.21, y=$3.1\times10^{-8}$
x=0.21, y=$3.3\times10^{-8}$
x=0.21, y=$3.6\times10^{-8}$
x=0.21, y=$3.9\times10^{-8}$
x=0.21, y=$4.2\times10^{-8}$
x=0.21, y=$4.6\times10^{-8}$
x=0.21, y=$5\times10^{-8}$
x=0.21, y=$5.4\times10^{-8}$
x=0.21, y=$5.9\times10^{-8}$
x=0.21, y=$6.4\times10^{-8}$
x=0.21, y=$6.9\times10^{-8}$
x=0.21, y=$7.5\times10^{-8}$
x=0.21, y=$8.1\times10^{-8}$
x=0.21, y=$8.8\times10^{-8}$
x=0.21, y=$9.5\times10^{-8}$
x=0.21, y=$10^{-7}$
x=0.21, y=$1.1\times10^{-7}$
x=0.21, y=$1.2\times10^{-7}$
x=0.21, y=$1.3\times10^{-7}$
x=0.21, y=$1.4\times10^{-7}$
x=0.21, y=$1.5\times10^{-7}$
x=0.21, y=$1.7\times10^{-7}$
x=0.21, y=$1.8\times10^{-7}$
x=0.21, y=$2\times10^{-7}$
x=0.21, y=$2.1\times10^{-7}$
x=0.21, y=$2.3\times10^{-7}$
x=0.21, y=$2.5\times10^{-7}$
x=0.21, y=$2.7\times10^{-7}$
x=0.21, y=$3\times10^{-7}$
x=0.21, y=$3.2\times10^{-7}$
x=0.21, y=$3.5\times10^{-7}$
x=0.21, y=$3.8\times10^{-7}$
x=0.21, y=$4.1\times10^{-7}$
x=0.21, y=$4.4\times10^{-7}$
x=0.21, y=$4.8\times10^{-7}$
x=0.21, y=$5.2\times10^{-7}$
x=0.21, y=$5.7\times10^{-7}$
x=0.21, y=$6.1\times10^{-7}$
x=0.21, y=$6.7\times10^{-7}$
x=0.21, y=$7.2\times10^{-7}$
x=0.21, y=$7.8\times10^{-7}$
x=0.21, y=$8.5\times10^{-7}$
x=0.21, y=$9.2\times10^{-7}$
x=0.21, y=$10^{-6}$
x=0.21, y=$1.1\times10^{-6}$
x=0.21, y=$1.2\times10^{-6}$
x=0.21, y=$1.3\times10^{-6}$
x=0.21, y=$1.4\times10^{-6}$
x=0.21, y=$1.5\times10^{-6}$
x=0.21, y=$1.6\times10^{-6}$
x=0.21, y=$1.8\times10^{-6}$
x=0.21, y=$1.9\times10^{-6}$
x=0.21, y=$2.1\times10^{-6}$
x=0.21, y=$2.2\times10^{-6}$
x=0.21, y=$2.4\times10^{-6}$
x=0.21, y=$2.6\times10^{-6}$
x=0.21, y=$2.9\times10^{-6}$
x=0.21, y=$3.1\times10^{-6}$
x=0.21, y=$3.4\times10^{-6}$
x=0.21, y=$3.6\times10^{-6}$
x=0.21, y=$4\times10^{-6}$
x=0.21, y=$4.3\times10^{-6}$
x=0.21, y=$4.7\times10^{-6}$
x=0.21, y=$5\times10^{-6}$
x=0.21, y=$5.5\times10^{-6}$
x=0.21, y=$5.9\times10^{-6}$
x=0.21, y=$6.4\times10^{-6}$
x=0.21, y=$7\times10^{-6}$
x=0.21, y=$7.6\times10^{-6}$
x=0.21, y=$8.2\times10^{-6}$
x=0.21, y=$8.9\times10^{-6}$
x=0.21, y=$9.6\times10^{-6}$
x=0.21, y=$10^{-5}$
x=0.21, y=$1.1\times10^{-5}$
x=0.21, y=$1.2\times10^{-5}$
x=0.21, y=$1.3\times10^{-5}$
x=0.21, y=$1.4\times10^{-5}$
x=0.21, y=$1.6\times10^{-5}$
x=0.21, y=$1.7\times10^{-5}$
x=0.21, y=$1.8\times10^{-5}$
x=0.21, y=$2\times10^{-5}$
x=0.21, y=$2.2\times10^{-5}$
x=0.21, y=$2.3\times10^{-5}$
x=0.21, y=$2.5\times10^{-5}$
x=0.21, y=$2.8\times10^{-5}$
x=0.21, y=$3\times10^{-5}$
x=0.21, y=$3.2\times10^{-5}$
x=0.21, y=$3.5\times10^{-5}$
x=0.21, y=$3.8\times10^{-5}$
x=0.21, y=$4.1\times10^{-5}$
x=0.21, y=$4.5\times10^{-5}$
x=0.21, y=$4.9\times10^{-5}$
x=0.21, y=$5.3\times10^{-5}$
x=0.21, y=$5.7\times10^{-5}$
x=0.21, y=$6.2\times10^{-5}$
x=0.21, y=$6.7\times10^{-5}$
x=0.21, y=$7.3\times10^{-5}$
x=0.21, y=$7.9\times10^{-5}$
x=0.21, y=$8.6\times10^{-5}$
x=0.21, y=$9.3\times10^{-5}$
x=0.21, y=$10^{-4}$
x=0.21, y=$1.1\times10^{-4}$
x=0.21, y=$1.2\times10^{-4}$
x=0.21, y=$1.3\times10^{-4}$
x=0.21, y=$1.4\times10^{-4}$
x=0.21, y=$1.5\times10^{-4}$
x=0.21, y=$1.6\times10^{-4}$
x=0.21, y=$1.8\times10^{-4}$
x=0.21, y=$1.9\times10^{-4}$
x=0.21, y=$2.1\times10^{-4}$
x=0.21, y=$2.3\times10^{-4}$
x=0.21, y=$2.5\times10^{-4}$
x=0.21, y=$2.7\times10^{-4}$
x=0.21, y=$2.9\times10^{-4}$
x=0.21, y=$3.1\times10^{-4}$
x=0.21, y=$3.4\times10^{-4}$
x=0.21, y=$3.7\times10^{-4}$
x=0.21, y=$4\times10^{-4}$
x=0.21, y=$4.3\times10^{-4}$
x=0.21, y=$4.7\times10^{-4}$
x=0.21, y=$5.1\times10^{-4}$
x=0.21, y=$5.5\times10^{-4}$
x=0.21, y=$6\times10^{-4}$
x=0.21, y=$6.5\times10^{-4}$
x=0.21, y=$7\times10^{-4}$
x=0.21, y=$7.6\times10^{-4}$
x=0.21, y=$8.2\times10^{-4}$
x=0.21, y=$8.9\times10^{-4}$
x=0.21, y=$9.7\times10^{-4}$
x=0.21, y=0.001
x=0.21, y=0.001
x=0.21, y=0.001
x=0.21, y=0.001
x=0.21, y=0.001
x=0.21, y=0.002
x=0.21, y=0.002
x=0.21, y=0.002
x=0.21, y=0.002
x=0.21, y=0.002
x=0.209, y=0.002
x=0.209, y=0.002
x=0.209, y=0.003
x=0.209, y=0.003
x=0.209, y=0.003
x=0.209, y=0.003
x=0.209, y=0.003
x=0.209, y=0.004
x=0.208, y=0.004
x=0.208, y=0.004
x=0.208, y=0.004
x=0.207, y=0.004
x=0.207, y=0.005
frequency (Hz)
from signal-processing
fs = 1000
ep = ellip (4 , 1 , 40 , "low" , 100 , fs)
c1 = cheby1 (4 , 1 , "low" , 100 , fs)
c2 = cheby2 (4 , 40 , "low" , 100 , fs)
print ("ellip stable: {is_stable(ep)}, cheby1 stable: {is_stable(c1)}, cheby2 stable: {is_stable(c2)}" )
fir = fir1 (6 , 100 , kind ="low" , window ="hamming" , fs =fs)
b = fir.b
a = [1 ]
n = 0 :1 :255
t = n / fs
x = sin (2 *pi*40 *t) + sin (2 *pi*300 *t)
y = filter_ba (b, a, x)
y2 = lfilter (b, a, x) # lfilter is the same builtin under another name
print ("filter_ba/lfilter agree: {max(abs(y - y2)) < 1e-12}" )
lsq = firls (20 , [0 , 0.2 , 0.3 , 1.0 ], [1 , 1 , 0 , 0 ]) # low-pass band edges/response
print ("firls taps: {length(lsq.b)}" )
gd = group_delay (fir, 256 )
print ("FIR group delay (should be ~order/2=3): {gd[10]}" )
print ("ellip filter has {length(poles(ep))} poles" )
ep.fvtool () # 2x2 magnitude/phase/group-delay/impulse-response figure
pzplot (ep) # pole-zero plot with the unit circle and stability verdict
output ellip stable: true, cheby1 stable: true, cheby2 stable: true
filter_ba/lfilter agree: true
firls taps: 21
FIR group delay (should be ~order/2=3): 3
ellip filter has 4 poles
-80
-60
-40
-20
0
0
150
300
450
Magnitude Response
Frequency (Hz)
Magnitude (dB)
-150
-100
-50
0
50
100
150
0
150
300
450
Phase Response
Frequency (Hz)
Phase (deg)
-250
-200
-150
-100
-50
0
0
150
300
450
Group Delay
Frequency (Hz)
Delay (samples)
-20
-10
0
10
20
0
20
40
60
x=-0.135, y=0.991
x=-0.135, y=-0.991
x=0.57, y=0.821
x=0.57, y=-0.821
Pole-Zero Plot (stable)
Real part
Imaginary part
from signal-processing
How it works
is_stable(filt) โ true iff every pole lies strictly inside the unit circle, the standard causal-LTI stability criterion. An FIR filter (all poles at the origin) is always stable, which falls out of this one general definition automatically rather than needing a special case.
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.