function concatenate (arrays) {
  if (arguments.length > 1) {
    arrays = [].slice.call(arguments);
  }
  var i, a;
  for (i = 0; i < arrays.length; i++) {
    a = arrays[i];
    arrays[i] = (a instanceof NdArray) ? a.tolist() : _.isNumber(a) ? [a] : a;
  }
  var m = arrays[0];
  for (i = 1; i < arrays.length; i++) {
    a = arrays[i];
    var mShape = _.getShape(m);
    var aShape = _.getShape(a);
    if (mShape.length !== aShape.length) {
      throw new errors.ValueError('all the input arrays must have same number of dimensions');
    } else if (mShape.length === 1 && aShape.length === 1) {
      m = m.concat(a);
    } else if ((mShape.length === 2 && aShape.length === 2 && mShape[0] === aShape[0]) ||
      (mShape.length === 1 && aShape.length === 2 && mShape[0] === aShape[0]) ||
      (mShape.length === 2 && aShape.length === 1 && mShape[0] === aShape[0])) {
      for (var row = 0; row < mShape[0]; row++) {
        m[row] = m[row].concat(a[row]);
      }
    } else if ((mShape.length === 3 && aShape.length === 3 && mShape[0] === aShape[0] && mShape[1] === aShape[1]) ||
      (mShape.length === 2 && aShape.length === 3 && mShape[0] === aShape[0] && mShape[1] === aShape[1]) ||
      (mShape.length === 3 && aShape.length === 2 && mShape[0] === aShape[0] && mShape[1] === aShape[1])) {
      for (var rowI = 0; rowI < mShape[0]; rowI++) {
        var rowV = new Array(mShape[1]);
        for (var colI = 0; colI < mShape[1]; colI++) {
          rowV[colI] = m[rowI][colI].concat(a[rowI][colI]);
        }
        m[rowI] = rowV;
      }
    } else {
      throw new errors.ValueError('cannot concatenate  "' + mShape + '" with "' + aShape + '"');
    }
  }
  return NdArray.new(m, arrays[0].dtype);
}
Join given arrays along the last axis.

@param {...(Array|NdArray)} arrays
@returns {NdArray}