dsp-collection 0.2.4 → 0.2.6
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/README.md +23 -1
- package/filter/SpecFilt.d.ts +10 -0
- package/filter/SpecFilt.js +98 -0
- package/math/Complex.d.ts +42 -42
- package/math/Complex.js +130 -130
- package/math/ComplexArray.d.ts +36 -32
- package/math/ComplexArray.js +170 -143
- package/math/MathUtils.d.ts +9 -7
- package/math/MathUtils.js +116 -82
- package/math/MutableComplex.d.ts +22 -22
- package/math/MutableComplex.js +64 -65
- package/math/NumApprox.d.ts +3 -3
- package/math/NumApprox.js +67 -68
- package/math/PolyReal.d.ts +13 -13
- package/math/PolyReal.js +226 -227
- package/package.json +13 -7
- package/signal/AdaptiveStft.d.ts +12 -12
- package/signal/AdaptiveStft.js +57 -58
- package/signal/Autocorrelation.d.ts +5 -5
- package/signal/Autocorrelation.js +53 -54
- package/signal/Dft.d.ts +9 -9
- package/signal/Dft.js +87 -88
- package/signal/EnvelopeDetection.d.ts +1 -1
- package/signal/EnvelopeDetection.js +9 -10
- package/signal/Fft.d.ts +9 -6
- package/signal/Fft.js +275 -201
- package/signal/Goertzel.d.ts +5 -5
- package/signal/Goertzel.js +48 -49
- package/signal/InstFreq.d.ts +8 -8
- package/signal/InstFreq.js +26 -27
- package/signal/PitchDetectionHarm.d.ts +26 -26
- package/signal/PitchDetectionHarm.js +68 -69
- package/signal/Resampling.d.ts +7 -0
- package/signal/Resampling.js +218 -0
- package/signal/WindowFunctions.d.ts +40 -40
- package/signal/WindowFunctions.js +194 -195
- package/utils/ArrayUtils.d.ts +9 -5
- package/utils/ArrayUtils.js +68 -51
- package/utils/DspUtils.d.ts +4 -2
- package/utils/DspUtils.js +12 -7
- package/utils/MiscUtils.d.ts +6 -1
- package/utils/MiscUtils.js +20 -16
- package/math/Complex.js.map +0 -1
- package/math/ComplexArray.js.map +0 -1
- package/math/MathUtils.js.map +0 -1
- package/math/MutableComplex.js.map +0 -1
- package/math/NumApprox.js.map +0 -1
- package/math/PolyReal.js.map +0 -1
- package/signal/AdaptiveStft.js.map +0 -1
- package/signal/Autocorrelation.js.map +0 -1
- package/signal/Dft.js.map +0 -1
- package/signal/EnvelopeDetection.js.map +0 -1
- package/signal/Fft.js.map +0 -1
- package/signal/Goertzel.js.map +0 -1
- package/signal/InstFreq.js.map +0 -1
- package/signal/PitchDetectionHarm.js.map +0 -1
- package/signal/WindowFunctions.js.map +0 -1
- package/utils/ArrayUtils.js.map +0 -1
- package/utils/DspUtils.js.map +0 -1
- package/utils/MiscUtils.js.map +0 -1
package/math/ComplexArray.js
CHANGED
|
@@ -1,143 +1,170 @@
|
|
|
1
|
-
import Complex from "./Complex";
|
|
2
|
-
import MutableComplex from "./MutableComplex";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
a2
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return Math.
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
this.re[i]
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
this.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this.
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
this.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.re[i]
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
1
|
+
import Complex from "./Complex.js";
|
|
2
|
+
import MutableComplex from "./MutableComplex.js";
|
|
3
|
+
import { assert } from "../utils/MiscUtils.js";
|
|
4
|
+
const emptyFloat64Array = new Float64Array(0);
|
|
5
|
+
export default class ComplexArray {
|
|
6
|
+
constructor(x = 0) {
|
|
7
|
+
if (typeof x == "number") {
|
|
8
|
+
this.constructByLength(x);
|
|
9
|
+
}
|
|
10
|
+
else if (Array.isArray(x) && x[0] instanceof Complex) {
|
|
11
|
+
this.constructByArrayOfComplex(x);
|
|
12
|
+
}
|
|
13
|
+
else if (x instanceof Object && x.length !== undefined) {
|
|
14
|
+
this.constructByArrayOfNumber(x);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
throw new Error("Invalid constructor argument.");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
constructByLength(length) {
|
|
21
|
+
this.length = length;
|
|
22
|
+
if (length) {
|
|
23
|
+
this.re = new Float64Array(length);
|
|
24
|
+
this.im = new Float64Array(length);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
this.re = emptyFloat64Array;
|
|
28
|
+
this.im = emptyFloat64Array;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
constructByArrayOfComplex(a) {
|
|
32
|
+
this.length = a.length;
|
|
33
|
+
this.re = new Float64Array(a.length);
|
|
34
|
+
this.im = new Float64Array(a.length);
|
|
35
|
+
for (let i = 0; i < a.length; i++) {
|
|
36
|
+
this.re[i] = a[i].re;
|
|
37
|
+
this.im[i] = a[i].im;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
constructByArrayOfNumber(a) {
|
|
41
|
+
this.length = a.length;
|
|
42
|
+
this.re = new Float64Array(a);
|
|
43
|
+
this.im = new Float64Array(a.length);
|
|
44
|
+
}
|
|
45
|
+
static fromPolar(absArray, argArray) {
|
|
46
|
+
const n = absArray.length;
|
|
47
|
+
assert(n == argArray.length);
|
|
48
|
+
const a = new ComplexArray(n);
|
|
49
|
+
for (let i = 0; i < n; i++) {
|
|
50
|
+
a.setPolar(i, absArray[i], argArray[i]);
|
|
51
|
+
}
|
|
52
|
+
return a;
|
|
53
|
+
}
|
|
54
|
+
slice(begin, end) {
|
|
55
|
+
const a2 = new ComplexArray();
|
|
56
|
+
a2.re = this.re.slice(begin, end);
|
|
57
|
+
a2.im = this.im.slice(begin, end);
|
|
58
|
+
a2.length = a2.re.length;
|
|
59
|
+
return a2;
|
|
60
|
+
}
|
|
61
|
+
subarray(begin, end) {
|
|
62
|
+
const a2 = new ComplexArray();
|
|
63
|
+
a2.re = this.re.subarray(begin, end);
|
|
64
|
+
a2.im = this.im.subarray(begin, end);
|
|
65
|
+
a2.length = end - begin;
|
|
66
|
+
return a2;
|
|
67
|
+
}
|
|
68
|
+
set(i, c) {
|
|
69
|
+
this.re[i] = c.re;
|
|
70
|
+
this.im[i] = c.im;
|
|
71
|
+
}
|
|
72
|
+
setReIm(i, re, im) {
|
|
73
|
+
this.re[i] = re;
|
|
74
|
+
this.im[i] = im;
|
|
75
|
+
}
|
|
76
|
+
setPolar(i, abs, arg) {
|
|
77
|
+
this.re[i] = abs * Math.cos(arg);
|
|
78
|
+
this.im[i] = abs * Math.sin(arg);
|
|
79
|
+
}
|
|
80
|
+
static copy1(a1, i1, a2, i2) {
|
|
81
|
+
a2.re[i2] = a1.re[i1];
|
|
82
|
+
a2.im[i2] = a1.im[i1];
|
|
83
|
+
}
|
|
84
|
+
get(i) {
|
|
85
|
+
return new MutableComplex(this.re[i], this.im[i]);
|
|
86
|
+
}
|
|
87
|
+
getAbs(i) {
|
|
88
|
+
return Math.hypot(this.re[i], this.im[i]);
|
|
89
|
+
}
|
|
90
|
+
getArg(i) {
|
|
91
|
+
return Math.atan2(this.im[i], this.re[i]);
|
|
92
|
+
}
|
|
93
|
+
toString() {
|
|
94
|
+
let s = "[";
|
|
95
|
+
for (let i = 0; i < this.length; i++) {
|
|
96
|
+
if (i > 0) {
|
|
97
|
+
s += ", ";
|
|
98
|
+
}
|
|
99
|
+
s += "(" + this.re[i] + ", " + this.im[i] + ")";
|
|
100
|
+
}
|
|
101
|
+
s += "]";
|
|
102
|
+
return s;
|
|
103
|
+
}
|
|
104
|
+
getAbsArray() {
|
|
105
|
+
const n = this.length;
|
|
106
|
+
const a = new Float64Array(n);
|
|
107
|
+
for (let i = 0; i < n; i++) {
|
|
108
|
+
a[i] = this.getAbs(i);
|
|
109
|
+
}
|
|
110
|
+
return a;
|
|
111
|
+
}
|
|
112
|
+
getArgArray() {
|
|
113
|
+
const n = this.length;
|
|
114
|
+
const a = new Float64Array(n);
|
|
115
|
+
for (let i = 0; i < n; i++) {
|
|
116
|
+
a[i] = this.getArg(i);
|
|
117
|
+
}
|
|
118
|
+
return a;
|
|
119
|
+
}
|
|
120
|
+
addRealTo(i, x) {
|
|
121
|
+
this.re[i] += x;
|
|
122
|
+
}
|
|
123
|
+
addTo(i, x) {
|
|
124
|
+
this.re[i] += x.re;
|
|
125
|
+
this.im[i] += x.im;
|
|
126
|
+
}
|
|
127
|
+
subRealFrom(i, x) {
|
|
128
|
+
this.re[i] -= x;
|
|
129
|
+
}
|
|
130
|
+
subFrom(i, x) {
|
|
131
|
+
this.re[i] -= x.re;
|
|
132
|
+
this.im[i] -= x.im;
|
|
133
|
+
}
|
|
134
|
+
mulByReal(i, x) {
|
|
135
|
+
this.re[i] *= x;
|
|
136
|
+
this.im[i] *= x;
|
|
137
|
+
}
|
|
138
|
+
mulBy(i, x) {
|
|
139
|
+
this.setMul(i, this.re[i], this.im[i], x.re, x.im);
|
|
140
|
+
}
|
|
141
|
+
divByReal(i, x) {
|
|
142
|
+
this.re[i] /= x;
|
|
143
|
+
this.im[i] /= x;
|
|
144
|
+
}
|
|
145
|
+
divBy(i, x) {
|
|
146
|
+
this.setDiv(i, this.re[i], this.im[i], x.re, x.im);
|
|
147
|
+
}
|
|
148
|
+
mulByArray(a2) {
|
|
149
|
+
const n = this.length;
|
|
150
|
+
assert(a2.length == n);
|
|
151
|
+
for (let i = 0; i < n; i++) {
|
|
152
|
+
this.setMul(i, this.re[i], this.im[i], a2.re[i], a2.im[i]);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
mulAllByReal(x) {
|
|
156
|
+
const n = this.length;
|
|
157
|
+
for (let i = 0; i < n; i++) {
|
|
158
|
+
this.mulByReal(i, x);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
setMul(i, re1, im1, re2, im2) {
|
|
162
|
+
this.re[i] = re1 * re2 - im1 * im2;
|
|
163
|
+
this.im[i] = re1 * im2 + im1 * re2;
|
|
164
|
+
}
|
|
165
|
+
setDiv(i, re1, im1, re2, im2) {
|
|
166
|
+
const m = re1 * re1 + im1 * im1;
|
|
167
|
+
this.re[i] = (re1 * re2 + im1 * im2) / m;
|
|
168
|
+
this.im[i] = (im1 * re2 - re1 * im2) / m;
|
|
169
|
+
}
|
|
170
|
+
}
|
package/math/MathUtils.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export declare function fuzzyEquals(a: number, b: number, eps: number): boolean;
|
|
2
|
-
export declare function isFuzzyInteger(i: number, eps: number): boolean;
|
|
3
|
-
export declare function isPowerOf2(i: number): boolean;
|
|
4
|
-
export declare function getNextPowerOf2(x: number): number;
|
|
5
|
-
export declare function floorLog2(x: number): number;
|
|
6
|
-
export declare function hyperbolicDecline(t: number, a: number, b: number): number;
|
|
7
|
-
export declare function
|
|
1
|
+
export declare function fuzzyEquals(a: number, b: number, eps: number): boolean;
|
|
2
|
+
export declare function isFuzzyInteger(i: number, eps: number): boolean;
|
|
3
|
+
export declare function isPowerOf2(i: number): boolean;
|
|
4
|
+
export declare function getNextPowerOf2(x: number): number;
|
|
5
|
+
export declare function floorLog2(x: number): number;
|
|
6
|
+
export declare function hyperbolicDecline(t: number, a: number, b: number): number;
|
|
7
|
+
export declare function simpleMovingAverage(a: ArrayLike<number>, windowWidth: number, shift?: boolean): Float64Array;
|
|
8
|
+
export declare function triangularMovingAverage(a: ArrayLike<number>, windowWidth: number): Float64Array;
|
|
9
|
+
export declare function triangularMovingAverageRef(a: ArrayLike<number>, windowWidth: number): Float64Array;
|
package/math/MathUtils.js
CHANGED
|
@@ -1,82 +1,116 @@
|
|
|
1
|
-
export function fuzzyEquals(a, b, eps) {
|
|
2
|
-
if (!isFinite(a) || !isFinite(b)) {
|
|
3
|
-
return false;
|
|
4
|
-
}
|
|
5
|
-
if (a == b) {
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
const diff = Math.abs(a - b);
|
|
9
|
-
if (diff <= eps) {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
const mag = Math.max(Math.abs(a), Math.abs(b));
|
|
13
|
-
return diff <= mag * eps;
|
|
14
|
-
}
|
|
15
|
-
export function isFuzzyInteger(i, eps) {
|
|
16
|
-
return Math.abs(i - Math.round(i)) <= eps;
|
|
17
|
-
}
|
|
18
|
-
export function isPowerOf2(i) {
|
|
19
|
-
if (!Number.isSafeInteger(i) || i < 1 || i > 0x40000000) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return (i & (i - 1)) == 0;
|
|
23
|
-
}
|
|
24
|
-
export function getNextPowerOf2(x) {
|
|
25
|
-
if (!isFinite(x)) {
|
|
26
|
-
return NaN;
|
|
27
|
-
}
|
|
28
|
-
let n = 1;
|
|
29
|
-
while (n <= x) {
|
|
30
|
-
n *= 2;
|
|
31
|
-
}
|
|
32
|
-
return n;
|
|
33
|
-
}
|
|
34
|
-
export function floorLog2(x) {
|
|
35
|
-
if (x > 0x7FFFFFFF || x < 1) {
|
|
36
|
-
throw new Error("Argument is not a valid integer.");
|
|
37
|
-
}
|
|
38
|
-
return 31 - Math.clz32(x);
|
|
39
|
-
}
|
|
40
|
-
export function hyperbolicDecline(t, a, b) {
|
|
41
|
-
switch (b) {
|
|
42
|
-
case 1: {
|
|
43
|
-
return 1 / (1 + a * t);
|
|
44
|
-
}
|
|
45
|
-
case 0: {
|
|
46
|
-
return Math.exp(-a * t);
|
|
47
|
-
}
|
|
48
|
-
case -1: {
|
|
49
|
-
return Math.max(0, 1 - a * t);
|
|
50
|
-
}
|
|
51
|
-
default: {
|
|
52
|
-
return 1 / (1 + b * a * t) ** (1 / b);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
export function
|
|
57
|
-
if (windowWidth < 2 || !Number.isSafeInteger(windowWidth)) {
|
|
58
|
-
throw new Error("Specified window width is not
|
|
59
|
-
}
|
|
60
|
-
const len = a.length;
|
|
61
|
-
const a2 = new Float64Array(len);
|
|
62
|
-
const halfWindowWidth = Math.floor(windowWidth / 2);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
1
|
+
export function fuzzyEquals(a, b, eps) {
|
|
2
|
+
if (!isFinite(a) || !isFinite(b)) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (a == b) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
const diff = Math.abs(a - b);
|
|
9
|
+
if (diff <= eps) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
const mag = Math.max(Math.abs(a), Math.abs(b));
|
|
13
|
+
return diff <= mag * eps;
|
|
14
|
+
}
|
|
15
|
+
export function isFuzzyInteger(i, eps) {
|
|
16
|
+
return Math.abs(i - Math.round(i)) <= eps;
|
|
17
|
+
}
|
|
18
|
+
export function isPowerOf2(i) {
|
|
19
|
+
if (!Number.isSafeInteger(i) || i < 1 || i > 0x40000000) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return (i & (i - 1)) == 0;
|
|
23
|
+
}
|
|
24
|
+
export function getNextPowerOf2(x) {
|
|
25
|
+
if (!isFinite(x)) {
|
|
26
|
+
return NaN;
|
|
27
|
+
}
|
|
28
|
+
let n = 1;
|
|
29
|
+
while (n <= x) {
|
|
30
|
+
n *= 2;
|
|
31
|
+
}
|
|
32
|
+
return n;
|
|
33
|
+
}
|
|
34
|
+
export function floorLog2(x) {
|
|
35
|
+
if (x > 0x7FFFFFFF || x < 1) {
|
|
36
|
+
throw new Error("Argument is not a valid integer.");
|
|
37
|
+
}
|
|
38
|
+
return 31 - Math.clz32(x);
|
|
39
|
+
}
|
|
40
|
+
export function hyperbolicDecline(t, a, b) {
|
|
41
|
+
switch (b) {
|
|
42
|
+
case 1: {
|
|
43
|
+
return 1 / (1 + a * t);
|
|
44
|
+
}
|
|
45
|
+
case 0: {
|
|
46
|
+
return Math.exp(-a * t);
|
|
47
|
+
}
|
|
48
|
+
case -1: {
|
|
49
|
+
return Math.max(0, 1 - a * t);
|
|
50
|
+
}
|
|
51
|
+
default: {
|
|
52
|
+
return 1 / (1 + b * a * t) ** (1 / b);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function simpleMovingAverage(a, windowWidth, shift = false) {
|
|
57
|
+
if (windowWidth < 2 || !Number.isSafeInteger(windowWidth)) {
|
|
58
|
+
throw new Error("Specified window width is not valid for SMA.");
|
|
59
|
+
}
|
|
60
|
+
const len = a.length;
|
|
61
|
+
const a2 = new Float64Array(len);
|
|
62
|
+
const halfWindowWidth = Math.floor(windowWidth / 2);
|
|
63
|
+
const posShift = (shift && windowWidth % 2 == 0) ? 1 : 0;
|
|
64
|
+
const extendedLen = len + halfWindowWidth;
|
|
65
|
+
let movingSum = 0;
|
|
66
|
+
let n = 0;
|
|
67
|
+
for (let p = 0; p < extendedLen; p++) {
|
|
68
|
+
if (p >= windowWidth) {
|
|
69
|
+
movingSum -= a[p - windowWidth];
|
|
70
|
+
n--;
|
|
71
|
+
}
|
|
72
|
+
if (p < len) {
|
|
73
|
+
movingSum += a[p];
|
|
74
|
+
n++;
|
|
75
|
+
}
|
|
76
|
+
const p2 = p - halfWindowWidth + posShift;
|
|
77
|
+
if (p2 >= 0 && p2 < len) {
|
|
78
|
+
a2[p2] = movingSum / n;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return a2;
|
|
82
|
+
}
|
|
83
|
+
export function triangularMovingAverage(a, windowWidth) {
|
|
84
|
+
if (windowWidth < 4 || !Number.isSafeInteger(windowWidth)) {
|
|
85
|
+
throw new Error("Specified window width is not valid for TMA.");
|
|
86
|
+
}
|
|
87
|
+
const w1 = Math.floor(windowWidth / 2);
|
|
88
|
+
const w2 = windowWidth - w1;
|
|
89
|
+
const a1 = simpleMovingAverage(a, w1);
|
|
90
|
+
const a2 = simpleMovingAverage(a1, w2, true);
|
|
91
|
+
return a2;
|
|
92
|
+
}
|
|
93
|
+
export function triangularMovingAverageRef(a, windowWidth) {
|
|
94
|
+
if (windowWidth < 4 || !Number.isSafeInteger(windowWidth)) {
|
|
95
|
+
throw new Error("Specified window width is not valid for TMA.");
|
|
96
|
+
}
|
|
97
|
+
const len = a.length;
|
|
98
|
+
const a2 = new Float64Array(len);
|
|
99
|
+
for (let p = 0; p < len; p++) {
|
|
100
|
+
a2[p] = computeTriangularAverageAt(a, p, windowWidth);
|
|
101
|
+
}
|
|
102
|
+
return a2;
|
|
103
|
+
}
|
|
104
|
+
function computeTriangularAverageAt(a, p, windowWidth) {
|
|
105
|
+
const len = a.length;
|
|
106
|
+
const p1 = Math.max(0, Math.ceil(p - windowWidth / 2 + 0.1));
|
|
107
|
+
const p2 = Math.min(len - 1, Math.floor(p + windowWidth / 2 - 0.1));
|
|
108
|
+
let sum = 0;
|
|
109
|
+
let weightSum = 0;
|
|
110
|
+
for (let i = p1; i <= p2; i++) {
|
|
111
|
+
const weight = 1 - Math.abs(i - p) / (windowWidth / 2);
|
|
112
|
+
sum += a[i] * weight;
|
|
113
|
+
weightSum += weight;
|
|
114
|
+
}
|
|
115
|
+
return sum / weightSum;
|
|
116
|
+
}
|
package/math/MutableComplex.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import Complex from "./Complex";
|
|
2
|
-
export default class MutableComplex extends Complex {
|
|
3
|
-
re: number;
|
|
4
|
-
im: number;
|
|
5
|
-
constructor(re?: number, im?: number);
|
|
6
|
-
static fromComplex(x: Complex): MutableComplex;
|
|
7
|
-
static expj(arg: number): MutableComplex;
|
|
8
|
-
static fromPolar(abs: number, arg: number): MutableComplex;
|
|
9
|
-
set(x: Complex): void;
|
|
10
|
-
setReIm(re: number, im?: number): void;
|
|
11
|
-
setExpj(arg: number): void;
|
|
12
|
-
addRealTo(x: number): void;
|
|
13
|
-
addTo(x: Complex): void;
|
|
14
|
-
subRealFrom(x: number): void;
|
|
15
|
-
subFrom(x: Complex): void;
|
|
16
|
-
mulByReal(x: number): void;
|
|
17
|
-
mulBy(x: Complex): void;
|
|
18
|
-
divByReal(x: number): void;
|
|
19
|
-
divBy(x: Complex): void;
|
|
20
|
-
setMul(re1: number, im1: number, re2: number, im2: number): void;
|
|
21
|
-
setDiv(re1: number, im1: number, re2: number, im2: number): void;
|
|
22
|
-
}
|
|
1
|
+
import Complex from "./Complex.ts";
|
|
2
|
+
export default class MutableComplex extends Complex {
|
|
3
|
+
re: number;
|
|
4
|
+
im: number;
|
|
5
|
+
constructor(re?: number, im?: number);
|
|
6
|
+
static fromComplex(x: Complex): MutableComplex;
|
|
7
|
+
static expj(arg: number): MutableComplex;
|
|
8
|
+
static fromPolar(abs: number, arg: number): MutableComplex;
|
|
9
|
+
set(x: Complex): void;
|
|
10
|
+
setReIm(re: number, im?: number): void;
|
|
11
|
+
setExpj(arg: number): void;
|
|
12
|
+
addRealTo(x: number): void;
|
|
13
|
+
addTo(x: Complex): void;
|
|
14
|
+
subRealFrom(x: number): void;
|
|
15
|
+
subFrom(x: Complex): void;
|
|
16
|
+
mulByReal(x: number): void;
|
|
17
|
+
mulBy(x: Complex): void;
|
|
18
|
+
divByReal(x: number): void;
|
|
19
|
+
divBy(x: Complex): void;
|
|
20
|
+
setMul(re1: number, im1: number, re2: number, im2: number): void;
|
|
21
|
+
setDiv(re1: number, im1: number, re2: number, im2: number): void;
|
|
22
|
+
}
|