BlockRealMatrix extends AbstractRealMatrix implements Serializable { @Override public BlockRealMatrix getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws OutOfRangeException, NumberIsTooSmallException { MatrixUtils.checkSubMatrixIndex(this, startRow, endRow, startColumn, endColumn); final BlockRealMatrix out = new BlockRealMatrix(endRow - startRow + 1, endColumn - startColumn + 1); final int blockStartRow = startRow / BLOCK_SIZE; final int rowsShift = startRow % BLOCK_SIZE; final int blockStartColumn = startColumn / BLOCK_SIZE; final int columnsShift = startColumn % BLOCK_SIZE; int pBlock = blockStartRow; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int iHeight = out.blockHeight(iBlock); int qBlock = blockStartColumn; for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int jWidth = out.blockWidth(jBlock); final int outIndex = iBlock * out.blockColumns + jBlock; final double[] outBlock = out.blocks[outIndex]; final int index = pBlock * blockColumns + qBlock; final int width = blockWidth(qBlock); final int heightExcess = iHeight + rowsShift - BLOCK_SIZE; final int widthExcess = jWidth + columnsShift - BLOCK_SIZE; if (heightExcess > 0) { if (widthExcess > 0) { final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, BLOCK_SIZE, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, BLOCK_SIZE, outBlock, jWidth, iHeight - heightExcess, 0); copyBlockPart(blocks[index + blockColumns + 1], width2, 0, heightExcess, 0, widthExcess, outBlock, jWidth, iHeight - heightExcess, jWidth - widthExcess); } else { copyBlockPart(blocks[index], width, rowsShift, BLOCK_SIZE, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + blockColumns], width, 0, heightExcess, columnsShift, jWidth + columnsShift, outBlock, jWidth, iHeight - heightExcess, 0); } } else { if (widthExcess > 0) { final int width2 = blockWidth(qBlock + 1); copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, BLOCK_SIZE, outBlock, jWidth, 0, 0); copyBlockPart(blocks[index + 1], width2, rowsShift, iHeight + rowsShift, 0, widthExcess, outBlock, jWidth, 0, jWidth - widthExcess); } else { copyBlockPart(blocks[index], width, rowsShift, iHeight + rowsShift, columnsShift, jWidth + columnsShift, outBlock, jWidth, 0, 0); } } ++qBlock; } ++pBlock; } return out; } BlockRealMatrix(final int rows, final int columns);  BlockRealMatrix(final double[][] rawData);  BlockRealMatrix(final int rows, final int columns,
                           final double[][] blockData, final boolean copyArray); static double[][] toBlocksLayout(final double[][] rawData); static double[][] createBlocksLayout(final int rows, final int columns); @Override BlockRealMatrix createMatrix(final int rowDimension,
                                        final int columnDimension); @Override BlockRealMatrix copy(); @Override BlockRealMatrix add(final RealMatrix m); BlockRealMatrix add(final BlockRealMatrix m); @Override BlockRealMatrix subtract(final RealMatrix m); BlockRealMatrix subtract(final BlockRealMatrix m); @Override BlockRealMatrix scalarAdd(final double d); @Override RealMatrix scalarMultiply(final double d); @Override BlockRealMatrix multiply(final RealMatrix m); BlockRealMatrix multiply(BlockRealMatrix m); @Override double[][] getData(); @Override double getNorm(); @Override double getFrobeniusNorm(); @Override BlockRealMatrix getSubMatrix(final int startRow, final int endRow,
                                        final int startColumn,
                                        final int endColumn); @Override void setSubMatrix(final double[][] subMatrix, final int row,
                             final int column); @Override BlockRealMatrix getRowMatrix(final int row); @Override void setRowMatrix(final int row, final RealMatrix matrix); void setRowMatrix(final int row, final BlockRealMatrix matrix); @Override BlockRealMatrix getColumnMatrix(final int column); @Override void setColumnMatrix(final int column, final RealMatrix matrix); @Override RealVector getRowVector(final int row); @Override void setRowVector(final int row, final RealVector vector); @Override RealVector getColumnVector(final int column); @Override void setColumnVector(final int column, final RealVector vector); @Override double[] getRow(final int row); @Override void setRow(final int row, final double[] array); @Override double[] getColumn(final int column); @Override void setColumn(final int column, final double[] array); @Override double getEntry(final int row, final int column); @Override void setEntry(final int row, final int column, final double value); @Override void addToEntry(final int row, final int column,
                           final double increment); @Override void multiplyEntry(final int row, final int column,
                              final double factor); @Override BlockRealMatrix transpose(); @Override int getRowDimension(); @Override int getColumnDimension(); @Override double[] operate(final double[] v); @Override double[] preMultiply(final double[] v); @Override double walkInRowOrder(final RealMatrixChangingVisitor visitor); @Override double walkInRowOrder(final RealMatrixPreservingVisitor visitor); @Override double walkInRowOrder(final RealMatrixChangingVisitor visitor,
                                 final int startRow, final int endRow,
                                 final int startColumn, final int endColumn); @Override double walkInRowOrder(final RealMatrixPreservingVisitor visitor,
                                 final int startRow, final int endRow,
                                 final int startColumn, final int endColumn); @Override double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor); @Override double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor); @Override double walkInOptimizedOrder(final RealMatrixChangingVisitor visitor,
                                       final int startRow, final int endRow,
                                       final int startColumn,
                                       final int endColumn); @Override double walkInOptimizedOrder(final RealMatrixPreservingVisitor visitor,
                                       final int startRow, final int endRow,
                                       final int startColumn,
                                       final int endColumn); static final int BLOCK_SIZE; }
@Test public void testGetSubMatrix() { RealMatrix m = new BlockRealMatrix(subTestData); checkGetSubMatrix(m, subRows23Cols00, 2 , 3 , 0, 0); checkGetSubMatrix(m, subRows00Cols33, 0 , 0 , 3, 3); checkGetSubMatrix(m, subRows01Cols23, 0 , 1 , 2, 3); checkGetSubMatrix(m, subRows02Cols13, new int[] { 0, 2 }, new int[] { 1, 3 }); checkGetSubMatrix(m, subRows03Cols12, new int[] { 0, 3 }, new int[] { 1, 2 }); checkGetSubMatrix(m, subRows03Cols123, new int[] { 0, 3 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows20Cols123, new int[] { 2, 0 }, new int[] { 1, 2, 3 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, subRows31Cols31, new int[] { 3, 1 }, new int[] { 3, 1 }); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, -1, 1, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 2); checkGetSubMatrix(m, null, 1, 0, 2, 4); checkGetSubMatrix(m, null, new int[] {}, new int[] { 0 }); checkGetSubMatrix(m, null, new int[] { 0 }, new int[] { 4 }); }