numz 0.3.0 → 0.5.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.
Files changed (31) hide show
  1. package/README.md +21 -0
  2. package/docs/astro.config.mjs +8 -7
  3. package/docs/src/assets/logo.png +0 -0
  4. package/docs/src/content/docs/index.mdx +40 -14
  5. package/docs/src/content/docs/philosophy.md +0 -2
  6. package/docs/src/content/docs/reference/typed-matrix/0-intro.md +74 -0
  7. package/docs/src/content/docs/reference/typed-matrix/1-declaration.mdx +65 -0
  8. package/docs/src/content/docs/reference/typed-matrix/accessors.md +5 -0
  9. package/docs/src/content/docs/reference/typed-matrix/arithmetic.md +12 -0
  10. package/docs/src/content/docs/reference/typed-matrix/checkers.md +11 -0
  11. package/docs/src/content/docs/reference/typed-matrix/float-only.md +5 -0
  12. package/docs/src/content/docs/reference/typed-matrix/rehsape.md +12 -0
  13. package/docs/src/styles/custom.css +18 -7
  14. package/package.json +8 -8
  15. package/src/signal/functions/periodic/index.js +3 -3
  16. package/src/signal/functions/pulse/index.js +3 -3
  17. package/src/signal/functions/window/index.js +0 -1
  18. package/src/typed-matrix/abstract/AbstractFloatMatrix.js +43 -0
  19. package/src/typed-matrix/abstract/AbstractIntMatrix.js +6 -0
  20. package/src/typed-matrix/abstract/AbstractTypedMatrix.js +230 -0
  21. package/src/typed-matrix/abstract/helpers/arithmetic.js +33 -0
  22. package/src/typed-matrix/abstract/helpers/constructor.js +37 -0
  23. package/src/typed-matrix/abstract/helpers/det.js +41 -0
  24. package/src/typed-matrix/abstract/helpers/index.js +7 -0
  25. package/src/typed-matrix/abstract/helpers/inv.js +66 -0
  26. package/src/typed-matrix/abstract/helpers/maintain.js +24 -0
  27. package/src/typed-matrix/abstract/helpers/rank.js +49 -0
  28. package/src/typed-matrix/abstract/helpers/stack.js +14 -0
  29. package/src/typed-matrix/abstract/index.js +2 -0
  30. package/src/typed-matrix/index.js +91 -0
  31. package/src/typed-matrix/test.js +29 -0
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?
@@ -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
- label: 'Guides',
41
- items: [
42
- { label: 'Example Guide', slug: 'guides/example' },
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/houston.webp
8
+ file: ../../assets/logo.png
9
9
  actions:
10
- - text: Example Guide
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
- ## Next steps
21
+ ## Features overview
22
22
 
23
23
  <CardGrid stagger>
24
- <Card title="Update content" icon="pencil">
25
- Edit `src/content/docs/index.mdx` to see this page change.
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="Change page layout" icon="document">
28
- Delete `template: splash` in `src/content/docs/index.mdx` to display a
29
- sidebar on this page.
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="Add new content" icon="add-document">
32
- Add Markdown or MDX files to `src/content/docs` to create new pages.
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="Configure your site" icon="setting">
35
- Edit your `sidebar` and other config in `astro.config.mjs`.
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
- <Card title="Read the docs" icon="open-book">
38
- Learn more in [the Starlight Docs](https://starlight.astro.build/).
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,5 @@
1
+ ---
2
+ title: accessors
3
+ description: about
4
+ tableOfContents: false
5
+ ---
@@ -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,11 @@
1
+ ---
2
+ title: checkers
3
+ description: checkers
4
+ # sidebar:
5
+ # order : 0
6
+ tableOfContents: false
7
+ ---
8
+
9
+ Hello world;
10
+
11
+ My name is Zakaria ELALAOUI, There’s nothing impressive here, just skip this part and go straight to the documentation.
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: float only
3
+ description: about
4
+ tableOfContents: false
5
+ ---
@@ -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 : darkblue;
8
- /* text-decoration: 2px underline blueviolet;
9
- text-decoration-skip-ink: auto; */
10
- /* border-bottom: 1px red solid; */
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
- /* strong{
20
- color: blueviolet;
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.0",
3
+ "version": "0.5.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
- "zikojs-addons"
21
+ "math"
22
22
  ],
23
23
  "license": "MIT",
24
24
  "devDependencies": {
25
- "@rollup/plugin-commonjs": "^28.0.0",
26
- "@rollup/plugin-node-resolve": "^15.3.0",
27
- "@rollup/plugin-terser": "^0.4.4",
28
- "cross-env": "^7.0.3",
29
- "rollup": "^4.24.0"
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.62.5"
30
30
  },
31
31
  "dependencies": {
32
- "ziko": "^0.57.0"
32
+ "ziko": "^1.8.0"
33
33
  }
34
34
  }
@@ -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 triangle = (t, T = 1, A = 1, duty = 0.5, t0 = 0) => {
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 sawtoothPeriodic = (t, T = 1, A = 1, duty = 1, t0 = 0) => {
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 pulseTrain = (t, T = 1, width = 0.5, A = 1, t0 = 0) => {
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 rampe = (t, t0 = 0, A = 1) => {
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 gaussian = (t, t0 = 0, sigma = 1, A = 1) => {
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 expPulse = (t, t0 = 0, alpha = 1, A = 1) => {
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);
@@ -109,7 +109,6 @@ export const gaussian_window = (N, sigma = 0.4, ArrayType = Float64Array) => {
109
109
  return w;
110
110
  };
111
111
 
112
-
113
112
  const sinc = (x) => x === 0 ? 1 : sin(PI * x) / (PI * x);
114
113
  export const lanczos_window = (N, ArrayType = Float64Array) => {
115
114
  const w = new ArrayType(N);
@@ -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,6 @@
1
+ import { AbstractTypedMatrix } from "./AbstractTypedMatrix.js";
2
+ export class AbstractIntMatrix extends AbstractTypedMatrix{
3
+ constructor(rows, cols, data, type){
4
+ super(rows, cols, data, type)
5
+ }
6
+ }
@@ -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,7 @@
1
+ export * from './constructor.js'
2
+ export * from './maintain.js'
3
+ export * from './stack.js'
4
+ export * from './arithmetic.js'
5
+ export * from './det.js'
6
+ export * from './inv.js'
7
+ export * from './rank.js'
@@ -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,2 @@
1
+ export * from './AbstractIntMatrix.js'
2
+ export * from './AbstractFloatMatrix.js'
@@ -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))