static calcReduce(a, axes, keepdims, op1, op2) {
        const dims = a.dims.slice(0);
        // if axes is not set, perform reduce on all axes
        if (axes.length === 0) {
            dims.forEach((d, ind) => axes.push(ind));
        }
        // get a temporary broadcastable output shape
        const outputDims = ReduceUtil.calcReduceShape(dims, axes, true);
        // loop through the output and calculate result one by one
        const size = ShapeUtil.size(outputDims);
        const y = new tensor_1.Tensor(outputDims, a.type);
        const strides = ShapeUtil.computeStrides(outputDims);
        const inputStrides = ShapeUtil.computeStrides(dims);
        const indicesY = new Array(dims.length);
        for (let i = 0; i < size; i++) {
            const indices = ShapeUtil.offsetToIndices(i, strides);
            // map index
            BroadcastUtil.fillIndex(indices, dims, indicesY);
            y.set(indices, ReduceUtil.calcReduceByAxis(a.numberData, axes, dims, 0, ShapeUtil.indicesToOffset(indicesY, inputStrides), op1, op2));
        }
        if (keepdims) {
            return y;
        }
        else {
            // keepdims == 0, calculate the expected shape
            return new tensor_1.Tensor(ReduceUtil.calcReduceShape(dims, axes, keepdims), y.type, undefined, undefined, y.data, y.dataId);
        }
    }
/**
     * Perform reduce operations on the specific operator
     * @param a Input tensor data
     * @param axes The dimensions along which the Tensor will be reduced
     * @param keepdims If set to true, the axes which are reduced are left in the
     *    result as dimensions with size one.
     * @param op1 The operation to be performed on each element in the tensor
     * @param op2 The operation to be performed between elements in the tensor
     */
Perform reduce operations on the specific operator
@param a Input tensor data
@param axes The dimensions along which the Tensor will be reduced
@param keepdims If set to true, the axes which are reduced are left in the
result as dimensions with size one.
@param op1 The operation to be performed on each element in the tensor
@param op2 The operation to be performed between elements in the tensor
Perform reduce operations on the specific operator @param a Input tensor data @param axes The dimensions along which the Tensor will be reduced @param keepdims If set to true the axes which are reduced are left in the result as dimensions with size one . @param op1 The operation to be performed on each element in the tensor @param op2 The operation to be performed between elements in the tensor
static calcReduce(a, axes, keepdims, op1, op2) {
        const dims = a.dims.slice(0);
        if (axes.length === 0) {
            dims.forEach((d, ind) => axes.push(ind));
        }
        const outputDims = ReduceUtil.calcReduceShape(dims, axes, true);
        const size = ShapeUtil.size(outputDims);
        const y = new tensor_1.Tensor(outputDims, a.type);
        const strides = ShapeUtil.computeStrides(outputDims);
        const inputStrides = ShapeUtil.computeStrides(dims);
        const indicesY = new Array(dims.length);
        for (let i = 0; i < size; i++) {
            const indices = ShapeUtil.offsetToIndices(i, strides);
            BroadcastUtil.fillIndex(indices, dims, indicesY);
            y.set(indices, ReduceUtil.calcReduceByAxis(a.numberData, axes, dims, 0, ShapeUtil.indicesToOffset(indicesY, inputStrides), op1, op2));
        }
        if (keepdims) {
            return y;
        }
        else {
            return new tensor_1.Tensor(ReduceUtil.calcReduceShape(dims, axes, keepdims), y.type, undefined, undefined, y.data, y.dataId);
        }
    }
static calcReduce ( a , axes , keepdims , op1 , op2 ) { const dims = a . dims . slice ( 0 ) ; if ( axes . length === 0 ) { dims . forEach ( ( d , ind ) => axes . push ( ind ) ) ; } const outputDims = ReduceUtil . calcReduceShape ( dims , axes , true ) ; const size = ShapeUtil . size ( outputDims ) ; const y = new tensor_1 . Tensor ( outputDims , a . type ) ; const strides = ShapeUtil . computeStrides ( outputDims ) ; const inputStrides = ShapeUtil . computeStrides ( dims ) ; const indicesY = new Array ( dims . length ) ; for ( let i = 0 ; i < size ; i ++ ) { const indices = ShapeUtil . offsetToIndices ( i , strides ) ; BroadcastUtil . fillIndex ( indices , dims , indicesY ) ; y . set ( indices , ReduceUtil . calcReduceByAxis ( a . numberData , axes , dims , 0 , ShapeUtil . indicesToOffset ( indicesY , inputStrides ) , op1 , op2 ) ) ; } if ( keepdims ) { return y ; } else { return new tensor_1 . Tensor ( ReduceUtil . calcReduceShape ( dims , axes , keepdims ) , y . type , undefined , undefined , y . data , y . dataId ) ; } }
Perform reduce operations on the specific operator
 @param a Input tensor data
 @param axes The dimensions along which the Tensor will be reduced
 @param keepdims If set to true, the axes which are reduced are left in the
    result as dimensions with size one.
Perform reduce operations on the specific operator @param a Input tensor data @param axes The dimensions along which the Tensor will be reduced @param keepdims If set to true the axes which are reduced are left in the result as dimensions with size one .
// if axes is not set, perform reduce on all axes // get a temporary broadcastable output shape // loop through the output and calculate result one by one // map index // keepdims == 0, calculate the expected shape