BlockFieldMatrix extends AbstractFieldMatrix<T> implements Serializable { @Override public FieldMatrix<T> getSubMatrix(final int startRow, final int endRow, final int startColumn, final int endColumn) throws OutOfRangeException, NumberIsTooSmallException { checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), 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 T[] 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; } BlockFieldMatrix(final Field<T> field, final int rows,
                            final int columns);  BlockFieldMatrix(final T[][] rawData);  BlockFieldMatrix(final int rows, final int columns,
                            final T[][] blockData, final boolean copyArray); static T[][] toBlocksLayout(final T[][] rawData); static T[][] createBlocksLayout(final Field<T> field,
                                                                       final int rows, final int columns); @Override FieldMatrix<T> createMatrix(final int rowDimension,
                                       final int columnDimension); @Override FieldMatrix<T> copy(); @Override FieldMatrix<T> add(final FieldMatrix<T> m); BlockFieldMatrix<T> add(final BlockFieldMatrix<T> m); @Override FieldMatrix<T> subtract(final FieldMatrix<T> m); BlockFieldMatrix<T> subtract(final BlockFieldMatrix<T> m); @Override FieldMatrix<T> scalarAdd(final T d); @Override FieldMatrix<T> scalarMultiply(final T d); @Override FieldMatrix<T> multiply(final FieldMatrix<T> m); BlockFieldMatrix<T> multiply(BlockFieldMatrix<T> m); @Override T[][] getData(); @Override FieldMatrix<T> getSubMatrix(final int startRow, final int endRow,
                                       final int startColumn,
                                       final int endColumn); @Override void setSubMatrix(final T[][] subMatrix, final int row,
                             final int column); @Override FieldMatrix<T> getRowMatrix(final int row); @Override void setRowMatrix(final int row, final FieldMatrix<T> matrix); void setRowMatrix(final int row, final BlockFieldMatrix<T> matrix); @Override FieldMatrix<T> getColumnMatrix(final int column); @Override void setColumnMatrix(final int column, final FieldMatrix<T> matrix); @Override FieldVector<T> getRowVector(final int row); @Override void setRowVector(final int row, final FieldVector<T> vector); @Override FieldVector<T> getColumnVector(final int column); @Override void setColumnVector(final int column, final FieldVector<T> vector); @Override T[] getRow(final int row); @Override void setRow(final int row, final T[] array); @Override T[] getColumn(final int column); @Override void setColumn(final int column, final T[] array); @Override T getEntry(final int row, final int column); @Override void setEntry(final int row, final int column, final T value); @Override void addToEntry(final int row, final int column, final T increment); @Override void multiplyEntry(final int row, final int column, final T factor); @Override FieldMatrix<T> transpose(); @Override int getRowDimension(); @Override int getColumnDimension(); @Override T[] operate(final T[] v); @Override T[] preMultiply(final T[] v); @Override T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor); @Override T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor); @Override T walkInRowOrder(final FieldMatrixChangingVisitor<T> visitor,
                            final int startRow, final int endRow,
                            final int startColumn, final int endColumn); @Override T walkInRowOrder(final FieldMatrixPreservingVisitor<T> visitor,
                            final int startRow, final int endRow,
                            final int startColumn, final int endColumn); @Override T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor); @Override T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor); @Override T walkInOptimizedOrder(final FieldMatrixChangingVisitor<T> visitor,
                                  final int startRow, final int endRow,
                                  final int startColumn, final int endColumn); @Override T walkInOptimizedOrder(final FieldMatrixPreservingVisitor<T> visitor,
                                  final int startRow, final int endRow,
                                  final int startColumn, final int endColumn); static final int BLOCK_SIZE; }
@Test public void testGetSubMatrix() { FieldMatrix<Fraction> m = new BlockFieldMatrix<Fraction>(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 }); }