/** * Chebyshev I/II and elliptic (Cauer) IIR filter design, plus the supporting * `zpk2sos`/`sosfilt`/`bilinear`/`buttord` utilities. Extends the Butterworth * pipeline in `../signal-filter-extra.ts` with two more analog prototypes and * reuses its shared zpk→transfer-function plumbing (`analogToDigital`, * `polyFromRoots`). Matches `scipy.signal` — every coefficient set pinned * against `scipy.signal.{cheby1,cheby2,ellip,bilinear,buttord}` (see * `functions/tests/iir-design.test.ts`). * * The elliptic prototype (`ellipap`) follows Orfanidis, "Lecture Notes on * Elliptic Filter Design" (the algorithm scipy itself implements): the filter * degree equation is solved in closed form via the theta-function nome * expansion (`ellipdeg`), and the "arc Jacobi sc" root (`arcJacSc1`) via the * descending Landen transformation (`arcJacSn`) — no numerical optimizer is * needed. Reuses the repo's existing AGM-based `ellipticKScalar` and * `jacobiSN`/`jacobiCN`/`jacobiDN` (Phase 5 special functions, `m = k²` * convention, matching scipy's `ellipk`/`ellipj`). */ import { Complex } from '@danielsimonjr/mathts-core'; import { type FilterBtype } from '../signal-filter-extra.js'; type Vec = readonly number[] | Float64Array; /** * Chebyshev Type I digital IIR filter design — equiripple in the passband, `rp` * dB of ripple. `Wn` is the cutoff (scalar) or `[low, high]` band edges, * normalized to Nyquist. Matches `scipy.signal.cheby1(N, rp, Wn, btype)`. */ export declare function cheby1(N: number, rp: number, Wn: number | readonly number[], btype?: FilterBtype): { b: number[]; a: number[]; }; /** * Chebyshev Type II digital IIR filter design — equiripple in the stopband, * `rs` dB of stopband attenuation, monotone passband. `Wn` is the cutoff * (scalar) or `[low, high]` band edges, normalized to Nyquist. Matches * `scipy.signal.cheby2(N, rs, Wn, btype)`. */ export declare function cheby2(N: number, rs: number, Wn: number | readonly number[], btype?: FilterBtype): { b: number[]; a: number[]; }; /** * Elliptic (Cauer) digital IIR filter design — equiripple in both passband * (`rp` dB) and stopband (`rs` dB); the steepest roll-off of the four classical * IIR families for a given order. `Wn` is the cutoff (scalar) or `[low, high]` * band edges, normalized to Nyquist. Matches `scipy.signal.ellip(N, rp, rs, Wn, * btype)` exactly (verified against `scipy.signal` 1.17.1 — see * `functions/tests/iir-design.test.ts`); this is a full port of scipy's * closed-form (nome-based) elliptic design, not an approximation. */ export declare function ellip(N: number, rp: number, rs: number, Wn: number | readonly number[], btype?: FilterBtype): { b: number[]; a: number[]; }; /** * Analog-to-digital bilinear (Tustin) transform of a transfer function: given * `H(s) = b(s)/a(s)` (coefficients highest-degree-first), substitutes * `s = 2·fs·(z−1)/(z+1)` to produce the digital `{ b, a }` (no pre-warping is * done — the caller pre-warps `fs`/critical frequencies if needed). Matches * `scipy.signal.bilinear(b, a, fs)`. */ export declare function bilinear(bIn: Vec, aIn: Vec, fs: number): { b: number[]; a: number[]; }; /** * Minimum Butterworth filter order and the corresponding natural frequency * `Wn` (the "3 dB" frequency) meeting a passband/stopband spec, for a digital * lowpass, highpass, bandpass, or bandstop filter. Frequencies are normalized * to Nyquist (`0..1`); `gpass`/`gstop` are in dB. For lowpass/highpass, `wp` * and `ws` are scalars and `Wn` is a scalar; for bandpass/bandstop, `wp` and * `ws` are `[low, high]` pairs and `Wn` is the `[low, high]` natural-frequency * array. Matches `scipy.signal.buttord(wp, ws, gpass, gstop)`. * * Filter type follows scipy: scalar `wp < ws` → lowpass, `wp > ws` → highpass; * array with `wp[0] > ws[0]` (passband inside stopband) → bandpass, `wp[0] < * ws[0]` (stopband inside passband) → bandstop. */ export declare function buttord(wp: number, ws: number, gpass: number, gstop: number): { N: number; Wn: number; }; export declare function buttord(wp: readonly [number, number], ws: readonly [number, number], gpass: number, gstop: number): { N: number; Wn: [number, number]; }; type ZpkRoot = number | Complex; /** * Group zeros/poles/gain into cascaded second-order sections: * `[[b0,b1,b2,a0,a1,a2], …]`, each a monic-denominator biquad (`a0 = 1`) with * the overall gain folded into the first section's numerator. `z` is * zero-padded (roots at the origin) if shorter than `p`. Matches * `scipy.signal.zpk2sos` in effect (the two decompositions can differ in * pairing order, but the resulting cascaded transfer function is identical). */ export declare function zpk2sos(z: readonly ZpkRoot[], p: readonly ZpkRoot[], k: number): number[][]; /** * Apply a cascade of second-order sections (`[[b0,b1,b2,a0,a1,a2], …]`, as * produced by `zpk2sos`) to `x`, each biquad in direct-form-II transposed. * Matches `scipy.signal.sosfilt(sos, x)`. */ export declare function sosfilt(sos: readonly (readonly number[])[], x: Vec): number[]; export {}; //# sourceMappingURL=iir-design.d.ts.map