nd4j-backends/nd4j-api-parent/nd4j-api/src/main/java/org/nd4j/linalg/indexing/ShapeOffsetResolution.java
public void exec(INDArrayIndex... indexes) {
        val shape = arr.shape();

        if (arr.isSparse()) {
            resolveFixedDimensionsCOO(indexes);
        }

        // Check that given point indexes are not out of bounds
        for (int i = 0; i < indexes.length; i++) {
            INDArrayIndex idx = indexes[i];
            // On vectors, the first dimension can be ignored when indexing them with a single point index
            if (idx instanceof PointIndex && (arr.isVector() && indexes.length == 1 ? idx.current() >= shape[i + 1]
                    : idx.current() >= shape[i])) {
                throw new IllegalArgumentException(
                        "INDArrayIndex[" + i + "] is out of bounds (value: " + idx.current() + ")");
            }
        }

        indexes = NDArrayIndex.resolve(arr.shapeInfoDataBuffer(), indexes);
        if (tryShortCircuit(indexes)) {
            return;
        }


        int numIntervals = 0;
        //number of new axes dimensions to prepend to the beginning
        int newAxesPrepend = 0;
        //whether we have encountered an all so far
        boolean encounteredAll = false;
        int lastPrependIndex = -1;
        List<Integer> oneDimensionWithAllEncountered = new ArrayList<>();

        //accumulate the results
        List<Long> accumShape = new ArrayList<>();
        List<Long> accumStrides = new ArrayList<>();
        List<Long> accumOffsets = new ArrayList<>();
        List<Long> intervalStrides = new ArrayList<>();

        //collect the indexes of the points that get removed
        //for point purposes
        //this will be used to compute the offset
        //for the new array
        List<Long> pointStrides = new ArrayList<>();
        List<Long> pointOffsets = new ArrayList<>();
        int numPointIndexes = 0;

        //bump number to read from the shape
        int shapeIndex = 0;
        //stride index to read strides from the array
        int strideIndex = 0;
        //list of indexes to prepend to for new axes
        //if all is encountered
        List<Integer> prependNewAxes = new ArrayList<>();
        for (int i = 0; i < indexes.length; i++) {
            INDArrayIndex idx = indexes[i];
            if (idx instanceof NDArrayIndexAll) {
                encounteredAll = true;
                if (i < arr.rank() && arr.size(i) == 1)
                    oneDimensionWithAllEncountered.add(i);
                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }
            }
            //point: do nothing but move the shape counter
            //also move the stride counter
            if (idx instanceof PointIndex) {
                pointOffsets.add(idx.offset());
                pointStrides.add((long) arr.stride(strideIndex));
                numPointIndexes++;
                shapeIndex++;
                strideIndex++;
                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }
                continue;
            }
            //new axes encountered, need to track whether to prepend or
            //to set the new axis in the middle
            else if (idx instanceof NewAxis) {
                //prepend the new axes at different indexes
                accumShape.add(1L);
                accumOffsets.add(0L);
                accumStrides.add(0L);
                prependNewAxes.add(i);
                continue;

            }

            //points and intervals both have a direct desired length
            else if (idx instanceof IntervalIndex && !(idx instanceof NDArrayIndexAll)
                    || idx instanceof SpecifiedIndex) {
                if (idx instanceof IntervalIndex) {
                    accumStrides.add(arr.stride(strideIndex) * idx.stride());
                    //used in computing an adjusted offset for the augmented strides
                    intervalStrides.add(idx.stride());
                    numIntervals++;
                }

                else
                    accumStrides.add((long) arr.stride(strideIndex));
                accumShape.add(idx.length());
                //the stride stays the same
                //add the offset for the index
                if (idx instanceof IntervalIndex) {
                    accumOffsets.add(idx.offset());
                } else
                    accumOffsets.add(idx.offset());

                shapeIndex++;
                strideIndex++;

                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }


                continue;
            }

            //add the shape and stride
            //based on the original stride/shape

            accumShape.add((long) shape[shapeIndex++]);
            //account for erroneous strides from dimensions of size 1
            //move the stride index if its one and fill it in at the bottom
            accumStrides.add((long) arr.stride(strideIndex++));

            //default offsets are zero
            accumOffsets.add(idx.offset());

        }



        //fill in missing strides and shapes
        while (shapeIndex < shape.length) {
            //scalar, should be 1 x 1 rather than the number of columns in the vector
            if (Shape.isVector(shape)) {
                accumShape.add(1L);
                shapeIndex++;
            } else
                accumShape.add((long) shape[shapeIndex++]);
        }


        //fill in the rest of the offsets with zero
        int delta = (shape.length <= 2 ? shape.length : shape.length - numPointIndexes);
        boolean needsFilledIn = accumShape.size() != accumStrides.size() && accumOffsets.size() != accumShape.size();
        while (accumOffsets.size() < delta && needsFilledIn)
            accumOffsets.add(0L);


        while (accumShape.size() < 2) {
            if (Shape.isRowVectorShape(arr.shape()))
                accumShape.add(0, 1L);
            else
                accumShape.add(1L);
        }

        while (strideIndex < accumShape.size()) {
            accumStrides.add((long) arr.stride(strideIndex++));
        }


        /**
         * For each dimension
         * where we want to prepend a dimension
         * we need to add it at the index such that
         * we account for the offset of the number of indexes
         * added up to that point.
         *
         * We do this by doing an offset
         * for each item added "so far"
         *
         * Note that we also have an offset of - 1
         * because we want to prepend to the given index.
         *
         * When prepend new axes for in the middle is triggered
         * i is already > 0
         */
       /* int numAdded = 0;
        for (int i = 0; i < prependNewAxes.size(); i++) {
            accumShape.add(prependNewAxes.get(i) - numAdded, 1L);
            //stride for the new axis is zero
            accumStrides.add(prependNewAxes.get(i) - numAdded, 0L);
            numAdded++;
        }
        for (int i = 0; i < newAxesPrepend; i++) {
            prependNewAxes.add(0, i);
        }

        prependAxis = Ints.toArray(prependNewAxes);
*/
        /**
         * Need to post process strides and offsets
         * for trailing ones here
         */
        //prune off extra zeros for trailing and leading ones
        int trailingZeroRemove = accumOffsets.size() - 1;
        while (accumOffsets.size() > accumShape.size()) {
            if (accumOffsets.get(trailingZeroRemove) == 0)
                accumOffsets.remove(accumOffsets.size() - 1);
            trailingZeroRemove--;
        }

        if (accumStrides.size() < accumOffsets.size())
            accumStrides.addAll(pointStrides);
        while (accumOffsets.size() < accumShape.size()) {
            if (Shape.isRowVectorShape(arr.shape()))
                accumOffsets.add(0, 0L);
            else
                accumOffsets.add(0L);
        }


        if (Shape.isMatrix(shape) && indexes[0] instanceof PointIndex && indexes[1] instanceof NDArrayIndexAll) {
            Collections.reverse(accumShape);
        }

        if (arr.isMatrix() && indexes[0] instanceof PointIndex && indexes[1] instanceof IntervalIndex) {
            this.shapes = new long[2];
            shapes[0] = 1;
            IntervalIndex idx = (IntervalIndex) indexes[1];
            shapes[1] = idx.length();

        } else
            this.shapes = Longs.toArray(accumShape);


        boolean isColumnVector = Shape.isColumnVectorShape(this.shapes);
        //finally fill in teh rest of the strides if any are left over
        while (accumStrides.size() < accumOffsets.size()) {
            if (!isColumnVector)
                accumStrides.add(0, (long) arr.elementStride());
            else
                accumStrides.add((long) arr.elementStride());
        }


        this.strides = Longs.toArray(accumStrides);
        this.offsets = Longs.toArray(accumOffsets);

        //compute point offsets differently
        /**
         * We need to prepend the strides for the point indexes
         * such that the point index offsets are counted.
         * Note here that we only use point strides
         * when points strides isn't empty.
         * When point strides is empty, this is
         * because a point index was encountered
         * but it was the lead index and therefore should
         * not be counted with the offset.
         *
         *
         * Another thing of note here is that the strides
         * and offsets should line up such that the point
         * and stride match up.
         */
        if (numPointIndexes > 0 && !pointStrides.isEmpty()) {
            //append to the end for tensors
            if (newAxesPrepend >= 1) {
                while (pointStrides.size() < accumOffsets.size()) {
                    pointStrides.add(1L);
                }
                //identify in the original accumulate strides
                //where zero was set and emulate the
                //same structure in the point strides
                for (int i = 0; i < accumStrides.size(); i++) {
                    if (accumStrides.get(i) == 0 && !(indexes[i] instanceof NewAxis) && lastPrependIndex <= 0)
                        pointStrides.set(i, 0L);
                }
            }

            //prepend any missing offsets where relevant for the dot product
            //note here we are using the point offsets and strides
            //for computing the offset
            //the point of a point index is to drop a dimension
            //and index in to a particular offset
            while (pointOffsets.size() < pointStrides.size()) {
                pointOffsets.add(0L);
            }
            //special case where offsets aren't caught
            if (arr.isRowVector() && !intervalStrides.isEmpty() && pointOffsets.get(0) == 0
                    && !(indexes[1] instanceof IntervalIndex))
                this.offset = indexes[1].offset();
            else
                this.offset = ArrayUtil.dotProductLong2(pointOffsets, pointStrides);
        } else {
            this.offset = 0;
        }
        if (numIntervals > 0 && arr.rank() > 2) {
            if (encounteredAll && arr.size(0) != 1 || indexes[0] instanceof PointIndex)
                // FIXME: LONG
                this.offset += ArrayUtil.dotProductLong2(accumOffsets, accumStrides);
            else
                // FIXME: LONG
                this.offset += ArrayUtil.dotProductLong2(accumOffsets, accumStrides);

        } else if (numIntervals > 0 && anyHaveStrideOne(indexes))
            this.offset += ArrayUtil.calcOffsetLong2(accumShape, accumOffsets, accumStrides);
        else
            this.offset += ArrayUtil.calcOffsetLong2(accumShape, accumOffsets, accumStrides)
                    / Math.max(1, numIntervals);


        //collapse singular dimensions with specified index
        List<Integer> removeShape = new ArrayList<>();
        for (int i = 0; i < Math.min(this.shapes.length, indexes.length); i++) {
            if (this.shapes[i] == 1 && indexes[i] instanceof SpecifiedIndex) {
                removeShape.add(i);
            }
        }


        if (!removeShape.isEmpty()) {
            List<Long> newShape = new ArrayList<>();
            List<Long> newStrides = new ArrayList<>();
            for (int i = 0; i < this.shapes.length; i++) {
                if (!removeShape.contains(i)) {
                    newShape.add(this.shapes[i]);
                    newStrides.add(this.strides[i]);
                }
            }

            this.shapes = Longs.toArray(newShape);
            this.strides = Longs.toArray(newStrides);
        }

    }
