numz 0.5.0 → 0.7.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "numz",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "scientific computing with zikojs",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -26,9 +26,9 @@
26
26
  "@rollup/plugin-node-resolve": "^16.0.3",
27
27
  "@rollup/plugin-terser": "^1.0.0",
28
28
  "cross-env": "^10.1.0",
29
- "rollup": "^4.62.5"
29
+ "rollup": "^4.63.0"
30
30
  },
31
31
  "dependencies": {
32
- "ziko": "^1.8.0"
32
+ "ziko": "^1.10.0"
33
33
  }
34
34
  }
@@ -0,0 +1,38 @@
1
+ export const complex_constructor = (Complex, a, b) => {
2
+ let _a, _b;
3
+ if (a instanceof Complex) {
4
+ _a = a.a;
5
+ _b = a.b;
6
+ }
7
+ else if (typeof a === "object") {
8
+ if ("a" in a && "b" in a) {
9
+ _a = a.a;
10
+ _b = a.b;
11
+ }
12
+ else if ("a" in a && "z" in a) {
13
+ _a = a.a;
14
+ _b = Math.sqrt(a.z ** 2 - a.a ** 2);
15
+ }
16
+ else if ("a" in a && "phi" in a) {
17
+ _a = a.a;
18
+ _b = a.a * Math.tan(a.phi);
19
+ }
20
+ else if ("b" in a && "z" in a) {
21
+ _b = a.b;
22
+ _a = Math.sqrt(a.z ** 2 - a.b ** 2);
23
+ }
24
+ else if ("b" in a && "phi" in a) {
25
+ _b = b;
26
+ _a = a.b / Math.tan(a.phi);
27
+ }
28
+ else if ("z" in a && "phi" in a) {
29
+ _a = +a.z * Math.cos(a.phi).toFixed(15);
30
+ _b = +a.z * Math.sin(a.phi).toFixed(15);
31
+ }
32
+ }
33
+ else if (typeof a === "number" && typeof b === "number") {
34
+ _a = +a.toFixed(32);
35
+ _b = +b.toFixed(32);
36
+ }
37
+ return [_a, _b]
38
+ };
@@ -0,0 +1 @@
1
+ export * from './constructor.js'
@@ -0,0 +1,231 @@
1
+ import type { Matrix } from "../matrix/index.js";
2
+
3
+ /**
4
+ * Represents a complex number.
5
+ *
6
+ * A complex number is represented as:
7
+ * a + bi
8
+ */
9
+ export declare class Complex {
10
+ a: number;
11
+ b: number;
12
+
13
+ constructor(a?: number, b?: number);
14
+ constructor(c: Complex);
15
+ constructor(value:
16
+ | { a: number; b: number }
17
+ | { a: number; z: number }
18
+ | { a: number; phi: number }
19
+ | { b: number; z: number }
20
+ | { b: number; phi: number }
21
+ | { z: number; phi: number }
22
+ );
23
+
24
+ /**
25
+ * Used by mapfun to identify complex values.
26
+ */
27
+ readonly __mapfun__: boolean;
28
+
29
+ /**
30
+ * Checks whether this value is a Complex instance.
31
+ */
32
+ isComplex(): true;
33
+
34
+ /**
35
+ * Converts the complex number to a string.
36
+ */
37
+ toString(): string;
38
+
39
+ /**
40
+ * Serializes the complex number.
41
+ */
42
+ serialize(): string;
43
+
44
+ /**
45
+ * Deserializes a serialized complex number.
46
+ */
47
+ static deserialize(json: string | object): Complex | TypeError;
48
+
49
+ /**
50
+ * Rounds real and imaginary parts.
51
+ *
52
+ * @param n Number of decimal digits.
53
+ */
54
+ toFixed(n: number): this;
55
+
56
+ /**
57
+ * Formats real and imaginary parts with precision.
58
+ *
59
+ * @param n Number of significant digits.
60
+ */
61
+ toPrecision(n: number): this;
62
+
63
+ /**
64
+ * Creates a copy of this complex number.
65
+ */
66
+ clone(): Complex;
67
+
68
+ /**
69
+ * Magnitude of the complex number.
70
+ */
71
+ readonly z: number;
72
+
73
+ /**
74
+ * Phase angle in radians.
75
+ */
76
+ readonly phi: number;
77
+
78
+ /**
79
+ * Complex conjugate.
80
+ */
81
+ readonly conj: Complex;
82
+
83
+ /**
84
+ * Multiplicative inverse.
85
+ */
86
+ readonly inv: Complex;
87
+
88
+ /**
89
+ * Exponential representation [magnitude, phase].
90
+ */
91
+ readonly expo: [number, number];
92
+
93
+ /**
94
+ * Adds complex numbers.
95
+ */
96
+ add(...c: (number | Complex)[]): this;
97
+
98
+ /**
99
+ * Subtracts complex numbers.
100
+ */
101
+ sub(...c: (number | Complex)[]): this;
102
+
103
+ /**
104
+ * Multiplies complex numbers.
105
+ */
106
+ mul(...c: (number | Complex)[]): this;
107
+
108
+ /**
109
+ * Divides complex numbers.
110
+ */
111
+ div(...c: (number | Complex)[]): this;
112
+
113
+ /**
114
+ * Computes modulo.
115
+ */
116
+ modulo(...c: (number | Complex)[]): this;
117
+
118
+ /**
119
+ * Raises the complex number to a power.
120
+ */
121
+ pow(...c: (number | Complex)[]): this;
122
+
123
+ /**
124
+ * Calculates the nth root.
125
+ */
126
+ nthr(n?: number): Complex;
127
+
128
+ /**
129
+ * Square root.
130
+ */
131
+ readonly sqrt: Complex;
132
+
133
+ /**
134
+ * Cube root.
135
+ */
136
+ readonly cbrt: Complex;
137
+
138
+ /**
139
+ * Complex logarithm.
140
+ */
141
+ readonly log: Complex;
142
+
143
+ /**
144
+ * Complex cosine.
145
+ */
146
+ readonly cos: Complex;
147
+
148
+ /**
149
+ * Complex sine.
150
+ */
151
+ readonly sin: Complex;
152
+
153
+ /**
154
+ * Complex tangent.
155
+ */
156
+ readonly tan: Complex;
157
+
158
+ /**
159
+ * Returns zero complex.
160
+ */
161
+ static zero(): Complex;
162
+
163
+ /**
164
+ * Creates a complex number from polar coordinates.
165
+ *
166
+ * @param z Magnitude.
167
+ * @param phi Angle in radians.
168
+ */
169
+ static fromPolar(
170
+ z: number,
171
+ phi: number
172
+ ): Complex;
173
+
174
+ /**
175
+ * Creates FFT twiddle factor.
176
+ */
177
+ static twiddle(
178
+ K: number,
179
+ N: number
180
+ ): Complex;
181
+
182
+ /**
183
+ * Generates random complex numbers.
184
+ */
185
+ static readonly random: {
186
+ int(
187
+ a?: number,
188
+ b?: number
189
+ ): Complex;
190
+
191
+ float(
192
+ a?: number,
193
+ b?: number
194
+ ): Complex;
195
+ };
196
+ }
197
+
198
+
199
+ /**
200
+ * Creates a complex number.
201
+ */
202
+ export declare function complex(
203
+ a?: number,
204
+ b?: number
205
+ ): Complex;
206
+
207
+ export declare function complex(
208
+ a: Complex
209
+ ): Complex;
210
+
211
+ export declare function complex(
212
+ a: object
213
+ ): Complex;
214
+
215
+
216
+ /**
217
+ * Creates arrays of complex numbers from two arrays.
218
+ */
219
+ export declare function complex(
220
+ a: number[] | ArrayLike<number>,
221
+ b: number[] | ArrayLike<number>
222
+ ): Complex[];
223
+
224
+
225
+ /**
226
+ * Creates a complex matrix by combining two matrices.
227
+ */
228
+ export declare function complex(
229
+ a: Matrix,
230
+ b: Matrix
231
+ ): Matrix;
@@ -0,0 +1,193 @@
1
+ import { Random } from "../random/index.js";
2
+ import { complex_constructor } from "./helpers/index.js";
3
+ class Complex{
4
+ constructor(a = 0, b = 0) {
5
+ [
6
+ this.a,
7
+ this.b
8
+ ] = complex_constructor(Complex, a, b)
9
+ }
10
+ get __mapfun__(){
11
+ return true
12
+ }
13
+ isComplex(){
14
+ return true
15
+ }
16
+ toString(){
17
+ let str = "";
18
+ if (this.a !== 0)
19
+ this.b >= 0
20
+ ? (str = `${this.a}+${this.b}*i`)
21
+ : (str = `${this.a}-${Math.abs(this.b)}*i`);
22
+ else
23
+ this.b >= 0
24
+ ? (str = `${this.b}*i`)
25
+ : (str = `-${Math.abs(this.b)}*i`);
26
+ return str;
27
+ }
28
+ serialize() {
29
+ return JSON.stringify({
30
+ type : 'complex',
31
+ data : this
32
+ });
33
+ }
34
+ static deserialize(json){
35
+ if(typeof json === 'string') json = JSON.parse(json);
36
+ let {data, type} = json;
37
+ return (type === 'complex' && ('a' in data) && ('b' in data))
38
+ ? new Complex(data.a, data.b)
39
+ : TypeError('Not a valid complex')
40
+ }
41
+ toFixed(n){
42
+ this.a = + this.a.toFixed(n);
43
+ this.b = + this.b.toFixed(n);
44
+ return this;
45
+ }
46
+ toPrecision(n){
47
+ this.a = + this.a.toPrecision(n);
48
+ this.b = + this.b.toPrecision(n);
49
+ return this;
50
+ }
51
+ clone() {
52
+ return new Complex(this.a, this.b);
53
+ }
54
+ get z(){
55
+ return Math.hypot(this.a,this.b);
56
+ }
57
+ get phi(){
58
+ return Math.atan2(this.b , this.a);
59
+ }
60
+ static zero() {
61
+ return new Complex(0, 0);
62
+ }
63
+ static fromPolar(z, phi) {
64
+ return new Complex(
65
+ +(z * cos(phi)).toFixed(13),
66
+ +(z * sin(phi)).toFixed(13)
67
+ );
68
+ }
69
+
70
+ static get random(){
71
+ return {
72
+ int : (a, b)=> new Complex(...Random.sample.int(2, a, b) ),
73
+ float : (a, b)=> new Complex(...Random.sample.float(2, a, b) ),
74
+ }
75
+ }
76
+ static twiddle(K, N){
77
+ const phi = -2 * Math.PI * K / N;
78
+ return new Complex(
79
+ Math.cos(phi),
80
+ Math.sin(phi)
81
+ );
82
+ }
83
+ get conj() {
84
+ return new Complex(this.a, -this.b);
85
+ }
86
+ get inv() {
87
+ return new Complex(
88
+ this.a / Math.hypot(this.a, this.b),
89
+ -this.b / Math.hypot(this.a, this.b)
90
+ );
91
+ }
92
+ add(...c) {
93
+ for (let i = 0; i < c.length; i++) {
94
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
95
+ this.a += c[i].a;
96
+ this.b += c[i].b;
97
+ }
98
+ return this;
99
+ }
100
+ sub(...c) {
101
+ for (let i = 0; i < c.length; i++) {
102
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
103
+ this.a -= c[i].a;
104
+ this.b -= c[i].b;
105
+ }
106
+ return this;
107
+ }
108
+ mul(...c){
109
+ let {z, phi} = this;
110
+ for (let i = 0; i < c.length; i++) {
111
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
112
+ z *= c[i].z;
113
+ phi += c[i].phi;
114
+ }
115
+ this.a = z * Math.cos(phi)
116
+ this.b = z * Math.sin(phi)
117
+ return this.toFixed(8);
118
+ }
119
+ div(...c){
120
+ let {z, phi} = this;
121
+ for (let i = 0; i < c.length; i++) {
122
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
123
+ z /= c[i].z;
124
+ phi -= c[i].phi;
125
+ }
126
+ this.a = z * Math.cos(phi)
127
+ this.b = z * Math.sin(phi)
128
+ return this.toFixed(8);;
129
+ }
130
+ modulo(...c) {
131
+ for (let i = 0; i < c.length; i++) {
132
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
133
+ this.a %= c[i].a;
134
+ this.b %= c[i].b;
135
+ }
136
+ return this;
137
+ }
138
+ pow(...c){
139
+ let {z, phi} = this;
140
+ for (let i = 0; i < c.length; i++) {
141
+ if (typeof c[i] === "number") c[i] = new Complex(c[i], 0);
142
+ z *= Math.exp(c[i].a * Math.log(z) - c[i].b * phi);
143
+ phi += c[i].b * Math.log(z) + c[i].a * phi;
144
+ }
145
+ this.a = z * Math.cos(phi)
146
+ this.b = z * Math.sin(phi)
147
+ return this;
148
+ }
149
+ get expo() {
150
+ return [this.z, this.phi];
151
+ }
152
+ nthr(n=2){
153
+ return complex({z: this.z ** (1/n), phi: this.phi / n});
154
+ }
155
+ get sqrt(){
156
+ return this.nthr(2);
157
+ }
158
+ get cbrt(){
159
+ return this.nthr(3);
160
+ }
161
+ get log(){
162
+ return complex(this.z, this.phi);
163
+ }
164
+ get cos(){
165
+ return complex(
166
+ Math.cos(this.a) * Math.cosh(this.b),
167
+ Math.sin(this.a) * Math.sinh(this.b)
168
+ )
169
+ }
170
+ get sin(){
171
+ return complex(
172
+ Math.sin(this.a) * Math.cosh(this.b),
173
+ Math.cos(this.a) * Math.sinh(this.b)
174
+ )
175
+ }
176
+ get tan(){
177
+ const D=cos(this.a*2)+cosh(this.b*2);
178
+ return complex(
179
+ Math.sin(2 * this.a) / D,
180
+ Math.sinh(2 * this.b) / D
181
+ );
182
+ }
183
+ }
184
+ const complex=(a,b)=>{
185
+ if((a instanceof Array||ArrayBuffer.isView(a)) && (b instanceof Array||ArrayBuffer.isView(a)))return a.map((n,i)=>complex(a[i],b[i]));
186
+ if(a.isMatrix?.() && b.isMatrix?.()){
187
+ if((a.shape[0]!==b.shape[0])||(a.shape[1]!==b.shape[1]))return Error(0)
188
+ const arr=a.arr.map((n,i)=>complex(a.arr[i],b.arr[i]))
189
+ return new a.constructor(a.rows,a.cols,...arr)
190
+ }
191
+ return new Complex(a,b)
192
+ }
193
+ export{complex,Complex}
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from './ufunc/index.js'
2
+ export * from './random/index.js'
3
+ export * from './complex/index.js'
2
4
  export * from './calculus/index.js'
