numpy-ts 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Nicolas Dupont
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # numpy-ts
2
+
3
+ Complete NumPy implementation for TypeScript and JavaScript
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
6
+ ![Under Construction](https://img.shields.io/badge/Under%20Construction-red)
7
+
8
+ > [!WARNING]
9
+ > This project is under construction and is currently unstable. Expect breaking changes.
10
+
11
+ ---
12
+
13
+ ## What is numpy-ts?
14
+
15
+ A complete, functionally-equivalent implementation of NumPy 2.0+ for the JavaScript ecosystem. (At least that's the goal!)
16
+
17
+ ### Goals
18
+
19
+ - ✅ **100% NumPy 2.0+ API** - All 800+ functions
20
+ - ✅ **Full Type Safety** - Complete TypeScript definitions
21
+ - ✅ **Cross-Platform** - Node.js and browsers
22
+ - ✅ **File Compatibility** - Read/write .npy and .npz files
23
+ - ✅ **Correctness First** - Validated against Python NumPy
24
+
25
+ ### Not Goals
26
+
27
+ - ❌ Matching Python NumPy's exact performance (initially)
28
+ - ❌ C API compatibility
29
+ - ❌ Legacy NumPy 1.x deprecated functions
30
+
31
+ ---
32
+
33
+ ## Quick Example
34
+
35
+ ```typescript
36
+ import * as np from 'numpy-ts';
37
+
38
+ // Create arrays (default float64 dtype)
39
+ const A = np.array([[1, 2], [3, 4]]);
40
+ const B = np.zeros([2, 2]);
41
+
42
+ // Create arrays with specific dtypes (11 types supported)
43
+ const intArr = np.ones([3, 3], 'int32');
44
+ const floatArr = np.arange(0, 10, 1, 'float32');
45
+ const boolArr = np.array([1, 0, 1], 'bool');
46
+ const bigIntArr = np.array([1n, 2n, 3n], 'int64'); // BigInt support
47
+
48
+ // All operations preserve dtype or follow NumPy promotion rules
49
+ const result = intArr.add(5); // Stays int32
50
+ const promoted = intArr.add(floatArr); // Promotes to float32
51
+
52
+ // Matrix operations
53
+ const C = A.matmul(B);
54
+ const eigenvalues = np.linalg.eig(A);
55
+
56
+ // Slicing (string-based syntax)
57
+ const row = A.slice('0', ':'); // First row
58
+ const col = A.col(1); // Second column
59
+
60
+ // Broadcasting (fully implemented!)
61
+ const scaled = A.add(5).multiply(2);
62
+
63
+ // Advanced broadcasting examples:
64
+ const row = np.array([1, 2, 3, 4]); // (4,)
65
+ const col = np.array([[1], [2], [3]]); // (3, 1)
66
+ const result = col.multiply(row); // (3, 4) via broadcasting!
67
+
68
+ // Reductions
69
+ const total = A.sum(); // Sum all elements
70
+ const columnMeans = A.mean(0); // Mean along axis 0
71
+ const rowMaxs = A.max(1, true); // Max along axis 1, keep dims
72
+
73
+ // Comparisons (return boolean arrays as uint8)
74
+ const mask = A.greater(5); // Element-wise A > 5
75
+ const equal = A.equal(B); // Element-wise A == B
76
+ const inRange = A.greater_equal(0); // A >= 0
77
+
78
+ // Tolerance comparisons (for floating point)
79
+ const close = A.isclose(B); // Element-wise closeness
80
+ const allClose = A.allclose(B); // True if all elements close
81
+
82
+ // Reshape operations (view vs copy semantics)
83
+ const reshaped = A.reshape(4, 1); // View if C-contiguous, copy otherwise
84
+ const flat = A.flatten(); // Always returns a copy
85
+ const ravel = A.ravel(); // View if C-contiguous, copy otherwise
86
+ const transposed = A.transpose(); // Always returns a view
87
+ const squeezed = A.squeeze(); // Always returns a view
88
+ const expanded = A.expand_dims(0); // Always returns a view
89
+
90
+ // View tracking (NumPy-compatible)
91
+ const view = A.slice('0:2', '0:2');
92
+ console.log(view.base === A); // true - view tracks base array
93
+ console.log(view.flags.OWNDATA); // false - doesn't own data
94
+ console.log(A.flags.OWNDATA); // true - owns data
95
+
96
+ // Memory layout flags
97
+ console.log(A.flags.C_CONTIGUOUS); // true - C-order (row-major)
98
+ console.log(A.flags.F_CONTIGUOUS); // false - not Fortran-order
99
+
100
+ // Random
101
+ const random = np.random.randn([100, 100]);
102
+
103
+ // I/O (Node.js)
104
+ np.save('matrix.npy', A);
105
+ const loaded = np.load('matrix.npy');
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Architecture
111
+
112
+ ```
113
+ ┌────────────────────────────────┐
114
+ │ NumPy-Compatible API │
115
+ └────────────┬───────────────────┘
116
+
117
+ ┌────────────┴───────────────────┐
118
+ │ NDArray (Memory & Views) │
119
+ │ Broadcasting, Slicing, DTypes │
120
+ └────────────┬───────────────────┘
121
+
122
+ ┌────────────┴───────────────────┐
123
+ │ Computational Backend │
124
+ │ @stdlib (BLAS/LAPACK) │
125
+ └────────────────────────────────┘
126
+ ```
127
+
128
+ **We build**: NumPy API, NDArray class, broadcasting, slicing, view tracking
129
+
130
+ **We use**: @stdlib for proven numerical computations
131
+
132
+ ---
133
+
134
+ ## Key Features
135
+
136
+ ### Comprehensive NumPy API
137
+ - **Array creation**: `zeros`, `ones`, `arange`, `linspace` (all support dtype parameter)
138
+ - **Arithmetic operations**: `add`, `subtract`, `multiply`, `divide` with broadcasting
139
+ - **Linear algebra**: `matmul` (using optimized BLAS)
140
+ - **Reductions**: `sum`, `mean`, `std`, `min`, `max` with axis support
141
+ - **DTypes**: 11 types supported (float32/64, int8/16/32/64, uint8/16/32/64, bool)
142
+ - Full dtype preservation across operations
143
+ - NumPy-compatible type promotion
144
+ - BigInt support for int64/uint64
145
+ - **View tracking**: `base` attribute tracks view relationships
146
+ - **Memory flags**: `C_CONTIGUOUS`, `F_CONTIGUOUS`, `OWNDATA`
147
+ - **Comparisons**: `greater`, `less`, `equal`, `isclose`, `allclose`
148
+ - **Reshaping**: `reshape`, `flatten`, `ravel`, `transpose`, `squeeze`, `expand_dims`
149
+
150
+ ### TypeScript Native
151
+ ```typescript
152
+ // Full type inference
153
+ const arr = np.zeros([3, 4]); // Type: NDArray<Float64>
154
+ arr.shape; // Type: readonly [3, 4]
155
+ arr.sum(); // Type: number
156
+
157
+ // Type-safe slicing
158
+ arr.slice('0:2', ':'); // Returns NDArray
159
+ arr.get([0, 1]); // Returns number
160
+ ```
161
+
162
+ ### Slicing Syntax
163
+
164
+ Since TypeScript doesn't support Python's `arr[0:5, :]` syntax, we use strings:
165
+
166
+ ```typescript
167
+ // String-based (primary)
168
+ arr.slice('0:5', '1:3'); // arr[0:5, 1:3]
169
+ arr.slice(':', '-1'); // arr[:, -1]
170
+ arr.slice('::2'); // arr[::2]
171
+
172
+ // Convenience helpers
173
+ arr.row(0); // arr[0, :]
174
+ arr.col(2); // arr[:, 2]
175
+ arr.rows(0, 5); // arr[0:5, :]
176
+ arr.cols(1, 3); // arr[:, 1:3]
177
+ ```
178
+
179
+ ### Broadcasting
180
+
181
+ Automatic NumPy-style broadcasting:
182
+
183
+ ```typescript
184
+ const a = np.ones([3, 4]);
185
+ const b = np.arange(4);
186
+ const c = a.add(b); // (3, 4) + (4,) → (3, 4)
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Installation (Future)
192
+
193
+ ```bash
194
+ npm install numpy-ts
195
+ ```
196
+
197
+ ### Node.js
198
+ ```typescript
199
+ import * as np from 'numpy-ts/node';
200
+ ```
201
+
202
+ ### Browser
203
+ ```typescript
204
+ import * as np from 'numpy-ts/browser';
205
+ ```
206
+
207
+ ---
208
+
209
+ ## Development Status
210
+
211
+ ### Phase 0: Project Setup ✅ COMPLETE
212
+ - [x] Package configuration
213
+ - [x] TypeScript setup
214
+ - [x] Build system (esbuild)
215
+ - [x] Test framework (Vitest)
216
+ - [x] Documentation consolidated
217
+ - [x] Linting (ESLint + Prettier)
218
+ - [x] @stdlib investigation and integration
219
+ - [x] First working implementation
220
+
221
+
222
+ ### Phase 1: Core Foundation ✅ **COMPLETE**
223
+ - [x] NDArray wrapper class (using @stdlib/ndarray)
224
+ - [x] Array creation: `zeros()`, `ones()`, `array()`, `arange()`, `linspace()`, `eye()`
225
+ - [x] Matrix operations: `matmul()` using optimized BLAS
226
+ - [x] Properties: `shape`, `ndim`, `size`, `dtype`, `data`, `strides`
227
+ - [x] View tracking: `base` attribute, `flags` property
228
+ - [x] Memory flags: `C_CONTIGUOUS`, `F_CONTIGUOUS`, `OWNDATA`
229
+ - [x] Basic arithmetic: `add()`, `subtract()`, `multiply()`, `divide()` with dtype preservation
230
+ - [x] Broadcasting ✅ **COMPLETE** (fully integrated into all operations)
231
+ - [x] String-based slicing ✅ **COMPLETE** (`arr.slice('0:5', ':')`, `row()`, `col()`, etc.)
232
+ - [x] Reductions with axis support ✅ **COMPLETE** (`sum(axis, keepdims)`, `mean()`, `max()`, `min()`)
233
+ - [x] Comparison operations ✅ **COMPLETE** (`greater()`, `less()`, `equal()`, `isclose()`, `allclose()`)
234
+ - [x] Reshape operations ✅ **COMPLETE** (`reshape()`, `flatten()`, `ravel()`, `transpose()`, `squeeze()`, `expand_dims()`)
235
+ - [x] DType system ✅ **COMPLETE** (11 types: float32/64, int8/16/32/64, uint8/16/32/64, bool)
236
+ - Full dtype preservation
237
+ - NumPy-compatible promotion rules
238
+ - BigInt support for int64/uint64
239
+ - [x] Testing ✅ **748/750 tests passing (99.7%)**
240
+ - Unit tests for all operations
241
+ - NumPy validation tests (cross-checked against Python NumPy 2.3.3)
242
+ - Edge case validation (overflow, underflow, special values)
243
+
244
+ ### Phase 2: Benchmarks & CI/CD
245
+ - [X] CI/CD (GitHub Actions)
246
+ - [X] PR workflow
247
+ - [X] Publish workflow
248
+ - [ ] Implement benchmarks
249
+ - [ ] Regression (vs. previous runs)
250
+ - [X] Comparison against Python NumPy
251
+ - [ ] Automated in CI/CD
252
+
253
+ ### Phase 3: Essential Operations
254
+ - [ ] Matrix operations (using @stdlib BLAS)
255
+ - [ ] Linear algebra (using @stdlib LAPACK)
256
+ - [ ] Reductions with axis support
257
+ - [ ] Mathematical functions
258
+ - [ ] Comparison operations
259
+ - [ ] dtype consistency testing
260
+
261
+ ### Phase 4: Extended Features
262
+ - [ ] Random number generation
263
+ - [ ] FFT operations (using fft.js)
264
+ - [ ] I/O operations (.npy/.npz)
265
+ - [ ] Advanced indexing
266
+ - [ ] Complex numbers, datetime
267
+ - [ ] Optional WASM mode
268
+
269
+ See [API-REFERENCE.md](./docs/API-REFERENCE.md) for complete function checklist.
270
+
271
+ ---
272
+
273
+ ## Documentation
274
+
275
+ ### User Documentation
276
+ - [API-REFERENCE.md](./docs/API-REFERENCE.md) - Complete API checklist
277
+
278
+ ### Developer Documentation
279
+ - [ARCHITECTURE.md](./docs/ARCHITECTURE.md) - Design and implementation details
280
+ - [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) - How to add tests (unit, validation, benchmarks)
281
+ - [IMPLEMENTATION-NOTES.md](./docs/IMPLEMENTATION-NOTES.md) - Development notes and decisions
282
+ - [benchmarks/README.md](./benchmarks/README.md) - Performance benchmarking guide
283
+
284
+ ---
285
+
286
+ ## Testing
287
+
288
+ Two-tier testing strategy:
289
+
290
+ 1. **Unit Tests** - Test our implementation
291
+ 2. **Python Comparison** - Validate against NumPy
292
+
293
+ ```typescript
294
+ // Unit test
295
+ it('creates 2D array of zeros', () => {
296
+ const arr = np.zeros([2, 3]);
297
+ expect(arr.shape).toEqual([2, 3]);
298
+ expect(arr.sum()).toBe(0);
299
+ });
300
+
301
+ // NumPy validation (cross-checked against Python)
302
+ it('matmul matches NumPy', () => {
303
+ const A = np.array([[1, 2], [3, 4]]);
304
+ const B = np.array([[5, 6], [7, 8]]);
305
+ const result = A.matmul(B);
306
+
307
+ const npResult = runNumPy(`
308
+ A = np.array([[1, 2], [3, 4]])
309
+ B = np.array([[5, 6], [7, 8]])
310
+ result = A @ B
311
+ `);
312
+
313
+ expect(result.toArray()).toEqual(npResult);
314
+ });
315
+
316
+ // Edge case validation
317
+ it('int8 overflow wraps like NumPy', () => {
318
+ const arr = np.array([127], 'int8');
319
+ const result = arr.add(1);
320
+ expect(result.get([0])).toBe(-128); // Wraps like NumPy
321
+ });
322
+ ```
323
+
324
+ ---
325
+
326
+ ## Design Decisions
327
+
328
+ ### 1. BigInt for int64/uint64
329
+ Exact representation over convenience. Different type but no precision loss.
330
+
331
+ ### 2. No Complex Number Support (for now)
332
+ Removed in favor of simplicity and focus on core numeric types. Can be added back if there's demand.
333
+
334
+ ### 3. String-Based Slicing
335
+ `arr.slice('0:5', ':')` instead of `arr[0:5, :]` - TypeScript limitation, Pythonic compromise.
336
+
337
+ ### 4. View Tracking
338
+ Track base array for views with `base` attribute. Enables zero-copy optimizations and matches NumPy semantics.
339
+
340
+ ### 5. @stdlib Under the Hood
341
+ Use battle-tested BLAS/LAPACK implementations. Focus on API, not reimplementing algorithms.
342
+
343
+ ### 6. Correctness First
344
+ Validate everything against Python NumPy before optimizing. WASM/SIMD later.
345
+
346
+ See [ARCHITECTURE.md](./docs/ARCHITECTURE.md) for full rationale.
347
+
348
+ ---
349
+
350
+ ## Contributing
351
+
352
+ Project is in early development. We welcome contributions!
353
+
354
+ ### Setup
355
+
356
+ ```bash
357
+ git clone https://github.com/dupontcyborg/numpy-ts.git
358
+ cd numpy-ts
359
+ npm install
360
+ npm test
361
+ ```
362
+
363
+ ### Adding New Features
364
+
365
+ 1. Pick a function from [API-REFERENCE.md](./docs/API-REFERENCE.md)
366
+ 2. Follow the [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) to add:
367
+ - Implementation in `src/`
368
+ - Unit tests in `tests/unit/`
369
+ - NumPy validation tests in `tests/validation/`
370
+ - Performance benchmarks in `benchmarks/`
371
+ 3. Ensure all tests pass: `npm test`
372
+ 4. Run benchmarks: `npm run bench:quick`
373
+ 5. Submit a pull request
374
+
375
+ See [TESTING-GUIDE.md](./docs/TESTING-GUIDE.md) for detailed instructions on adding tests.
376
+
377
+ ---
378
+
379
+ ## Comparison with Alternatives
380
+
381
+ | Feature | numpy-ts | numjs | ndarray | TensorFlow.js |
382
+ |---------|----------|-------|---------|---------------|
383
+ | API Coverage | 100% NumPy | ~20% | Different | ML-focused |
384
+ | TypeScript | Native | Partial | No | Yes |
385
+ | .npy files | Yes | No | No | No |
386
+ | Python-compatible | Yes | Mostly | No | No |
387
+ | Size | TBD | Small | Tiny | Large |
388
+
389
+ ---
390
+
391
+ ## Benchmarking
392
+
393
+ Compare numpy-ts performance against Python NumPy:
394
+
395
+ ```bash
396
+ # Run quick benchmarks (~1-2 min)
397
+ npm run bench:quick
398
+
399
+ # Run standard benchmarks (~5-10 min)
400
+ npm run bench
401
+
402
+ # Run comprehensive benchmarks (~30-60 min)
403
+ npm run bench:full
404
+
405
+ # View interactive HTML report
406
+ npm run bench:view
407
+ ```
408
+
409
+ ### Performance Overview
410
+
411
+ ![Benchmark Results](./benchmarks/results/plots/latest.png)
412
+
413
+ See [benchmarks/README.md](./benchmarks/README.md) for detailed benchmarking guide.
414
+
415
+ ---
416
+
417
+ ## Performance Expectations
418
+
419
+ **v1.0** (Pure JS + @stdlib):
420
+ - 10-100x slower than NumPy - acceptable for correctness focus
421
+
422
+ **v2.0** (Selective WASM):
423
+ - 2-20x slower - optimized bottlenecks only
424
+
425
+ **v3.0** (Advanced):
426
+ - 1-10x slower - SIMD, GPU for specific operations
427
+
428
+ Focus is correctness and completeness first, then performance.
429
+
430
+ ---
431
+
432
+ ## License
433
+
434
+ [MIT License](./LICENSE) - Copyright (c) 2025 Nicolas Dupont
435
+
436
+ ---
437
+
438
+ ## Links
439
+
440
+ - **Documentation**: [`docs/`](./docs)
441
+ - **NumPy**: https://numpy.org/
442
+ - **@stdlib**: https://stdlib.io/
443
+ - **Issues**: https://github.com/dupontcyborg/numpy-ts/issues
444
+
445
+ ---
446
+
447
+ **Ready to bring NumPy to JavaScript!** ⭐