starlight-numera 1.0.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/README.md +150 -0
- package/dist/index.cjs +518 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +492 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# starlight-numera
|
|
2
|
+
|
|
3
|
+
A fast, lightweight numerical computing library for JavaScript inspired by NumPy.
|
|
4
|
+
|
|
5
|
+
Built for performance using TypedArrays and optimized loops.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- Fast ndarray implementation (TypedArray-based)
|
|
12
|
+
- Vectorized operations (add, sub, mul, div)
|
|
13
|
+
- Matrix operations (matmul, transpose, dot)
|
|
14
|
+
- Broadcasting (NumPy-style)
|
|
15
|
+
- Math functions (sqrt, exp, log, trig)
|
|
16
|
+
- Modular and tree-shakeable
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install starlight-numera
|
|
24
|
+
````
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import { array, add, matmul, sqrt } from 'starlight-numera';
|
|
32
|
+
|
|
33
|
+
// Create arrays
|
|
34
|
+
const a = array([[1, 2], [3, 4]]);
|
|
35
|
+
const b = array([[5, 6], [7, 8]]);
|
|
36
|
+
|
|
37
|
+
// Element-wise operations
|
|
38
|
+
const c = add(a, b);
|
|
39
|
+
|
|
40
|
+
// Matrix multiplication
|
|
41
|
+
const d = matmul(a, b);
|
|
42
|
+
|
|
43
|
+
// Math functions
|
|
44
|
+
const e = sqrt(a);
|
|
45
|
+
|
|
46
|
+
console.log(c);
|
|
47
|
+
console.log(d);
|
|
48
|
+
console.log(e);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## ndarray Structure
|
|
54
|
+
|
|
55
|
+
Each array is stored as:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
{
|
|
59
|
+
data: Float32Array,
|
|
60
|
+
shape: number[],
|
|
61
|
+
stride: number[],
|
|
62
|
+
size: number
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Operations
|
|
69
|
+
|
|
70
|
+
### Element-wise
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
add(a, b)
|
|
74
|
+
sub(a, b)
|
|
75
|
+
mul(a, b)
|
|
76
|
+
div(a, b)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Broadcasting
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
const a = array([[1, 2, 3]]);
|
|
83
|
+
const b = array([[10], [20]]);
|
|
84
|
+
|
|
85
|
+
add(a, b);
|
|
86
|
+
// [
|
|
87
|
+
// [11,12,13],
|
|
88
|
+
// [21,22,23]
|
|
89
|
+
// ]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Linear Algebra
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
transpose(a)
|
|
98
|
+
dot(a, b)
|
|
99
|
+
matmul(a, b)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Math Functions
|
|
105
|
+
|
|
106
|
+
```js
|
|
107
|
+
sqrt(a)
|
|
108
|
+
exp(a)
|
|
109
|
+
log(a)
|
|
110
|
+
|
|
111
|
+
sin(a)
|
|
112
|
+
cos(a)
|
|
113
|
+
tan(a)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Performance
|
|
119
|
+
|
|
120
|
+
* Uses Float32Array for fast memory access
|
|
121
|
+
* Avoids unnecessary allocations
|
|
122
|
+
* Optimized loops for numerical operations
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Roadmap
|
|
127
|
+
|
|
128
|
+
* Advanced broadcasting optimizations
|
|
129
|
+
* Slicing and indexing
|
|
130
|
+
* GPU acceleration (WebGL / WebGPU)
|
|
131
|
+
* SIMD optimizations
|
|
132
|
+
* Higher-dimensional tensors
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Contributing
|
|
137
|
+
|
|
138
|
+
Contributions are welcome.
|
|
139
|
+
|
|
140
|
+
1. Fork the repository
|
|
141
|
+
2. Create a feature branch
|
|
142
|
+
3. Submit a pull request
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT License
|
|
149
|
+
|
|
150
|
+
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Core ndarray structure
|
|
5
|
+
* Stores:
|
|
6
|
+
* - data (TypedArray)
|
|
7
|
+
* - shape
|
|
8
|
+
* - stride (for indexing)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
function computeStride$1(shape) {
|
|
12
|
+
const stride = new Array(shape.length);
|
|
13
|
+
let acc = 1;
|
|
14
|
+
|
|
15
|
+
for (let i = shape.length - 1; i >= 0; i--) {
|
|
16
|
+
stride[i] = acc;
|
|
17
|
+
acc *= shape[i];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return stride;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function ndarray(data, shape) {
|
|
24
|
+
if (!(data instanceof Float32Array)) {
|
|
25
|
+
throw new TypeError('Data must be Float32Array');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!Array.isArray(shape)) {
|
|
29
|
+
throw new TypeError('Shape must be an array');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const size = shape.reduce((a, b) => a * b, 1);
|
|
33
|
+
|
|
34
|
+
if (size !== data.length) {
|
|
35
|
+
throw new Error('Data size does not match shape');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
data,
|
|
40
|
+
shape,
|
|
41
|
+
stride: computeStride$1(shape),
|
|
42
|
+
size
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check if a value is a TypedArray
|
|
48
|
+
* Covers all standard JS typed arrays.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
function isTypedArray(value) {
|
|
52
|
+
return (
|
|
53
|
+
value != null &&
|
|
54
|
+
typeof value === 'object' &&
|
|
55
|
+
ArrayBuffer.isView(value) &&
|
|
56
|
+
!(value instanceof DataView)
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Flatten nested arrays into a flat TypedArray
|
|
62
|
+
* Also returns the inferred shape.
|
|
63
|
+
*
|
|
64
|
+
* Example:
|
|
65
|
+
* flatten([[1,2],[3,4]])
|
|
66
|
+
* → { data: Float32Array([1,2,3,4]), shape: [2,2] }
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
function flatten(input) {
|
|
71
|
+
const shape = [];
|
|
72
|
+
const flat = [];
|
|
73
|
+
|
|
74
|
+
function recurse(arr, depth) {
|
|
75
|
+
if (Array.isArray(arr)) {
|
|
76
|
+
if (shape.length <= depth) {
|
|
77
|
+
shape.push(arr.length);
|
|
78
|
+
} else if (shape[depth] !== arr.length) {
|
|
79
|
+
throw new Error('Inconsistent array shape');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (let i = 0; i < arr.length; i++) {
|
|
83
|
+
recurse(arr[i], depth + 1);
|
|
84
|
+
}
|
|
85
|
+
} else if (isTypedArray(arr)) {
|
|
86
|
+
// Treat typed arrays as leaf nodes
|
|
87
|
+
for (let i = 0; i < arr.length; i++) {
|
|
88
|
+
flat.push(arr[i]);
|
|
89
|
+
}
|
|
90
|
+
} else if (typeof arr === 'number') {
|
|
91
|
+
flat.push(arr);
|
|
92
|
+
} else {
|
|
93
|
+
throw new TypeError('Unsupported data type in array');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
recurse(input, 0);
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
data: new Float32Array(flat),
|
|
101
|
+
shape
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Shape utilities
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
function getSize(shape) {
|
|
110
|
+
return shape.reduce((a, b) => a * b, 1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function validateShape(shape) {
|
|
114
|
+
if (!Array.isArray(shape)) {
|
|
115
|
+
throw new TypeError('Shape must be an array');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (let i = 0; i < shape.length; i++) {
|
|
119
|
+
const dim = shape[i];
|
|
120
|
+
|
|
121
|
+
if (!Number.isInteger(dim) || dim <= 0) {
|
|
122
|
+
throw new Error('Shape must contain positive integers');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function areShapesEqual(a, b) {
|
|
130
|
+
if (a.length !== b.length) return false;
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < a.length; i++) {
|
|
133
|
+
if (a[i] !== b[i]) return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Array creation functions
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Create ndarray from nested array
|
|
146
|
+
*/
|
|
147
|
+
function array(input) {
|
|
148
|
+
const { data, shape } = flatten(input);
|
|
149
|
+
return ndarray(data, shape);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Create array filled with zeros
|
|
154
|
+
*/
|
|
155
|
+
function zeros(shape) {
|
|
156
|
+
validateShape(shape);
|
|
157
|
+
|
|
158
|
+
const size = getSize(shape);
|
|
159
|
+
const data = new Float32Array(size); // auto zero-filled
|
|
160
|
+
|
|
161
|
+
return ndarray(data, shape);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Create array filled with ones
|
|
166
|
+
*/
|
|
167
|
+
function ones(shape) {
|
|
168
|
+
validateShape(shape);
|
|
169
|
+
|
|
170
|
+
const size = getSize(shape);
|
|
171
|
+
const data = new Float32Array(size);
|
|
172
|
+
|
|
173
|
+
for (let i = 0; i < size; i++) {
|
|
174
|
+
data[i] = 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return ndarray(data, shape);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Reshape ndarray without changing data
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
function reshape(arr, newShape) {
|
|
186
|
+
validateShape(newShape);
|
|
187
|
+
|
|
188
|
+
const newSize = getSize(newShape);
|
|
189
|
+
|
|
190
|
+
if (newSize !== arr.size) {
|
|
191
|
+
throw new Error('Total size must remain the same in reshape');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// reuse same data buffer (fast)
|
|
195
|
+
return ndarray(arr.data, newShape);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Broadcasting rules (NumPy-style)
|
|
200
|
+
*
|
|
201
|
+
* Align shapes from right to left:
|
|
202
|
+
* - Dimensions must be equal OR one must be 1
|
|
203
|
+
*/
|
|
204
|
+
|
|
205
|
+
function broadcastShapes(shapeA, shapeB) {
|
|
206
|
+
const result = [];
|
|
207
|
+
|
|
208
|
+
const len = Math.max(shapeA.length, shapeB.length);
|
|
209
|
+
|
|
210
|
+
for (let i = 0; i < len; i++) {
|
|
211
|
+
const a = shapeA[shapeA.length - 1 - i] ?? 1;
|
|
212
|
+
const b = shapeB[shapeB.length - 1 - i] ?? 1;
|
|
213
|
+
|
|
214
|
+
if (a === b || a === 1 || b === 1) {
|
|
215
|
+
result.unshift(Math.max(a, b));
|
|
216
|
+
} else {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Cannot broadcast shapes ${shapeA} and ${shapeB}`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Broadcasting execution helpers
|
|
228
|
+
*/
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Compute stride for shape
|
|
233
|
+
*/
|
|
234
|
+
function computeStride(shape) {
|
|
235
|
+
const stride = new Array(shape.length);
|
|
236
|
+
let acc = 1;
|
|
237
|
+
|
|
238
|
+
for (let i = shape.length - 1; i >= 0; i--) {
|
|
239
|
+
stride[i] = acc;
|
|
240
|
+
acc *= shape[i];
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return stride;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Convert flat index → multi-dimensional index
|
|
248
|
+
*/
|
|
249
|
+
function unravelIndex(index, shape) {
|
|
250
|
+
const idx = new Array(shape.length);
|
|
251
|
+
|
|
252
|
+
for (let i = 0; i < shape.length; i++) {
|
|
253
|
+
const stride = shape.slice(i + 1).reduce((a, b) => a * b, 1);
|
|
254
|
+
idx[i] = Math.floor(index / stride) % shape[i];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return idx;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Apply broadcasting for two ndarrays
|
|
262
|
+
*/
|
|
263
|
+
function broadcastBinaryOp(a, b, fn) {
|
|
264
|
+
const outShape = broadcastShapes(a.shape, b.shape);
|
|
265
|
+
const outSize = outShape.reduce((x, y) => x * y, 1);
|
|
266
|
+
|
|
267
|
+
const out = new Float32Array(outSize);
|
|
268
|
+
|
|
269
|
+
const strideA = computeStride(a.shape);
|
|
270
|
+
const strideB = computeStride(b.shape);
|
|
271
|
+
|
|
272
|
+
const offsetA = outShape.length - a.shape.length;
|
|
273
|
+
const offsetB = outShape.length - b.shape.length;
|
|
274
|
+
|
|
275
|
+
for (let i = 0; i < outSize; i++) {
|
|
276
|
+
const idx = unravelIndex(i, outShape);
|
|
277
|
+
|
|
278
|
+
let indexA = 0;
|
|
279
|
+
let indexB = 0;
|
|
280
|
+
|
|
281
|
+
for (let d = 0; d < outShape.length; d++) {
|
|
282
|
+
const aDim = a.shape[d - offsetA] ?? 1;
|
|
283
|
+
const bDim = b.shape[d - offsetB] ?? 1;
|
|
284
|
+
|
|
285
|
+
const iA = aDim === 1 ? 0 : idx[d];
|
|
286
|
+
const iB = bDim === 1 ? 0 : idx[d];
|
|
287
|
+
|
|
288
|
+
if (d - offsetA >= 0) {
|
|
289
|
+
indexA += iA * strideA[d - offsetA];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (d - offsetB >= 0) {
|
|
293
|
+
indexB += iB * strideB[d - offsetB];
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
out[i] = fn(a.data[indexA], b.data[indexB]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return ndarray(out, outShape);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Core element-wise operation engine
|
|
305
|
+
* Supports:
|
|
306
|
+
* - ndarray + ndarray (with broadcasting)
|
|
307
|
+
* - ndarray + scalar
|
|
308
|
+
* - scalar + ndarray
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
function map(a, b, fn) {
|
|
313
|
+
const isAScalar = typeof a === 'number';
|
|
314
|
+
const isBScalar = typeof b === 'number';
|
|
315
|
+
|
|
316
|
+
// Case 1: scalar + scalar
|
|
317
|
+
if (isAScalar && isBScalar) {
|
|
318
|
+
return fn(a, b);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Case 2: ndarray + scalar
|
|
322
|
+
if (!isAScalar && isBScalar) {
|
|
323
|
+
const out = new Float32Array(a.size);
|
|
324
|
+
|
|
325
|
+
for (let i = 0; i < a.size; i++) {
|
|
326
|
+
out[i] = fn(a.data[i], b);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return ndarray(out, a.shape);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Case 3: scalar + ndarray
|
|
333
|
+
if (isAScalar && !isBScalar) {
|
|
334
|
+
const out = new Float32Array(b.size);
|
|
335
|
+
|
|
336
|
+
for (let i = 0; i < b.size; i++) {
|
|
337
|
+
out[i] = fn(a, b.data[i]);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return ndarray(out, b.shape);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Case 4: ndarray + ndarray (with broadcasting)
|
|
344
|
+
return broadcastBinaryOp(a, b, fn);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function add(a, b) {
|
|
348
|
+
return map(a, b, (x, y) => x + y);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function sub(a, b) {
|
|
352
|
+
return map(a, b, (x, y) => x - y);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function mul(a, b) {
|
|
356
|
+
return map(a, b, (x, y) => x * y);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function div(a, b) {
|
|
360
|
+
return map(a, b, (x, y) => x / y);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Element-wise square root
|
|
365
|
+
*/
|
|
366
|
+
function sqrt(a) {
|
|
367
|
+
return map(a, 0, (x) => Math.sqrt(x));
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Element-wise exponential (e^x)
|
|
372
|
+
*/
|
|
373
|
+
function exp(a) {
|
|
374
|
+
return map(a, 0, (x) => Math.exp(x));
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Element-wise natural logarithm (ln)
|
|
379
|
+
*/
|
|
380
|
+
function log(a) {
|
|
381
|
+
return map(a, 0, (x) => Math.log(x));
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Trigonometric functions (element-wise)
|
|
386
|
+
*/
|
|
387
|
+
|
|
388
|
+
function sin(a) {
|
|
389
|
+
return map(a, 0, (x) => Math.sin(x));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function cos(a) {
|
|
393
|
+
return map(a, 0, (x) => Math.cos(x));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function tan(a) {
|
|
397
|
+
return map(a, 0, (x) => Math.tan(x));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
function asin(a) {
|
|
401
|
+
return map(a, 0, (x) => Math.asin(x));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function acos(a) {
|
|
405
|
+
return map(a, 0, (x) => Math.acos(x));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function atan(a) {
|
|
409
|
+
return map(a, 0, (x) => Math.atan(x));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Transpose a 2D ndarray
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
function transpose(a) {
|
|
418
|
+
if (a.shape.length !== 2) {
|
|
419
|
+
throw new Error('Transpose currently supports only 2D arrays');
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const [rows, cols] = a.shape;
|
|
423
|
+
|
|
424
|
+
const out = new Float32Array(a.size);
|
|
425
|
+
|
|
426
|
+
for (let i = 0; i < rows; i++) {
|
|
427
|
+
for (let j = 0; j < cols; j++) {
|
|
428
|
+
out[j * rows + i] = a.data[i * cols + j];
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return ndarray(out, [cols, rows]);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Dot product (1D vectors) or matrix multiplication (2D simplified)
|
|
437
|
+
*/
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
function dot(a, b) {
|
|
441
|
+
// Vector dot product
|
|
442
|
+
if (a.shape.length === 1 && b.shape.length === 1) {
|
|
443
|
+
if (a.size !== b.size) {
|
|
444
|
+
throw new Error('Vectors must have same length');
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
let sum = 0;
|
|
448
|
+
|
|
449
|
+
for (let i = 0; i < a.size; i++) {
|
|
450
|
+
sum += a.data[i] * b.data[i];
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return sum;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
throw new Error('dot currently supports only 1D vectors');
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Matrix multiplication (2D only)
|
|
461
|
+
*/
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
function matmul(a, b) {
|
|
465
|
+
if (a.shape.length !== 2 || b.shape.length !== 2) {
|
|
466
|
+
throw new Error('matmul supports only 2D matrices');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const [m, n] = a.shape;
|
|
470
|
+
const [n2, p] = b.shape;
|
|
471
|
+
|
|
472
|
+
if (n !== n2) {
|
|
473
|
+
throw new Error('Inner dimensions must match for matmul');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const out = new Float32Array(m * p);
|
|
477
|
+
|
|
478
|
+
for (let i = 0; i < m; i++) {
|
|
479
|
+
for (let j = 0; j < p; j++) {
|
|
480
|
+
let sum = 0;
|
|
481
|
+
|
|
482
|
+
for (let k = 0; k < n; k++) {
|
|
483
|
+
sum += a.data[i * n + k] * b.data[k * p + j];
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
out[i * p + j] = sum;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return ndarray(out, [m, p]);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
exports.acos = acos;
|
|
494
|
+
exports.add = add;
|
|
495
|
+
exports.areShapesEqual = areShapesEqual;
|
|
496
|
+
exports.array = array;
|
|
497
|
+
exports.asin = asin;
|
|
498
|
+
exports.atan = atan;
|
|
499
|
+
exports.cos = cos;
|
|
500
|
+
exports.div = div;
|
|
501
|
+
exports.dot = dot;
|
|
502
|
+
exports.exp = exp;
|
|
503
|
+
exports.getSize = getSize;
|
|
504
|
+
exports.log = log;
|
|
505
|
+
exports.map = map;
|
|
506
|
+
exports.matmul = matmul;
|
|
507
|
+
exports.mul = mul;
|
|
508
|
+
exports.ndarray = ndarray;
|
|
509
|
+
exports.ones = ones;
|
|
510
|
+
exports.reshape = reshape;
|
|
511
|
+
exports.sin = sin;
|
|
512
|
+
exports.sqrt = sqrt;
|
|
513
|
+
exports.sub = sub;
|
|
514
|
+
exports.tan = tan;
|
|
515
|
+
exports.transpose = transpose;
|
|
516
|
+
exports.validateShape = validateShape;
|
|
517
|
+
exports.zeros = zeros;
|
|
518
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/ndarray/ndarray.js","../src/utils/isTypedArray.js","../src/utils/flatten.js","../src/ndarray/shape.js","../src/ndarray/create.js","../src/ndarray/reshape.js","../src/broadcast/rules.js","../src/broadcast/broadcast.js","../src/ops/map.js","../src/ops/add.js","../src/ops/sub.js","../src/ops/mul.js","../src/ops/div.js","../src/math/sqrt.js","../src/math/exp.js","../src/math/log.js","../src/math/trig.js","../src/linalg/transpose.js","../src/linalg/dot.js","../src/linalg/matmul.js"],"sourcesContent":["/**\r\n * Core ndarray structure\r\n * Stores:\r\n * - data (TypedArray)\r\n * - shape\r\n * - stride (for indexing)\r\n */\r\n\r\nfunction computeStride(shape) {\r\n const stride = new Array(shape.length);\r\n let acc = 1;\r\n\r\n for (let i = shape.length - 1; i >= 0; i--) {\r\n stride[i] = acc;\r\n acc *= shape[i];\r\n }\r\n\r\n return stride;\r\n}\r\n\r\nexport function ndarray(data, shape) {\r\n if (!(data instanceof Float32Array)) {\r\n throw new TypeError('Data must be Float32Array');\r\n }\r\n\r\n if (!Array.isArray(shape)) {\r\n throw new TypeError('Shape must be an array');\r\n }\r\n\r\n const size = shape.reduce((a, b) => a * b, 1);\r\n\r\n if (size !== data.length) {\r\n throw new Error('Data size does not match shape');\r\n }\r\n\r\n return {\r\n data,\r\n shape,\r\n stride: computeStride(shape),\r\n size\r\n };\r\n}","/**\r\n * Check if a value is a TypedArray\r\n * Covers all standard JS typed arrays.\r\n */\r\n\r\nexport function isTypedArray(value) {\r\n return (\r\n value != null &&\r\n typeof value === 'object' &&\r\n ArrayBuffer.isView(value) &&\r\n !(value instanceof DataView)\r\n );\r\n}","/**\r\n * Flatten nested arrays into a flat TypedArray\r\n * Also returns the inferred shape.\r\n *\r\n * Example:\r\n * flatten([[1,2],[3,4]])\r\n * → { data: Float32Array([1,2,3,4]), shape: [2,2] }\r\n */\r\n\r\nimport { isTypedArray } from './isTypedArray.js';\r\n\r\nexport function flatten(input) {\r\n const shape = [];\r\n const flat = [];\r\n\r\n function recurse(arr, depth) {\r\n if (Array.isArray(arr)) {\r\n if (shape.length <= depth) {\r\n shape.push(arr.length);\r\n } else if (shape[depth] !== arr.length) {\r\n throw new Error('Inconsistent array shape');\r\n }\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n recurse(arr[i], depth + 1);\r\n }\r\n } else if (isTypedArray(arr)) {\r\n // Treat typed arrays as leaf nodes\r\n for (let i = 0; i < arr.length; i++) {\r\n flat.push(arr[i]);\r\n }\r\n } else if (typeof arr === 'number') {\r\n flat.push(arr);\r\n } else {\r\n throw new TypeError('Unsupported data type in array');\r\n }\r\n }\r\n\r\n recurse(input, 0);\r\n\r\n return {\r\n data: new Float32Array(flat),\r\n shape\r\n };\r\n}","/**\r\n * Shape utilities\r\n */\r\n\r\nexport function getSize(shape) {\r\n return shape.reduce((a, b) => a * b, 1);\r\n}\r\n\r\nexport function validateShape(shape) {\r\n if (!Array.isArray(shape)) {\r\n throw new TypeError('Shape must be an array');\r\n }\r\n\r\n for (let i = 0; i < shape.length; i++) {\r\n const dim = shape[i];\r\n\r\n if (!Number.isInteger(dim) || dim <= 0) {\r\n throw new Error('Shape must contain positive integers');\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function areShapesEqual(a, b) {\r\n if (a.length !== b.length) return false;\r\n\r\n for (let i = 0; i < a.length; i++) {\r\n if (a[i] !== b[i]) return false;\r\n }\r\n\r\n return true;\r\n}","/**\r\n * Array creation functions\r\n */\r\n\r\nimport { ndarray } from './ndarray.js';\r\nimport { flatten } from '../utils/flatten.js';\r\nimport { getSize, validateShape } from './shape.js';\r\n\r\n/**\r\n * Create ndarray from nested array\r\n */\r\nexport function array(input) {\r\n const { data, shape } = flatten(input);\r\n return ndarray(data, shape);\r\n}\r\n\r\n/**\r\n * Create array filled with zeros\r\n */\r\nexport function zeros(shape) {\r\n validateShape(shape);\r\n\r\n const size = getSize(shape);\r\n const data = new Float32Array(size); // auto zero-filled\r\n\r\n return ndarray(data, shape);\r\n}\r\n\r\n/**\r\n * Create array filled with ones\r\n */\r\nexport function ones(shape) {\r\n validateShape(shape);\r\n\r\n const size = getSize(shape);\r\n const data = new Float32Array(size);\r\n\r\n for (let i = 0; i < size; i++) {\r\n data[i] = 1;\r\n }\r\n\r\n return ndarray(data, shape);\r\n}","/**\r\n * Reshape ndarray without changing data\r\n */\r\n\r\nimport { ndarray } from './ndarray.js';\r\nimport { getSize, validateShape } from './shape.js';\r\n\r\nexport function reshape(arr, newShape) {\r\n validateShape(newShape);\r\n\r\n const newSize = getSize(newShape);\r\n\r\n if (newSize !== arr.size) {\r\n throw new Error('Total size must remain the same in reshape');\r\n }\r\n\r\n // reuse same data buffer (fast)\r\n return ndarray(arr.data, newShape);\r\n}","/**\r\n * Broadcasting rules (NumPy-style)\r\n *\r\n * Align shapes from right to left:\r\n * - Dimensions must be equal OR one must be 1\r\n */\r\n\r\nexport function broadcastShapes(shapeA, shapeB) {\r\n const result = [];\r\n\r\n const len = Math.max(shapeA.length, shapeB.length);\r\n\r\n for (let i = 0; i < len; i++) {\r\n const a = shapeA[shapeA.length - 1 - i] ?? 1;\r\n const b = shapeB[shapeB.length - 1 - i] ?? 1;\r\n\r\n if (a === b || a === 1 || b === 1) {\r\n result.unshift(Math.max(a, b));\r\n } else {\r\n throw new Error(\r\n `Cannot broadcast shapes ${shapeA} and ${shapeB}`\r\n );\r\n }\r\n }\r\n\r\n return result;\r\n}","/**\r\n * Broadcasting execution helpers\r\n */\r\n\r\nimport { broadcastShapes } from './rules.js';\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\n/**\r\n * Compute stride for shape\r\n */\r\nfunction computeStride(shape) {\r\n const stride = new Array(shape.length);\r\n let acc = 1;\r\n\r\n for (let i = shape.length - 1; i >= 0; i--) {\r\n stride[i] = acc;\r\n acc *= shape[i];\r\n }\r\n\r\n return stride;\r\n}\r\n\r\n/**\r\n * Convert flat index → multi-dimensional index\r\n */\r\nfunction unravelIndex(index, shape) {\r\n const idx = new Array(shape.length);\r\n\r\n for (let i = 0; i < shape.length; i++) {\r\n const stride = shape.slice(i + 1).reduce((a, b) => a * b, 1);\r\n idx[i] = Math.floor(index / stride) % shape[i];\r\n }\r\n\r\n return idx;\r\n}\r\n\r\n/**\r\n * Convert multi-index → flat index\r\n */\r\nfunction ravelIndex(idx, stride) {\r\n let index = 0;\r\n for (let i = 0; i < idx.length; i++) {\r\n index += idx[i] * stride[i];\r\n }\r\n return index;\r\n}\r\n\r\n/**\r\n * Apply broadcasting for two ndarrays\r\n */\r\nexport function broadcastBinaryOp(a, b, fn) {\r\n const outShape = broadcastShapes(a.shape, b.shape);\r\n const outSize = outShape.reduce((x, y) => x * y, 1);\r\n\r\n const out = new Float32Array(outSize);\r\n\r\n const strideA = computeStride(a.shape);\r\n const strideB = computeStride(b.shape);\r\n\r\n const offsetA = outShape.length - a.shape.length;\r\n const offsetB = outShape.length - b.shape.length;\r\n\r\n for (let i = 0; i < outSize; i++) {\r\n const idx = unravelIndex(i, outShape);\r\n\r\n let indexA = 0;\r\n let indexB = 0;\r\n\r\n for (let d = 0; d < outShape.length; d++) {\r\n const aDim = a.shape[d - offsetA] ?? 1;\r\n const bDim = b.shape[d - offsetB] ?? 1;\r\n\r\n const iA = aDim === 1 ? 0 : idx[d];\r\n const iB = bDim === 1 ? 0 : idx[d];\r\n\r\n if (d - offsetA >= 0) {\r\n indexA += iA * strideA[d - offsetA];\r\n }\r\n\r\n if (d - offsetB >= 0) {\r\n indexB += iB * strideB[d - offsetB];\r\n }\r\n }\r\n\r\n out[i] = fn(a.data[indexA], b.data[indexB]);\r\n }\r\n\r\n return ndarray(out, outShape);\r\n}","/**\r\n * Core element-wise operation engine\r\n * Supports:\r\n * - ndarray + ndarray (with broadcasting)\r\n * - ndarray + scalar\r\n * - scalar + ndarray\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\nimport { broadcastBinaryOp } from '../broadcast/broadcast.js';\r\n\r\nexport function map(a, b, fn) {\r\n const isAScalar = typeof a === 'number';\r\n const isBScalar = typeof b === 'number';\r\n\r\n // Case 1: scalar + scalar\r\n if (isAScalar && isBScalar) {\r\n return fn(a, b);\r\n }\r\n\r\n // Case 2: ndarray + scalar\r\n if (!isAScalar && isBScalar) {\r\n const out = new Float32Array(a.size);\r\n\r\n for (let i = 0; i < a.size; i++) {\r\n out[i] = fn(a.data[i], b);\r\n }\r\n\r\n return ndarray(out, a.shape);\r\n }\r\n\r\n // Case 3: scalar + ndarray\r\n if (isAScalar && !isBScalar) {\r\n const out = new Float32Array(b.size);\r\n\r\n for (let i = 0; i < b.size; i++) {\r\n out[i] = fn(a, b.data[i]);\r\n }\r\n\r\n return ndarray(out, b.shape);\r\n }\r\n\r\n // Case 4: ndarray + ndarray (with broadcasting)\r\n return broadcastBinaryOp(a, b, fn);\r\n}","import { map } from './map.js';\r\n\r\nexport function add(a, b) {\r\n return map(a, b, (x, y) => x + y);\r\n}","import { map } from './map.js';\r\n\r\nexport function sub(a, b) {\r\n return map(a, b, (x, y) => x - y);\r\n}","import { map } from './map.js';\r\n\r\nexport function mul(a, b) {\r\n return map(a, b, (x, y) => x * y);\r\n}","import { map } from './map.js';\r\n\r\nexport function div(a, b) {\r\n return map(a, b, (x, y) => x / y);\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise square root\r\n */\r\nexport function sqrt(a) {\r\n return map(a, 0, (x) => Math.sqrt(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise exponential (e^x)\r\n */\r\nexport function exp(a) {\r\n return map(a, 0, (x) => Math.exp(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise natural logarithm (ln)\r\n */\r\nexport function log(a) {\r\n return map(a, 0, (x) => Math.log(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Trigonometric functions (element-wise)\r\n */\r\n\r\nexport function sin(a) {\r\n return map(a, 0, (x) => Math.sin(x));\r\n}\r\n\r\nexport function cos(a) {\r\n return map(a, 0, (x) => Math.cos(x));\r\n}\r\n\r\nexport function tan(a) {\r\n return map(a, 0, (x) => Math.tan(x));\r\n}\r\n\r\nexport function asin(a) {\r\n return map(a, 0, (x) => Math.asin(x));\r\n}\r\n\r\nexport function acos(a) {\r\n return map(a, 0, (x) => Math.acos(x));\r\n}\r\n\r\nexport function atan(a) {\r\n return map(a, 0, (x) => Math.atan(x));\r\n}","/**\r\n * Transpose a 2D ndarray\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function transpose(a) {\r\n if (a.shape.length !== 2) {\r\n throw new Error('Transpose currently supports only 2D arrays');\r\n }\r\n\r\n const [rows, cols] = a.shape;\r\n\r\n const out = new Float32Array(a.size);\r\n\r\n for (let i = 0; i < rows; i++) {\r\n for (let j = 0; j < cols; j++) {\r\n out[j * rows + i] = a.data[i * cols + j];\r\n }\r\n }\r\n\r\n return ndarray(out, [cols, rows]);\r\n}","/**\r\n * Dot product (1D vectors) or matrix multiplication (2D simplified)\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function dot(a, b) {\r\n // Vector dot product\r\n if (a.shape.length === 1 && b.shape.length === 1) {\r\n if (a.size !== b.size) {\r\n throw new Error('Vectors must have same length');\r\n }\r\n\r\n let sum = 0;\r\n\r\n for (let i = 0; i < a.size; i++) {\r\n sum += a.data[i] * b.data[i];\r\n }\r\n\r\n return sum;\r\n }\r\n\r\n throw new Error('dot currently supports only 1D vectors');\r\n}","/**\r\n * Matrix multiplication (2D only)\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function matmul(a, b) {\r\n if (a.shape.length !== 2 || b.shape.length !== 2) {\r\n throw new Error('matmul supports only 2D matrices');\r\n }\r\n\r\n const [m, n] = a.shape;\r\n const [n2, p] = b.shape;\r\n\r\n if (n !== n2) {\r\n throw new Error('Inner dimensions must match for matmul');\r\n }\r\n\r\n const out = new Float32Array(m * p);\r\n\r\n for (let i = 0; i < m; i++) {\r\n for (let j = 0; j < p; j++) {\r\n let sum = 0;\r\n\r\n for (let k = 0; k < n; k++) {\r\n sum += a.data[i * n + k] * b.data[k * p + j];\r\n }\r\n\r\n out[i * p + j] = sum;\r\n }\r\n }\r\n\r\n return ndarray(out, [m, p]);\r\n}"],"names":["computeStride"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core ndarray structure
|
|
3
|
+
* Stores:
|
|
4
|
+
* - data (TypedArray)
|
|
5
|
+
* - shape
|
|
6
|
+
* - stride (for indexing)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
function computeStride$1(shape) {
|
|
10
|
+
const stride = new Array(shape.length);
|
|
11
|
+
let acc = 1;
|
|
12
|
+
|
|
13
|
+
for (let i = shape.length - 1; i >= 0; i--) {
|
|
14
|
+
stride[i] = acc;
|
|
15
|
+
acc *= shape[i];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return stride;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function ndarray(data, shape) {
|
|
22
|
+
if (!(data instanceof Float32Array)) {
|
|
23
|
+
throw new TypeError('Data must be Float32Array');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!Array.isArray(shape)) {
|
|
27
|
+
throw new TypeError('Shape must be an array');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const size = shape.reduce((a, b) => a * b, 1);
|
|
31
|
+
|
|
32
|
+
if (size !== data.length) {
|
|
33
|
+
throw new Error('Data size does not match shape');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
data,
|
|
38
|
+
shape,
|
|
39
|
+
stride: computeStride$1(shape),
|
|
40
|
+
size
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Check if a value is a TypedArray
|
|
46
|
+
* Covers all standard JS typed arrays.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
function isTypedArray(value) {
|
|
50
|
+
return (
|
|
51
|
+
value != null &&
|
|
52
|
+
typeof value === 'object' &&
|
|
53
|
+
ArrayBuffer.isView(value) &&
|
|
54
|
+
!(value instanceof DataView)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Flatten nested arrays into a flat TypedArray
|
|
60
|
+
* Also returns the inferred shape.
|
|
61
|
+
*
|
|
62
|
+
* Example:
|
|
63
|
+
* flatten([[1,2],[3,4]])
|
|
64
|
+
* → { data: Float32Array([1,2,3,4]), shape: [2,2] }
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
function flatten(input) {
|
|
69
|
+
const shape = [];
|
|
70
|
+
const flat = [];
|
|
71
|
+
|
|
72
|
+
function recurse(arr, depth) {
|
|
73
|
+
if (Array.isArray(arr)) {
|
|
74
|
+
if (shape.length <= depth) {
|
|
75
|
+
shape.push(arr.length);
|
|
76
|
+
} else if (shape[depth] !== arr.length) {
|
|
77
|
+
throw new Error('Inconsistent array shape');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (let i = 0; i < arr.length; i++) {
|
|
81
|
+
recurse(arr[i], depth + 1);
|
|
82
|
+
}
|
|
83
|
+
} else if (isTypedArray(arr)) {
|
|
84
|
+
// Treat typed arrays as leaf nodes
|
|
85
|
+
for (let i = 0; i < arr.length; i++) {
|
|
86
|
+
flat.push(arr[i]);
|
|
87
|
+
}
|
|
88
|
+
} else if (typeof arr === 'number') {
|
|
89
|
+
flat.push(arr);
|
|
90
|
+
} else {
|
|
91
|
+
throw new TypeError('Unsupported data type in array');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
recurse(input, 0);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
data: new Float32Array(flat),
|
|
99
|
+
shape
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Shape utilities
|
|
105
|
+
*/
|
|
106
|
+
|
|
107
|
+
function getSize(shape) {
|
|
108
|
+
return shape.reduce((a, b) => a * b, 1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function validateShape(shape) {
|
|
112
|
+
if (!Array.isArray(shape)) {
|
|
113
|
+
throw new TypeError('Shape must be an array');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
for (let i = 0; i < shape.length; i++) {
|
|
117
|
+
const dim = shape[i];
|
|
118
|
+
|
|
119
|
+
if (!Number.isInteger(dim) || dim <= 0) {
|
|
120
|
+
throw new Error('Shape must contain positive integers');
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function areShapesEqual(a, b) {
|
|
128
|
+
if (a.length !== b.length) return false;
|
|
129
|
+
|
|
130
|
+
for (let i = 0; i < a.length; i++) {
|
|
131
|
+
if (a[i] !== b[i]) return false;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Array creation functions
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Create ndarray from nested array
|
|
144
|
+
*/
|
|
145
|
+
function array(input) {
|
|
146
|
+
const { data, shape } = flatten(input);
|
|
147
|
+
return ndarray(data, shape);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Create array filled with zeros
|
|
152
|
+
*/
|
|
153
|
+
function zeros(shape) {
|
|
154
|
+
validateShape(shape);
|
|
155
|
+
|
|
156
|
+
const size = getSize(shape);
|
|
157
|
+
const data = new Float32Array(size); // auto zero-filled
|
|
158
|
+
|
|
159
|
+
return ndarray(data, shape);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Create array filled with ones
|
|
164
|
+
*/
|
|
165
|
+
function ones(shape) {
|
|
166
|
+
validateShape(shape);
|
|
167
|
+
|
|
168
|
+
const size = getSize(shape);
|
|
169
|
+
const data = new Float32Array(size);
|
|
170
|
+
|
|
171
|
+
for (let i = 0; i < size; i++) {
|
|
172
|
+
data[i] = 1;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return ndarray(data, shape);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Reshape ndarray without changing data
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
function reshape(arr, newShape) {
|
|
184
|
+
validateShape(newShape);
|
|
185
|
+
|
|
186
|
+
const newSize = getSize(newShape);
|
|
187
|
+
|
|
188
|
+
if (newSize !== arr.size) {
|
|
189
|
+
throw new Error('Total size must remain the same in reshape');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// reuse same data buffer (fast)
|
|
193
|
+
return ndarray(arr.data, newShape);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Broadcasting rules (NumPy-style)
|
|
198
|
+
*
|
|
199
|
+
* Align shapes from right to left:
|
|
200
|
+
* - Dimensions must be equal OR one must be 1
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
function broadcastShapes(shapeA, shapeB) {
|
|
204
|
+
const result = [];
|
|
205
|
+
|
|
206
|
+
const len = Math.max(shapeA.length, shapeB.length);
|
|
207
|
+
|
|
208
|
+
for (let i = 0; i < len; i++) {
|
|
209
|
+
const a = shapeA[shapeA.length - 1 - i] ?? 1;
|
|
210
|
+
const b = shapeB[shapeB.length - 1 - i] ?? 1;
|
|
211
|
+
|
|
212
|
+
if (a === b || a === 1 || b === 1) {
|
|
213
|
+
result.unshift(Math.max(a, b));
|
|
214
|
+
} else {
|
|
215
|
+
throw new Error(
|
|
216
|
+
`Cannot broadcast shapes ${shapeA} and ${shapeB}`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Broadcasting execution helpers
|
|
226
|
+
*/
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Compute stride for shape
|
|
231
|
+
*/
|
|
232
|
+
function computeStride(shape) {
|
|
233
|
+
const stride = new Array(shape.length);
|
|
234
|
+
let acc = 1;
|
|
235
|
+
|
|
236
|
+
for (let i = shape.length - 1; i >= 0; i--) {
|
|
237
|
+
stride[i] = acc;
|
|
238
|
+
acc *= shape[i];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return stride;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Convert flat index → multi-dimensional index
|
|
246
|
+
*/
|
|
247
|
+
function unravelIndex(index, shape) {
|
|
248
|
+
const idx = new Array(shape.length);
|
|
249
|
+
|
|
250
|
+
for (let i = 0; i < shape.length; i++) {
|
|
251
|
+
const stride = shape.slice(i + 1).reduce((a, b) => a * b, 1);
|
|
252
|
+
idx[i] = Math.floor(index / stride) % shape[i];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return idx;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Apply broadcasting for two ndarrays
|
|
260
|
+
*/
|
|
261
|
+
function broadcastBinaryOp(a, b, fn) {
|
|
262
|
+
const outShape = broadcastShapes(a.shape, b.shape);
|
|
263
|
+
const outSize = outShape.reduce((x, y) => x * y, 1);
|
|
264
|
+
|
|
265
|
+
const out = new Float32Array(outSize);
|
|
266
|
+
|
|
267
|
+
const strideA = computeStride(a.shape);
|
|
268
|
+
const strideB = computeStride(b.shape);
|
|
269
|
+
|
|
270
|
+
const offsetA = outShape.length - a.shape.length;
|
|
271
|
+
const offsetB = outShape.length - b.shape.length;
|
|
272
|
+
|
|
273
|
+
for (let i = 0; i < outSize; i++) {
|
|
274
|
+
const idx = unravelIndex(i, outShape);
|
|
275
|
+
|
|
276
|
+
let indexA = 0;
|
|
277
|
+
let indexB = 0;
|
|
278
|
+
|
|
279
|
+
for (let d = 0; d < outShape.length; d++) {
|
|
280
|
+
const aDim = a.shape[d - offsetA] ?? 1;
|
|
281
|
+
const bDim = b.shape[d - offsetB] ?? 1;
|
|
282
|
+
|
|
283
|
+
const iA = aDim === 1 ? 0 : idx[d];
|
|
284
|
+
const iB = bDim === 1 ? 0 : idx[d];
|
|
285
|
+
|
|
286
|
+
if (d - offsetA >= 0) {
|
|
287
|
+
indexA += iA * strideA[d - offsetA];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (d - offsetB >= 0) {
|
|
291
|
+
indexB += iB * strideB[d - offsetB];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
out[i] = fn(a.data[indexA], b.data[indexB]);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return ndarray(out, outShape);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Core element-wise operation engine
|
|
303
|
+
* Supports:
|
|
304
|
+
* - ndarray + ndarray (with broadcasting)
|
|
305
|
+
* - ndarray + scalar
|
|
306
|
+
* - scalar + ndarray
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
function map(a, b, fn) {
|
|
311
|
+
const isAScalar = typeof a === 'number';
|
|
312
|
+
const isBScalar = typeof b === 'number';
|
|
313
|
+
|
|
314
|
+
// Case 1: scalar + scalar
|
|
315
|
+
if (isAScalar && isBScalar) {
|
|
316
|
+
return fn(a, b);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Case 2: ndarray + scalar
|
|
320
|
+
if (!isAScalar && isBScalar) {
|
|
321
|
+
const out = new Float32Array(a.size);
|
|
322
|
+
|
|
323
|
+
for (let i = 0; i < a.size; i++) {
|
|
324
|
+
out[i] = fn(a.data[i], b);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return ndarray(out, a.shape);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Case 3: scalar + ndarray
|
|
331
|
+
if (isAScalar && !isBScalar) {
|
|
332
|
+
const out = new Float32Array(b.size);
|
|
333
|
+
|
|
334
|
+
for (let i = 0; i < b.size; i++) {
|
|
335
|
+
out[i] = fn(a, b.data[i]);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return ndarray(out, b.shape);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Case 4: ndarray + ndarray (with broadcasting)
|
|
342
|
+
return broadcastBinaryOp(a, b, fn);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function add(a, b) {
|
|
346
|
+
return map(a, b, (x, y) => x + y);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function sub(a, b) {
|
|
350
|
+
return map(a, b, (x, y) => x - y);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function mul(a, b) {
|
|
354
|
+
return map(a, b, (x, y) => x * y);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function div(a, b) {
|
|
358
|
+
return map(a, b, (x, y) => x / y);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Element-wise square root
|
|
363
|
+
*/
|
|
364
|
+
function sqrt(a) {
|
|
365
|
+
return map(a, 0, (x) => Math.sqrt(x));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Element-wise exponential (e^x)
|
|
370
|
+
*/
|
|
371
|
+
function exp(a) {
|
|
372
|
+
return map(a, 0, (x) => Math.exp(x));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Element-wise natural logarithm (ln)
|
|
377
|
+
*/
|
|
378
|
+
function log(a) {
|
|
379
|
+
return map(a, 0, (x) => Math.log(x));
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Trigonometric functions (element-wise)
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
function sin(a) {
|
|
387
|
+
return map(a, 0, (x) => Math.sin(x));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function cos(a) {
|
|
391
|
+
return map(a, 0, (x) => Math.cos(x));
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function tan(a) {
|
|
395
|
+
return map(a, 0, (x) => Math.tan(x));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function asin(a) {
|
|
399
|
+
return map(a, 0, (x) => Math.asin(x));
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function acos(a) {
|
|
403
|
+
return map(a, 0, (x) => Math.acos(x));
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function atan(a) {
|
|
407
|
+
return map(a, 0, (x) => Math.atan(x));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Transpose a 2D ndarray
|
|
412
|
+
*/
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
function transpose(a) {
|
|
416
|
+
if (a.shape.length !== 2) {
|
|
417
|
+
throw new Error('Transpose currently supports only 2D arrays');
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const [rows, cols] = a.shape;
|
|
421
|
+
|
|
422
|
+
const out = new Float32Array(a.size);
|
|
423
|
+
|
|
424
|
+
for (let i = 0; i < rows; i++) {
|
|
425
|
+
for (let j = 0; j < cols; j++) {
|
|
426
|
+
out[j * rows + i] = a.data[i * cols + j];
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
return ndarray(out, [cols, rows]);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Dot product (1D vectors) or matrix multiplication (2D simplified)
|
|
435
|
+
*/
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
function dot(a, b) {
|
|
439
|
+
// Vector dot product
|
|
440
|
+
if (a.shape.length === 1 && b.shape.length === 1) {
|
|
441
|
+
if (a.size !== b.size) {
|
|
442
|
+
throw new Error('Vectors must have same length');
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
let sum = 0;
|
|
446
|
+
|
|
447
|
+
for (let i = 0; i < a.size; i++) {
|
|
448
|
+
sum += a.data[i] * b.data[i];
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return sum;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
throw new Error('dot currently supports only 1D vectors');
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Matrix multiplication (2D only)
|
|
459
|
+
*/
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
function matmul(a, b) {
|
|
463
|
+
if (a.shape.length !== 2 || b.shape.length !== 2) {
|
|
464
|
+
throw new Error('matmul supports only 2D matrices');
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const [m, n] = a.shape;
|
|
468
|
+
const [n2, p] = b.shape;
|
|
469
|
+
|
|
470
|
+
if (n !== n2) {
|
|
471
|
+
throw new Error('Inner dimensions must match for matmul');
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
const out = new Float32Array(m * p);
|
|
475
|
+
|
|
476
|
+
for (let i = 0; i < m; i++) {
|
|
477
|
+
for (let j = 0; j < p; j++) {
|
|
478
|
+
let sum = 0;
|
|
479
|
+
|
|
480
|
+
for (let k = 0; k < n; k++) {
|
|
481
|
+
sum += a.data[i * n + k] * b.data[k * p + j];
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
out[i * p + j] = sum;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
return ndarray(out, [m, p]);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export { acos, add, areShapesEqual, array, asin, atan, cos, div, dot, exp, getSize, log, map, matmul, mul, ndarray, ones, reshape, sin, sqrt, sub, tan, transpose, validateShape, zeros };
|
|
492
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/ndarray/ndarray.js","../src/utils/isTypedArray.js","../src/utils/flatten.js","../src/ndarray/shape.js","../src/ndarray/create.js","../src/ndarray/reshape.js","../src/broadcast/rules.js","../src/broadcast/broadcast.js","../src/ops/map.js","../src/ops/add.js","../src/ops/sub.js","../src/ops/mul.js","../src/ops/div.js","../src/math/sqrt.js","../src/math/exp.js","../src/math/log.js","../src/math/trig.js","../src/linalg/transpose.js","../src/linalg/dot.js","../src/linalg/matmul.js"],"sourcesContent":["/**\r\n * Core ndarray structure\r\n * Stores:\r\n * - data (TypedArray)\r\n * - shape\r\n * - stride (for indexing)\r\n */\r\n\r\nfunction computeStride(shape) {\r\n const stride = new Array(shape.length);\r\n let acc = 1;\r\n\r\n for (let i = shape.length - 1; i >= 0; i--) {\r\n stride[i] = acc;\r\n acc *= shape[i];\r\n }\r\n\r\n return stride;\r\n}\r\n\r\nexport function ndarray(data, shape) {\r\n if (!(data instanceof Float32Array)) {\r\n throw new TypeError('Data must be Float32Array');\r\n }\r\n\r\n if (!Array.isArray(shape)) {\r\n throw new TypeError('Shape must be an array');\r\n }\r\n\r\n const size = shape.reduce((a, b) => a * b, 1);\r\n\r\n if (size !== data.length) {\r\n throw new Error('Data size does not match shape');\r\n }\r\n\r\n return {\r\n data,\r\n shape,\r\n stride: computeStride(shape),\r\n size\r\n };\r\n}","/**\r\n * Check if a value is a TypedArray\r\n * Covers all standard JS typed arrays.\r\n */\r\n\r\nexport function isTypedArray(value) {\r\n return (\r\n value != null &&\r\n typeof value === 'object' &&\r\n ArrayBuffer.isView(value) &&\r\n !(value instanceof DataView)\r\n );\r\n}","/**\r\n * Flatten nested arrays into a flat TypedArray\r\n * Also returns the inferred shape.\r\n *\r\n * Example:\r\n * flatten([[1,2],[3,4]])\r\n * → { data: Float32Array([1,2,3,4]), shape: [2,2] }\r\n */\r\n\r\nimport { isTypedArray } from './isTypedArray.js';\r\n\r\nexport function flatten(input) {\r\n const shape = [];\r\n const flat = [];\r\n\r\n function recurse(arr, depth) {\r\n if (Array.isArray(arr)) {\r\n if (shape.length <= depth) {\r\n shape.push(arr.length);\r\n } else if (shape[depth] !== arr.length) {\r\n throw new Error('Inconsistent array shape');\r\n }\r\n\r\n for (let i = 0; i < arr.length; i++) {\r\n recurse(arr[i], depth + 1);\r\n }\r\n } else if (isTypedArray(arr)) {\r\n // Treat typed arrays as leaf nodes\r\n for (let i = 0; i < arr.length; i++) {\r\n flat.push(arr[i]);\r\n }\r\n } else if (typeof arr === 'number') {\r\n flat.push(arr);\r\n } else {\r\n throw new TypeError('Unsupported data type in array');\r\n }\r\n }\r\n\r\n recurse(input, 0);\r\n\r\n return {\r\n data: new Float32Array(flat),\r\n shape\r\n };\r\n}","/**\r\n * Shape utilities\r\n */\r\n\r\nexport function getSize(shape) {\r\n return shape.reduce((a, b) => a * b, 1);\r\n}\r\n\r\nexport function validateShape(shape) {\r\n if (!Array.isArray(shape)) {\r\n throw new TypeError('Shape must be an array');\r\n }\r\n\r\n for (let i = 0; i < shape.length; i++) {\r\n const dim = shape[i];\r\n\r\n if (!Number.isInteger(dim) || dim <= 0) {\r\n throw new Error('Shape must contain positive integers');\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\nexport function areShapesEqual(a, b) {\r\n if (a.length !== b.length) return false;\r\n\r\n for (let i = 0; i < a.length; i++) {\r\n if (a[i] !== b[i]) return false;\r\n }\r\n\r\n return true;\r\n}","/**\r\n * Array creation functions\r\n */\r\n\r\nimport { ndarray } from './ndarray.js';\r\nimport { flatten } from '../utils/flatten.js';\r\nimport { getSize, validateShape } from './shape.js';\r\n\r\n/**\r\n * Create ndarray from nested array\r\n */\r\nexport function array(input) {\r\n const { data, shape } = flatten(input);\r\n return ndarray(data, shape);\r\n}\r\n\r\n/**\r\n * Create array filled with zeros\r\n */\r\nexport function zeros(shape) {\r\n validateShape(shape);\r\n\r\n const size = getSize(shape);\r\n const data = new Float32Array(size); // auto zero-filled\r\n\r\n return ndarray(data, shape);\r\n}\r\n\r\n/**\r\n * Create array filled with ones\r\n */\r\nexport function ones(shape) {\r\n validateShape(shape);\r\n\r\n const size = getSize(shape);\r\n const data = new Float32Array(size);\r\n\r\n for (let i = 0; i < size; i++) {\r\n data[i] = 1;\r\n }\r\n\r\n return ndarray(data, shape);\r\n}","/**\r\n * Reshape ndarray without changing data\r\n */\r\n\r\nimport { ndarray } from './ndarray.js';\r\nimport { getSize, validateShape } from './shape.js';\r\n\r\nexport function reshape(arr, newShape) {\r\n validateShape(newShape);\r\n\r\n const newSize = getSize(newShape);\r\n\r\n if (newSize !== arr.size) {\r\n throw new Error('Total size must remain the same in reshape');\r\n }\r\n\r\n // reuse same data buffer (fast)\r\n return ndarray(arr.data, newShape);\r\n}","/**\r\n * Broadcasting rules (NumPy-style)\r\n *\r\n * Align shapes from right to left:\r\n * - Dimensions must be equal OR one must be 1\r\n */\r\n\r\nexport function broadcastShapes(shapeA, shapeB) {\r\n const result = [];\r\n\r\n const len = Math.max(shapeA.length, shapeB.length);\r\n\r\n for (let i = 0; i < len; i++) {\r\n const a = shapeA[shapeA.length - 1 - i] ?? 1;\r\n const b = shapeB[shapeB.length - 1 - i] ?? 1;\r\n\r\n if (a === b || a === 1 || b === 1) {\r\n result.unshift(Math.max(a, b));\r\n } else {\r\n throw new Error(\r\n `Cannot broadcast shapes ${shapeA} and ${shapeB}`\r\n );\r\n }\r\n }\r\n\r\n return result;\r\n}","/**\r\n * Broadcasting execution helpers\r\n */\r\n\r\nimport { broadcastShapes } from './rules.js';\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\n/**\r\n * Compute stride for shape\r\n */\r\nfunction computeStride(shape) {\r\n const stride = new Array(shape.length);\r\n let acc = 1;\r\n\r\n for (let i = shape.length - 1; i >= 0; i--) {\r\n stride[i] = acc;\r\n acc *= shape[i];\r\n }\r\n\r\n return stride;\r\n}\r\n\r\n/**\r\n * Convert flat index → multi-dimensional index\r\n */\r\nfunction unravelIndex(index, shape) {\r\n const idx = new Array(shape.length);\r\n\r\n for (let i = 0; i < shape.length; i++) {\r\n const stride = shape.slice(i + 1).reduce((a, b) => a * b, 1);\r\n idx[i] = Math.floor(index / stride) % shape[i];\r\n }\r\n\r\n return idx;\r\n}\r\n\r\n/**\r\n * Convert multi-index → flat index\r\n */\r\nfunction ravelIndex(idx, stride) {\r\n let index = 0;\r\n for (let i = 0; i < idx.length; i++) {\r\n index += idx[i] * stride[i];\r\n }\r\n return index;\r\n}\r\n\r\n/**\r\n * Apply broadcasting for two ndarrays\r\n */\r\nexport function broadcastBinaryOp(a, b, fn) {\r\n const outShape = broadcastShapes(a.shape, b.shape);\r\n const outSize = outShape.reduce((x, y) => x * y, 1);\r\n\r\n const out = new Float32Array(outSize);\r\n\r\n const strideA = computeStride(a.shape);\r\n const strideB = computeStride(b.shape);\r\n\r\n const offsetA = outShape.length - a.shape.length;\r\n const offsetB = outShape.length - b.shape.length;\r\n\r\n for (let i = 0; i < outSize; i++) {\r\n const idx = unravelIndex(i, outShape);\r\n\r\n let indexA = 0;\r\n let indexB = 0;\r\n\r\n for (let d = 0; d < outShape.length; d++) {\r\n const aDim = a.shape[d - offsetA] ?? 1;\r\n const bDim = b.shape[d - offsetB] ?? 1;\r\n\r\n const iA = aDim === 1 ? 0 : idx[d];\r\n const iB = bDim === 1 ? 0 : idx[d];\r\n\r\n if (d - offsetA >= 0) {\r\n indexA += iA * strideA[d - offsetA];\r\n }\r\n\r\n if (d - offsetB >= 0) {\r\n indexB += iB * strideB[d - offsetB];\r\n }\r\n }\r\n\r\n out[i] = fn(a.data[indexA], b.data[indexB]);\r\n }\r\n\r\n return ndarray(out, outShape);\r\n}","/**\r\n * Core element-wise operation engine\r\n * Supports:\r\n * - ndarray + ndarray (with broadcasting)\r\n * - ndarray + scalar\r\n * - scalar + ndarray\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\nimport { broadcastBinaryOp } from '../broadcast/broadcast.js';\r\n\r\nexport function map(a, b, fn) {\r\n const isAScalar = typeof a === 'number';\r\n const isBScalar = typeof b === 'number';\r\n\r\n // Case 1: scalar + scalar\r\n if (isAScalar && isBScalar) {\r\n return fn(a, b);\r\n }\r\n\r\n // Case 2: ndarray + scalar\r\n if (!isAScalar && isBScalar) {\r\n const out = new Float32Array(a.size);\r\n\r\n for (let i = 0; i < a.size; i++) {\r\n out[i] = fn(a.data[i], b);\r\n }\r\n\r\n return ndarray(out, a.shape);\r\n }\r\n\r\n // Case 3: scalar + ndarray\r\n if (isAScalar && !isBScalar) {\r\n const out = new Float32Array(b.size);\r\n\r\n for (let i = 0; i < b.size; i++) {\r\n out[i] = fn(a, b.data[i]);\r\n }\r\n\r\n return ndarray(out, b.shape);\r\n }\r\n\r\n // Case 4: ndarray + ndarray (with broadcasting)\r\n return broadcastBinaryOp(a, b, fn);\r\n}","import { map } from './map.js';\r\n\r\nexport function add(a, b) {\r\n return map(a, b, (x, y) => x + y);\r\n}","import { map } from './map.js';\r\n\r\nexport function sub(a, b) {\r\n return map(a, b, (x, y) => x - y);\r\n}","import { map } from './map.js';\r\n\r\nexport function mul(a, b) {\r\n return map(a, b, (x, y) => x * y);\r\n}","import { map } from './map.js';\r\n\r\nexport function div(a, b) {\r\n return map(a, b, (x, y) => x / y);\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise square root\r\n */\r\nexport function sqrt(a) {\r\n return map(a, 0, (x) => Math.sqrt(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise exponential (e^x)\r\n */\r\nexport function exp(a) {\r\n return map(a, 0, (x) => Math.exp(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Element-wise natural logarithm (ln)\r\n */\r\nexport function log(a) {\r\n return map(a, 0, (x) => Math.log(x));\r\n}","import { map } from '../ops/map.js';\r\n\r\n/**\r\n * Trigonometric functions (element-wise)\r\n */\r\n\r\nexport function sin(a) {\r\n return map(a, 0, (x) => Math.sin(x));\r\n}\r\n\r\nexport function cos(a) {\r\n return map(a, 0, (x) => Math.cos(x));\r\n}\r\n\r\nexport function tan(a) {\r\n return map(a, 0, (x) => Math.tan(x));\r\n}\r\n\r\nexport function asin(a) {\r\n return map(a, 0, (x) => Math.asin(x));\r\n}\r\n\r\nexport function acos(a) {\r\n return map(a, 0, (x) => Math.acos(x));\r\n}\r\n\r\nexport function atan(a) {\r\n return map(a, 0, (x) => Math.atan(x));\r\n}","/**\r\n * Transpose a 2D ndarray\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function transpose(a) {\r\n if (a.shape.length !== 2) {\r\n throw new Error('Transpose currently supports only 2D arrays');\r\n }\r\n\r\n const [rows, cols] = a.shape;\r\n\r\n const out = new Float32Array(a.size);\r\n\r\n for (let i = 0; i < rows; i++) {\r\n for (let j = 0; j < cols; j++) {\r\n out[j * rows + i] = a.data[i * cols + j];\r\n }\r\n }\r\n\r\n return ndarray(out, [cols, rows]);\r\n}","/**\r\n * Dot product (1D vectors) or matrix multiplication (2D simplified)\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function dot(a, b) {\r\n // Vector dot product\r\n if (a.shape.length === 1 && b.shape.length === 1) {\r\n if (a.size !== b.size) {\r\n throw new Error('Vectors must have same length');\r\n }\r\n\r\n let sum = 0;\r\n\r\n for (let i = 0; i < a.size; i++) {\r\n sum += a.data[i] * b.data[i];\r\n }\r\n\r\n return sum;\r\n }\r\n\r\n throw new Error('dot currently supports only 1D vectors');\r\n}","/**\r\n * Matrix multiplication (2D only)\r\n */\r\n\r\nimport { ndarray } from '../ndarray/ndarray.js';\r\n\r\nexport function matmul(a, b) {\r\n if (a.shape.length !== 2 || b.shape.length !== 2) {\r\n throw new Error('matmul supports only 2D matrices');\r\n }\r\n\r\n const [m, n] = a.shape;\r\n const [n2, p] = b.shape;\r\n\r\n if (n !== n2) {\r\n throw new Error('Inner dimensions must match for matmul');\r\n }\r\n\r\n const out = new Float32Array(m * p);\r\n\r\n for (let i = 0; i < m; i++) {\r\n for (let j = 0; j < p; j++) {\r\n let sum = 0;\r\n\r\n for (let k = 0; k < n; k++) {\r\n sum += a.data[i * n + k] * b.data[k * p + j];\r\n }\r\n\r\n out[i * p + j] = sum;\r\n }\r\n }\r\n\r\n return ndarray(out, [m, p]);\r\n}"],"names":["computeStride"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "starlight-numera",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A performance-focused numerical computing library for JavaScript inspired by NumPy",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"require": "./dist/index.cjs"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "rollup -c",
|
|
19
|
+
"dev": "rollup -c -w",
|
|
20
|
+
"test": "echo \"No tests yet\"",
|
|
21
|
+
"bench": "node benchmarks/performance.test.js"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"math",
|
|
25
|
+
"numerical",
|
|
26
|
+
"ndarray",
|
|
27
|
+
"matrix",
|
|
28
|
+
"linear-algebra",
|
|
29
|
+
"numpy",
|
|
30
|
+
"vector",
|
|
31
|
+
"performance",
|
|
32
|
+
"scientific-computing"
|
|
33
|
+
],
|
|
34
|
+
"author": "Dominex Macedon",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"rollup": "^4.0.0",
|
|
38
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
39
|
+
"@rollup/plugin-commonjs": "^25.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|