function bandPart_(a, numLower, numUpper) {
    const $a = (0, _tensorUtilEnv.convertToTensor)(a, "a", "bandPart");
    (0, _util.assert)($a.rank >= 2, ()=>`bandPart(): Rank must be at least 2, got ${$a.rank}.`);
    const shape = $a.shape;
    const [M, N] = $a.shape.slice(-2);
    let $numLower;
    let $numUpper;
    if (typeof numLower === "number") {
        (0, _util.assert)(numLower % 1 === 0, ()=>`bandPart(): numLower must be an integer, got ${numLower}.`);
        (0, _util.assert)(numLower <= M, ()=>`bandPart(): numLower (${numLower})` + ` must not be greater than the number of rows (${M}).`);
        $numLower = (0, _tensorUtilEnv.convertToTensor)(numLower < 0 ? M : numLower, "numLower", "bandPart");
    } else {
        (0, _util.assert)(numLower.dtype === "int32", ()=>`bandPart(): numLower's dtype must be an int32.`);
        // If numLower is a Scalar, checking `numLower <= M` could hurt performance,
        // but minimum(numLower, M) could avoid unexpected results.
        $numLower = (0, _where.where)((0, _less.less)(numLower, 0), M, (0, _minimum.minimum)(numLower, M));
    }
    if (typeof numUpper === "number") {
        (0, _util.assert)(numUpper % 1 === 0, ()=>`bandPart(): numUpper must be an integer, got ${numUpper}.`);
        (0, _util.assert)(numUpper <= N, ()=>`bandPart(): numUpper (${numUpper})` + ` must not be greater than the number of columns (${N}).`);
        $numUpper = (0, _tensorUtilEnv.convertToTensor)(numUpper < 0 ? N : numUpper, "numUpper", "bandPart");
    } else {
        (0, _util.assert)(numUpper.dtype === "int32", ()=>`bandPart(): numUpper's dtype must be an int32.`);
        $numUpper = (0, _where.where)((0, _less.less)(numUpper, 0), N, (0, _minimum.minimum)(numUpper, N));
    }
    const i = (0, _reshape.reshape)((0, _range.range)(0, M, 1, "int32"), [
        -1,
        1
    ]);
    const j = (0, _range.range)(0, N, 1, "int32");
    const ij = (0, _sub.sub)(i, j);
    const inBand = (0, _logicalAnd.logicalAnd)((0, _lessEqual.lessEqual)(ij, $numLower), (0, _greaterEqual.greaterEqual)(ij, (0, _neg.neg)($numUpper)));
    const zero = (0, _zeros.zeros)([
        M,
        N
    ], $a.dtype);
    return (0, _reshape.reshape)((0, _stack.stack)((0, _unstack.unstack)((0, _reshape.reshape)($a, [
        -1,
        M,
        N
    ])).map((mat)=>(0, _where.where)(inBand, mat, zero))), shape);
}
Copy a tensor setting everything outside a central band in each innermost
matrix to zero.

The band part is computed as follows: Assume input has `k` dimensions
`[I, J, K, ..., M, N]`, then the output is a tensor with the same shape where
`band[i, j, k, ..., m, n] = in_band(m, n) * input[i, j, k, ..., m, n]`.
The indicator function
`in_band(m, n) = (num_lower < 0 || (m-n) <= num_lower)`
`&& (num_upper < 0 || (n-m) <= num_upper)`

```js
const x = tf.tensor2d([[ 0,  1,  2, 3],
                       [-1,  0,  1, 2],
                       [-2, -1,  0, 1],
                       [-3, -2, -1, 0]]);
let y = tf.linalg.bandPart(x, 1, -1);
y.print(); // [[ 0,  1,  2, 3],
           //  [-1,  0,  1, 2],
           //  [ 0, -1,  0, 1],
           //  [ 0, 0 , -1, 0]]
let z = tf.linalg.bandPart(x, 2, 1);
z.print(); // [[ 0,  1,  0, 0],
           //  [-1,  0,  1, 0],
           //  [-2, -1,  0, 1],
           //  [ 0, -2, -1, 0]]
```

@param x Rank `k` tensor
@param numLower Number of subdiagonals to keep.
  If negative, keep entire lower triangle.
@param numUpper Number of subdiagonals to keep.
  If negative, keep entire upper triangle.
@returns Rank `k` tensor of the same shape as input.
  The extracted banded tensor.

@doc {heading:'Operations', subheading:'Linear Algebra', namespace:'linalg'}