@danielsimonjr/mathts-functions 0.32.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2182 -583
- package/dist/numbertheory/extra.d.ts +142 -0
- package/dist/numbertheory/extra.d.ts.map +1 -0
- package/dist/numeric/gauss-nodes.d.ts +35 -0
- package/dist/numeric/gauss-nodes.d.ts.map +1 -0
- package/dist/signal/conv.d.ts +113 -0
- package/dist/signal/conv.d.ts.map +1 -0
- package/dist/signal/fft-helpers.d.ts +56 -0
- package/dist/signal/fft-helpers.d.ts.map +1 -0
- package/dist/signal/fft.d.ts +136 -0
- package/dist/signal/fft.d.ts.map +1 -0
- package/dist/signal/fir-smoothing.d.ts +62 -0
- package/dist/signal/fir-smoothing.d.ts.map +1 -0
- package/dist/signal/iir-design.d.ts +94 -0
- package/dist/signal/iir-design.d.ts.map +1 -0
- package/dist/signal/spectral-peaks.d.ts +115 -0
- package/dist/signal/spectral-peaks.d.ts.map +1 -0
- package/dist/signal/wavelets.d.ts +55 -0
- package/dist/signal/wavelets.d.ts.map +1 -0
- package/dist/signal-filter-extra.d.ts +42 -3
- package/dist/signal-filter-extra.d.ts.map +1 -1
- package/dist/special/hypergeometric.d.ts +91 -0
- package/dist/special/hypergeometric.d.ts.map +1 -0
- package/dist/special/jacobi-elliptic.d.ts +60 -0
- package/dist/special/jacobi-elliptic.d.ts.map +1 -0
- package/dist/special/polygamma-orthopoly.d.ts +79 -0
- package/dist/special/polygamma-orthopoly.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Number-theory fills — closes gaps left by the existing combinatorics/number-theory
|
|
3
|
+
* surface (`typed/combinatorics.ts`): continued fractions, Euler numbers, the signed
|
|
4
|
+
* Stirling numbers of the first kind, discrete logarithm (BSGS), primitive roots,
|
|
5
|
+
* multiplicative order, the Kronecker symbol, and lexicographic
|
|
6
|
+
* permutation/combination *enumerators* (the existing `permutations`/`combinations`
|
|
7
|
+
* only return counts, not the tuples themselves).
|
|
8
|
+
*
|
|
9
|
+
* Plain exported functions (not `mathTyped` dispatch) — all take/return `number`
|
|
10
|
+
* or generic arrays, matching the style of `descriptive-stats.ts`.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Simple continued fraction expansion `[a0, a1, a2, ...]` of `x`, where
|
|
16
|
+
* `a_i = floor(r)` and `r <- 1 / (r - a_i)`.
|
|
17
|
+
*
|
|
18
|
+
* Stops after `maxTerms` (default 20) or once the fractional part is smaller
|
|
19
|
+
* than `1e-12` (the remaining value is effectively an integer).
|
|
20
|
+
*
|
|
21
|
+
* @param x - The number to expand
|
|
22
|
+
* @param maxTerms - Maximum number of terms to compute (default 20)
|
|
23
|
+
* @returns The sequence of partial-quotient terms
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* continuedFraction(3.245, 5) // => [3, 4, 12, 4, ...]
|
|
27
|
+
*/
|
|
28
|
+
export declare function continuedFraction(x: number, maxTerms?: number): number[];
|
|
29
|
+
/**
|
|
30
|
+
* Euler numbers `E_0..E_n` (the coefficients in the secant Maclaurin series).
|
|
31
|
+
*
|
|
32
|
+
* `E_0 = 1`; all odd-index Euler numbers are 0; for even `m > 0`:
|
|
33
|
+
* `E_m = -sum_{k=0}^{m/2-1} C(m, 2k) * E_{2k}`.
|
|
34
|
+
*
|
|
35
|
+
* @param n - Non-negative integer: compute E_0 through E_n
|
|
36
|
+
* @returns Array of length `n + 1`: `[E_0, E_1, ..., E_n]`
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* eulerNumbers(6) // => [1, 0, -1, 0, 5, 0, -61]
|
|
40
|
+
*/
|
|
41
|
+
export declare function eulerNumbers(n: number): number[];
|
|
42
|
+
/**
|
|
43
|
+
* Signed Stirling number of the first kind `s(n, k)`.
|
|
44
|
+
*
|
|
45
|
+
* Recurrence: `s(n, k) = s(n-1, k-1) - (n-1)*s(n-1, k)`, with `s(0, 0) = 1`
|
|
46
|
+
* and `s(n, 0) = 0` for `n > 0`.
|
|
47
|
+
*
|
|
48
|
+
* @param n - Non-negative integer
|
|
49
|
+
* @param k - Non-negative integer, `0 <= k <= n`
|
|
50
|
+
* @returns The signed Stirling number `s(n, k)`
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* stirlingS1(5, 2) // => -50
|
|
54
|
+
*/
|
|
55
|
+
export declare function stirlingS1(n: number, k: number): number;
|
|
56
|
+
/**
|
|
57
|
+
* Discrete logarithm via baby-step giant-step: the smallest `x >= 0` such
|
|
58
|
+
* that `g^x === h (mod p)`, or `-1` if none exists within `[0, p-1]`.
|
|
59
|
+
*
|
|
60
|
+
* Uses `BigInt` internally for modular exponentiation/inversion to avoid
|
|
61
|
+
* overflow. `m = ceil(sqrt(p-1))` baby steps are stored in a map; the giant
|
|
62
|
+
* steps multiply by `g^(-m) mod p` each round.
|
|
63
|
+
*
|
|
64
|
+
* @param g - Base
|
|
65
|
+
* @param h - Target
|
|
66
|
+
* @param p - Prime modulus
|
|
67
|
+
* @returns The smallest non-negative `x` with `g^x === h (mod p)`, or `-1`
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* discreteLog(2, 3, 5) // => 3 (2^3 = 8 === 3 mod 5)
|
|
71
|
+
*/
|
|
72
|
+
export declare function discreteLog(g: number, h: number, p: number): number;
|
|
73
|
+
/**
|
|
74
|
+
* Smallest primitive root modulo a prime `p`.
|
|
75
|
+
*
|
|
76
|
+
* For each candidate `g = 2, 3, ...`, `g` is a primitive root iff
|
|
77
|
+
* `g^((p-1)/q) !== 1 (mod p)` for every prime factor `q` of `p - 1`.
|
|
78
|
+
*
|
|
79
|
+
* @param p - An odd prime (p = 2 returns 1 trivially)
|
|
80
|
+
* @returns The smallest primitive root modulo p
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* primitiveRoot(7) // => 3
|
|
84
|
+
*/
|
|
85
|
+
export declare function primitiveRoot(p: number): number;
|
|
86
|
+
/**
|
|
87
|
+
* Multiplicative order of `a` modulo `n`: the smallest `k > 0` with
|
|
88
|
+
* `a^k === 1 (mod n)`. Returns `-1` if `gcd(a, n) !== 1` (no order exists).
|
|
89
|
+
*
|
|
90
|
+
* @param a - Integer
|
|
91
|
+
* @param n - Positive integer modulus
|
|
92
|
+
* @returns The multiplicative order, or -1 if undefined
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* multiplicativeOrder(2, 7) // => 3
|
|
96
|
+
*/
|
|
97
|
+
export declare function multiplicativeOrder(a: number, n: number): number;
|
|
98
|
+
/**
|
|
99
|
+
* Kronecker symbol `(a|n)`, generalizing the Jacobi symbol `(a|n)` (odd
|
|
100
|
+
* positive `n`) to all integers `n`.
|
|
101
|
+
*
|
|
102
|
+
* - `(a|0) = 1` if `|a| = 1`, else `0`.
|
|
103
|
+
* - Sign of `n` is extracted first: `(a|-1) = -1` if `a < 0`, else `1`.
|
|
104
|
+
* - Factors of 2 are extracted from `n` using `(a|2)`: `0` if `a` even,
|
|
105
|
+
* `1` if `a === ±1 (mod 8)`, `-1` if `a === ±3 (mod 8)`.
|
|
106
|
+
* - The remaining odd part is evaluated via the standard Jacobi reciprocity
|
|
107
|
+
* recursion.
|
|
108
|
+
*
|
|
109
|
+
* @param a - Integer
|
|
110
|
+
* @param n - Integer
|
|
111
|
+
* @returns -1, 0, or 1
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* kroneckerSymbol(2, 3) // => -1
|
|
115
|
+
*/
|
|
116
|
+
export declare function kroneckerSymbol(a: number, n: number): number;
|
|
117
|
+
/**
|
|
118
|
+
* Enumerate all length-`k` combinations of `arr` (index-order subsequences,
|
|
119
|
+
* i.e. lexicographic order for a sorted input) as an array of tuples.
|
|
120
|
+
*
|
|
121
|
+
* @param arr - Source array
|
|
122
|
+
* @param k - Combination length
|
|
123
|
+
* @returns All `C(arr.length, k)` combinations, in lexicographic order
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* combinationsGen([1, 2, 3], 2) // => [[1,2],[1,3],[2,3]]
|
|
127
|
+
*/
|
|
128
|
+
export declare function combinationsGen<T>(arr: readonly T[], k: number): T[][];
|
|
129
|
+
/**
|
|
130
|
+
* Enumerate all length-`k` permutations (ordered arrangements) of `arr`
|
|
131
|
+
* as an array of tuples, in lexicographic order of index selection.
|
|
132
|
+
* `k` defaults to `arr.length` (full permutations).
|
|
133
|
+
*
|
|
134
|
+
* @param arr - Source array
|
|
135
|
+
* @param k - Permutation length (default: `arr.length`)
|
|
136
|
+
* @returns All `n! / (n-k)!` permutations, in lexicographic order
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* permutationsGen([1, 2, 3], 2) // => 6 tuples: [1,2],[1,3],[2,1],[2,3],[3,1],[3,2]
|
|
140
|
+
*/
|
|
141
|
+
export declare function permutationsGen<T>(arr: readonly T[], k?: number): T[][];
|
|
142
|
+
//# sourceMappingURL=extra.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extra.d.ts","sourceRoot":"","sources":["../../src/numbertheory/extra.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM,EAAE,CAcpE;AAiBD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBhD;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAevD;AAqCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA+BnE;AAoBD;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAmB/C;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAehE;AAaD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CA0C5D;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAoBtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,GAAE,MAAmB,GAAG,CAAC,EAAE,EAAE,CAwBnF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gauss-Legendre quadrature nodes and weights.
|
|
3
|
+
*
|
|
4
|
+
* `rootsLegendre(n)` finds the n roots of the degree-n Legendre polynomial
|
|
5
|
+
* P_n via Newton's method (initial guess from the standard asymptotic
|
|
6
|
+
* approximation), then derives the corresponding quadrature weights. This is
|
|
7
|
+
* the classical fixed-node table underlying Gauss-Legendre quadrature on
|
|
8
|
+
* [-1, 1]; callers needing a custom node count (rather than the library's
|
|
9
|
+
* built-in fixed-order `integrate`/`gaussLegendre` routines) use this
|
|
10
|
+
* directly.
|
|
11
|
+
*
|
|
12
|
+
* @packageDocumentation
|
|
13
|
+
*/
|
|
14
|
+
/** Result of {@link rootsLegendre}: nodes ascending on [-1, 1] with matching weights. */
|
|
15
|
+
export interface RootsLegendreResult {
|
|
16
|
+
nodes: number[];
|
|
17
|
+
weights: number[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* n-point Gauss-Legendre quadrature nodes and weights on [-1, 1].
|
|
21
|
+
*
|
|
22
|
+
* Nodes are the roots of the degree-n Legendre polynomial P_n, refined by
|
|
23
|
+
* Newton's method from the standard asymptotic initial guess
|
|
24
|
+
* `cos(pi*(i+0.75)/(n+0.5))`. Weights are `2 / ((1-x_i^2) * P'_n(x_i)^2)`.
|
|
25
|
+
*
|
|
26
|
+
* @param n - Number of quadrature points (positive integer)
|
|
27
|
+
* @returns Nodes (ascending) and matching weights
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* rootsLegendre(3)
|
|
31
|
+
* // { nodes: [-0.7745966692, 0, 0.7745966692],
|
|
32
|
+
* // weights: [0.5555555556, 0.8888888889, 0.5555555556] }
|
|
33
|
+
*/
|
|
34
|
+
export declare function rootsLegendre(n: number): RootsLegendreResult;
|
|
35
|
+
//# sourceMappingURL=gauss-nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gauss-nodes.d.ts","sourceRoot":"","sources":["../../src/numeric/gauss-nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,mBAAmB,CA+B5D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convolution Operations
|
|
3
|
+
*
|
|
4
|
+
* Implements 1D and 2D convolution using both direct and FFT methods.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Convolution mode - determines output size
|
|
10
|
+
*/
|
|
11
|
+
export type ConvMode = 'full' | 'same' | 'valid';
|
|
12
|
+
/**
|
|
13
|
+
* Direct 1D convolution (for small inputs)
|
|
14
|
+
*
|
|
15
|
+
* @param x - Input signal
|
|
16
|
+
* @param h - Convolution kernel
|
|
17
|
+
* @param mode - Output mode: 'full', 'same', or 'valid'
|
|
18
|
+
* @returns Convolution result
|
|
19
|
+
*/
|
|
20
|
+
export declare function convDirect(x: number[] | Float64Array, h: number[] | Float64Array, mode?: ConvMode): number[];
|
|
21
|
+
/**
|
|
22
|
+
* FFT-based 1D convolution (efficient for large inputs)
|
|
23
|
+
*
|
|
24
|
+
* Uses the convolution theorem: conv(x,h) = IFFT(FFT(x) * FFT(h))
|
|
25
|
+
*
|
|
26
|
+
* @param x - Input signal
|
|
27
|
+
* @param h - Convolution kernel
|
|
28
|
+
* @param mode - Output mode: 'full', 'same', or 'valid'
|
|
29
|
+
* @returns Convolution result
|
|
30
|
+
*/
|
|
31
|
+
export declare function convFFT(x: number[] | Float64Array, h: number[] | Float64Array, mode?: ConvMode): number[];
|
|
32
|
+
/**
|
|
33
|
+
* 1D Convolution with automatic method selection
|
|
34
|
+
*
|
|
35
|
+
* Automatically selects direct or FFT method based on input sizes.
|
|
36
|
+
*
|
|
37
|
+
* @param x - Input signal
|
|
38
|
+
* @param h - Convolution kernel
|
|
39
|
+
* @param mode - Output mode: 'full' (default), 'same', or 'valid'
|
|
40
|
+
* @returns Convolution result
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* // Simple convolution
|
|
45
|
+
* const signal = [1, 2, 3, 4, 5];
|
|
46
|
+
* const kernel = [1, 0, -1]; // Edge detection
|
|
47
|
+
* const result = conv(signal, kernel, 'same');
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare function conv(x: number[] | Float64Array, h: number[] | Float64Array, mode?: ConvMode): number[];
|
|
51
|
+
/**
|
|
52
|
+
* Cross-correlation of two signals
|
|
53
|
+
*
|
|
54
|
+
* Cross-correlation is convolution with the kernel reversed.
|
|
55
|
+
*
|
|
56
|
+
* @param x - First signal
|
|
57
|
+
* @param h - Second signal
|
|
58
|
+
* @param mode - Output mode
|
|
59
|
+
* @returns Cross-correlation result
|
|
60
|
+
*/
|
|
61
|
+
export declare function xcorr(x: number[] | Float64Array, h: number[] | Float64Array, mode?: ConvMode): number[];
|
|
62
|
+
/**
|
|
63
|
+
* Auto-correlation of a signal
|
|
64
|
+
*
|
|
65
|
+
* @param x - Input signal
|
|
66
|
+
* @param mode - Output mode
|
|
67
|
+
* @returns Auto-correlation result
|
|
68
|
+
*/
|
|
69
|
+
export declare function autocorr(x: number[] | Float64Array, mode?: ConvMode): number[];
|
|
70
|
+
/**
|
|
71
|
+
* Direct 2D convolution
|
|
72
|
+
*
|
|
73
|
+
* @param image - 2D input array
|
|
74
|
+
* @param kernel - 2D convolution kernel
|
|
75
|
+
* @param mode - Output mode
|
|
76
|
+
* @returns 2D convolution result
|
|
77
|
+
*/
|
|
78
|
+
export declare function conv2Direct(image: number[][], kernel: number[][], mode?: ConvMode): number[][];
|
|
79
|
+
/**
|
|
80
|
+
* FFT-based 2D convolution
|
|
81
|
+
*
|
|
82
|
+
* @param image - 2D input array
|
|
83
|
+
* @param kernel - 2D convolution kernel
|
|
84
|
+
* @param mode - Output mode
|
|
85
|
+
* @returns 2D convolution result
|
|
86
|
+
*/
|
|
87
|
+
export declare function conv2FFT(image: number[][], kernel: number[][], mode?: ConvMode): number[][];
|
|
88
|
+
/**
|
|
89
|
+
* 2D Convolution with automatic method selection
|
|
90
|
+
*
|
|
91
|
+
* @param image - 2D input array
|
|
92
|
+
* @param kernel - 2D convolution kernel
|
|
93
|
+
* @param mode - Output mode: 'full' (default), 'same', or 'valid'
|
|
94
|
+
* @returns 2D convolution result
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* // Edge detection with Sobel kernel
|
|
99
|
+
* const image = [
|
|
100
|
+
* [1, 2, 3],
|
|
101
|
+
* [4, 5, 6],
|
|
102
|
+
* [7, 8, 9],
|
|
103
|
+
* ];
|
|
104
|
+
* const sobelX = [
|
|
105
|
+
* [-1, 0, 1],
|
|
106
|
+
* [-2, 0, 2],
|
|
107
|
+
* [-1, 0, 1],
|
|
108
|
+
* ];
|
|
109
|
+
* const edges = conv2(image, sobelX, 'same');
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare function conv2(image: number[][], kernel: number[][], mode?: ConvMode): number[][];
|
|
113
|
+
//# sourceMappingURL=conv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conv.d.ts","sourceRoot":"","sources":["../../src/signal/conv.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAYjD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,CA8CV;AAED;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACrB,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,CAsDV;AAOD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAClB,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,CAWV;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAC1B,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,CAKV;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,IAAI,GAAE,QAAiB,GAAG,MAAM,EAAE,CAEtF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EAAE,EAAE,EACjB,MAAM,EAAE,MAAM,EAAE,EAAE,EAClB,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,EAAE,CA8DZ;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EAAE,EAAE,EACjB,MAAM,EAAE,MAAM,EAAE,EAAE,EAClB,IAAI,GAAE,QAAiB,GACtB,MAAM,EAAE,EAAE,CAiGZ;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,GAAE,QAAiB,GAAG,MAAM,EAAE,EAAE,CAgBhG"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real FFT: compute the full FFT of a real signal and keep only the first
|
|
3
|
+
* `floor(n/2)+1` bins — the non-redundant half of the conjugate-symmetric spectrum.
|
|
4
|
+
*
|
|
5
|
+
* @param x Real input signal
|
|
6
|
+
* @returns `{ re, im }` arrays of length `floor(n/2)+1`
|
|
7
|
+
*/
|
|
8
|
+
export declare function rfft(x: number[]): {
|
|
9
|
+
re: number[];
|
|
10
|
+
im: number[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Inverse real FFT: reconstruct the full conjugate-symmetric spectrum of length `n`
|
|
14
|
+
* from the non-redundant half produced by {@link rfft} (bins `n/2+1..n-1` are the
|
|
15
|
+
* conjugates of bins `n/2-1..1`), inverse-FFT it, and return the real parts.
|
|
16
|
+
*
|
|
17
|
+
* @param spec `{ re, im }` half-spectrum (bins `0..floor(n/2)`)
|
|
18
|
+
* @param n Length of the reconstructed real signal
|
|
19
|
+
* @returns Real-valued signal of length `n`
|
|
20
|
+
*/
|
|
21
|
+
export declare function irfft(spec: {
|
|
22
|
+
re: number[];
|
|
23
|
+
im: number[];
|
|
24
|
+
}, n: number): number[];
|
|
25
|
+
/**
|
|
26
|
+
* Shift the zero-frequency component to the center of the spectrum (roll by `floor(n/2)`).
|
|
27
|
+
*/
|
|
28
|
+
export declare function fftshift(x: number[]): number[];
|
|
29
|
+
/**
|
|
30
|
+
* Inverse of {@link fftshift} (roll by `ceil(n/2)`).
|
|
31
|
+
*/
|
|
32
|
+
export declare function ifftshift(x: number[]): number[];
|
|
33
|
+
/**
|
|
34
|
+
* DFT sample frequencies: `[0, 1, ..., ceil(n/2)-1, -floor(n/2), ..., -1] / (n*d)`.
|
|
35
|
+
*
|
|
36
|
+
* @param n Number of samples
|
|
37
|
+
* @param d Sample spacing (default 1)
|
|
38
|
+
*/
|
|
39
|
+
export declare function fftfreq(n: number, d?: number): number[];
|
|
40
|
+
/**
|
|
41
|
+
* DFT sample frequencies matching {@link rfft} output: `[0, 1, ..., floor(n/2)] / (n*d)`.
|
|
42
|
+
*
|
|
43
|
+
* @param n Number of samples
|
|
44
|
+
* @param d Sample spacing (default 1)
|
|
45
|
+
*/
|
|
46
|
+
export declare function rfftfreq(n: number, d?: number): number[];
|
|
47
|
+
/**
|
|
48
|
+
* 2-D FFT: FFT each row, then FFT each column of the result. Delegates directly to
|
|
49
|
+
* the package's N-dimensional `fft`, which already performs exactly this row-then-
|
|
50
|
+
* column transform when given a 2-D array.
|
|
51
|
+
*/
|
|
52
|
+
export declare function fftn(x: number[][]): {
|
|
53
|
+
re: number[][];
|
|
54
|
+
im: number[][];
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=fft-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fft-helpers.d.ts","sourceRoot":"","sources":["../../src/signal/fft-helpers.ts"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,CAYhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAY/E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAI9C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAI/C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAE,MAAU,GAAG,MAAM,EAAE,CAW1D;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAE,MAAU,GAAG,MAAM,EAAE,CAO3D;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG;IAAE,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,CAKtE"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast Fourier Transform (FFT)
|
|
3
|
+
*
|
|
4
|
+
* Implements the Cooley-Tukey radix-2 decimation-in-time FFT algorithm.
|
|
5
|
+
* For non-power-of-2 lengths, zero-pads to next power of 2.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Complex number representation for FFT
|
|
11
|
+
*/
|
|
12
|
+
export interface ComplexNumber {
|
|
13
|
+
re: number;
|
|
14
|
+
im: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* FFT result containing the frequency spectrum
|
|
18
|
+
*/
|
|
19
|
+
export interface FFTResult {
|
|
20
|
+
/** Complex frequency components */
|
|
21
|
+
spectrum: ComplexNumber[];
|
|
22
|
+
/** Original signal length before padding */
|
|
23
|
+
originalLength: number;
|
|
24
|
+
/** Padded length (power of 2) */
|
|
25
|
+
paddedLength: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a complex number
|
|
29
|
+
*/
|
|
30
|
+
export declare function complex(re: number, im?: number): ComplexNumber;
|
|
31
|
+
/**
|
|
32
|
+
* Complex conjugate
|
|
33
|
+
*/
|
|
34
|
+
export declare function complexConj(a: ComplexNumber): ComplexNumber;
|
|
35
|
+
/**
|
|
36
|
+
* Complex magnitude
|
|
37
|
+
*/
|
|
38
|
+
export declare function complexAbs(a: ComplexNumber): number;
|
|
39
|
+
/**
|
|
40
|
+
* Complex phase/argument
|
|
41
|
+
*/
|
|
42
|
+
export declare function complexArg(a: ComplexNumber): number;
|
|
43
|
+
/**
|
|
44
|
+
* Compute the Fast Fourier Transform of a real or complex signal.
|
|
45
|
+
*
|
|
46
|
+
* Uses the Cooley-Tukey radix-2 decimation-in-time algorithm.
|
|
47
|
+
* Input is zero-padded to the next power of 2 if necessary.
|
|
48
|
+
*
|
|
49
|
+
* @param signal - Input signal (real numbers or complex numbers)
|
|
50
|
+
* @returns FFT result with spectrum and length info
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* // FFT of a real signal
|
|
55
|
+
* const signal = [1, 0, -1, 0];
|
|
56
|
+
* const result = fft(signal);
|
|
57
|
+
* console.log(result.spectrum); // Frequency components
|
|
58
|
+
*
|
|
59
|
+
* // FFT of a complex signal
|
|
60
|
+
* const complexSignal = [
|
|
61
|
+
* { re: 1, im: 0 },
|
|
62
|
+
* { re: 0, im: 1 },
|
|
63
|
+
* ];
|
|
64
|
+
* const result2 = fft(complexSignal);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export declare function fft(signal: number[] | Float64Array | ComplexNumber[]): FFTResult;
|
|
68
|
+
/**
|
|
69
|
+
* Compute the Inverse Fast Fourier Transform.
|
|
70
|
+
*
|
|
71
|
+
* Recovers the time-domain signal from its frequency spectrum.
|
|
72
|
+
*
|
|
73
|
+
* @param spectrum - Complex frequency spectrum
|
|
74
|
+
* @param originalLength - Optional: truncate result to this length
|
|
75
|
+
* @returns Recovered signal
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* // Round-trip test
|
|
80
|
+
* const signal = [1, 2, 3, 4];
|
|
81
|
+
* const result = fft(signal);
|
|
82
|
+
* const recovered = ifft(result.spectrum, result.originalLength);
|
|
83
|
+
* // recovered ≈ signal
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare function ifft(spectrum: ComplexNumber[], originalLength?: number): ComplexNumber[];
|
|
87
|
+
/**
|
|
88
|
+
* Compute the real part of IFFT result
|
|
89
|
+
*/
|
|
90
|
+
export declare function ifftReal(spectrum: ComplexNumber[], originalLength?: number): number[];
|
|
91
|
+
/**
|
|
92
|
+
* Compute the magnitude spectrum (|X(k)|)
|
|
93
|
+
*/
|
|
94
|
+
export declare function fftMagnitude(spectrum: ComplexNumber[]): number[];
|
|
95
|
+
/**
|
|
96
|
+
* Compute the power spectrum (|X(k)|²)
|
|
97
|
+
*/
|
|
98
|
+
export declare function fftPower(spectrum: ComplexNumber[]): number[];
|
|
99
|
+
/**
|
|
100
|
+
* Compute the phase spectrum (arg(X(k)))
|
|
101
|
+
*/
|
|
102
|
+
export declare function fftPhase(spectrum: ComplexNumber[]): number[];
|
|
103
|
+
/**
|
|
104
|
+
* Compute FFT frequency bins for a given sample rate
|
|
105
|
+
*
|
|
106
|
+
* @param n - Number of FFT points
|
|
107
|
+
* @param sampleRate - Sample rate in Hz
|
|
108
|
+
* @returns Array of frequencies in Hz
|
|
109
|
+
*/
|
|
110
|
+
export declare function fftFrequencies(n: number, sampleRate?: number): number[];
|
|
111
|
+
/**
|
|
112
|
+
* Compute the 2D FFT of a matrix
|
|
113
|
+
*
|
|
114
|
+
* @param matrix - 2D array of real or complex values
|
|
115
|
+
* @returns 2D frequency spectrum
|
|
116
|
+
*/
|
|
117
|
+
export declare function fft2(matrix: number[][] | ComplexNumber[][]): ComplexNumber[][];
|
|
118
|
+
/**
|
|
119
|
+
* Compute the 2D inverse FFT
|
|
120
|
+
*
|
|
121
|
+
* @param spectrum - 2D frequency spectrum
|
|
122
|
+
* @returns 2D spatial domain result
|
|
123
|
+
*/
|
|
124
|
+
export declare function ifft2(spectrum: ComplexNumber[][]): ComplexNumber[][];
|
|
125
|
+
/**
|
|
126
|
+
* Shift zero-frequency component to center of spectrum
|
|
127
|
+
*
|
|
128
|
+
* @param spectrum - FFT spectrum
|
|
129
|
+
* @returns Shifted spectrum
|
|
130
|
+
*/
|
|
131
|
+
export declare function fftshift<T>(spectrum: T[]): T[];
|
|
132
|
+
/**
|
|
133
|
+
* Inverse of fftshift
|
|
134
|
+
*/
|
|
135
|
+
export declare function ifftshift<T>(spectrum: T[]): T[];
|
|
136
|
+
//# sourceMappingURL=fft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fft.d.ts","sourceRoot":"","sources":["../../src/signal/fft.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,mCAAmC;IACnC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,GAAE,MAAU,GAAG,aAAa,CAEjE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,GAAG,aAAa,CAE3D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAEnD;AA0DD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,GAAG,aAAa,EAAE,GAAG,SAAS,CAqChF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CAuBxF;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAGrF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAEhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAE5D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,EAAE,CAE5D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,GAAE,MAAU,GAAG,MAAM,EAAE,CAa1E;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,CAoC9E;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,CA8BpE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAI9C;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAI/C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type Vec = readonly number[] | Float64Array;
|
|
2
|
+
/** Polynomial/deconvolution division result: `signal = conv(divisor, quotient) + remainder`. */
|
|
3
|
+
export interface DeconvolveResult {
|
|
4
|
+
quotient: number[];
|
|
5
|
+
remainder: number[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* FIR bandpass filter coefficients by the windowed-sinc method (Hamming
|
|
9
|
+
* window): `h[n] = (f2·sinc(f2·(n−M/2)) − f1·sinc(f1·(n−M/2)))·hamming[n]`,
|
|
10
|
+
* `M = numtaps−1`. `[f1, f2]` are cutoffs normalized to Nyquist (1 = Nyquist).
|
|
11
|
+
* This is the array-cutoff (bandpass) case the scalar-only `firwin` in
|
|
12
|
+
* `../signal-filter-extra.ts` didn't support (resolves the Phase-0 note).
|
|
13
|
+
*/
|
|
14
|
+
export declare function firwinBandpass(numtaps: number, cutoffs: readonly [number, number]): number[];
|
|
15
|
+
/**
|
|
16
|
+
* Savitzky-Golay smoothing (`scipy.signal.savgol_filter`, default `mode='interp'`).
|
|
17
|
+
* For each interior position, fits a degree-`polyorder` polynomial (via the
|
|
18
|
+
* normal equations over a Vandermonde of the window offsets) to the centered
|
|
19
|
+
* `windowLength`-point window and takes the fitted value at the center. Edge
|
|
20
|
+
* points reuse the nearest full boundary window's fit, evaluated at the edge
|
|
21
|
+
* point's actual offset from that window's center (scipy's boundary handling).
|
|
22
|
+
* Exact on polynomials of degree <= `polyorder`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function savgol(x: Vec, windowLength: number, polyorder: number): number[];
|
|
25
|
+
/**
|
|
26
|
+
* FIR/polynomial deconvolution (`scipy.signal.deconvolve`): standard
|
|
27
|
+
* synthetic long division so that `signal = conv(divisor, quotient) + remainder`,
|
|
28
|
+
* with `quotient` of length `signal.length - divisor.length + 1` and
|
|
29
|
+
* `remainder` the same length as `signal` (zero when `divisor` exactly divides).
|
|
30
|
+
*/
|
|
31
|
+
export declare function deconvolve(signal: Vec, divisor: Vec): DeconvolveResult;
|
|
32
|
+
/**
|
|
33
|
+
* Wiener adaptive filter (`scipy.signal.wiener`-style, per-sample noise
|
|
34
|
+
* estimate): local mean `m` and variance `v` over a sliding window of size
|
|
35
|
+
* `mysize` (same-length, zero-padded at the edges — matches `convDirect`'s
|
|
36
|
+
* `'same'` convention), noise power `= mean(v)`; output
|
|
37
|
+
* `m + max(0, v−noise)/max(v, noise)·(x−m)` (0 where both `v` and `noise` are 0).
|
|
38
|
+
*/
|
|
39
|
+
export declare function wiener(x: Vec, mysize?: number): number[];
|
|
40
|
+
/**
|
|
41
|
+
* Least-squares linear-phase FIR design (`scipy.signal.firls`): `bands` is a
|
|
42
|
+
* flat list of `[lo, hi]` band-edge pairs (normalized to Nyquist, 1 = Nyquist)
|
|
43
|
+
* and `desired` the corresponding response values at those edges (linearly
|
|
44
|
+
* interpolated within each band; gaps between bands are unconstrained
|
|
45
|
+
* transition regions). Solves the normal equations of the cosine-basis
|
|
46
|
+
* representation of a symmetric (Type I odd-length / Type II even-length)
|
|
47
|
+
* linear-phase filter against a dense trapezoid-quadrature sampling of the
|
|
48
|
+
* specified bands, then maps the fitted basis coefficients back to taps.
|
|
49
|
+
*/
|
|
50
|
+
export declare function firls(numtaps: number, bands: readonly number[], desired: readonly number[]): number[];
|
|
51
|
+
/**
|
|
52
|
+
* Parks-McClellan-style equiripple FIR design. **This is NOT the exact
|
|
53
|
+
* Remez-exchange algorithm** — it is Lawson's algorithm, an iteratively
|
|
54
|
+
* reweighted least squares (IRLS) scheme that approximates the minimax
|
|
55
|
+
* (Chebyshev) solution by repeatedly re-solving the `firls` normal equations
|
|
56
|
+
* with per-sample weights pushed up wherever the previous iteration's error
|
|
57
|
+
* was largest, converging toward (but not guaranteed to reach) a true
|
|
58
|
+
* equiripple response. Documented as approximate per the Task 3 spec.
|
|
59
|
+
*/
|
|
60
|
+
export declare function remez(numtaps: number, bands: readonly number[], desired: readonly number[]): number[];
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=fir-smoothing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fir-smoothing.d.ts","sourceRoot":"","sources":["../../src/signal/fir-smoothing.ts"],"names":[],"mappings":"AAUA,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAG5C,gGAAgG;AAChG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAsCD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAa5F;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CA4BhF;AAID;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,gBAAgB,CAiBtE;AAID;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,SAAI,GAAG,MAAM,EAAE,CAsBnD;AAoHD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,EAAE,CAUV;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,EAAE,CAkBV"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chebyshev I/II and elliptic (Cauer) IIR filter design, plus the supporting
|
|
3
|
+
* `zpk2sos`/`sosfilt`/`bilinear`/`buttord` utilities. Extends the Butterworth
|
|
4
|
+
* pipeline in `../signal-filter-extra.ts` with two more analog prototypes and
|
|
5
|
+
* reuses its shared zpk→transfer-function plumbing (`analogToDigital`,
|
|
6
|
+
* `polyFromRoots`). Matches `scipy.signal` — every coefficient set pinned
|
|
7
|
+
* against `scipy.signal.{cheby1,cheby2,ellip,bilinear,buttord}` (see
|
|
8
|
+
* `functions/tests/iir-design.test.ts`).
|
|
9
|
+
*
|
|
10
|
+
* The elliptic prototype (`ellipap`) follows Orfanidis, "Lecture Notes on
|
|
11
|
+
* Elliptic Filter Design" (the algorithm scipy itself implements): the filter
|
|
12
|
+
* degree equation is solved in closed form via the theta-function nome
|
|
13
|
+
* expansion (`ellipdeg`), and the "arc Jacobi sc" root (`arcJacSc1`) via the
|
|
14
|
+
* descending Landen transformation (`arcJacSn`) — no numerical optimizer is
|
|
15
|
+
* needed. Reuses the repo's existing AGM-based `ellipticKScalar` and
|
|
16
|
+
* `jacobiSN`/`jacobiCN`/`jacobiDN` (Phase 5 special functions, `m = k²`
|
|
17
|
+
* convention, matching scipy's `ellipk`/`ellipj`).
|
|
18
|
+
*/
|
|
19
|
+
import { Complex } from '@danielsimonjr/mathts-core';
|
|
20
|
+
import { type FilterBtype } from '../signal-filter-extra.js';
|
|
21
|
+
type Vec = readonly number[] | Float64Array;
|
|
22
|
+
/**
|
|
23
|
+
* Chebyshev Type I digital IIR filter design — equiripple in the passband, `rp`
|
|
24
|
+
* dB of ripple. `Wn` is the cutoff (scalar) or `[low, high]` band edges,
|
|
25
|
+
* normalized to Nyquist. Matches `scipy.signal.cheby1(N, rp, Wn, btype)`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function cheby1(N: number, rp: number, Wn: number | readonly number[], btype?: FilterBtype): {
|
|
28
|
+
b: number[];
|
|
29
|
+
a: number[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Chebyshev Type II digital IIR filter design — equiripple in the stopband,
|
|
33
|
+
* `rs` dB of stopband attenuation, monotone passband. `Wn` is the cutoff
|
|
34
|
+
* (scalar) or `[low, high]` band edges, normalized to Nyquist. Matches
|
|
35
|
+
* `scipy.signal.cheby2(N, rs, Wn, btype)`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function cheby2(N: number, rs: number, Wn: number | readonly number[], btype?: FilterBtype): {
|
|
38
|
+
b: number[];
|
|
39
|
+
a: number[];
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Elliptic (Cauer) digital IIR filter design — equiripple in both passband
|
|
43
|
+
* (`rp` dB) and stopband (`rs` dB); the steepest roll-off of the four classical
|
|
44
|
+
* IIR families for a given order. `Wn` is the cutoff (scalar) or `[low, high]`
|
|
45
|
+
* band edges, normalized to Nyquist. Matches `scipy.signal.ellip(N, rp, rs, Wn,
|
|
46
|
+
* btype)` exactly (verified against `scipy.signal` 1.17.1 — see
|
|
47
|
+
* `functions/tests/iir-design.test.ts`); this is a full port of scipy's
|
|
48
|
+
* closed-form (nome-based) elliptic design, not an approximation.
|
|
49
|
+
*/
|
|
50
|
+
export declare function ellip(N: number, rp: number, rs: number, Wn: number | readonly number[], btype?: FilterBtype): {
|
|
51
|
+
b: number[];
|
|
52
|
+
a: number[];
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Analog-to-digital bilinear (Tustin) transform of a transfer function: given
|
|
56
|
+
* `H(s) = b(s)/a(s)` (coefficients highest-degree-first), substitutes
|
|
57
|
+
* `s = 2·fs·(z−1)/(z+1)` to produce the digital `{ b, a }` (no pre-warping is
|
|
58
|
+
* done — the caller pre-warps `fs`/critical frequencies if needed). Matches
|
|
59
|
+
* `scipy.signal.bilinear(b, a, fs)`.
|
|
60
|
+
*/
|
|
61
|
+
export declare function bilinear(bIn: Vec, aIn: Vec, fs: number): {
|
|
62
|
+
b: number[];
|
|
63
|
+
a: number[];
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Minimum Butterworth filter order (and the corresponding `-3dB`-ish natural
|
|
67
|
+
* frequency `Wn`) meeting a passband/stopband spec, for a digital lowpass
|
|
68
|
+
* (`wp < ws`) or highpass (`wp > ws`) filter. `wp`/`ws` are normalized to
|
|
69
|
+
* Nyquist (0..1); `gpass`/`gstop` are in dB. Matches
|
|
70
|
+
* `scipy.signal.buttord(wp, ws, gpass, gstop)` (scalar/digital case only —
|
|
71
|
+
* the bandpass/bandstop array form is not implemented).
|
|
72
|
+
*/
|
|
73
|
+
export declare function buttord(wp: number, ws: number, gpass: number, gstop: number): {
|
|
74
|
+
N: number;
|
|
75
|
+
Wn: number;
|
|
76
|
+
};
|
|
77
|
+
type ZpkRoot = number | Complex;
|
|
78
|
+
/**
|
|
79
|
+
* Group zeros/poles/gain into cascaded second-order sections:
|
|
80
|
+
* `[[b0,b1,b2,a0,a1,a2], …]`, each a monic-denominator biquad (`a0 = 1`) with
|
|
81
|
+
* the overall gain folded into the first section's numerator. `z` is
|
|
82
|
+
* zero-padded (roots at the origin) if shorter than `p`. Matches
|
|
83
|
+
* `scipy.signal.zpk2sos` in effect (the two decompositions can differ in
|
|
84
|
+
* pairing order, but the resulting cascaded transfer function is identical).
|
|
85
|
+
*/
|
|
86
|
+
export declare function zpk2sos(z: readonly ZpkRoot[], p: readonly ZpkRoot[], k: number): number[][];
|
|
87
|
+
/**
|
|
88
|
+
* Apply a cascade of second-order sections (`[[b0,b1,b2,a0,a1,a2], …]`, as
|
|
89
|
+
* produced by `zpk2sos`) to `x`, each biquad in direct-form-II transposed.
|
|
90
|
+
* Matches `scipy.signal.sosfilt(sos, x)`.
|
|
91
|
+
*/
|
|
92
|
+
export declare function sosfilt(sos: readonly (readonly number[])[], x: Vec): number[];
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=iir-design.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iir-design.d.ts","sourceRoot":"","sources":["../../src/signal/iir-design.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,2BAA2B,CAAC;AAKnC,KAAK,GAAG,GAAG,SAAS,MAAM,EAAE,GAAG,YAAY,CAAC;AAoB5C;;;;GAIG;AACH,wBAAgB,MAAM,CACpB,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAC9B,KAAK,GAAE,WAAmB,GACzB;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAI9B;AAgCD;;;;;GAKG;AACH,wBAAgB,MAAM,CACpB,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAC9B,KAAK,GAAE,WAAmB,GACzB;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAI9B;AAkJD;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAC9B,KAAK,GAAE,WAAmB,GACzB;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAK9B;AA4BD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,GAAG;IAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CA8BrF;AAID;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAc3B;AAID,KAAK,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAoDhC;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAmB3F;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,GAAG,MAAM,EAAE,CAS7E"}
|