BlockFieldMatrix extends AbstractFieldMatrix<T> implements Serializable { @Override public FieldMatrix<T> multiply(final FieldMatrix<T> m) throws DimensionMismatchException { try { return multiply((BlockFieldMatrix<T>) m); } catch (ClassCastException cce) { checkMultiplicationCompatible(m); final BlockFieldMatrix<T> out = new BlockFieldMatrix<T>(getField(), rows, m.getColumnDimension()); final T zero = getField().getZero(); int blockIndex = 0; for (int iBlock = 0; iBlock < out.blockRows; ++iBlock) { final int pStart = iBlock * BLOCK_SIZE; final int pEnd = FastMath.min(pStart + BLOCK_SIZE, rows); for (int jBlock = 0; jBlock < out.blockColumns; ++jBlock) { final int qStart = jBlock * BLOCK_SIZE; final int qEnd = FastMath.min(qStart + BLOCK_SIZE, m.getColumnDimension()); final T[] outBlock = out.blocks[blockIndex]; for (int kBlock = 0; kBlock < blockColumns; ++kBlock) { final int kWidth = blockWidth(kBlock); final T[] tBlock = blocks[iBlock * blockColumns + kBlock]; final int rStart = kBlock * BLOCK_SIZE; int k = 0; for (int p = pStart; p < pEnd; ++p) { final int lStart = (p - pStart) * kWidth; final int lEnd = lStart + kWidth; for (int q = qStart; q < qEnd; ++q) { T sum = zero; int r = rStart; for (int l = lStart; l < lEnd; ++l) { sum = sum.add(tBlock[l].multiply(m.getEntry(r, q))); ++r; } outBlock[k] = outBlock[k].add(sum); ++k; } } } ++blockIndex; } } 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 testMultiply() { BlockFieldMatrix<Fraction> m = new BlockFieldMatrix<Fraction>(testData); BlockFieldMatrix<Fraction> mInv = new BlockFieldMatrix<Fraction>(testDataInv); BlockFieldMatrix<Fraction> identity = new BlockFieldMatrix<Fraction>(id); BlockFieldMatrix<Fraction> m2 = new BlockFieldMatrix<Fraction>(testData2); TestUtils.assertEquals(m.multiply(mInv), identity); TestUtils.assertEquals(mInv.multiply(m), identity); TestUtils.assertEquals(m.multiply(identity), m); TestUtils.assertEquals(identity.multiply(mInv), mInv); TestUtils.assertEquals(m2.multiply(identity), m2); try { m.multiply(new BlockFieldMatrix<Fraction>(bigSingular)); Assert.fail("Expecting illegalArgumentException"); } catch (MathIllegalArgumentException ex) { } }
@Test public void testMultiply2() { FieldMatrix<Fraction> m3 = new BlockFieldMatrix<Fraction>(d3); FieldMatrix<Fraction> m4 = new BlockFieldMatrix<Fraction>(d4); FieldMatrix<Fraction> m5 = new BlockFieldMatrix<Fraction>(d5); TestUtils.assertEquals(m3.multiply(m4), m5); }