numz 0.0.2 → 0.0.3

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/demo/index.html CHANGED
@@ -5,10 +5,10 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Vite App</title>
8
- <link
8
+ <!-- <link
9
9
  href="https://fonts.googleapis.com/css?family=Gloria+Hallelujah&display=swap"
10
10
  rel="stylesheet"
11
- />
11
+ /> -->
12
12
  <!-- <style>
13
13
  body{
14
14
  font-family: "Gloria Hallelujah", cursive;
package/demo/main.js CHANGED
@@ -1,4 +1,11 @@
1
- import { FileBasedRouting } from "ziko";
2
- FileBasedRouting(import.meta.glob("./src/pages/**/*.js"))
3
- // const pages = import.meta.glob("./src/pages/**/*.js")
4
- // console.log(Object.keys(pages))
1
+ import { percentile } from "numz/stats";
2
+ import { fft1d } from 'numz/signal'
3
+ import { Complex } from "ziko/math/complex";
4
+
5
+ console.log(
6
+ percentile([1,2,3,4,5,6,7,8,9,10], 50)
7
+ )
8
+
9
+ // console.log(fft1d([1, 2, 1, -1, 1.5]))
10
+
11
+ // console.log(Complex)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "numz",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
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.54.2"
32
+ "ziko": "^0.54.4"
33
33
  }
34
34
  }
@@ -1,20 +1,24 @@
1
- function fft1d(arr) {
1
+ import { Complex } from 'ziko/math/complex'
2
+ import {add, sub} from 'ziko/math/functions/arithmetic'
3
+ export function fft1d(arr) {
2
4
  const N = arr.length;
3
5
  if (N === 1) return [arr[0]];
4
6
 
5
7
  const even = fft1d(arr.filter((_, i) => i % 2 === 0));
6
8
  const odd = fft1d(arr.filter((_, i) => i % 2 === 1));
9
+
10
+
7
11
 
8
12
  const out = new Array(N);
9
13
  for (let k = 0; k < N/2; k++) {
10
- const t = Complex.Twiddle(N, k).mul(odd[k]);
11
- out[k] = even[k].add(t);
12
- out[k + N/2] = even[k].sub(t);
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)
13
17
  }
14
18
  return out;
15
19
  }
16
20
 
