numz 0.2.0 → 0.4.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/README.md +21 -0
- package/package.json +1 -1
- package/src/signal/functions/index.js +2 -1
- package/src/signal/functions/periodic/index.js +3 -3
- package/src/signal/functions/pulse/index.js +3 -3
- package/src/signal/functions/window/index.js +141 -0
- package/src/typed-matrix/abstract/AbstractFloatMatrix.js +43 -0
- package/src/typed-matrix/abstract/AbstractIntMatrix.js +6 -0
- package/src/typed-matrix/abstract/AbstractTypedMatrix.js +230 -0
- package/src/typed-matrix/abstract/helpers/arithmetic.js +33 -0
- package/src/typed-matrix/abstract/helpers/constructor.js +37 -0
- package/src/typed-matrix/abstract/helpers/det.js +41 -0
- package/src/typed-matrix/abstract/helpers/index.js +7 -0
- package/src/typed-matrix/abstract/helpers/inv.js +66 -0
- package/src/typed-matrix/abstract/helpers/maintain.js +24 -0
- package/src/typed-matrix/abstract/helpers/rank.js +49 -0
- package/src/typed-matrix/abstract/helpers/stack.js +14 -0
- package/src/typed-matrix/abstract/index.js +2 -0
- package/src/typed-matrix/index.js +91 -0
- package/src/typed-matrix/test.js +29 -0
- package/test/index.js +49 -36
package/README.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
# Numz
|
|
2
2
|
Scientific computing in [zikojs](https://github.com/zakarialaoui10/zikojs)
|
|
3
3
|
|
|
4
|
+
## API Reference
|
|
5
|
+
|
|
6
|
+
### Typed Matrix
|
|
7
|
+
- Class Constructors : `I8Matrix`, `I16Matrix`, `I32Matrix`,`U8Matrix`, `U16Matrix`, `U32Matrix`, `F16Matrix`, `F32Matrix`, `F64Matrix`, `BI64Matrix`, `BU64Matrix`
|
|
8
|
+
- Functional Constrcuctors : `matrix_i8`, `matrix_i16`, `matrix_i32`, `matrix_u8`, `matrix_u16`, `matrix_u32`, `matrix_f16`, `matrix_f32`, `matrix_f64`, `matrix_bi64`, `matrix_bu64`,
|
|
9
|
+
|
|
10
|
+
### Signal
|
|
11
|
+
|
|
12
|
+
- Sequence functions : `zeros`, `ones`, `nums`, `arange`, `linspace`, `logspace`, `geomspace`.
|
|
13
|
+
|
|
14
|
+
- Pulse functions : `signum`, `ramp`, `rect`, `tri`, `dirac`, `lorentz`, `sinc`, `gaussian_pulse`, `exp_pulse`, `trapezoid`.
|
|
15
|
+
|
|
16
|
+
- Periodic functions : `square`, `tri_wave`, `sawtooth_wave`, `pulse_train`, `pwm`, `sinusoid`
|
|
17
|
+
|
|
18
|
+
- Window functions : `hamming_window`, `hanning_window`, `kaiser_window`, `blackman_window`, `bartlett_window`, `blackman_harris_window`, `nuttall_window`, `flat_top_window`, `tukey_window`, `gaussian_window`, `lanczos_window`, `poisson_window`, `rect_window`, `tri_window`.
|
|
19
|
+
|
|
20
|
+
- conv : `conv`, `conv2`,
|
|
21
|
+
|
|
22
|
+
- fft : `fft`, `ifft`, `fft2`, `ifft2`
|
|
23
|
+
|
|
24
|
+
|
|
4
25
|
<!--
|
|
5
26
|
wasm ?
|
|
6
27
|
golang?
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@ export const square = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// Triangle wave: amplitude A, period T, duty cycle, centered at t0
|
|
16
|
-
export const
|
|
16
|
+
export const tri_wave = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
|
|
17
17
|
const f = (v) => {
|
|
18
18
|
const phase = ((v - t0) % T + T) % T;
|
|
19
19
|
if (phase < duty * T) {
|
|
@@ -27,7 +27,7 @@ export const triangle = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
// Sawtooth wave: amplitude A, period T, duty cycle, centered at t0
|
|
30
|
-
export const
|
|
30
|
+
export const sawtooth_wave = (t, T = 1, A = 1, duty = 1, t0 = 0) => {
|
|
31
31
|
const f = (v) => {
|
|
32
32
|
const phase = ((v - t0) % T + T) % T;
|
|
33
33
|
if (phase < duty * T) {
|
|
@@ -41,7 +41,7 @@ export const sawtoothPeriodic = (t, T = 1, A = 1, duty = 1, t0 = 0) => {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
// Pulse train: amplitude A, period T, pulse width, centered at t0
|
|
44
|
-
export const
|
|
44
|
+
export const pulse_train = (t, T = 1, width = 0.5, A = 1, t0 = 0) => {
|
|
45
45
|
const f = (v) => {
|
|
46
46
|
const phase = ((v - t0) % T + T) % T;
|
|
47
47
|
return phase < width ? A : 0;
|
|
@@ -6,7 +6,7 @@ export const signum = (t, t0 = 0, A = 1) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// Ramp function
|
|
9
|
-
export const
|
|
9
|
+
export const ramp = (t, t0 = 0, A = 1) => {
|
|
10
10
|
if (Array.isArray(t)) return t.map(v => v < t0 ? 0 : A * (v - t0));
|
|
11
11
|
return t < t0 ? 0 : A * (t - t0);
|
|
12
12
|
};
|
|
@@ -59,14 +59,14 @@ export const sinc = (t, t0 = 0, A = 1) => {
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
// Gaussian pulse
|
|
62
|
-
export const
|
|
62
|
+
export const gaussian_pulse = (t, t0 = 0, sigma = 1, A = 1) => {
|
|
63
63
|
const f = (v) => A * Math.exp(-((v - t0) ** 2) / (2 * sigma ** 2));
|
|
64
64
|
if (Array.isArray(t)) return t.map(f);
|
|
65
65
|
return f(t);
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
// Exponential pulse (causal)
|
|
69
|
-
export const
|
|
69
|
+
export const exp_pulse = (t, t0 = 0, alpha = 1, A = 1) => {
|
|
70
70
|
const f = (v) => (v >= t0 ? A * Math.exp(-alpha * (v - t0)) : 0);
|
|
71
71
|
if (Array.isArray(t)) return t.map(f);
|
|
72
72
|
return f(t);
|
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
const sinc = (x) => x === 0 ? 1 : sin(PI * x) / (PI * x);
|
|
113
|
+
export const lanczos_window = (N, ArrayType = Float64Array) => {
|
|
114
|
+
const w = new ArrayType(N);
|
|
115
|
+
for (let n = 0; n < N; n++)
|
|
116
|
+
w[n] = sinc(2 * n / (N - 1) - 1);
|
|
117
|
+
return w;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export const poisson_window = (N, alpha = 3, ArrayType = Float64Array) => {
|
|
121
|
+
const w = new ArrayType(N);
|
|
122
|
+
const m = (N - 1) / 2;
|
|
123
|
+
for (let n = 0; n < N; n++)
|
|
124
|
+
w[n] = exp(-alpha * abs(n - m) / m);
|
|
125
|
+
return w;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export const rect_window = (N, ArrayType = Float64Array) => {
|
|
129
|
+
const w = new ArrayType(N);
|
|
130
|
+
w.fill(1);
|
|
131
|
+
return w;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
export const tri_window = (N, ArrayType = Float64Array) => {
|
|
135
|
+
const w = new ArrayType(N);
|
|
136
|
+
const M = (N - 1) / 2;
|
|
137
|
+
for (let n = 0; n < N; n++) {
|
|
138
|
+
w[n] = 1 - abs((n - M) / M);
|
|
139
|
+
}
|
|
140
|
+
return w;
|
|
141
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AbstractIntMatrix } from "./AbstractIntMatrix.js";
|
|
2
|
+
import { typed_matrix_inv } from './helpers/index.js'
|
|
3
|
+
import {
|
|
4
|
+
map,
|
|
5
|
+
lerp,
|
|
6
|
+
clamp,
|
|
7
|
+
norm,
|
|
8
|
+
} from 'ziko/math/functions'
|
|
9
|
+
export class AbstractFloatMatrix extends AbstractIntMatrix{
|
|
10
|
+
constructor(rows, cols, data, type){
|
|
11
|
+
super(rows, cols, data, type)
|
|
12
|
+
}
|
|
13
|
+
get inv(){
|
|
14
|
+
return typed_matrix_inv(this)
|
|
15
|
+
}
|
|
16
|
+
get range(){
|
|
17
|
+
return {
|
|
18
|
+
map : (xmin, xmax, ymin, ymax) => {
|
|
19
|
+
// To Do
|
|
20
|
+
return this;
|
|
21
|
+
},
|
|
22
|
+
norm : (min, max) => {
|
|
23
|
+
this.data = this.data.map(
|
|
24
|
+
n => min !== max ? (n - min) / ( max - min) : 0
|
|
25
|
+
)
|
|
26
|
+
return this;
|
|
27
|
+
},
|
|
28
|
+
lerp : (min, max) => {
|
|
29
|
+
this.data = this.data.map(
|
|
30
|
+
n => min !== max ? (max - min) * n + min : 0
|
|
31
|
+
)
|
|
32
|
+
return this;
|
|
33
|
+
},
|
|
34
|
+
clamp : (min, max) => {
|
|
35
|
+
this.data = this.data.map(
|
|
36
|
+
n => Math.min(Math.max(n, min), max)
|
|
37
|
+
);
|
|
38
|
+
return this;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import {
|
|
2
|
+
typed_matrix_constructor,
|
|
3
|
+
maintain_indexes,
|
|
4
|
+
maintain_arr,
|
|
5
|
+
hstack,
|
|
6
|
+
vstack,
|
|
7
|
+
arithmetic,
|
|
8
|
+
typed_matrix_dot,
|
|
9
|
+
typed_matrix_det,
|
|
10
|
+
typed_matrix_rank,
|
|
11
|
+
} from './helpers/index.js'
|
|
12
|
+
export class AbstractTypedMatrix{
|
|
13
|
+
constructor(rows, cols, arr, type){
|
|
14
|
+
[
|
|
15
|
+
this.rows,
|
|
16
|
+
this.cols,
|
|
17
|
+
this.data,
|
|
18
|
+
this.type
|
|
19
|
+
] = typed_matrix_constructor(rows, cols, arr, type);
|
|
20
|
+
maintain_indexes(this)
|
|
21
|
+
}
|
|
22
|
+
isMatrix(){
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
isTypedMatrix(){
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
clone(){
|
|
29
|
+
return new this.constructor(this.rows, this.cols, this.data, this.type);
|
|
30
|
+
}
|
|
31
|
+
get size(){
|
|
32
|
+
return this.rows * this.cols;
|
|
33
|
+
}
|
|
34
|
+
get shape(){
|
|
35
|
+
return [this.rows, this.cols]
|
|
36
|
+
}
|
|
37
|
+
get arr(){
|
|
38
|
+
const arr = new Array(this.rows);
|
|
39
|
+
for(let i = 0; i < this.rows; i++){
|
|
40
|
+
const arr_col = new this.type(this.cols);
|
|
41
|
+
for(let j = 0; j < this.cols; j++)
|
|
42
|
+
arr_col[j] = this.data[i * this.cols + j]
|
|
43
|
+
arr[i] = arr_col
|
|
44
|
+
}
|
|
45
|
+
return arr;
|
|
46
|
+
}
|
|
47
|
+
at(i, j){
|
|
48
|
+
if(i < 0) i += this.rows;
|
|
49
|
+
if(i < 0 || i >= this.rows) throw new Error('Row index out of bounds');
|
|
50
|
+
if(j === undefined)
|
|
51
|
+
return this.data.slice(i * this.cols, (i + 1) * this.cols);
|
|
52
|
+
if(j < 0) j += this.cols;
|
|
53
|
+
if(j < 0 || j >= this.cols) throw new Error('Column index out of bounds');
|
|
54
|
+
return this.data[i * this.cols + j];
|
|
55
|
+
}
|
|
56
|
+
[Symbol.iterator](){
|
|
57
|
+
return this.arr[Symbol.iterator]
|
|
58
|
+
}
|
|
59
|
+
serialize(){
|
|
60
|
+
return JSON.stringify({
|
|
61
|
+
type : 'TypedMatrix',
|
|
62
|
+
data : {
|
|
63
|
+
rows : this.rows,
|
|
64
|
+
cols : this.cols,
|
|
65
|
+
t : this.type.name,
|
|
66
|
+
arr : [...this.data]
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
static deserialize(json){
|
|
71
|
+
const {type, data} = JSON.parse(json);
|
|
72
|
+
const {rows, cols, arr, t} = data
|
|
73
|
+
return new this(rows, cols, arr, globalThis[t])
|
|
74
|
+
}
|
|
75
|
+
reshape(newRows, newCols){
|
|
76
|
+
if(!(newRows * newCols === this.rows * this.cols)) throw Error('size not matched');
|
|
77
|
+
const oldRows = this.rows;
|
|
78
|
+
this.rows = newRows;
|
|
79
|
+
this.cols = newCols;
|
|
80
|
+
maintain_indexes(this, oldRows)
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
get T(){
|
|
84
|
+
let transpose = new this.data.constructor(this.size);
|
|
85
|
+
let i, j;
|
|
86
|
+
for (i = 0; i < this.cols; i++) {
|
|
87
|
+
for (j = 0; j < this.rows; j++)
|
|
88
|
+
transpose[i * this.rows + j] = this.data[j * this.rows + i]
|
|
89
|
+
}
|
|
90
|
+
[this.cols, this.rows] = this.shape;
|
|
91
|
+
return this
|
|
92
|
+
}
|
|
93
|
+
get det(){
|
|
94
|
+
return + typed_matrix_det(this).toFixed(14)
|
|
95
|
+
}
|
|
96
|
+
get rank(){
|
|
97
|
+
return typed_matrix_rank(this)
|
|
98
|
+
}
|
|
99
|
+
static zeros(rows, cols){
|
|
100
|
+
return new this(rows, cols, new Array(rows * cols).fill(0), this.type)
|
|
101
|
+
}
|
|
102
|
+
static ones(rows, cols){
|
|
103
|
+
return new this(rows, cols, new Array(rows * cols).fill(1), this.type)
|
|
104
|
+
}
|
|
105
|
+
static nums(rows, cols, num){
|
|
106
|
+
return new this(rows, cols, new Array(rows * cols).fill(num), this.type)
|
|
107
|
+
}
|
|
108
|
+
static eye(n){
|
|
109
|
+
const data = new this.type(n * n);
|
|
110
|
+
let i, j;
|
|
111
|
+
for(i = 0; i < n; i++)
|
|
112
|
+
for(j = 0; j <n; j++)
|
|
113
|
+
data[i * n + j] = i === j ? 1 : 0
|
|
114
|
+
return new this(n, n, data);
|
|
115
|
+
}
|
|
116
|
+
toPrecesion(p){
|
|
117
|
+
this.data = this.data.map(n => n.toPrecesion(p));
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
toFixed(p){
|
|
121
|
+
this.data = this.data.map(n => n.toFixed(p));
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
hstack(...matrices){
|
|
125
|
+
Object.assign(
|
|
126
|
+
this,
|
|
127
|
+
[this, ...matrices].reduce((a, b) => hstack(a, b))
|
|
128
|
+
);
|
|
129
|
+
maintain_arr(this);
|
|
130
|
+
return this;
|
|
131
|
+
}
|
|
132
|
+
vstack(...matrices){
|
|
133
|
+
Object.assign(
|
|
134
|
+
this,
|
|
135
|
+
[this, ...matrices].reduce((a, b) => vstack(a, b))
|
|
136
|
+
);
|
|
137
|
+
maintain_arr(this);
|
|
138
|
+
maintain_indexes(this, this.rows);
|
|
139
|
+
return this;
|
|
140
|
+
}
|
|
141
|
+
hqueue(...matrices){
|
|
142
|
+
Object.assign(
|
|
143
|
+
this,
|
|
144
|
+
[this, ...matrices].reverse().reduce((a,b)=>hstack(a, b))
|
|
145
|
+
);
|
|
146
|
+
maintain_arr(this);
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
vqueue(...matrices){
|
|
150
|
+
Object.assign(
|
|
151
|
+
this,
|
|
152
|
+
[this, ...matrices].reverse().reduce((a,b)=>vstack(a, b))
|
|
153
|
+
);
|
|
154
|
+
maintain_arr(this);
|
|
155
|
+
maintain_indexes(this, this.rows);
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
forEach(fn){
|
|
159
|
+
this.data.forEach(fn);
|
|
160
|
+
return this;
|
|
161
|
+
}
|
|
162
|
+
forEachRow(fn){
|
|
163
|
+
|
|
164
|
+
}
|
|
165
|
+
map(fn){
|
|
166
|
+
this.data = this.data.map(fn);
|
|
167
|
+
return this;
|
|
168
|
+
}
|
|
169
|
+
sort(fn){
|
|
170
|
+
this.data = this.data.sort(fn);
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
shuffle(){
|
|
174
|
+
return this.sort(() => 0.5-Math.random())
|
|
175
|
+
}
|
|
176
|
+
reduce(fn, initialValue){
|
|
177
|
+
return this.data.reduce(fn, initialValue);
|
|
178
|
+
}
|
|
179
|
+
every(fn){
|
|
180
|
+
return this.data.every(fn);
|
|
181
|
+
}
|
|
182
|
+
some(fn){
|
|
183
|
+
return this.data.some(fn)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
get isSquare(){
|
|
187
|
+
return this.rows === this.cols;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
add(...M){
|
|
191
|
+
return arithmetic.call(
|
|
192
|
+
this,
|
|
193
|
+
(a, b) => a + b,
|
|
194
|
+
...M
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
sub(...M){
|
|
198
|
+
return arithmetic.call(
|
|
199
|
+
this,
|
|
200
|
+
(a, b) => a - b,
|
|
201
|
+
...M
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
mul(...M){
|
|
205
|
+
return arithmetic.call(
|
|
206
|
+
this,
|
|
207
|
+
(a, b) => a * b,
|
|
208
|
+
...M
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
div(...M){
|
|
212
|
+
return arithmetic.call(
|
|
213
|
+
this,
|
|
214
|
+
(a, b) => a / b,
|
|
215
|
+
...M
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
modulo(...M){
|
|
219
|
+
return arithmetic.call(
|
|
220
|
+
this,
|
|
221
|
+
(a, b) => a % b,
|
|
222
|
+
...M
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
dot(...M){
|
|
226
|
+
typed_matrix_dot(this, ...M)
|
|
227
|
+
return this
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { maintain_arr } from "./maintain.js";
|
|
2
|
+
export function arithmetic(fn, ...M){
|
|
3
|
+
let i, j, k;
|
|
4
|
+
for(k = 0; k < M.length; k++)
|
|
5
|
+
for(i = 0; i < this.rows; i++)
|
|
6
|
+
for(j = 0; j < this.cols; j++)
|
|
7
|
+
this.data[i * this.cols + j] = fn(this.data[i * this.cols + j], M[k].data[i * this.cols + j])
|
|
8
|
+
maintain_arr(this)
|
|
9
|
+
return this;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function typed_matrix_dot(M1, ...Ms) {
|
|
13
|
+
for (const M2 of Ms) {
|
|
14
|
+
if (M1.cols !== M2.rows)
|
|
15
|
+
throw new Error("Matrix shape mismatch");
|
|
16
|
+
const {rows, cols} = M1
|
|
17
|
+
const outCols = M2.cols;
|
|
18
|
+
const out = new M1.type(rows * outCols);
|
|
19
|
+
for (let i = 0; i < rows; i++) {
|
|
20
|
+
const aRowOffset = i * cols;
|
|
21
|
+
const outRowOffset = i * outCols;
|
|
22
|
+
for (let j = 0; j < outCols; j++) {
|
|
23
|
+
let sum = 0;
|
|
24
|
+
for (let k = 0; k < cols; k++)
|
|
25
|
+
sum += M1.data[aRowOffset + k] * M2.data[k * outCols + j];
|
|
26
|
+
out[outRowOffset + j] = sum;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
M1.data = out;
|
|
30
|
+
M1.cols = outCols;
|
|
31
|
+
}
|
|
32
|
+
return M1;
|
|
33
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const typed_matrix_constructor = (rows, cols, arr, type = Float32Array) => {
|
|
2
|
+
if(typeof rows === 'number' && typeof cols === 'number'){
|
|
3
|
+
if(arr instanceof Array){
|
|
4
|
+
let typed_arr = new type(rows * cols), i;
|
|
5
|
+
for(i = 0; i < rows * cols ; i++)
|
|
6
|
+
typed_arr[i] = arr[i]
|
|
7
|
+
arr = typed_arr
|
|
8
|
+
}
|
|
9
|
+
return [
|
|
10
|
+
rows,
|
|
11
|
+
cols,
|
|
12
|
+
arr,
|
|
13
|
+
type
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
if(rows instanceof Array){
|
|
17
|
+
const r = rows.length;
|
|
18
|
+
const c = rows[0].length;
|
|
19
|
+
let i;
|
|
20
|
+
arr = new type(r * c);
|
|
21
|
+
for(i = 0; i < r*c ; i++){
|
|
22
|
+
arr[i] = rows.flat(1)[i]
|
|
23
|
+
}
|
|
24
|
+
return [
|
|
25
|
+
r,
|
|
26
|
+
c,
|
|
27
|
+
arr,
|
|
28
|
+
type
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// const [r,c, arr]= typed_matrix_constructor([[1,2],[3,4]], null, null, Float64Array)
|
|
36
|
+
|
|
37
|
+
// console.log(r,c, arr)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const typed_matrix_det = M => {
|
|
2
|
+
if (!M.isSquare)
|
|
3
|
+
throw new Error("Determinant is defined only for square matrices");
|
|
4
|
+
|
|
5
|
+
const n = M.rows;
|
|
6
|
+
const A = new M.data.constructor(M.data); // clone data
|
|
7
|
+
let det = 1;
|
|
8
|
+
let sign = 1;
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < n; i++) {
|
|
11
|
+
// Find pivot
|
|
12
|
+
let pivot = i;
|
|
13
|
+
for (let r = i + 1; r < n; r++) {
|
|
14
|
+
if (Math.abs(A[r * n + i]) > Math.abs(A[pivot * n + i]))
|
|
15
|
+
pivot = r;
|
|
16
|
+
}
|
|
17
|
+
// Zero pivot → det = 0
|
|
18
|
+
if (A[pivot * n + i] === 0)
|
|
19
|
+
return 0;
|
|
20
|
+
// Row swap
|
|
21
|
+
if (pivot !== i) {
|
|
22
|
+
for (let c = 0; c < n; c++) {
|
|
23
|
+
const tmp = A[i * n + c];
|
|
24
|
+
A[i * n + c] = A[pivot * n + c];
|
|
25
|
+
A[pivot * n + c] = tmp;
|
|
26
|
+
}
|
|
27
|
+
sign *= -1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const pivotVal = A[i * n + i];
|
|
31
|
+
det *= pivotVal;
|
|
32
|
+
// Eliminate below
|
|
33
|
+
for (let r = i + 1; r < n; r++) {
|
|
34
|
+
const factor = A[r * n + i] / pivotVal;
|
|
35
|
+
for (let c = i; c < n; c++) {
|
|
36
|
+
A[r * n + c] -= factor * A[i * n + c];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return det * sign;
|
|
41
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const typed_matrix_inv = M =>{
|
|
2
|
+
if (!M.isSquare)
|
|
3
|
+
throw new Error("Inverse is defined only for square matrices");
|
|
4
|
+
if(M.det === 0) return NaN
|
|
5
|
+
|
|
6
|
+
const n = M.rows;
|
|
7
|
+
const Type = M.type;
|
|
8
|
+
|
|
9
|
+
// Copy of A
|
|
10
|
+
const A = new Type(M.data);
|
|
11
|
+
|
|
12
|
+
// Identity matrix
|
|
13
|
+
const I = new Type(n * n);
|
|
14
|
+
for (let i = 0; i < n; i++)
|
|
15
|
+
I[i * n + i] = 1;
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < n; i++) {
|
|
18
|
+
// Find pivot
|
|
19
|
+
let pivot = i;
|
|
20
|
+
let max = Math.abs(A[i * n + i]);
|
|
21
|
+
|
|
22
|
+
for (let r = i + 1; r < n; r++) {
|
|
23
|
+
const v = Math.abs(A[r * n + i]);
|
|
24
|
+
if (v > max) {
|
|
25
|
+
max = v;
|
|
26
|
+
pivot = r;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (A[pivot * n + i] === 0)
|
|
31
|
+
throw new Error("Matrix is singular and cannot be inverted");
|
|
32
|
+
|
|
33
|
+
// Swap rows in A and I
|
|
34
|
+
if (pivot !== i) {
|
|
35
|
+
for (let c = 0; c < n; c++) {
|
|
36
|
+
let tmp = A[i * n + c];
|
|
37
|
+
A[i * n + c] = A[pivot * n + c];
|
|
38
|
+
A[pivot * n + c] = tmp;
|
|
39
|
+
|
|
40
|
+
tmp = I[i * n + c];
|
|
41
|
+
I[i * n + c] = I[pivot * n + c];
|
|
42
|
+
I[pivot * n + c] = tmp;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Normalize pivot row
|
|
47
|
+
const pivotVal = A[i * n + i];
|
|
48
|
+
for (let c = 0; c < n; c++) {
|
|
49
|
+
A[i * n + c] /= pivotVal;
|
|
50
|
+
I[i * n + c] /= pivotVal;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Eliminate other rows
|
|
54
|
+
for (let r = 0; r < n; r++) {
|
|
55
|
+
if (r === i) continue;
|
|
56
|
+
const factor = A[r * n + i];
|
|
57
|
+
if (factor === 0) continue;
|
|
58
|
+
for (let c = 0; c < n; c++) {
|
|
59
|
+
A[r * n + c] -= factor * A[i * n + c];
|
|
60
|
+
I[r * n + c] -= factor * I[i * n + c];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return new M.constructor(n, n, I, Type);
|
|
66
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const maintain_arr = (Matrix) =>{
|
|
2
|
+
const arr = new Array(Matrix.rows);
|
|
3
|
+
for(let i = 0; i < Matrix.rows; i++){
|
|
4
|
+
const arr_col = new Matrix.type(Matrix.cols);
|
|
5
|
+
for(let j = 0; j < Matrix.cols; j++)
|
|
6
|
+
arr_col[j] = Matrix.data[i * Matrix.cols + j]
|
|
7
|
+
arr[i] = arr_col
|
|
8
|
+
}
|
|
9
|
+
Matrix.arr = arr
|
|
10
|
+
}
|
|
11
|
+
export const maintain_indexes = (Matrix, oldRows) =>{
|
|
12
|
+
for (let i = 0; i < Matrix.arr.length; i++) {
|
|
13
|
+
Object.defineProperty(Matrix, i, {
|
|
14
|
+
value: Matrix.arr[i],
|
|
15
|
+
writable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
enumerable: false
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
for (let i = Matrix.arr.length; i < oldRows; i++) {
|
|
21
|
+
delete Matrix[i];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export const typed_matrix_rank = M =>{
|
|
2
|
+
const m = M.rows;
|
|
3
|
+
const n = M.cols;
|
|
4
|
+
const A = M.clone();
|
|
5
|
+
const eps = 1e-12;
|
|
6
|
+
|
|
7
|
+
let rank = 0;
|
|
8
|
+
let row = 0;
|
|
9
|
+
|
|
10
|
+
for (let col = 0; col < n && row < m; col++) {
|
|
11
|
+
// Find pivot
|
|
12
|
+
let pivot = row;
|
|
13
|
+
let max = Math.abs(A[row * n + col]);
|
|
14
|
+
|
|
15
|
+
for (let r = row + 1; r < m; r++) {
|
|
16
|
+
const v = Math.abs(A[r * n + col]);
|
|
17
|
+
if (v > max) {
|
|
18
|
+
max = v;
|
|
19
|
+
pivot = r;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// No pivot in this column
|
|
24
|
+
if (max < eps) continue;
|
|
25
|
+
|
|
26
|
+
// Swap rows
|
|
27
|
+
if (pivot !== row) {
|
|
28
|
+
for (let c = col; c < n; c++) {
|
|
29
|
+
const tmp = A[row * n + c];
|
|
30
|
+
A[row * n + c] = A[pivot * n + c];
|
|
31
|
+
A[pivot * n + c] = tmp;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Eliminate below
|
|
36
|
+
const pivotVal = A[row * n + col];
|
|
37
|
+
for (let r = row + 1; r < m; r++) {
|
|
38
|
+
const factor = A[r * n + col] / pivotVal;
|
|
39
|
+
if (Math.abs(factor) < eps) continue;
|
|
40
|
+
for (let c = col; c < n; c++)
|
|
41
|
+
A[r * n + c] -= factor * A[row * n + c];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rank++;
|
|
45
|
+
row++;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return rank;
|
|
49
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function hstack(M1, M2){
|
|
2
|
+
M1 = M1.clone();
|
|
3
|
+
M2 = M2.clone();
|
|
4
|
+
if (M1.rows !== M2.rows) return;
|
|
5
|
+
if (M1.type !== M2.type) return;
|
|
6
|
+
const data = new M1.type(M1.size + M2.size)
|
|
7
|
+
data.set(M1.data, 0)
|
|
8
|
+
data.set(M2.data, M1.data.length)
|
|
9
|
+
return new M1.constructor(M1.rows, M1.cols + M2.cols, data);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function vstack(M1, M2){
|
|
13
|
+
return hstack(M1.T, M2.T).T
|
|
14
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractIntMatrix,
|
|
3
|
+
AbstractFloatMatrix
|
|
4
|
+
} from "./abstract/index.js";
|
|
5
|
+
export class I8Matrix extends AbstractIntMatrix{
|
|
6
|
+
constructor(rows, cols, data){
|
|
7
|
+
super(rows, cols, data, Int8Array)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class I16Matrix extends AbstractIntMatrix{
|
|
11
|
+
constructor(rows, cols, data){
|
|
12
|
+
super(rows, cols, data, Int16Array)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class I32Matrix extends AbstractIntMatrix{
|
|
16
|
+
constructor(rows, cols, data){
|
|
17
|
+
super(rows, cols, data, Int32Array)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// export class I64Matrix extends AbstractIntMatrix{
|
|
21
|
+
// constructor(rows, cols, data){
|
|
22
|
+
// super(rows, cols, data, Int64Array)
|
|
23
|
+
// }
|
|
24
|
+
// }
|
|
25
|
+
|
|
26
|
+
export class U8Matrix extends AbstractIntMatrix{
|
|
27
|
+
constructor(rows, cols, data){
|
|
28
|
+
super(rows, cols, data, Uint8Array)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class U16Matrix extends AbstractIntMatrix{
|
|
32
|
+
constructor(rows, cols, data){
|
|
33
|
+
super(rows, cols, data, Uint16Array)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class U32Matrix extends AbstractIntMatrix{
|
|
37
|
+
constructor(rows, cols, data){
|
|
38
|
+
super(rows, cols, data, Uint32Array)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// export class U64Matrix extends AbstractTypedMatrix{
|
|
42
|
+
// constructor(rows, cols, data){
|
|
43
|
+
// super(rows, cols, data, Uint64Array)
|
|
44
|
+
// }
|
|
45
|
+
// }
|
|
46
|
+
|
|
47
|
+
export class F16Matrix extends AbstractFloatMatrix{
|
|
48
|
+
constructor(rows, cols, data){
|
|
49
|
+
super(rows, cols, data, Float16Array)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export class F32Matrix extends AbstractFloatMatrix{
|
|
53
|
+
constructor(rows, cols, data){
|
|
54
|
+
super(rows, cols, data, Float32Array)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export class F64Matrix extends AbstractFloatMatrix{
|
|
58
|
+
static type = Float64Array
|
|
59
|
+
constructor(rows, cols, data){
|
|
60
|
+
super(rows, cols, data, Float64Array)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export class BI64Matrix extends AbstractIntMatrix{
|
|
65
|
+
constructor(rows, cols, data){
|
|
66
|
+
super(rows, cols, data, BigInt64Array)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export class BU64Matrix extends AbstractIntMatrix{
|
|
71
|
+
constructor(rows, cols, data){
|
|
72
|
+
super(rows, cols, data, BigUint64Array)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const matrix_i8 = (rows, cols, data) => new I8Matrix(rows, cols, data)
|
|
77
|
+
export const matrix_i16 = (rows, cols, data) => new I16Matrix(rows, cols, data)
|
|
78
|
+
export const matrix_i32 = (rows, cols, data) => new I32Matrix(rows, cols, data)
|
|
79
|
+
export const matrix_i64 = (rows, cols, data) => new I16Matrix(rows, cols, data)
|
|
80
|
+
|
|
81
|
+
export const matrix_u8 = (rows, cols, data) => new U8Matrix(rows, cols, data)
|
|
82
|
+
export const matrix_u16 = (rows, cols, data) => new U16Matrix(rows, cols, data)
|
|
83
|
+
export const matrix_u32 = (rows, cols, data) => new U32Matrix(rows, cols, data)
|
|
84
|
+
export const matrix_u64 = (rows, cols, data) => new U16Matrix(rows, cols, data)
|
|
85
|
+
|
|
86
|
+
export const matrix_f16 = (rows, cols, data) => new F16Matrix(rows, cols, data)
|
|
87
|
+
export const matrix_f32 = (rows, cols, data) => new F32Matrix(rows, cols, data)
|
|
88
|
+
export const matrix_f64 = (rows, cols, data) => new F16Matrix(rows, cols, data)
|
|
89
|
+
|
|
90
|
+
export const matrix_bi64 = (rows, cols, data) => new BI64Matrix(rows, cols, data)
|
|
91
|
+
export const matrix_bu64 = (rows, cols, data) => new BI64Matrix(rows, cols, data)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { F64Matrix } from "./index.js";
|
|
2
|
+
|
|
3
|
+
const M = new F64Matrix(3,3, [1,2,3,4,5,6,7,8,9], Int16Array)
|
|
4
|
+
const M1 = M.clone()
|
|
5
|
+
// const M2 = new AbstractTypedMatrix()
|
|
6
|
+
|
|
7
|
+
// console.log(M.data)
|
|
8
|
+
// console.log(M.at(0))
|
|
9
|
+
// console.log(M.T.at(0))
|
|
10
|
+
|
|
11
|
+
// console.log(M.hstack(M).arr)
|
|
12
|
+
|
|
13
|
+
// console.log(M.arr)
|
|
14
|
+
|
|
15
|
+
// M.arr[0][0] = 17
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
// console.log(M.mul(M).T)
|
|
19
|
+
|
|
20
|
+
// console.log(M.range.norm(0, 10).rank)
|
|
21
|
+
|
|
22
|
+
// console.log(F64Matrix.ones(3,3).rank)
|
|
23
|
+
|
|
24
|
+
// console.log(F64Matrix.eye(3).reshape(1,)[0])
|
|
25
|
+
|
|
26
|
+
const S = M.serialize()
|
|
27
|
+
console.log(S)
|
|
28
|
+
|
|
29
|
+
console.log(F64Matrix.deserialize(S))
|
package/test/index.js
CHANGED
|
@@ -1,39 +1,52 @@
|
|
|
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'
|
|
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
|
+
// )
|
|
5
21
|
|
|
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
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'));
|
|
40
|
+
|
|
41
|
+
function hanning(N, ArrayType = Float64Array) {
|
|
42
|
+
const w = new ArrayType(N);
|
|
43
|
+
const factor = 2 * Math.PI / N;
|
|
44
|
+
|
|
45
|
+
for (let n = 0; n < N; n++) {
|
|
46
|
+
w[n] = 0.5 - 0.5 * Math.cos(factor * n);
|
|
47
|
+
}
|
|
48
|
+
return w;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(hanning(10).map(a=>a*20))
|
|
12
52
|
|
|
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'));
|