numz 0.1.0 → 0.3.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/docs/.vscode/extensions.json +4 -0
- package/docs/.vscode/launch.json +11 -0
- package/docs/README.md +49 -0
- package/docs/astro.config.mjs +64 -0
- package/docs/package-lock.json +7592 -0
- package/docs/package.json +19 -0
- package/docs/public/favicon.svg +1 -0
- package/docs/src/assets/houston.webp +0 -0
- package/docs/src/content/docs/about.md +11 -0
- package/docs/src/content/docs/guides/example.md +11 -0
- package/docs/src/content/docs/index.mdx +40 -0
- package/docs/src/content/docs/philosophy.md +15 -0
- package/docs/src/content/docs/reference/complex/complex.mdx +66 -0
- package/docs/src/content/docs/reference/functions/arithmetic.md +14 -0
- package/docs/src/content/docs/reference/functions/mapfun.md +81 -0
- package/docs/src/content/docs/reference/functions/ufunc.md +41 -0
- package/docs/src/content/docs/reference/functions/utils.md +16 -0
- package/docs/src/content/docs/reference/matrix/matrix.mdx +97 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/pulse-train.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/pwm.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/sawtooth-train.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/sinusoid.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/square.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/periodic/triangle.md +6 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/dirac.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/noise.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/rampe.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/rect.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/signum.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/sinc.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/trapezoid.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/pulse/tri.md +12 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/arange.md +21 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/geomspace.md +21 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/linspace.md +16 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/logspace.md +20 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/nums.md +17 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/ones.md +19 -0
- package/docs/src/content/docs/reference/signal/functions/sequences/zeros.md +20 -0
- package/docs/src/content/docs/reference/stats/accum/accum-max.md +4 -0
- package/docs/src/content/docs/reference/stats/accum/accum-min.md +4 -0
- package/docs/src/content/docs/reference/stats/accum/accum-prod.md +4 -0
- package/docs/src/content/docs/reference/stats/accum/accum-sum.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/contraharmonic-mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/geo_mean.md +6 -0
- package/docs/src/content/docs/reference/stats/averages/harmonic_mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/iq-mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/mean.md +6 -0
- package/docs/src/content/docs/reference/stats/averages/midhinge.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/midrange.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/power_mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/rms.md +12 -0
- package/docs/src/content/docs/reference/stats/averages/trimmed_mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/weighted_mean.md +4 -0
- package/docs/src/content/docs/reference/stats/averages/winsorized_mean.md +4 -0
- package/docs/src/content.config.ts +7 -0
- package/docs/src/pages/a.astro +0 -0
- package/docs/src/styles/custom.css +21 -0
- package/docs/tsconfig.json +5 -0
- package/package.json +2 -2
- package/src/signal/conv/conv.js +43 -0
- package/src/signal/conv/conv2.js +71 -0
- package/src/signal/conv/index.js +2 -0
- package/src/signal/fft/fft.js +47 -0
- package/src/signal/fft/ifft.js +16 -0
- package/src/signal/fft/index.js +2 -52
- package/src/signal/fft/utils/index.js +1 -19
- package/src/signal/functions/index.js +2 -1
- package/src/signal/functions/sequence/index.js +13 -3
- package/src/signal/functions/window/index.js +142 -0
- package/src/signal/index.js +1 -1
- package/src/stats/average/index.js +2 -2
- package/test/index.js +52 -0
- package/test/index.py +14 -0
- package/src/signal/fft/fft1d/index.js +0 -18
- package/src/signal/fft/fftnd/index.js +0 -27
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: nums
|
|
3
|
+
description: nums
|
|
4
|
+
sidebar :
|
|
5
|
+
order: 2
|
|
6
|
+
---
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
## Signature
|
|
10
|
+
```ts
|
|
11
|
+
nums(num : number, n : number) : number[]
|
|
12
|
+
```
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const z = nums(1.5, 10) // [1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5]
|
|
17
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: zeros
|
|
3
|
+
description: zeros
|
|
4
|
+
sidebar:
|
|
5
|
+
order : 0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Defintion
|
|
9
|
+
|
|
10
|
+
## Signature
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
zeros(n : number) : []number
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const z = zeros(10) // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
20
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { defineCollection } from 'astro:content';
|
|
2
|
+
import { docsLoader } from '@astrojs/starlight/loaders';
|
|
3
|
+
import { docsSchema } from '@astrojs/starlight/schema';
|
|
4
|
+
|
|
5
|
+
export const collections = {
|
|
6
|
+
docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
|
|
7
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--sl-content-width: 50rem;
|
|
3
|
+
--sl-text-5xl: 3.5rem;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
h1{
|
|
7
|
+
color : darkblue;
|
|
8
|
+
/* text-decoration: 2px underline blueviolet;
|
|
9
|
+
text-decoration-skip-ink: auto; */
|
|
10
|
+
/* border-bottom: 1px red solid; */
|
|
11
|
+
}
|
|
12
|
+
p a{
|
|
13
|
+
color: blueviolet;
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
&:hover{
|
|
16
|
+
text-decoration: underline;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/* strong{
|
|
20
|
+
color: blueviolet;
|
|
21
|
+
} */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "scientific computing with zikojs",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -29,6 +29,6 @@
|
|
|
29
29
|
"rollup": "^4.24.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ziko": "^0.
|
|
32
|
+
"ziko": "^0.57.0"
|
|
33
33
|
}
|
|
34
34
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Complex } from 'ziko/math/complex';
|
|
2
|
+
import { add, mul} from 'ziko/math/functions'
|
|
3
|
+
|
|
4
|
+
// const nextPow2 = n => 1 << Math.ceil(Math.log2(n));
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function conv(signal, kernel, mode = 'full') {
|
|
8
|
+
const N = signal.length;
|
|
9
|
+
const M = kernel.length;
|
|
10
|
+
if(signal.some(n => n?.isComplex?.()) || kernel.some(n => n?.isComplex?.())){
|
|
11
|
+
signal = new Complex(signal, 0);
|
|
12
|
+
kernel = new Complex(kernel, 0);
|
|
13
|
+
}
|
|
14
|
+
let outLength;
|
|
15
|
+
let startIdx;
|
|
16
|
+
switch(mode){
|
|
17
|
+
case 'full' : {
|
|
18
|
+
outLength = N + M - 1;
|
|
19
|
+
startIdx = 0;
|
|
20
|
+
}; break;
|
|
21
|
+
case 'same' : {
|
|
22
|
+
outLength = N;
|
|
23
|
+
startIdx = Math.floor((M - 1) / 2);
|
|
24
|
+
}; break;
|
|
25
|
+
case 'valid' : {
|
|
26
|
+
outLength = Math.max(N - M + 1, 0);
|
|
27
|
+
startIdx = M - 1;
|
|
28
|
+
}; break;
|
|
29
|
+
default : throw new Error(`Invalid mode: ${mode}. Must be 'full', 'same', or 'valid'`);
|
|
30
|
+
}
|
|
31
|
+
const out = new Array(outLength);
|
|
32
|
+
for (let n = 0; n < outLength; n++) {
|
|
33
|
+
let sum = new Complex(0, 0);
|
|
34
|
+
const actualN = n + startIdx;
|
|
35
|
+
for (let k = 0; k < M; k++) {
|
|
36
|
+
const idx = actualN - k;
|
|
37
|
+
if (idx >= 0 && idx < N)
|
|
38
|
+
sum = add(mul(signal[idx], kernel[k]))
|
|
39
|
+
}
|
|
40
|
+
out[n] = sum;
|
|
41
|
+
}
|
|
42
|
+
return out;
|
|
43
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Complex } from 'ziko/math/complex';
|
|
2
|
+
import { add, mul} from 'ziko/math/functions'
|
|
3
|
+
export function conv2(signal, kernel, mode = 'full', boundary = 'fill', fillValue = 0) {
|
|
4
|
+
const isMatix = signal?.isMatix?.() || kernel?.isMatix?.();
|
|
5
|
+
const signalRows = signal.length;
|
|
6
|
+
const signalCols = signal[0].length;
|
|
7
|
+
const kernelRows = kernel.length;
|
|
8
|
+
const kernelCols = kernel[0].length;
|
|
9
|
+
|
|
10
|
+
const flippedKernel = kernel.map(row => [...row].reverse()).reverse();
|
|
11
|
+
|
|
12
|
+
// Determine output size
|
|
13
|
+
let outRows, outCols;
|
|
14
|
+
switch(mode){
|
|
15
|
+
case 'full':{
|
|
16
|
+
outRows = signalRows + kernelRows - 1;
|
|
17
|
+
outCols = signalCols + kernelCols - 1;
|
|
18
|
+
}; break;
|
|
19
|
+
case 'same':{
|
|
20
|
+
outRows = signalRows;
|
|
21
|
+
outCols = signalCols;
|
|
22
|
+
}; break;
|
|
23
|
+
case 'valid':{
|
|
24
|
+
outRows = signalRows - kernelRows + 1;
|
|
25
|
+
outCols = signalCols - kernelCols + 1;
|
|
26
|
+
}; break;
|
|
27
|
+
default: throw new Error("mode must be 'full', 'same', or 'valid'");
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
// Initialize output
|
|
31
|
+
const output = Array.from({ length: outRows }, () => Array(outCols).fill(0));
|
|
32
|
+
|
|
33
|
+
// Helper to get signal value considering boundary
|
|
34
|
+
function getSignalValue(i, j) {
|
|
35
|
+
if (i < 0 || i >= signalRows || j < 0 || j >= signalCols) {
|
|
36
|
+
if (boundary === 'fill') return fillValue;
|
|
37
|
+
if (boundary === 'wrap') return signal[(i + signalRows) % signalRows][(j + signalCols) % signalCols];
|
|
38
|
+
if (boundary === 'symm') {
|
|
39
|
+
const ii = i < 0 ? -i - 1 : i >= signalRows ? 2*signalRows - i - 1 : i;
|
|
40
|
+
const jj = j < 0 ? -j - 1 : j >= signalCols ? 2*signalCols - j - 1 : j;
|
|
41
|
+
return signal[ii][jj];
|
|
42
|
+
}
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
return signal[i][j];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Convolution
|
|
49
|
+
for (let i = 0; i < outRows; i++) {
|
|
50
|
+
for (let j = 0; j < outCols; j++) {
|
|
51
|
+
let sum = 0;
|
|
52
|
+
for (let m = 0; m < kernelRows; m++) {
|
|
53
|
+
for (let n = 0; n < kernelCols; n++) {
|
|
54
|
+
const ii = i + m - Math.floor(kernelRows / 2);
|
|
55
|
+
const jj = j + n - Math.floor(kernelCols / 2);
|
|
56
|
+
sum += flippedKernel[m][n] * getSignalValue(ii, jj);
|
|
57
|
+
sum = add(
|
|
58
|
+
mul(
|
|
59
|
+
flippedKernel[m][n],
|
|
60
|
+
getSignalValue(ii, jj)
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
output[i][j] = sum;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return output;
|
|
70
|
+
}
|
|
71
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Complex } from 'ziko/math/complex'
|
|
2
|
+
import { isPow2 } from './utils/index.js';
|
|
3
|
+
|
|
4
|
+
export function dft(arr) {
|
|
5
|
+
const N = arr.length;
|
|
6
|
+
const out = new Array(N);
|
|
7
|
+
|
|
8
|
+
for (let k = 0; k < N; k++) {
|
|
9
|
+
let sum = new Complex(0, 0);
|
|
10
|
+
for (let n = 0; n < N; n++) {
|
|
11
|
+
const W = Complex.twiddle(k * n, N);
|
|
12
|
+
sum = sum.add(W.mul(arr[n]));
|
|
13
|
+
}
|
|
14
|
+
out[k] = sum;
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function fft(arr) {
|
|
20
|
+
const N = arr.length;
|
|
21
|
+
|
|
22
|
+
// fallback for non power-of-two
|
|
23
|
+
if (!isPow2(N)) {
|
|
24
|
+
return dft(arr);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (N === 1) return [arr[0]];
|
|
28
|
+
|
|
29
|
+
const even = new Array(N / 2);
|
|
30
|
+
const odd = new Array(N / 2);
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < N / 2; i++) {
|
|
33
|
+
even[i] = arr[2*i];
|
|
34
|
+
odd[i] = arr[2*i+1];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const Fe = fft(even);
|
|
38
|
+
const Fo = fft(odd);
|
|
39
|
+
|
|
40
|
+
const out = new Array(N);
|
|
41
|
+
for (let k = 0; k < N / 2; k++) {
|
|
42
|
+
const t = Complex.twiddle(k, N).mul(Fo[k]);
|
|
43
|
+
out[k] = Fe[k].add(t);
|
|
44
|
+
out[k+N/2] = Fe[k].sub(t);
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Complex } from 'ziko/math/complex';
|
|
2
|
+
import { fft, dft } from './fft.js';
|
|
3
|
+
import { isPow2 } from './utils/index.js';
|
|
4
|
+
|
|
5
|
+
export function ifft(arr) {
|
|
6
|
+
const N = arr.length;
|
|
7
|
+
|
|
8
|
+
// Step 1: conjugate input
|
|
9
|
+
const conjugated = arr.map(n => new Complex(n, 0).conj)
|
|
10
|
+
|
|
11
|
+
// Step 2: compute FFT (or DFT if not power-of-2)
|
|
12
|
+
const y = isPow2(N) ? fft(conjugated) : dft(conjugated);
|
|
13
|
+
|
|
14
|
+
// Step 3: conjugate output and normalize
|
|
15
|
+
return y.map(c => new Complex(c.a / N, -c.b / N));
|
|
16
|
+
}
|
package/src/signal/fft/index.js
CHANGED
|
@@ -1,52 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export function fft1d(arr) {
|
|
4
|
-
const N = arr.length;
|
|
5
|
-
if (N === 1) return [arr[0]];
|
|
6
|
-
|
|
7
|
-
const even = fft1d(arr.filter((_, i) => i % 2 === 0));
|
|
8
|
-
const odd = fft1d(arr.filter((_, i) => i % 2 === 1));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const out = new Array(N);
|
|
13
|
-
for (let k = 0; k < N/2; k++) {
|
|
14
|
-
const t = Complex.Twidlle(N, k).mul(odd[k]);
|
|
15
|
-
out[k] = add(even[k], t)
|
|
16
|
-
out[k + N/2] = sub(even[k], t)
|
|
17
|
-
}
|
|
18
|
-
return out;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function fftnd(data) {
|
|
22
|
-
if (data instanceof Matrix) data = data.toComplex();
|
|
23
|
-
|
|
24
|
-
if (Array.isArray(data) && !Array.isArray(data[0])) {
|
|
25
|
-
return fft1d(data);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (data instanceof Matrix) {
|
|
29
|
-
const rows = data.rows;
|
|
30
|
-
const cols = data.cols;
|
|
31
|
-
|
|
32
|
-
// FFT along rows
|
|
33
|
-
let rowFFT = new Matrix(rows, cols, []);
|
|
34
|
-
for (let i = 0; i < rows; i++) {
|
|
35
|
-
rowFFT.arr[i] = fft1d(data.arr[i]);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
let colFFT = new Matrix(cols, rows, []);
|
|
39
|
-
const rowFFT_T = rowFFT.T;
|
|
40
|
-
for (let i = 0; i < cols; i++) {
|
|
41
|
-
colFFT.arr[i] = fft1d(rowFFT_T.arr[i]);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return colFFT.T;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (Array.isArray(data)) {
|
|
48
|
-
return data.map(fftnd);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
throw new Error("Invalid data type for FFT");
|
|
52
|
-
}
|
|
1
|
+
export * from './fft.js';
|
|
2
|
+
export * from './ifft.js'
|
|
@@ -1,19 +1 @@
|
|
|
1
|
-
|
|
2
|
-
// export function twiddle(N, k) {
|
|
3
|
-
// const angle = -2 * Math.PI * k / N;
|
|
4
|
-
// return new Complex(Math.cos(angle), Math.sin(angle));
|
|
5
|
-
// }
|
|
6
|
-
|
|
7
|
-
// function normalizeComplexND(data) {
|
|
8
|
-
// if (data instanceof Matrix) {
|
|
9
|
-
// return new Matrix(
|
|
10
|
-
// data.rows,
|
|
11
|
-
// data.cols,
|
|
12
|
-
// data.arr.flat(1).map(C)
|
|
13
|
-
// );
|
|
14
|
-
// } else if (Array.isArray(data)) {
|
|
15
|
-
// return data.map(normalizeComplexND);
|
|
16
|
-
// } else {
|
|
17
|
-
// return C(data);
|
|
18
|
-
// }
|
|
19
|
-
// }
|
|
1
|
+
export const isPow2 = n => (n & (n - 1)) === 0;
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { mapfun, nthr, pow } from "ziko/math/functions";
|
|
2
|
+
import { Matrix } from 'ziko/math/matrix'
|
|
2
3
|
|
|
3
|
-
export const zeros = n =>
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
export const zeros = (n, m, d) => {
|
|
5
|
+
if(m) return Matrix.zeros(n, m);
|
|
6
|
+
return new Array(n).fill(0)
|
|
7
|
+
}
|
|
8
|
+
export const ones = (n, m) => {
|
|
9
|
+
if(m) return Matrix.ones(n, m);
|
|
10
|
+
return new Array(n).fill(1)
|
|
11
|
+
};
|
|
12
|
+
export const nums = (num, n, m, d) => {
|
|
13
|
+
if(m) return Matrix.nums(n, m);
|
|
14
|
+
return new Array(n).fill(num)
|
|
15
|
+
};
|
|
6
16
|
|
|
7
17
|
|
|
8
18
|
export const arange = (a, b, step, include = false) => {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const {cos, sin, abs, sqrt, exp, PI} = Math
|
|
2
|
+
export const hanning_window=(N, ArrayType = Float64Array)=>{
|
|
3
|
+
const w = new ArrayType(N);
|
|
4
|
+
const factor = 2 * PI / N;
|
|
5
|
+
for (let n = 0; n < N; n++)
|
|
6
|
+
w[n] = 0.5 - 0.5 * cos(factor * n);
|
|
7
|
+
return w;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const hamming_window=(N, ArrayType = Float64Array)=>{
|
|
11
|
+
const w = new ArrayType(N);
|
|
12
|
+
const factor = 2 * PI / N;
|
|
13
|
+
for (let n = 0; n < N; n++)
|
|
14
|
+
w[n] = 0.54 - 0.46 * cos(factor * n);
|
|
15
|
+
return w;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const I0 = (x) => {
|
|
19
|
+
let sum = 1;
|
|
20
|
+
let u = 1;
|
|
21
|
+
let k = 1;
|
|
22
|
+
const x2 = (x * x) / 4;
|
|
23
|
+
while (true) {
|
|
24
|
+
// const prev = u;
|
|
25
|
+
u *= x2 / (k * k);
|
|
26
|
+
sum += u;
|
|
27
|
+
if (u < 1e-10 * sum) break;
|
|
28
|
+
k++;
|
|
29
|
+
}
|
|
30
|
+
return sum;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const kaiser_window = (N, beta = 5, ArrayType = Float64Array) => {
|
|
34
|
+
const w = new ArrayType(N);
|
|
35
|
+
const denom = I0(beta);
|
|
36
|
+
for (let n = 0; n < N; n++) {
|
|
37
|
+
const r = (2 * n) / (N - 1) - 1;
|
|
38
|
+
w[n] = I0(beta * sqrt(1 - r * r)) / denom;
|
|
39
|
+
}
|
|
40
|
+
return w;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const blackman_window = (N, beta = 0.16, ArrayType = Float64Array) => {
|
|
44
|
+
const w = new ArrayType(N);
|
|
45
|
+
const factor = 2 * PI / N;
|
|
46
|
+
const a0 = (1 - beta) / 2;
|
|
47
|
+
const a1 = 0.5;
|
|
48
|
+
const a2 = beta / 2;
|
|
49
|
+
for (let n = 0; n < N; n++)
|
|
50
|
+
w[n] = a0,- a1 * cos(factor * n) + a2 * cos(2 * factor * n);
|
|
51
|
+
return w;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const bartlett_window = (N, ArrayType = Float64Array) => {
|
|
55
|
+
const w = new ArrayType(N);
|
|
56
|
+
for (let n = 0; n < N; n++)
|
|
57
|
+
w[n] = 1 - abs((2 * n) / (N - 1) - 1);
|
|
58
|
+
return w;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const blackman_harris_window = (N, ArrayType = Float64Array) => {
|
|
62
|
+
const w = new ArrayType(N);
|
|
63
|
+
const a0 = 0.35875;
|
|
64
|
+
const a1 = 0.48829;
|
|
65
|
+
const a2 = 0.14128;
|
|
66
|
+
const a3 = 0.01168;
|
|
67
|
+
const f = 2 * PI / N;
|
|
68
|
+
for (let n = 0; n < N; n++)
|
|
69
|
+
w[n] = a0 - a1 * cos(f * n) + a2 * cos(2 * f * n) - a3 * cos(3 * f * n);
|
|
70
|
+
return w;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const nuttall_window = (N, ArrayType = Float64Array) => {
|
|
74
|
+
const w = new ArrayType(N);
|
|
75
|
+
const f = 2 * PI / N;
|
|
76
|
+
for (let n = 0; n < N; n++)
|
|
77
|
+
w[n] = 0.355768 - 0.487396 * cos(f * n) + 0.144232 * cos(2 * f * n) - 0.012604 * cos(3 * f * n);
|
|
78
|
+
return w;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const flat_top_window = (N, ArrayType = Float64Array) => {
|
|
82
|
+
const w = new ArrayType(N);
|
|
83
|
+
const f = 2 * PI / N;
|
|
84
|
+
for (let n = 0; n < N; n++)
|
|
85
|
+
w[n] = 1 - 1.93 * cos(f * n) + 1.29 * cos(2 * f * n) - 0.388 * cos(3 * f * n) + 0.028 * cos(4 * f * n);
|
|
86
|
+
return w;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export const tukey_window = (N, alpha = 0.5, ArrayType = Float64Array) => {
|
|
90
|
+
const w = new ArrayType(N);
|
|
91
|
+
const edge = alpha * (N - 1) / 2;
|
|
92
|
+
for (let n = 0; n < N; n++) {
|
|
93
|
+
if (n < edge)
|
|
94
|
+
w[n] = 0.5 * (1 + cos(PI * (2*n/(alpha*(N-1)) - 1)));
|
|
95
|
+
else if (n > (N - 1 - edge))
|
|
96
|
+
w[n] = 0.5 * (1 + cos(PI * (2*n/(alpha*(N-1)) - 2/alpha + 1)));
|
|
97
|
+
else
|
|
98
|
+
w[n] = 1;
|
|
99
|
+
}
|
|
100
|
+
return w;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const gaussian_window = (N, sigma = 0.4, ArrayType = Float64Array) => {
|
|
104
|
+
const w = new ArrayType(N);
|
|
105
|
+
const m = (N - 1) / 2;
|
|
106
|
+
const s2 = sigma * m;
|
|
107
|
+
for (let n = 0; n < N; n++)
|
|
108
|
+
w[n] = exp(-0.5 * ((n - m) / s2) ** 2);
|
|
109
|
+
return w;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
const sinc = (x) => x === 0 ? 1 : sin(PI * x) / (PI * x);
|
|
114
|
+
export const lanczos_window = (N, ArrayType = Float64Array) => {
|
|
115
|
+
const w = new ArrayType(N);
|
|
116
|
+
for (let n = 0; n < N; n++)
|
|
117
|
+
w[n] = sinc(2 * n / (N - 1) - 1);
|
|
118
|
+
return w;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const poisson_window = (N, alpha = 3, ArrayType = Float64Array) => {
|
|
122
|
+
const w = new ArrayType(N);
|
|
123
|
+
const m = (N - 1) / 2;
|
|
124
|
+
for (let n = 0; n < N; n++)
|
|
125
|
+
w[n] = exp(-alpha * abs(n - m) / m);
|
|
126
|
+
return w;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const rect_window = (N, ArrayType = Float64Array) => {
|
|
130
|
+
const w = new ArrayType(N);
|
|
131
|
+
w.fill(1);
|
|
132
|
+
return w;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const tri_window = (N, ArrayType = Float64Array) => {
|
|
136
|
+
const w = new ArrayType(N);
|
|
137
|
+
const M = (N - 1) / 2;
|
|
138
|
+
for (let n = 0; n < N; n++) {
|
|
139
|
+
w[n] = 1 - abs((n - M) / M);
|
|
140
|
+
}
|
|
141
|
+
return w;
|
|
142
|
+
};
|
package/src/signal/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './functions/index.js'
|
|
2
|
-
|
|
2
|
+
export * from './fft/index.js'
|
|
@@ -55,8 +55,8 @@ export const midhinge = (...x) =>{
|
|
|
55
55
|
return (q1 + q3) / 2;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
export const
|
|
58
|
+
// interquartile_mean
|
|
59
|
+
export const iq_mean = (...x) =>{
|
|
60
60
|
let a = x.sort((a,b)=>a-b);
|
|
61
61
|
let q1 = a[Math.floor((a.length - 1) * 0.25)];
|
|
62
62
|
let q3 = a[Math.floor((a.length - 1) * 0.75)];
|