matrix
matrix copied to clipboard
Apply function row/column-wise
Hello,
thanks for the great library, I use it quite often in my work. Something I didn't find in the API and thus copy around my projects is an apply
function? Like R's apply
or numpy's apply_along_axis
.
It seems like a simple function, my implementation is basically
function apply(M, fun, axis = 1) {
// axis = 0: apply and collapse along cols (= output length is # rows)
// axis = 1: apply and collapse along rows (= output length is # cols)
const collapseRows = axis === 1;
const n = collapseRows ? M.columns : M.rows;
const result = [];
for (let i = 0; i < n; i++) {
const x = collapseRows ? M.getColumn(i) : M.getRow(i);
result.push(fun(x));
}
return Matrix.rowVector(result); // NOTE could also be columnVector depending on `axis`, I just never wanted one...
}
Would this be something that you would consider adding to your library?
This seems like a useful feature. Pull request welcome (please add test cases and update matrix.d.ts
)!
We suggest the following signature:
class Matrix {
applyAlongAxis(
callback: (vector: number[], index: number) => number,
by: MatrixDimension
): Matrix
}
class MatrixExt extends Matrix {
mapColumns(fun: (column: number[], rowIndex: number, matrix: this) => number | number[]): Matrix {
const n = this.columns;
const result = Array();
for (let i = 0; i < n; i++) {
const x = this.getColumn(i)
result.push(fun(x, i, this));
}
if (Array.isArray(result[0])) {
return new Matrix(result).transpose()
} else {
return Matrix.rowVector(result);
}
}
}
let m = new MatrixExt([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
console.log(
m,
/**
* Matrix {
* [
* 147 258 369
* ]
*/
m.mapColumns(
(row, i, a) => row.reduce((r, x) => r * 10 + x)
),
/**
* Matrix {
* [
* 1 2 3
* 11 22 33
* 4 5 6
* 44 55 66
* 7 8 9
* 77 88 99
* ]
*/
m.mapColumns(
(row, i, a) => row.flatMap(x => [x, x * 11])
),
)
Here's implementation of an extended variant
What part of it is technically usable?
Hi, sorry for the late reply, I have actually no idea where the notifications go, if they go somewhere at all.
@Dimava: I like your approach because it's more flexible regarding the resulting matrix dimensions.
@targos: What do you think about it? Should it rather match what exists in other libraries / languages?