17
- function fftnd(data) {
21
+ export function fftnd(data) {
18
22
  if (data instanceof Matrix) data = data.toComplex();
19
23
 
20
24
  if (Array.isArray(data) && !Array.isArray(data[0])) {
@@ -41,7 +45,7 @@ function fftnd(data) {
41
45
  }
42
46
 
43
47
  if (Array.isArray(data)) {
44
- return data.map(fftND);
48
+ return data.map(fftnd);
45
49
  }
46
50
 
47
51
  throw new Error("Invalid data type for FFT");
@@ -0,0 +1,3 @@
1
+ export * from './pulse/index.js'
2
+ export * from './sequence/index.js'
3
+ export * from './periodic'
@@ -0,0 +1,69 @@
1
+ // --------------------------
2
+ // Corrected Periodic Functions with Duty
3
+ // --------------------------
4
+
5
+ // Square wave: amplitude A, period T, duty cycle, centered at t0
6
+ export const square = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
7
+ const f = (v) => {
8
+ const phase = ((v - t0) % T + T) % T; // normalize to [0,T)
9
+ return phase < duty * T ? A : -A;
10
+ };
11
+ if (Array.isArray(t)) return t.map(f);
12
+ return f(t);
13
+ };
14
+
15
+ // Triangle wave: amplitude A, period T, duty cycle, centered at t0
16
+ export const triangle = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
17
+ const f = (v) => {
18
+ const phase = ((v - t0) % T + T) % T;
19
+ if (phase < duty * T) {
20
+ return (A / (duty * T)) * phase * 2 - A; // rising slope
21
+ } else {
22
+ return A - (A / ((1 - duty) * T)) * (phase - duty * T) * 2; // falling slope
23
+ }
24
+ };
25
+ if (Array.isArray(t)) return t.map(f);
26
+ return f(t);
27
+ };
28
+
29
+ // Sawtooth wave: amplitude A, period T, duty cycle, centered at t0
30
+ export const sawtoothPeriodic = (t, T = 1, A = 1, duty = 1, t0 = 0) => {
31
+ const f = (v) => {
32
+ const phase = ((v - t0) % T + T) % T;
33
+ if (phase < duty * T) {
34
+ return (A / (duty * T)) * phase - A; // rising part
35
+ } else {
36
+ return A - (A / ((1 - duty) * T)) * (phase - duty * T); // optional falling part
37
+ }
38
+ };
39
+ if (Array.isArray(t)) return t.map(f);
40
+ return f(t);
41
+ };
42
+
43
+ // Pulse train: amplitude A, period T, pulse width, centered at t0
44
+ export const pulseTrain = (t, T = 1, width = 0.5, A = 1, t0 = 0) => {
45
+ const f = (v) => {
46
+ const phase = ((v - t0) % T + T) % T;
47
+ return phase < width ? A : 0;
48
+ };
49
+ if (Array.isArray(t)) return t.map(f);
50
+ return f(t);
51
+ };
52
+
53
+ // PWM: amplitude A, period T, duty cycle, centered at t0
54
+ export const pwm = (t, T = 1, duty = 0.5, A = 1, t0 = 0) => {
55
+ const f = (v) => {
56
+ const phase = ((v - t0) % T + T) % T;
57
+ return phase < duty * T ? A : -A;
58
+ };
59
+ if (Array.isArray(t)) return t.map(f);
60
+ return f(t);
61
+ };
62
+
63
+
64
+ // Sinusoidal wave
65
+ export const sinusoid = (t, f = 1, A = 1, phase = 0) => {
66
+ const fcn = (v) => A * Math.sin(2 * Math.PI * f * v + phase);
67
+ if (Array.isArray(t)) return t.map(fcn);
68
+ return fcn(t);
69
+ };
@@ -0,0 +1,116 @@
1
+ export const noise = null
2
+ // Sign function (signum)
3
+ export const signum = (t, t0 = 0, A = 1) => {
4
+ if (Array.isArray(t)) return t.map(v => (v - t0) > 0 ? A : (v - t0) < 0 ? -A : 0);
5
+ return (t - t0) > 0 ? A : (t - t0) < 0 ? -A : 0;
6
+ };
7
+
8
+ // Ramp function
9
+ export const rampe = (t, t0 = 0, A = 1) => {
10
+ if (Array.isArray(t)) return t.map(v => v < t0 ? 0 : A * (v - t0));
11
+ return t < t0 ? 0 : A * (t - t0);
12
+ };
13
+
14
+ // Rectangular pulse (width = 1 for simplicity, centered at t0)
15
+ export const rect = (t, t0 = 0, A = 1, width = 1) => {
16
+ const half = width / 2;
17
+ if (Array.isArray(t)) return t.map(v => (v >= t0 - half && v <= t0 + half ? A : 0));
18
+ return (t >= t0 - half && t <= t0 + half ? A : 0);
19
+ };
20
+
21
+ // Triangular pulse (period T, centered at t0)
22
+ export const tri = (t, T = 1, t0 = 0, A = 1) => {
23
+ const half = T / 2;
24
+ const x = t - t0;
25
+ if (Array.isArray(t)) {
26
+ return t.map(v => {
27
+ const y = v - t0;
28
+ return (Math.abs(y) <= half) ? A * (1 - 2 * Math.abs(y) / T) : 0;
29
+ });
30
+ }
31
+ return (Math.abs(x) <= half) ? A * (1 - 2 * Math.abs(x) / T) : 0;
32
+ };
33
+
34
+
35
+ // Dirac delta approximation
36
+ // Since δ(t) is not a true function, we approximate with a narrow pulse
37
+ export const dirac = (t, t0 = 0, eps = 1e-6, A = 1) => {
38
+ if (Array.isArray(t)) return t.map(v => Math.abs(v - t0) < eps ? A / eps : 0);
39
+ return Math.abs(t - t0) < eps ? A / eps : 0;
40
+ };
41
+
42
+ // Lorentzian (Cauchy) function
43
+ // L(t) = (A / π) * (gamma / ((t - t0)^2 + gamma^2))
44
+ export const lorentz = (t, t0 = 0, gamma = 1, A = 1) => {
45
+ const value = (v) => (A / Math.PI) * (gamma / ((v - t0) ** 2 + gamma ** 2));
46
+ if (Array.isArray(t)) return t.map(value);
47
+ return value(t);
48
+ };
49
+
50
+ // Sinc function: sin(pi*(t-t0)) / (pi*(t-t0))
51
+ export const sinc = (t, t0 = 0, A = 1) => {
52
+ const f = (v) => {
53
+ const x = Math.PI * (v - t0);
54
+ return x === 0 ? A : A * Math.sin(x) / x;
55
+ };
56
+ if (Array.isArray(t)) return t.map(f);
57
+ return f(t);
58
+ };
59
+
60
+
61
+ // Gaussian pulse
62
+ export const gaussian = (t, t0 = 0, sigma = 1, A = 1) => {
63
+ const f = (v) => A * Math.exp(-((v - t0) ** 2) / (2 * sigma ** 2));
64
+ if (Array.isArray(t)) return t.map(f);
65
+ return f(t);
66
+ };
67
+
68
+ // Exponential pulse (causal)
69
+ export const expPulse = (t, t0 = 0, alpha = 1, A = 1) => {
70
+ const f = (v) => (v >= t0 ? A * Math.exp(-alpha * (v - t0)) : 0);
71
+ if (Array.isArray(t)) return t.map(f);
72
+ return f(t);
73
+ };
74
+
75
+ // Trapezoidal pulse
76
+ export const trapezoid = (t, t0 = 0, rise = 0.5, width = 1, fall = 0.5, A = 1) => {
77
+ const f = (v) => {
78
+ const x = v - t0;
79
+ if (x < 0 || x > rise + width + fall) return 0;
80
+ if (x < rise) return A * (x / rise);
81
+ if (x < rise + width) return A;
82
+ return A * (1 - (x - rise - width) / fall);
83
+ };
84
+ if (Array.isArray(t)) return t.map(f);
85
+ return f(t);
86
+ };
87
+
88
+ // Hamming window (useful for DSP)
89
+ export const hamming = (t, t0 = 0, T = 1, A = 1) => {
90
+ const f = (v) => {
91
+ const x = (v - t0) / T;
92
+ return (x >= 0 && x <= 1) ? A * (0.54 - 0.46 * Math.cos(2 * Math.PI * x)) : 0;
93
+ };
94
+ if (Array.isArray(t)) return t.map(f);
95
+ return f(t);
96
+ };
97
+
98
+ // Hanning window
99
+ export const hanning = (t, t0 = 0, T = 1, A = 1) => {
100
+ const f = (v) => {
101
+ const x = (v - t0) / T;
102
+ return (x >= 0 && x <= 1) ? A * 0.5 * (1 - Math.cos(2 * Math.PI * x)) : 0;
103
+ };
104
+ if (Array.isArray(t)) return t.map(f);
105
+ return f(t);
106
+ };
107
+
108
+ // Dirichlet (periodic sinc) function
109
+ export const dirichlet = (t, N = 5, t0 = 0, A = 1) => {
110
+ const f = (v) => {
111
+ const x = Math.PI * (v - t0);
112
+ return x === 0 ? A : A * Math.sin(N * x) / (N * Math.sin(x));
113
+ };
114
+ if (Array.isArray(t)) return t.map(f);
115
+ return f(t);
116
+ };
@@ -0,0 +1,103 @@
1
+ import { mapfun, nthr, pow } from "ziko/math/functions";
2
+
3
+ export const zeros = n => new Array(n).fill(0);
4
+ export const ones = n => new Array(n).fill(1);
5
+ export const nums = (n, num) => new Array(n).fill(num);
6
+
7
+
8
+ export const arange = (a, b, step, include = false) => {
9
+ if(a instanceof Array && typeof b === 'number') return mapfun(x => arange(x, b, step, include), ...a);
10
+ if(b instanceof Array && typeof a === 'number') return mapfun(x => arange(a, x, step, include), ...b);
11
+ if(a instanceof Array && b instanceof Array){
12
+ if(a.length !== b.length) return TypeError('');
13
+ let res = new Array(a.length).fill(null)
14
+ return res.map((_, i) => arange(a[i], b[i], step, include))
15
+ }
16
+ if(typeof a === 'number' && typeof b === 'number'){
17
+ const values = [];
18
+ let i;
19
+ if(a<b){
20
+ for (i = a; include ? i<=b : i<b ; i += step)
21
+ values.push((i * 10) / 10);
22
+ }
23
+ else{
24
+ for(i = a; include ? i>=b: i>b ; i -= step)
25
+ values.push((i * 10) / 10);
26
+ }
27
+ return values
28
+ }
29
+ }
30
+
31
+ export const linspace = (a, b, n = Math.abs(b-a) + 1, endpoint = true) =>{
32
+ if(Math.floor(n) !== n) return TypeError('');
33
+ let c = [a, b].find(n => n.isComplex?.())
34
+ if(c){
35
+ let z1 = new c.constructor(a);
36
+ let z2 = new c.constructor(b)
37
+ if (!n) n = Math.abs(z1.a - z2.a) + 1;
38
+ const X = linspace(z1.a, z2.a, n, endpoint);
39
+ const Y = linspace(z1.a, z2.a, n, endpoint);
40
+ let Z = new Array(n).fill(null);
41
+ Z = Z.map((_, i) => new z1.constructor(X[i], Y[i]));
42
+ return Z;
43
+ }
44
+ if(a instanceof Array && typeof b === 'number') return mapfun(x => linspace(x, b, step, include), ...a);
45
+ if(b instanceof Array && typeof a === 'number') return mapfun(x => linspace(a, x, step, include), ...b);
46
+ if(a instanceof Array && b instanceof Array){
47
+ if(a.length !== b.length) return TypeError('');
48
+ let res = new Array(a.length).fill(null)
49
+ return res.map((_, i) => linspace(a[i], b[i], step, include))
50
+ }
51
+ if(typeof a === 'number' && typeof b === 'number'){
52
+ const [max, min] = [a, b].sort((a, b) => b-a);
53
+ let Y = [], step, i;
54
+ endpoint ? step = (max - min) / (n - 1) : step = (max - min) / n;
55
+ if(a < b)
56
+ for(i = 0; i < n; i++)
57
+ Y.push(+(min + step * i).toFixed(8))
58
+ else
59
+ for(i = 0; i < n; i++)
60
+ Y.push(+(max - step * i).toFixed(8))
61
+ return Y
62
+ }
63
+ }
64
+
65
+ export const logspace = (a, b, n = Math.abs(b-a) + 1, base = Math.E, endpoint = true) => {
66
+ const ls = linspace(a, b, n, endpoint);
67
+ return mapfun(x => pow(base, x), ...ls)
68
+ }
69
+
70
+ export const geomspace = (a, b, n = Math.abs(b-a) + 1, endpoint = true, precison = 8) =>{
71
+ if(Math.floor(n) !== n) return TypeError('n must be and integer');
72
+ let c = [a, b].find(n => n.isComplex?.())
73
+ if(c){
74
+ let z1 = new c.constructor(a);
75
+ let z2 = new c.constructor(b);
76
+ if (!n) n = Math.abs(z1.a - z2.a) + 1;
77
+ const ratio = nthr(z2.clone().div(z1.clone()), n-1);
78
+ let i;
79
+ const Y = [];
80
+ for(i = 0; i < n; i++){
81
+ Y[i] = z1.clone().mul(pow(ratio.clone(), i))
82
+ }
83
+
84
+ return Y.map(n => n.toFixed(precison))
85
+ }
86
+ if(a instanceof Array && typeof b === 'number') return mapfun(x => geomspace(x, b, n, endpoint, precison), ...a);
87
+ if(b instanceof Array && typeof a === 'number') return mapfun(x => geomspace(a, x, n, endpoint, precison), ...b);
88
+ if(a instanceof Array && b instanceof Array){
89
+ if(a.length !== b.length) return TypeError('');
90
+ let res = new Array(a.length).fill(null)
91
+ return res.map((_, i) => geomspace(a[i], b[i], n, endpoint, precison))
92
+ }
93
+ if(typeof a === 'number' && typeof b === 'number'){
94
+ const [max, min]= [a, b].sort((a, b) => b-a);
95
+ let base = endpoint ? nthr(max/min, n-1) : nthr(max/min, n);
96
+ const Y = [min];
97
+ let i;
98
+ for(i = 1; i < n; i++)
99
+ Y.push(Y[i-1] * base )
100
+ const Fixed = Y.map(n => + n.toFixed(precison))
101
+ return a < b ? Fixed : Fixed.reverse()
102
+ }
103
+ }
@@ -0,0 +1,2 @@
1
+ export * from './functions/index.js'
2
+ // export * from './fft/index.js'
package/test.js ADDED
File without changes