numz 0.0.3 → 0.2.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/calculus/derivative/index.js +16 -0
- package/src/calculus/index.js +22 -0
- package/src/calculus/integral/index.js +21 -0
- package/src/discret/bitwise/index.js +34 -0
- package/src/discret/combination/index.js +86 -0
- package/src/discret/index-dep.js +110 -0
- package/src/discret/index.js +4 -0
- package/src/discret/permutation/index.js +89 -0
- package/src/discret/sequences/index.js +30 -0
- package/src/index.js +6 -1
- 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 +1 -1
- package/src/signal/functions/sequence/index.js +13 -3
- package/src/signal/index.js +1 -1
- package/src/stats/average/index.js +2 -2
- package/src/stats/distributions/continuos/index.js +35 -0
- package/src/stats/distributions/discret/index.js +45 -0
- package/src/stats/distributions/index.js +3 -0
- package/src/stats/distributions/multivar/index.js +40 -0
- package/src/stats/index.js +2 -1
- package/src/ufunc/index.js +1 -0
- package/test/index.js +39 -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,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) => {
|
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)];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const dist_normal = (x, mean = 0, std = 1) => {
|
|
2
|
+
const coeff = 1 / (std * Math.sqrt(2 * Math.PI));
|
|
3
|
+
const expPart = Math.exp(-((x - mean) ** 2) / (2 * std ** 2));
|
|
4
|
+
return coeff * expPart;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const dist_uniform = (x, a = 0, b = 1) => (x < a || x > b ? 0 : 1 / (b - a));
|
|
8
|
+
|
|
9
|
+
export const dist_exponential = (x, lambda = 1) => (x < 0 ? 0 : lambda * Math.exp(-lambda * x));
|
|
10
|
+
|
|
11
|
+
export const dist_gamma = (x, k, theta = 1) => {
|
|
12
|
+
if (x < 0) return 0;
|
|
13
|
+
const gamma = (n) => {
|
|
14
|
+
if (n <= 1) return 1;
|
|
15
|
+
return (n - 1) * gamma(n - 1);
|
|
16
|
+
};
|
|
17
|
+
return Math.pow(x, k - 1) * Math.exp(-x / theta) / (gamma(k) * Math.pow(theta, k));
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const dist_beta = (x, alpha, beta) => {
|
|
21
|
+
if (x < 0 || x > 1) return 0;
|
|
22
|
+
const gamma = (n) => (n <= 1 ? 1 : (n - 1) * gamma(n - 1));
|
|
23
|
+
const B = (alpha, beta) => gamma(alpha) * gamma(beta) / gamma(alpha + beta);
|
|
24
|
+
return Math.pow(x, alpha - 1) * Math.pow(1 - x, beta - 1) / B(alpha, beta);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const dist_cauchy = (x, x0 = 0, gamma = 1) => 1 / (Math.PI * gamma * (1 + ((x - x0) / gamma) ** 2));
|
|
28
|
+
|
|
29
|
+
export const dist_chi2 = (x, k) => dist_gamma(x, k / 2, 2);
|
|
30
|
+
|
|
31
|
+
export const dist_student_t = (x, nu) => {
|
|
32
|
+
const gamma = (n) => (n <= 1 ? 1 : (n - 1) * gamma(n - 1));
|
|
33
|
+
const coeff = gamma((nu + 1) / 2) / (Math.sqrt(nu * Math.PI) * gamma(nu / 2));
|
|
34
|
+
return coeff * Math.pow(1 + (x ** 2) / nu, -(nu + 1) / 2);
|
|
35
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// ------------------------------
|
|
2
|
+
// Discrete Distributions
|
|
3
|
+
// ------------------------------
|
|
4
|
+
export const dist_binomial = (k, n, p) => {
|
|
5
|
+
if (k < 0 || k > n) return 0;
|
|
6
|
+
const comb = (n, k) => {
|
|
7
|
+
if (k === 0 || k === n) return 1;
|
|
8
|
+
let res = 1;
|
|
9
|
+
for (let i = 1; i <= k; i++) res *= (n - i + 1) / i;
|
|
10
|
+
return res;
|
|
11
|
+
};
|
|
12
|
+
return comb(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const dist_poisson = (k, lambda) => {
|
|
16
|
+
if (k < 0) return 0;
|
|
17
|
+
const factorial = (n) => (n <= 1 ? 1 : n * factorial(n - 1));
|
|
18
|
+
return Math.pow(lambda, k) * Math.exp(-lambda) / factorial(k);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const dist_geometric = (k, p) => (k < 1 ? 0 : p * Math.pow(1 - p, k - 1));
|
|
22
|
+
|
|
23
|
+
export const dist_negative_binomial = (k, r, p) => {
|
|
24
|
+
if (k < 0) return 0;
|
|
25
|
+
const comb = (n, k) => {
|
|
26
|
+
if (k === 0 || k === n) return 1;
|
|
27
|
+
let res = 1;
|
|
28
|
+
for (let i = 1; i <= k; i++) res *= (n - i + 1) / i;
|
|
29
|
+
return res;
|
|
30
|
+
};
|
|
31
|
+
return comb(k + r - 1, k) * Math.pow(p, r) * Math.pow(1 - p, k);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const dist_hypergeometric = (k, N, K, n) => {
|
|
35
|
+
if (k < 0 || k > n || k > K) return 0;
|
|
36
|
+
const comb = (n, k) => {
|
|
37
|
+
if (k === 0 || k === n) return 1;
|
|
38
|
+
let res = 1;
|
|
39
|
+
for (let i = 1; i <= k; i++) res *= (n - i + 1) / i;
|
|
40
|
+
return res;
|
|
41
|
+
};
|
|
42
|
+
return (comb(K, k) * comb(N - K, n - k)) / comb(N, n);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const dist_bernoulli = (k, p) => (k === 0 ? 1 - p : k === 1 ? p : 0);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// ------------------------------
|
|
2
|
+
// Multivariate Distributions
|
|
3
|
+
// ------------------------------
|
|
4
|
+
export const dist_multinomial = (kArray, n, pArray) => {
|
|
5
|
+
const factorial = (x) => (x <= 1 ? 1 : x * factorial(x - 1));
|
|
6
|
+
const comb = factorial(n) / kArray.reduce((acc, k) => acc * factorial(k), 1);
|
|
7
|
+
const prob = kArray.reduce((acc, ki, i) => acc * Math.pow(pArray[i], ki), 1);
|
|
8
|
+
return comb * prob;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const dist_multivariate_normal = (xArray, meanArray, covMatrix) => {
|
|
12
|
+
const n = xArray.length;
|
|
13
|
+
const det = (m) => {
|
|
14
|
+
if (n === 1) return m[0][0];
|
|
15
|
+
if (n === 2) return m[0][0] * m[1][1] - m[0][1] * m[1][0];
|
|
16
|
+
throw new Error('Only 1x1 and 2x2 supported for now');
|
|
17
|
+
};
|
|
18
|
+
const inv = (m) => {
|
|
19
|
+
if (n === 1) return [[1 / m[0][0]]];
|
|
20
|
+
if (n === 2) {
|
|
21
|
+
const [[a,b],[c,d]] = m;
|
|
22
|
+
const detM = a*d-b*c;
|
|
23
|
+
return [[d/detM,-b/detM],[-c/detM,a/detM]];
|
|
24
|
+
}
|
|
25
|
+
throw new Error('Only 1x1 and 2x2 supported for now');
|
|
26
|
+
};
|
|
27
|
+
const diff = xArray.map((xi, i) => xi - meanArray[i]);
|
|
28
|
+
const covInv = inv(covMatrix);
|
|
29
|
+
const exponent = -0.5 * diff.reduce((sum, _, i) =>
|
|
30
|
+
sum + diff[i] * (covInv[i][0] * diff[0] + covInv[i][1] * diff[1] || 0), 0);
|
|
31
|
+
const denom = Math.sqrt((2 * Math.PI) ** n * det(covMatrix));
|
|
32
|
+
return Math.exp(exponent) / denom;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const dist_dirichlet = (xArray, alphaArray) => {
|
|
36
|
+
const gamma = (n) => (n <= 1 ? 1 : (n - 1) * gamma(n - 1));
|
|
37
|
+
const B = alphaArray.reduce((acc, a) => acc * gamma(a), 1) / gamma(alphaArray.reduce((a,b)=>a+b,0));
|
|
38
|
+
const prod = xArray.reduce((acc, xi, i) => acc * Math.pow(xi, alphaArray[i]-1),1);
|
|
39
|
+
return prod / B;
|
|
40
|
+
};
|
package/src/stats/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'ziko/math/functions'
|
package/test/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { fft, ifft } from "../src/signal/fft/index.js";
|
|
2
|
+
import { conv, conv2 } from '../src/signal/conv/index.js'
|
|
3
|
+
import { Complex } from "ziko/math/complex";
|
|
4
|
+
// import { cos } from 'ziko/math/functions'
|
|
5
|
+
|
|
6
|
+
// const x = Array.from({ length: 100 }, (_, j)=> j/10)
|
|
7
|
+
// const y = cos(x)
|
|
8
|
+
|
|
9
|
+
// const ff = fft(x)
|
|
10
|
+
// // const ff = fft([1,2,3])
|
|
11
|
+
// // console.log(ff)
|
|
12
|
+
|
|
13
|
+
// // console.log(ifft(ff))
|
|
14
|
+
const signal = [1, 2, 3, 4, 5];
|
|
15
|
+
let kernel = [1, 0.5];
|
|
16
|
+
// kernel = [1, new Complex(0, 0.5)];
|
|
17
|
+
const result = conv(signal, kernel);
|
|
18
|
+
console.log(
|
|
19
|
+
result
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
// console.log(ff)
|
|
23
|
+
// console.log(ifft(ff).map(n=>+ n.a.toFixed(7)))
|
|
24
|
+
// console.log(x)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
// Example usage:
|
|
28
|
+
const image = [
|
|
29
|
+
[1, 2, 3],
|
|
30
|
+
[4, 5, 6],
|
|
31
|
+
[7, 8, 9]
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const filter = [
|
|
35
|
+
[1, 0],
|
|
36
|
+
[0, 1]
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
console.log(conv2(image, filter, 'full', 'fill'));
|
package/test/index.py
ADDED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { twiddle } from "../utils/index.js";
|
|
2
|
-
export function fft1d(arr) {
|
|
3
|
-
const N = arr.length;
|
|
4
|
-
if (N === 1) return [arr[0]];
|
|
5
|
-
|
|
6
|
-
// Split even/odd
|
|
7
|
-
const even = fft1d(arr.filter((_, i) => i % 2 === 0));
|
|
8
|
-
const odd = fft1d(arr.filter((_, i) => i % 2 === 1));
|
|
9
|
-
|
|
10
|
-
const out = new Array(N);
|
|
11
|
-
for (let k = 0; k < N/2; k++) {
|
|
12
|
-
const w = twiddle(N, k);
|
|
13
|
-
const t = w.mul(odd[k]);
|
|
14
|
-
out[k] = even[k].add(t);
|
|
15
|
-
out[k + N/2] = even[k].sub(t);
|
|
16
|
-
}
|
|
17
|
-
return out;
|
|
18
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { normalizeComplexND } from '../utils/index.js'
|
|
2
|
-
import { fft1d } from '../fft1d/index.js';
|
|
3
|
-
function fftND(arr) {
|
|
4
|
-
arr = normalizeComplexND(arr);
|
|
5
|
-
|
|
6
|
-
// Base case: 1-D
|
|
7
|
-
if (!Array.isArray(arr[0]))
|
|
8
|
-
return fft1d(arr);
|
|
9
|
-
|
|
10
|
-
const transformed = arr.map(sub => fftND(sub));
|
|
11
|
-
|
|
12
|
-
const rows = transformed.length;
|
|
13
|
-
const cols = transformed[0].length;
|
|
14
|
-
|
|
15
|
-
const colsData = Array.from({ length: cols }, (_, c) =>
|
|
16
|
-
Array.from({ length: rows }, (_, r) => transformed[r][c])
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
const colsTransformed = colsData.map(col => fft1d(col));
|
|
20
|
-
|
|
21
|
-
// Transpose back
|
|
22
|
-
const out = Array.from({ length: rows }, (_, r) =>
|
|
23
|
-
Array.from({ length: cols }, (_, c) => colsTransformed[c][r])
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
return out;
|
|
27
|
-
}
|