numz 0.5.0 → 0.6.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 +3 -3
- package/src/complex/helpers/constructor.js +38 -0
- package/src/complex/helpers/index.js +1 -0
- package/src/complex/index.d.ts +231 -0
- package/src/complex/index.js +193 -0
- package/src/index.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "numz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.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.
|
|
29
|
+
"rollup": "^4.63.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ziko": "^1.
|
|
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