-1

I'm trying to get a sub-array from double[][] 3x3 matrices (to calculate a determinant). I keep getting the ArrayIndexOutOfBoundsException.

Any idea why ?

public double[][] get2DSubArray(double[][] largeArray, int rowStartIndex, int rowEndIndex, int columnStartIndex, int columnEndIndex) {
    double[][] subArray = new double[rowEndIndex-rowStartIndex+1][columnEndIndex-columnStartIndex+1];
    for (int row = rowStartIndex; row < rowEndIndex; row++) {
        subArray[row] = Arrays.copyOfRange(largeArray[row], columnStartIndex, columnEndIndex);
    }
    return subArray;
}
Jack Berstrem
  • 535
  • 1
  • 5
  • 22

2 Answers2

1

If the row start was 500 and the end was 505, the variable in the for loop would start at 500 instead of 0. You want to replace "subArray[row] =" with "subArray[row-rowStartIndex] =". You are referencing where it would of been in the larger array compared to where the copy will be in the smaller array.

Edit:

//Fixed Version:

public static double[][] get2DSubArray(double[][] largeArray, int rowStartIndex, int rowEndIndex, int columnStartIndex,
            int columnEndIndex) {
        double[][] subArray = new double[rowEndIndex - rowStartIndex + 1][columnEndIndex - columnStartIndex + 1];
        for (int row = rowStartIndex; row <= rowEndIndex; row++) {
            subArray[row-rowStartIndex] = Arrays.copyOfRange(largeArray[row], columnStartIndex, columnEndIndex+1);
        }
        return subArray;
    }
Locke
  • 7,626
  • 2
  • 21
  • 41
  • I just changed that but am still getting the exception. It seems that Eclipse is not understanding that I want to make an actual matrix (2D Array), as it fails to recognize that there is a second column in my 2D Array. Here is my exact output (I am printing the matrix just to make sure it works) http://imgur.com/a/lmEDF – Jack Berstrem Feb 12 '17 at 22:39
1

Looks like it has something to do with array initialization, the array passed to the method does not seem to be 3x3. E.g, following does not produce an Exception:

public static void main(String[] args) throws IOException {
    double[][] array = new double[][]{{1d,1d,1d},{2d,2d,2d},{3d,3d,3d}};
    double[][] subArray = get2DSubArray(array, 1, 2, 1, 2);
    for(double[] arrayElement : subArray){
        for(double number : arrayElement){
            System.out.println(number);
        }
    }
}

public static double[][] get2DSubArray(double[][] largeArray, int rowStartIndex, int rowEndIndex, int columnStartIndex,
        int columnEndIndex) {
    double[][] subArray = new double[rowEndIndex - rowStartIndex + 1][columnEndIndex - columnStartIndex + 1];
    for (int row = rowStartIndex; row < rowEndIndex; row++) {
        subArray[row] = Arrays.copyOfRange(largeArray[row], columnStartIndex, columnEndIndex);
    }
    return subArray;
}

Update

Although the above solution does not produce an Exception, it does not produce correct output as well. Mainly because of the following reasons:

  • Third argument for Arrays.copyOfRange method is exclusive, so we have to pass columnEndIndex+1 for it to work
  • for loop only executes once for provided set of arguments whereas it should execute at least twice
  • Instead of assigning Arrays.copyOfRange to subArray[row], we need to assign it to subArray[<zero based index>]

Below solution does work:

public double[][] get2DSubArray(double[][] largeArray, int rowStartIndex, int rowEndIndex, int columnStartIndex,
        int columnEndIndex) {
    double[][] subArray = new double[rowEndIndex - rowStartIndex + 1][columnEndIndex - columnStartIndex + 1];
    int index = 0;
    for (int row = rowStartIndex; row <= rowEndIndex; row++) {
        subArray[index++] = Arrays.copyOfRange(largeArray[row], columnStartIndex, columnEndIndex+1);
    }
    return subArray;
}
Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • It would be more efficient if you subtracted rowStartIndex instead of creating a new variable. – Locke Feb 12 '17 at 22:51
  • Thanks. I added 1 to the columnEndIndex, used 'row <= rowEndIndex' instead of 'row < rowEndIndex', but didn't use the unnecessary 'index' variable (row-rowStartIndex) works fine, and it works :) – Jack Berstrem Feb 12 '17 at 23:44