nicolaspanel / numjs

Like NumPy, in JavaScript
MIT License
2.4k stars 184 forks source link

Provide concatenate along other axes #104

Open RReverser opened 3 years ago

RReverser commented 3 years ago

While README mentions that it's possible to achieve concatenation along various axes by using transposition, it's pretty hard to wrap my head around how to do that on multi-dimensional arrays. It would be a lot easier if such concatenation was part of the user-facing API, like it is in numpy.

Example code that I'm trying to convert right now:

        image = np.concatenate((image, image[(h - dh) :, :, :]), axis = 0)
        image = np.concatenate((image, image[:, (w - dw) :, :]), axis = 1)

        image = np.concatenate((image, image[(h - offset) :, :, :]), axis = 0)
        image = np.concatenate((image[: offset, :, :], image), axis = 0)
        image = np.concatenate((image, image[:, (w - offset) :, :]), axis = 1)
        image = np.concatenate((image[:, : offset, :], image), axis = 1)

Even if I manage to rewrite it using transpositions, I feel it won't be very readable / maintainable going forward.

RReverser commented 3 years ago

This is what I came up with for now as a helper that seems to work:

function concatenateAlong(axis, ...arrays) {
  let lastAxis = arrays[0].shape.length - 1;
  let axes = arrays[0].shape.map((_, i) => {
    // swap the required axis with the last one
    switch (i) {
      case lastAxis:
        return axis;
      case axis:
        return lastAxis;
      default:
        return i;
    }
  });
  arrays = arrays.map(a => a.transpose(...axes));
  let result = numjs.concatenate(...arrays);
  return result.transpose(...axes);
}

Does it look reasonable? Is it perhaps worth adding it to the library?