// Reused by both MR and Spark for performing zero out
  public static IndexRange getSelectedRangeForZeroOut(
      IndexedMatrixValue in, int blockRowFactor, int blockColFactor, IndexRange indexRange) {
    IndexRange tempRange = new IndexRange(-1, -1, -1, -1);

    long topBlockRowIndex = UtilFunctions.computeBlockIndex(indexRange.rowStart, blockRowFactor);
    int topRowInTopBlock = UtilFunctions.computeCellInBlock(indexRange.rowStart, blockRowFactor);
    long bottomBlockRowIndex = UtilFunctions.computeBlockIndex(indexRange.rowEnd, blockRowFactor);
    int bottomRowInBottomBlock =
        UtilFunctions.computeCellInBlock(indexRange.rowEnd, blockRowFactor);

    long leftBlockColIndex = UtilFunctions.computeBlockIndex(indexRange.colStart, blockColFactor);
    int leftColInLeftBlock = UtilFunctions.computeCellInBlock(indexRange.colStart, blockColFactor);
    long rightBlockColIndex = UtilFunctions.computeBlockIndex(indexRange.colEnd, blockColFactor);
    int rightColInRightBlock = UtilFunctions.computeCellInBlock(indexRange.colEnd, blockColFactor);

    // no overlap
    if (in.getIndexes().getRowIndex() < topBlockRowIndex
        || in.getIndexes().getRowIndex() > bottomBlockRowIndex
        || in.getIndexes().getColumnIndex() < leftBlockColIndex
        || in.getIndexes().getColumnIndex() > rightBlockColIndex) {
      tempRange.set(-1, -1, -1, -1);
      return tempRange;
    }

    // get the index range inside the block
    tempRange.set(0, in.getValue().getNumRows() - 1, 0, in.getValue().getNumColumns() - 1);
    if (topBlockRowIndex == in.getIndexes().getRowIndex()) tempRange.rowStart = topRowInTopBlock;
    if (bottomBlockRowIndex == in.getIndexes().getRowIndex())
      tempRange.rowEnd = bottomRowInBottomBlock;
    if (leftBlockColIndex == in.getIndexes().getColumnIndex())
      tempRange.colStart = leftColInLeftBlock;
    if (rightBlockColIndex == in.getIndexes().getColumnIndex())
      tempRange.colEnd = rightColInRightBlock;

    return tempRange;
  }