Reputation: 61
I'm trying to get a sub matrix of a matrix, but I'm having difficulty with the logic behind it. For a matrix like this:
1 2 3
4 5 6
7 8 9
I need to be able to get submatrix(A, 3, 2):
1 3
4 6
This is what I've tried so far
public Matrix submatrix(Matrix A, int i, int j) {
Matrix subM = new Matrix(this.rows + 1, this.columns + 1);
for (int r = i; r < this.rows; r++) {
for (int c = j; c < this.columns; c++) {
subM.data[r - i][c - j] = A.data[r][c];
}
}
return subM;
}
And this is how I'm trying to call it in main
Matrix A = new Matrix(new double[][]{{1, 2, 3},{4, 5, 6},{7, 8, 9}});
int i = 3;
int j = 2;
Matrix m = A.submatrix(A, i, j);
System.out.println("L:\n" + m);
I'm new to java so I'd appreciate any help.
Upvotes: 2
Views: 1157
Reputation: 51483
You should pass to your method the scope of the sub-matrix you want to copy, namely its starting
and ending
positions, both regarding the rows
and columns
, something like:
public Matrix submatrix(Matrix A, int row_begin, int row_end, int col_begin, int col_end) {
Matrix subM = new Matrix(row_end - row_begin, col_end - col_begin);
for (int r = row_begin, i=0; r < row_end; r++, i++)
for (int c = col_begin, j= 0; c < col_end; c++, j++)
subM.data[i][j] = A.data[r][c];
return subM;
}
Typically, in problems that you need to simultaneously iterate over two different data structures, and you do not start iterating from the same positions, it is easier to use a different index variable for each of those structures. In the code below, I use the variables i
and j
to iterate over the matrix subM.data
and the variables r
and c
to iterate over the matrix A.data
Then you would call submatrix(A, 0, 2, 0, 3)
. The output would be:
1 2 3
4 5 6
which I think is what you really want, but correct me if I am wrong.
Btw I am assuming a well-behaved input. Normally, you would need to add additional checks on the variables row_begin
, row_end
, col_begin
, col_end
to ensure that you will not get into troubles (e.g., IndexOutofbounds
).
Now if you really want to be able to skip rows and columns in the middle, then things get more complicated. One solution is to pass as a parameter also the range of columns/rows to be skipped, something like:
int[][] submatrix(int [][] data, int row_begin, int row_end,
int skip_row_begin, int skip_row_end,
int col_begin, int col_end,
int skip_col_begin, int skip_col_end) {
int number_rows = row_end - row_begin - (skip_row_end - skip_row_begin);
int number_cols = col_end - col_begin - (skip_col_end - skip_col_begin);
int [][] subM = new int[number_rows] [number_cols];
for (int r = row_begin, i=0; r < row_end; r++) {
if(r < skip_row_begin || r >= skip_row_end) {
for (int c = col_begin, j = 0; c < col_end; c++) {
if(c < skip_col_begin || c >= skip_col_end) {
subM[i][j] = data[r][c];
j++;
}
}
i++;
}
}
return subM;
}
If you do not want to skip the rows or the columns just give as range the size of the matrix itself. In your example you want to skip the middle columns for that you would call the submatrix
method as follows:
int [][] submatrix(data, 0 , 2, data.length, data.length, 0 , 3, 1, 2);
for (int[] ints : a) {
for (int anInt : ints)
System.out.print(anInt + " ");
System.out.println("\n");
}
This would output:
1 3
4 6
Upvotes: 2