ndarray/tensor data processing for modern browsers
MIT License
Easy n-dimensional data manipulation with NumPy syntax.
npm i nadder # or yarn add nadder, or pnpm add nadder
import { ndarray, array, add, evaluate, arange } from 'nadder';
const dataSource = new Float32Array(1_000_000);
// load data into dataSource manually here...
// Initialize (1000, 1000) ndarray
const t = ndarray(dataSource, [1000, 1000]);
// NumPy slicing fully supported
console.log(t['100:110, 305:300:-1']);
t['..., :100'] = 1.23;
// np.newaxis is now +
console.log(t['0, 0, +']);
const leapYears = Array.from(
{ length: 1000 },
(_, i) => i % 4 == 0 && (i % 400 == 0 || i % 100 != 0)
);
// nadder.array automatically creates an efficient representation of your
// Array object and translates nested lists into dimensions in the ndarray
const boolIndex = array(leapYears);
// You can even use other ndarrays in the indices!
console.log(t[`..., ${boolIndex}`]);
// You can evaluate things using a Python-esque DSL
console.log(evaluate`${t}[:, 0] * 2 + 1 / ${arange(1000)}`)
// ufuncs also supported through explicit syntax
// broadcasting, typecasting done automatically
console.log(add(t, boolIndex));
The embedded DSL supports a wide variety of common constructs and Python syntax (e.g. @
matrix multiplication, //
floor division, keyword arguments). All syntax works both on scalars and ndarrays. The DSL can also use JavaScript values interpolated within the code.
import { parse, argument, arange } from 'nadder';
const calcTrace = parse`
mat = ${argument('matrix')}.astype(float64);
n = mat.shape[0];
trace = 0;
if ${process.env.DEBUG} {
${console.log}(mat);
}
for i in arange(n) {
trace += mat[i, i];
}
# Last line with no semicolon is the return value
trace
`;
// 13
const example = calcTrace({
matrix: array([
[1, 4, 5],
[2, 3, 6],
[7, 1, 9]
])
});
// [154., 158., 162., 166., 170.]
const multiElem = calcTrace({
matrix: arange(1, 81).reshape(4, 4, 5)
});
evaluate
evaluate
matmul
MIT