3
5
  export * from './signal/index.js'
4
6
  export * from './stats/index.js'
5
-
6
-
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Utility class for generating random values.
3
+ */
4
+ export declare class Random {
5
+
6
+ /**
7
+ * Generates a random integer.
8
+ * @param a Minimum value (inclusive).
9
+ * @param b Maximum value (exclusive).
10
+ */
11
+ static int(a: number, b?: number): number;
12
+
13
+ /**
14
+ * Generates a random floating-point number.
15
+ * @param a Minimum value.
16
+ * @param b Maximum value.
17
+ */
18
+ static float(a: number, b?: number): number;
19
+
20
+ /**
21
+ * Generates a random binary value.
22
+ */
23
+ static bin(): 0 | 1;
24
+
25
+ /**
26
+ * Generates a random octal digit.
27
+ */
28
+ static oct(): number;
29
+
30
+ /**
31
+ * Generates a random decimal digit.
32
+ */
33
+ static dec(): number;
34
+
35
+ /**
36
+ * Generates a random hexadecimal digit.
37
+ */
38
+ static hex(): string;
39
+
40
+ /**
41
+ * Generates a random alphabetic character.
42
+ * @param upperCase Generate uppercase character when true.
43
+ */
44
+ static char(upperCase?: boolean): string;
45
+
46
+ /**
47
+ * Generates a random boolean value.
48
+ */
49
+ static bool(): boolean;
50
+
51
+ /**
52
+ * Random color generators.
53
+ */
54
+ static readonly color: {
55
+ /** Generates a random HEX color. */
56
+ hex(): string;
57
+
58
+ /** Generates a random HEXA color with alpha channel. */
59
+ hexa(): string;
60
+
61
+ /** Generates a random RGB color. */
62
+ rgb(): string;
63
+
64
+ /** Generates a random RGBA color. */
65
+ rgba(): string;
66
+
67
+ /** Generates a random HSL color. */
68
+ hsl(): string;
69
+
70
+ /** Generates a random HSLA color with alpha channel. */
71
+ hsla(): string;
72
+
73
+ /** Generates a random grayscale RGB color. */
74
+ gray(): string;
75
+ };
76
+
77
+ /**
78
+ * Generates arrays of random values.
79
+ */
80
+ static readonly sample: {
81
+
82
+ /**
83
+ * Generates an array of random integers.
84
+ */
85
+ int(n: number, a: number, b?: number): number[];
86
+
87
+ /**
88
+ * Generates an array of random floats.
89
+ */
90
+ float(n: number, a: number, b?: number): number[];
91
+
92
+ /**
93
+ * Generates an array of random characters.
94
+ */
95
+ char(n: number, upper?: boolean): string[];
96
+
97
+ /**
98
+ * Generates an array of random booleans.
99
+ */
100
+ bool(n: number): boolean[];
101
+
102
+ /**
103
+ * Generates an array of random binary values.
104
+ */
105
+ bin(n: number): (0 | 1)[];
106
+
107
+ /**
108
+ * Generates an array of random octal digits.
109
+ */
110
+ oct(n: number): number[];
111
+
112
+ /**
113
+ * Generates an array of random decimal digits.
114
+ */
115
+ dec(n: number): number[];
116
+
117
+ /**
118
+ * Generates an array of random hexadecimal digits.
119
+ */
120
+ hex(n: number): string[];
121
+
122
+ /**
123
+ * Generates arrays of random colors.
124
+ */
125
+ readonly color: {
126
+ hex(n: number): string[];
127
+ hexa(n: number): string[];
128
+ rgb(n: number): string[];
129
+ rgba(n: number): string[];
130
+ hsl(n: number): string[];
131
+ hsla(n: number): string[];
132
+ gray(n: number): string[];
133
+ };
134
+
135
+ /**
136
+ * Generates an array of random choices from a list.
137
+ * @param n Number of generated values.
138
+ * @param choices Available values.
139
+ * @param p Probability distribution for each value.
140
+ */
141
+ choice<T>(
142
+ n: number,
143
+ choices: T[],
144
+ p?: number[]
145
+ ): T[];
146
+ };
147
+
148
+ /**
149
+ * Returns a shuffled copy of an array.
150
+ */
151
+ static shuffle<T>(arr: T[]): T[];
152
+
153
+ /**
154
+ * Randomly selects a value from a list.
155
+ * @param choices Available values.
156
+ * @param p Probability distribution for each value.
157
+ */
158
+ static choice<T>(
159
+ choices?: T[],
160
+ p?: number[]
161
+ ): T;
162
+ }
@@ -0,0 +1,111 @@
1
+ // import { base2base } from "../../../dep/--from-ziko/functions/conversions/index.js";
2
+ import { accum_sum } from "../stats";
3
+
4
+ export class Random {
5
+ static int(a, b){
6
+ return Math.floor(this.float(a, b));
7
+ }
8
+ static float(a, b){
9
+ return b !== undefined
10
+ ? Math.random() * (b - a) + a
11
+ : Math.random() * a;
12
+ }
13
+ static bin(){
14
+ return this.int(2);
15
+ }
16
+ static oct(){
17
+ return this.int(8);
18
+ }
19
+ static dec(){
20
+ return this.int(10);
21
+ }
22
+ // static hex(){
23
+ // return base2base(this.int(16), 10, 16);
24
+ // }
25
+ static char(upperCase = false){
26
+ const i = upperCase
27
+ ? this.int(65, 91)
28
+ : this.int(97, 123);
29
+ return String.fromCharCode(i);
30
+ }
31
+ static bool(){
32
+ return Boolean(this.int(2));
33
+ }
34
+ static get color(){
35
+ return {
36
+ hex : () =>
37
+ `#${this.int(0xffffff).toString(16).padStart(6, '0')}`,
38
+
39
+ hexa : () => {
40
+ const [r,g,b,a] = Array.from(
41
+ {length:4},
42
+ () => this.int(0xff).toString(16).padStart(2,'0')
43
+ );
44
+ return `#${r}${g}${b}${a}`;
45
+ },
46
+ rgb : () => {
47
+ const [r,g,b] = Array.from({length:3}, () => this.int(0xff));
48
+ return `rgb(${r}, ${g}, ${b})`;
49
+ },
50
+ rgba : () => {
51
+ const [r,g,b] = Array.from({length:3}, () => this.int(0xff));
52
+ const a = Math.random().toFixed(2);
53
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
54
+ },
55
+ hsl : () => {
56
+ const h = this.int(360);
57
+ const s = this.int(100);
58
+ const l = this.int(100);
59
+ return `hsl(${h}, ${s}%, ${l}%)`;
60
+ },
61
+ hsla : () => {
62
+ const h = this.int(360);
63
+ const s = this.int(100);
64
+ const l = this.int(100);
65
+ const a = Math.random().toFixed(2);
66
+ return `hsla(${h}, ${s}%, ${l}%, ${a})`;
67
+ },
68
+ gray : () => {
69
+ const g = this.int(0xff);
70
+ return `rgb(${g}, ${g}, ${g})`;
71
+ }
72
+ };
73
+ }
74
+ static get sample(){
75
+ const R = this;
76
+ return {
77
+ int : (n, a, b) => Array.from({length:n}, () => R.int(a, b)),
78
+ float : (n, a, b) => Array.from({length:n}, () => R.float(a, b)),
79
+ char : (n, upper=false) => Array.from({length:n}, () => R.char(upper)),
80
+ bool : n => Array.from({length:n}, () => R.bool()),
81
+ bin : n => Array.from({length:n}, () => R.bin()),
82
+ oct : n => Array.from({length:n}, () => R.oct()),
83
+ dec : n => Array.from({length:n}, () => R.dec()),
84
+ hex : n => Array.from({length:n}, () => R.hex()),
85
+ get color(){
86
+ return {
87
+ hex : n => Array.from({length:n}, () => R.color.hex()),
88
+ hexa : n => Array.from({length:n}, () => R.color.hexa()),
89
+ rgb : n => Array.from({length:n}, () => R.color.rgb()),
90
+ rgba : n => Array.from({length:n}, () => R.color.rgba()),
91
+ hsl : n => Array.from({length:n}, () => R.color.hsl()),
92
+ hsla : n => Array.from({length:n}, () => R.color.hsla()),
93
+ gray : n => Array.from({length:n}, () => R.color.gray())
94
+ };
95
+ },
96
+ choice : (n, choices, p) =>
97
+ Array.from({length:n}, () => R.choice(choices, p))
98
+ };
99
+ }
100
+ static shuffle(arr){
101
+ return [...arr].sort(() => 0.5 - Math.random());
102
+ }
103
+ // static choice(choices = [1,2,3], p = new Array(choices.length).fill(1 / choices.length)){
104
+ // const acc = accum_sum(...p).map(v => v * 100);
105
+ // const pool = new Array(100);
106
+ // pool.fill(choices[0], 0, acc[0]);
107
+ // for(let i=1;i<choices.length;i++)
108
+ // pool.fill(choices[i], acc[i-1], acc[i]);
109
+ // return pool[this.int(pool.length)];
110
+ // }
111
+ }