public void exec(INDArrayIndex... indexes) {
        val shape = arr.shape();

        if (arr.isSparse()) {
            resolveFixedDimensionsCOO(indexes);
        }

        // Check that given point indexes are not out of bounds
        for (int i = 0; i < indexes.length; i++) {
            INDArrayIndex idx = indexes[i];
            // On vectors, the first dimension can be ignored when indexing them with a single point index
            if (idx instanceof PointIndex && (arr.isVector() && indexes.length == 1 ? idx.current() >= shape[i + 1]
                    : idx.current() >= shape[i])) {
                throw new IllegalArgumentException(
                        "INDArrayIndex[" + i + "] is out of bounds (value: " + idx.current() + ")");
            }
        }

        indexes = NDArrayIndex.resolve(arr.shapeInfoDataBuffer(), indexes);
        if (tryShortCircuit(indexes)) {
            return;
        }


        int numIntervals = 0;
        //number of new axes dimensions to prepend to the beginning
        int newAxesPrepend = 0;
        //whether we have encountered an all so far
        boolean encounteredAll = false;
        int lastPrependIndex = -1;
        List<Integer> oneDimensionWithAllEncountered = new ArrayList<>();

        //accumulate the results
        List<Long> accumShape = new ArrayList<>();
        List<Long> accumStrides = new ArrayList<>();
        List<Long> accumOffsets = new ArrayList<>();
        List<Long> intervalStrides = new ArrayList<>();

        //collect the indexes of the points that get removed
        //for point purposes
        //this will be used to compute the offset
        //for the new array
        List<Long> pointStrides = new ArrayList<>();
        List<Long> pointOffsets = new ArrayList<>();
        int numPointIndexes = 0;

        //bump number to read from the shape
        int shapeIndex = 0;
        //stride index to read strides from the array
        int strideIndex = 0;
        //list of indexes to prepend to for new axes
        //if all is encountered
        List<Integer> prependNewAxes = new ArrayList<>();
        for (int i = 0; i < indexes.length; i++) {
            INDArrayIndex idx = indexes[i];
            if (idx instanceof NDArrayIndexAll) {
                encounteredAll = true;
                if (i < arr.rank() && arr.size(i) == 1)
                    oneDimensionWithAllEncountered.add(i);
                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }
            }
            //point: do nothing but move the shape counter
            //also move the stride counter
            if (idx instanceof PointIndex) {
                pointOffsets.add(idx.offset());
                pointStrides.add((long) arr.stride(strideIndex));
                numPointIndexes++;
                shapeIndex++;
                strideIndex++;
                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }
                continue;
            }
            //new axes encountered, need to track whether to prepend or
            //to set the new axis in the middle
            else if (idx instanceof NewAxis) {
                //prepend the new axes at different indexes
                accumShape.add(1L);
                accumOffsets.add(0L);
                accumStrides.add(0L);
                prependNewAxes.add(i);
                continue;

            }

            //points and intervals both have a direct desired length
            else if (idx instanceof IntervalIndex && !(idx instanceof NDArrayIndexAll)
                    || idx instanceof SpecifiedIndex) {
                if (idx instanceof IntervalIndex) {
                    accumStrides.add(arr.stride(strideIndex) * idx.stride());
                    //used in computing an adjusted offset for the augmented strides
                    intervalStrides.add(idx.stride());
                    numIntervals++;
                }

                else
                    accumStrides.add((long) arr.stride(strideIndex));
                accumShape.add(idx.length());
                //the stride stays the same
                //add the offset for the index
                if (idx instanceof IntervalIndex) {
                    accumOffsets.add(idx.offset());
                } else
                    accumOffsets.add(idx.offset());

                shapeIndex++;
                strideIndex++;

                //different dimension from new axis (look for new axis dimensions
                //at at the beginning. track when the last new axis is encountered.
                if (newAxesPrepend > 0 && lastPrependIndex < 0) {
                    lastPrependIndex = i - 1;
                }


                continue;
            }

            //add the shape and stride
            //based on the original stride/shape

            accumShape.add((long) shape[shapeIndex++]);
            //account for erroneous strides from dimensions of size 1
            //move the stride index if its one and fill it in at the bottom
            accumStrides.add((long) arr.stride(strideIndex++));

            //default offsets are zero
            accumOffsets.add(idx.offset());

        }



        //fill in missing strides and shapes
        while (shapeIndex < shape.length) {
            //scalar, should be 1 x 1 rather than the number of columns in the vector
            if (Shape.isVector(shape)) {
                accumShape.add(1L);
                shapeIndex++;
            } else
                accumShape.add((long) shape[shapeIndex++]);
        }


        //fill in the rest of the offsets with zero
        int delta = (shape.length <= 2 ? shape.length : shape.length - numPointIndexes);
        boolean needsFilledIn = accumShape.size() != accumStrides.size() && accumOffsets.size() != accumShape.size();
        while (accumOffsets.size() < delta && needsFilledIn)
            accumOffsets.add(0L);


        while (accumShape.size() < 2) {
            if (Shape.isRowVectorShape(arr.shape()))
                accumShape.add(0, 1L);
            else
                accumShape.add(1L);
        }

        while (strideIndex < accumShape.size()) {
            accumStrides.add((long) arr.stride(strideIndex++));
        }


        /**
         * For each dimension
         * where we want to prepend a dimension
         * we need to add it at the index such that
         * we account for the offset of the number of indexes
         * added up to that point.
         *
         * We do this by doing an offset
         * for each item added "so far"
         *
         * Note that we also have an offset of - 1
         * because we want to prepend to the given index.
         *
         * When prepend new axes for in the middle is triggered
         * i is already > 0
         */
       /* int numAdded = 0;
        for (int i = 0; i < prependNewAxes.size(); i++) {
            accumShape.add(prependNewAxes.get(i) - numAdded, 1L);
            //stride for the new axis is zero
            accumStrides.add(prependNewAxes.get(i) - numAdded, 0L);
            numAdded++;
        }
        for (int i = 0; i < newAxesPrepend; i++) {
            prependNewAxes.add(0, i);
        }

        prependAxis = Ints.toArray(prependNewAxes);
*/
        /**
         * Need to post process strides and offsets
         * for trailing ones here
         */
        //prune off extra zeros for trailing and leading ones
        int trailingZeroRemove = accumOffsets.size() - 1;
        while (accumOffsets.size() > accumShape.size()) {
            if (accumOffsets.get(trailingZeroRemove) == 0)
                accumOffsets.remove(accumOffsets.size() - 1);
            trailingZeroRemove--;
        }

        if (accumStrides.size() < accumOffsets.size())
            accumStrides.addAll(pointStrides);
        while (accumOffsets.size() < accumShape.size()) {
            if (Shape.isRowVectorShape(arr.shape()))
                accumOffsets.add(0, 0L);
            else
                accumOffsets.add(0L);
        }


        if (Shape.isMatrix(shape) && indexes[0] instanceof PointIndex && indexes[1] instanceof NDArrayIndexAll) {
            Collections.reverse(accumShape);
        }

        if (arr.isMatrix() && indexes[0] instanceof PointIndex && indexes[1] instanceof IntervalIndex) {
            this.shapes = new long[2];
            shapes[0] = 1;
            IntervalIndex idx = (IntervalIndex) indexes[1];
            shapes[1] = idx.length();

        } else
            this.shapes = Longs.toArray(accumShape);


        boolean isColumnVector = Shape.isColumnVectorShape(this.shapes);
        //finally fill in teh rest of the strides if any are left over
        while (accumStrides.size() < accumOffsets.size()) {
            if (!isColumnVector)
                accumStrides.add(0, (long) arr.elementStride());
            else
                accumStrides.add((long) arr.elementStride());
        }


        this.strides = Longs.toArray(accumStrides);
        this.offsets = Longs.toArray(accumOffsets);

        //compute point offsets differently
        /**
         * We need to prepend the strides for the point indexes
         * such that the point index offsets are counted.
         * Note here that we only use point strides
         * when points strides isn't empty.
         * When point strides is empty, this is
         * because a point index was encountered
         * but it was the lead index and therefore should
         * not be counted with the offset.
         *
         *
         * Another thing of note here is that the strides
         * and offsets should line up such that the point
         * and stride match up.
         */
        if (numPointIndexes > 0 && !pointStrides.isEmpty()) {
            //append to the end for tensors
            if (newAxesPrepend >= 1) {
                while (pointStrides.size() < accumOffsets.size()) {
                    pointStrides.add(1L);
                }
                //identify in the original accumulate strides
                //where zero was set and emulate the
                //same structure in the point strides
                for (int i = 0; i < accumStrides.size(); i++) {
                    if (accumStrides.get(i) == 0 && !(indexes[i] instanceof NewAxis) && lastPrependIndex <= 0)
                        pointStrides.set(i, 0L);
                }
            }

            //prepend any missing offsets where relevant for the dot product
            //note here we are using the point offsets and strides
            //for computing the offset
            //the point of a point index is to drop a dimension
            //and index in to a particular offset
            while (pointOffsets.size() < pointStrides.size()) {
                pointOffsets.add(0L);
            }
            //special case where offsets aren't caught
            if (arr.isRowVector() && !intervalStrides.isEmpty() && pointOffsets.get(0) == 0
                    && !(indexes[1] instanceof IntervalIndex))
                this.offset = indexes[1].offset();
            else
                this.offset = ArrayUtil.dotProductLong2(pointOffsets, pointStrides);
        } else {
            this.offset = 0;
        }
        if (numIntervals > 0 && arr.rank() > 2) {
            if (encounteredAll && arr.size(0) != 1 || indexes[0] instanceof PointIndex)
                // FIXME: LONG
                this.offset += ArrayUtil.dotProductLong2(accumOffsets, accumStrides);
            else
                // FIXME: LONG
                this.offset += ArrayUtil.dotProductLong2(accumOffsets, accumStrides);

        } else if (numIntervals > 0 && anyHaveStrideOne(indexes))
            this.offset += ArrayUtil.calcOffsetLong2(accumShape, accumOffsets, accumStrides);
        else
            this.offset += ArrayUtil.calcOffsetLong2(accumShape, accumOffsets, accumStrides)
                    / Math.max(1, numIntervals);


        //collapse singular dimensions with specified index
        List<Integer> removeShape = new ArrayList<>();
        for (int i = 0; i < Math.min(this.shapes.length, indexes.length); i++) {
            if (this.shapes[i] == 1 && indexes[i] instanceof SpecifiedIndex) {
                removeShape.add(i);
            }
        }


        if (!removeShape.isEmpty()) {
            List<Long> newShape = new ArrayList<>();
            List<Long> newStrides = new ArrayList<>();
            for (int i = 0; i < this.shapes.length; i++) {
                if (!removeShape.contains(i)) {
                    newShape.add(this.shapes[i]);
                    newStrides.add(this.strides[i]);
                }
            }

            this.shapes = Longs.toArray(newShape);
            this.strides = Longs.toArray(newStrides);
        }

    }
Based on the passed in array
compute the shape,offsets, and strides
for the given indexes
@param indexes the indexes
to compute this based on