numz 0.4.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/docs/astro.config.mjs +8 -7
- package/docs/src/assets/logo.png +0 -0
- package/docs/src/content/docs/index.mdx +40 -14
- package/docs/src/content/docs/philosophy.md +0 -2
- package/docs/src/content/docs/reference/typed-matrix/0-intro.md +74 -0
- package/docs/src/content/docs/reference/typed-matrix/1-declaration.mdx +65 -0
- package/docs/src/content/docs/reference/typed-matrix/accessors.md +5 -0
- package/docs/src/content/docs/reference/typed-matrix/arithmetic.md +12 -0
- package/docs/src/content/docs/reference/typed-matrix/checkers.md +11 -0
- package/docs/src/content/docs/reference/typed-matrix/float-only.md +5 -0
- package/docs/src/content/docs/reference/typed-matrix/rehsape.md +12 -0
- package/docs/src/styles/custom.css +18 -7
- package/package.json +8 -8
- 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/docs/astro.config.mjs
CHANGED
|
@@ -6,8 +6,9 @@ import starlightThemeObsidian from 'starlight-theme-obsidian'
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const referenceModules = [
|
|
9
|
+
'typed-matrix',
|
|
9
10
|
'functions',
|
|
10
|
-
'matrix',
|
|
11
|
+
// 'matrix',
|
|
11
12
|
'complex',
|
|
12
13
|
'signal',
|
|
13
14
|
'stats',
|
|
@@ -36,12 +37,12 @@ export default defineConfig({
|
|
|
36
37
|
href: 'https://github.com/zakarialaoui10/numz.git'
|
|
37
38
|
}],
|
|
38
39
|
sidebar: [
|
|
39
|
-
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
40
|
+
// {
|
|
41
|
+
// label: 'Guides',
|
|
42
|
+
// items: [
|
|
43
|
+
// { label: 'Example Guide', slug: 'guides/example' },
|
|
44
|
+
// ],
|
|
45
|
+
// },
|
|
45
46
|
{
|
|
46
47
|
label : 'philosophy',
|
|
47
48
|
slug : 'philosophy'
|
|
Binary file
|
|
@@ -5,9 +5,9 @@ template: splash # Remove or comment out this line to display the site sidebar o
|
|
|
5
5
|
hero:
|
|
6
6
|
tagline: Scientific computation with zikojs
|
|
7
7
|
image:
|
|
8
|
-
file: ../../assets/
|
|
8
|
+
file: ../../assets/logo.png
|
|
9
9
|
actions:
|
|
10
|
-
- text:
|
|
10
|
+
- text: Read the docs
|
|
11
11
|
link: /guides/example/
|
|
12
12
|
icon: right-arrow
|
|
13
13
|
- text: Read Zikojs docs
|
|
@@ -18,23 +18,49 @@ hero:
|
|
|
18
18
|
|
|
19
19
|
import { Card, CardGrid } from '@astrojs/starlight/components';
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Features overview
|
|
22
22
|
|
|
23
23
|
<CardGrid stagger>
|
|
24
|
-
<Card title="
|
|
25
|
-
|
|
24
|
+
<Card title="Extended Array Programming">
|
|
25
|
+
Numz brings NumPy-like array programming to JavaScript with native, flexible data structures.
|
|
26
|
+
- Preserves original structure and types
|
|
27
|
+
- No manual loops or recursion required
|
|
26
28
|
</Card>
|
|
27
|
-
<Card title="
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
<Card title="Built on the top of zikojs">
|
|
30
|
+
Numz fully supports and extends core **ZikoJS data types**.
|
|
31
|
+
- Extend mathematical utilities and functions
|
|
32
|
+
- Supoorts :
|
|
33
|
+
- Complex numbers
|
|
34
|
+
- Matrices
|
|
35
|
+
- ...
|
|
30
36
|
</Card>
|
|
31
|
-
<Card title="
|
|
32
|
-
|
|
37
|
+
<Card title="Typed Matrices">
|
|
38
|
+
High-performance matrix types backed by TypedArrays.
|
|
39
|
+
- Arithmetic operations
|
|
40
|
+
- Reshape
|
|
41
|
+
- Serialization / deserialization
|
|
42
|
+
- ...
|
|
33
43
|
</Card>
|
|
34
|
-
<Card title="
|
|
35
|
-
|
|
44
|
+
<Card title="Signal Processing">
|
|
45
|
+
Built-in tools for discrete signals and DSP :
|
|
46
|
+
- Sequences
|
|
47
|
+
- Pulses
|
|
48
|
+
- Windows
|
|
49
|
+
- Convolution
|
|
50
|
+
- FFT
|
|
51
|
+
- ...
|
|
36
52
|
</Card>
|
|
37
|
-
|
|
38
|
-
|
|
53
|
+
<Card title="Advanced Statistics Utilities">
|
|
54
|
+
A comprehensive statistics toolbox designed for large datasets and numerical analysis.
|
|
55
|
+
|
|
56
|
+
- Descriptive statistics (mean, median, mode, variance, std)
|
|
57
|
+
- Reductions (min, max, sum, product)
|
|
58
|
+
- Percentiles and quantiles
|
|
59
|
+
- Covariance and correlation
|
|
60
|
+
- Distributions
|
|
61
|
+
</Card>
|
|
62
|
+
<Card title="Modular & Composable">
|
|
63
|
+
- Tree-shakable modules
|
|
64
|
+
- Easy integration with other libraries
|
|
39
65
|
</Card>
|
|
40
66
|
</CardGrid>
|
|
@@ -11,5 +11,3 @@ It is inspired by:
|
|
|
11
11
|
- **MATLAB**
|
|
12
12
|
|
|
13
13
|
Numz guarantees a **layered, shape-safe, function-first numerical computing model**, designed to scale naturally from scalars to tensors while preserving mathematical correctness and clarity.
|
|
14
|
-
|
|
15
|
-
<!-- Numz is a layered, shape-safe, function-first numerical computing library that brings true array programming and scientific mathematics to JavaScript, built on the top of [Zikojs](). -->
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Introduction
|
|
3
|
+
description: Typed matrices overview
|
|
4
|
+
tableOfContents: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Typed Matrices** in **Numz** are an extension of **Zikojs Matrix**, designed to provide
|
|
8
|
+
**high-performance**, **memory-efficient**, and **type-safe** matrix operations.
|
|
9
|
+
|
|
10
|
+
Unlike regular matrices that rely on standard JavaScript arrays, Typed Matrices are
|
|
11
|
+
backed by **TypedArray** structures, enabling contiguous memory layout and faster
|
|
12
|
+
numerical computation.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## TypedMatrix Variants
|
|
17
|
+
|
|
18
|
+
Numz provides multiple TypedMatrix classes, each mapped to a specific
|
|
19
|
+
JavaScript `TypedArray` implementation.
|
|
20
|
+
|
|
21
|
+
### Floating-Point Matrices
|
|
22
|
+
|
|
23
|
+
| Class | Backing Type | Precision | Use case |
|
|
24
|
+
|-------------|---------------|-----------|----------|
|
|
25
|
+
| `F16Matrix` | `Float16Array`| 16-bit | ML, GPU-style data |
|
|
26
|
+
| `F32Matrix` | `Float32Array`| 32-bit | GPU, graphics, signals |
|
|
27
|
+
| `F64Matrix` | `Float64Array`| 64-bit | Scientific computing |
|
|
28
|
+
|
|
29
|
+
### Integer Matrices
|
|
30
|
+
|
|
31
|
+
| Class | Backing Type | Range | Use case |
|
|
32
|
+
|-------------|--------------------|-------|----------|
|
|
33
|
+
| `I8Matrix` | `Int8Array` | −128 → 127 | Compact data |
|
|
34
|
+
| `U8Matrix` | `Uint8Array` | 0 → 255 | Images, buffers |
|
|
35
|
+
| `I16Matrix` | `Int16Array` | −32K → 32K | DSP, audio |
|
|
36
|
+
| `U16Matrix` | `Uint16Array` | 0 → 65K | Indexing |
|
|
37
|
+
| `I32Matrix` | `Int32Array` | 32-bit | General integers |
|
|
38
|
+
| `U32Matrix` | `Uint32Array` | 32-bit | Large indices |
|
|
39
|
+
|
|
40
|
+
### Big Integer Matrices
|
|
41
|
+
|
|
42
|
+
| Class | Backing Type | Notes |
|
|
43
|
+
|--------------|----------------------|-------|
|
|
44
|
+
| `BI64Matrix` | `BigInt64Array` | Requires `BigInt` |
|
|
45
|
+
| `BU64Matrix` | `BigUint64Array` | Large integer arithmetic |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Example
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
import { F64Matrix } from 'numz';
|
|
53
|
+
|
|
54
|
+
const A = new F64Matrix(2, 2, [
|
|
55
|
+
1, 2,
|
|
56
|
+
3, 4
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
A.add(2).mul(3);
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
### Note
|
|
65
|
+
> During the construction phase, the provided data is accepted as a regular
|
|
66
|
+
JavaScript array only as a temporary input.
|
|
67
|
+
Internally, Numz copies the values into a TypedArray (``Float64Array`` in this case),
|
|
68
|
+
and the original array is discarded and no longer used.
|
|
69
|
+
|
|
70
|
+
> This guarantees:
|
|
71
|
+
- contiguous memory layout
|
|
72
|
+
- predictable numeric type
|
|
73
|
+
- better performance for subsequent operations
|
|
74
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: declaration
|
|
3
|
+
description: about
|
|
4
|
+
tableOfContents: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
import { Tabs, TabItem } from '@astrojs/starlight/components';
|
|
8
|
+
|
|
9
|
+
## Matrix Constructor
|
|
10
|
+
|
|
11
|
+
<Tabs>
|
|
12
|
+
<TabItem label="Class Constructor">
|
|
13
|
+
- `new [Type]Matrix(r, c, arr: (number)[])` : Creates an `r × c` matrix using the provided **array of numbers**.
|
|
14
|
+
- `new [Type]Matrix(m : [Type]Matrix)` : Creates a **copy** of an existing `[Type]Matrix`.
|
|
15
|
+
- `new [Type]Matrix(arr : (number)[][])` : Creates a matrix from a **2-dimensional array**. The number of rows and columns
|
|
16
|
+
is inferred from the array shape.
|
|
17
|
+
### Example
|
|
18
|
+
```js
|
|
19
|
+
const M1 = new I8Matrix(3, 3, [1, 2, 3, -4, -5, 6, 7, 8, 9])
|
|
20
|
+
const M2 = new I8Matrix(M1)
|
|
21
|
+
const M3 = new F32Matrix([
|
|
22
|
+
[1.3, 1.2],
|
|
23
|
+
[-3.7, 2.75]
|
|
24
|
+
])
|
|
25
|
+
```
|
|
26
|
+
</TabItem>
|
|
27
|
+
<TabItem label="Functional Constructors">
|
|
28
|
+
- `matrix_[type](r, c, arr: (number)[])` : Functional version of the constructor that creates an `r × c` matrix from a flat array.
|
|
29
|
+
|
|
30
|
+
- `matrix_[type](m : [Type]Matrix)` : Functional copy of an existing `[Type]Matrix`.
|
|
31
|
+
- `matrix_[type](arr : (number)[])` : Functional constructor that creates a matrix from a **2-dimensional array**.
|
|
32
|
+
### Example
|
|
33
|
+
```js
|
|
34
|
+
const M1 = matrix_i8(3, 3, [1, 2, 3, -4, -5, 6, 7, 8, 9])
|
|
35
|
+
const M2 = matrix_i8(M1)
|
|
36
|
+
const M3 = matrix_f32([
|
|
37
|
+
[1.3, 1.2],
|
|
38
|
+
[-3.7, 2.75]
|
|
39
|
+
])
|
|
40
|
+
```
|
|
41
|
+
</TabItem>
|
|
42
|
+
</Tabs>
|
|
43
|
+
|
|
44
|
+
## Static Factory Methods
|
|
45
|
+
|
|
46
|
+
All TypedMatrix classes (`F16Matrix`, `F32Matrix`, `F64Matrix`, `I8Matrix`, etc.) provide
|
|
47
|
+
the following **static factory methods** for convenient construction:
|
|
48
|
+
|
|
49
|
+
- `[Type]Matrix.zeros(r, c)` : Creates an `r × c` matrix filled with zeros.
|
|
50
|
+
- `[Type]Matrix.ones(r, c)` : Creates an `r × c` matrix filled with ones.
|
|
51
|
+
- `[Type]Matrix.eye(n)` : Creates an `n × n` identity matrix (ones on the diagonal, zeros elsewhere).
|
|
52
|
+
- `[Type]Matrix.nums(r, c, num : number)` : Creates an r × c matrix filled with the specified value num
|
|
53
|
+
- `Matrix.random.int(min, max)`
|
|
54
|
+
- `Matrix.random.float(min, max)`
|
|
55
|
+
|
|
56
|
+
### Example
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const M1 = F64Matrix.zeros(2,7)
|
|
60
|
+
const M2 = U32Matrix.ones(4,5)
|
|
61
|
+
const M3 = I32Matrix.eye(4)
|
|
62
|
+
const M4 = F32Matrix.nums(3, 3, -1.25)
|
|
63
|
+
const M5 = I16Matrix.random.int(-7, 7)
|
|
64
|
+
const M6 = F32Matrix.random.float(-7, 7)
|
|
65
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: arithmetic
|
|
3
|
+
description: about
|
|
4
|
+
tableOfContents: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
- `.add(...m: (Matrix | number)[])` : Element-wise addition with one or more matrices or scalars.
|
|
8
|
+
- `.sub(...m: (Matrix | number)[])` : Element-wise subtraction with one or more matrices or scalars.
|
|
9
|
+
- `.mul(...m: (Matrix | number)[])` : Element-wise multiplication with one or more matrices or scalars.
|
|
10
|
+
- `.div(...m: (Matrix | number)[])` : Element-wise division with one or more matrices or scalars.
|
|
11
|
+
- `.modulo(...m: (Matrix | number)[])` : Element-wise modulo operation with one or more matrices or scalars.
|
|
12
|
+
- `.dot(m: Matrix)` : Matrix multiplication (linear algebra dot product).
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: reshape
|
|
3
|
+
description: reshape
|
|
4
|
+
tableOfContents: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
- `.reshape(r, c)` : Reshapes the matrix to `(r × c)` without changing the total number of elements.
|
|
8
|
+
- `.reshape(r0, c0, r1, c1)` :
|
|
9
|
+
- `.hstack(...matrices: Matrix[])` : Horizontally stacks matrices by columns (same number of rows required).
|
|
10
|
+
- `.vstack(...matrices: Matrix[])` : Vertically stacks matrices by rows (same number of columns required).
|
|
11
|
+
- `.hqueue(...matrices: Matrix[])` : Appends matrices horizontally, preserving row order (row-wise concatenation).
|
|
12
|
+
- `.vqueue(...matrices: Matrix[])` : Appends matrices vertically, preserving column order (column-wise concatenation).
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
--sl-content-width: 50rem;
|
|
3
3
|
--sl-text-5xl: 3.5rem;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
5
|
h1{
|
|
7
|
-
color :
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
color : var(--sl-color-accent-high);
|
|
7
|
+
}
|
|
8
|
+
h2{
|
|
9
|
+
color : var(--slsg-node-color-7);
|
|
10
|
+
}
|
|
11
|
+
h3{
|
|
12
|
+
color : var(--slsg-node-color-8);
|
|
13
|
+
|
|
11
14
|
}
|
|
15
|
+
|
|
16
|
+
/* a, summary span{
|
|
17
|
+
color: var(--sl-color-accent-lows);
|
|
18
|
+
} */
|
|
12
19
|
p a{
|
|
13
20
|
color: blueviolet;
|
|
14
21
|
text-decoration: none;
|
|
@@ -16,6 +23,10 @@ p a{
|
|
|
16
23
|
text-decoration: underline;
|
|
17
24
|
}
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
color:
|
|
26
|
+
strong{
|
|
27
|
+
color: var(--slsg-node-color-8);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* #starlight__sidebar li, .group-label span{
|
|
31
|
+
color: gray;
|
|
21
32
|
} */
|
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",
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
"author": "zakaria elalaoui",
|
|
19
19
|
"keywords": [
|
|
20
20
|
"zikojs",
|
|
21
|
-
"
|
|
21
|
+
"math"
|
|
22
22
|
],
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@rollup/plugin-commonjs": "^
|
|
26
|
-
"@rollup/plugin-node-resolve": "^
|
|
27
|
-
"@rollup/plugin-terser": "^0.
|
|
28
|
-
"cross-env": "^
|
|
29
|
-
"rollup": "^4.
|
|
25
|
+
"@rollup/plugin-commonjs": "^29.0.3",
|
|
26
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
27
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
28
|
+
"cross-env": "^10.1.0",
|
|
29
|
+
"rollup": "^4.63.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ziko": "^
|
|
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