diff --git a/src/java/org/apache/commons/math/linear/AbstractRealMatrix.java b/src/java/org/apache/commons/math/linear/AbstractRealMatrix.java index 35025b617..980ae45e2 100644 --- a/src/java/org/apache/commons/math/linear/AbstractRealMatrix.java +++ b/src/java/org/apache/commons/math/linear/AbstractRealMatrix.java @@ -227,19 +227,7 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable { final int startColumn, final int endColumn) throws MatrixIndexException { - checkRowIndex(startRow); - checkRowIndex(endRow); - if (startRow > endRow) { - throw new MatrixIndexException("initial row {0} after final row {1}", - new Object[] { startRow, endRow }); - } - - checkColumnIndex(startColumn); - checkColumnIndex(endColumn); - if (startColumn > endColumn) { - throw new MatrixIndexException("initial column {0} after final column {1}", - new Object[] { startColumn, endColumn }); - } + checkSubMatrixIndex(startRow, endRow, startColumn, endColumn); final RealMatrix subMatrix = createMatrix(endRow - startRow + 1, endColumn - startColumn + 1); @@ -257,29 +245,13 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable { public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns) throws MatrixIndexException { - if (selectedRows.length * selectedColumns.length == 0) { - if (selectedRows.length == 0) { - throw new MatrixIndexException("empty selected row index array", null); - } - throw new MatrixIndexException("empty selected column index array", null); - } + checkSubMatrixIndex(selectedRows, selectedColumns); final RealMatrix subMatrix = createMatrix(selectedRows.length, selectedColumns.length); - try { - for (int i = 0; i < selectedRows.length; i++) { - for (int j = 0; j < selectedColumns.length; j++) { - subMatrix.setEntry(i, j, getEntry(selectedRows[i], selectedColumns[j])); - } - } - } catch (ArrayIndexOutOfBoundsException e) { - // we redo the loop with checks enabled - // in order to generate an appropriate message - for (final int row : selectedRows) { - checkRowIndex(row); - } - for (final int column : selectedColumns) { - checkColumnIndex(column); + for (int i = 0; i < selectedRows.length; i++) { + for (int j = 0; j < selectedColumns.length; j++) { + subMatrix.setEntry(i, j, getEntry(selectedRows[i], selectedColumns[j])); } } @@ -525,6 +497,14 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable { public abstract void setEntry(int row, int column, double value) throws MatrixIndexException; + /** {@inheritDoc} */ + public abstract void addToEntry(int row, int column, double increment) + throws MatrixIndexException; + + /** {@inheritDoc} */ + public abstract void multiplyEntry(int row, int column, double factor) + throws MatrixIndexException; + /** {@inheritDoc} */ public RealMatrix transpose() { @@ -858,6 +838,59 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable { } } + /** + * Check if submatrix ranges indices are valid. + * Rows and columns are indicated counting from 0 to n-1. + * + * @param startRow Initial row index + * @param endRow Final row index + * @param startColumn Initial column index + * @param endColumn Final column index + * @exception MatrixIndexException if the indices are not valid + */ + protected void checkSubMatrixIndex(final int startRow, final int endRow, + final int startColumn, final int endColumn) { + checkRowIndex(startRow); + checkRowIndex(endRow); + if (startRow > endRow) { + throw new MatrixIndexException("initial row {0} after final row {1}", + new Object[] { startRow, endRow }); + } + + checkColumnIndex(startColumn); + checkColumnIndex(endColumn); + if (startColumn > endColumn) { + throw new MatrixIndexException("initial column {0} after final column {1}", + new Object[] { startColumn, endColumn }); + } + + + } + + /** + * Check if submatrix ranges indices are valid. + * Rows and columns are indicated counting from 0 to n-1. + * + * @param selectedRows Array of row indices. + * @param selectedColumns Array of column indices. + * @exception MatrixIndexException if row or column selections are not valid + */ + protected void checkSubMatrixIndex(final int[] selectedRows, final int[] selectedColumns) { + if (selectedRows.length * selectedColumns.length == 0) { + if (selectedRows.length == 0) { + throw new MatrixIndexException("empty selected row index array", null); + } + throw new MatrixIndexException("empty selected column index array", null); + } + + for (final int row : selectedRows) { + checkRowIndex(row); + } + for (final int column : selectedColumns) { + checkColumnIndex(column); + } + } + /** * Check if a matrix is addition compatible with the instance * @param m matrix to check diff --git a/src/java/org/apache/commons/math/linear/RealMatrix.java b/src/java/org/apache/commons/math/linear/RealMatrix.java index 91ca3936c..a954bccc4 100644 --- a/src/java/org/apache/commons/math/linear/RealMatrix.java +++ b/src/java/org/apache/commons/math/linear/RealMatrix.java @@ -359,6 +359,42 @@ public interface RealMatrix { */ void setEntry(int row, int column, double value) throws MatrixIndexException; + /** + * Change an entry in the specified row and column. + *

+ * Row and column indices start at 0 and must satisfy + *

+ * otherwise a MatrixIndexException is thrown.

+ * + * @param row row location of entry to be set + * @param column column location of entry to be set + * @param increment value to add to the current matrix entry in row,column + * @throws MatrixIndexException if the row or column index is not valid + * @since 2.0 + */ + void addToEntry(int row, int column, double increment) throws MatrixIndexException; + + /** + * Change an entry in the specified row and column. + *

+ * Row and column indices start at 0 and must satisfy + *

+ * otherwise a MatrixIndexException is thrown.

+ * + * @param row row location of entry to be set + * @param column column location of entry to be set + * @param factor multiplication factor for the current matrix entry in row,column + * @throws MatrixIndexException if the row or column index is not valid + * @since 2.0 + */ + void multiplyEntry(int row, int column, double factor) throws MatrixIndexException; + /** * Returns the transpose of this matrix. * diff --git a/src/java/org/apache/commons/math/linear/RealMatrixImpl.java b/src/java/org/apache/commons/math/linear/RealMatrixImpl.java index 7e5a6d515..830d97939 100644 --- a/src/java/org/apache/commons/math/linear/RealMatrixImpl.java +++ b/src/java/org/apache/commons/math/linear/RealMatrixImpl.java @@ -370,6 +370,34 @@ public class RealMatrixImpl extends AbstractRealMatrix implements Serializable { } } + /** {@inheritDoc} */ + public void addToEntry(final int row, final int column, final double increment) + throws MatrixIndexException { + try { + data[row][column] += increment; + } catch (ArrayIndexOutOfBoundsException e) { + throw new MatrixIndexException("no entry at indices ({0}, {1}) in a {2}x{3} matrix", + new Object[] { + row, column, + getRowDimension(), getColumnDimension() + }); + } + } + + /** {@inheritDoc} */ + public void multiplyEntry(final int row, final int column, final double factor) + throws MatrixIndexException { + try { + data[row][column] *= factor; + } catch (ArrayIndexOutOfBoundsException e) { + throw new MatrixIndexException("no entry at indices ({0}, {1}) in a {2}x{3} matrix", + new Object[] { + row, column, + getRowDimension(), getColumnDimension() + }); + } + } + /** {@inheritDoc} */ public int getRowDimension() { return (data == null) ? 0 : data.length; diff --git a/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java b/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java index 3a50ab946..fa2d3156e 100644 --- a/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java +++ b/src/test/org/apache/commons/math/linear/RealMatrixImplTest.java @@ -746,14 +746,6 @@ public final class RealMatrixImplTest extends TestCase { (new double[][] {{3.0,4.0,5.0},{4.0,7.0,5.0},{3.0,2.0,10.0}}); assertEquals(expected, m); - // javadoc example - RealMatrixImpl matrix = (RealMatrixImpl) MatrixUtils.createRealMatrix - (new double[][] {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1 , 2}}); - matrix.setSubMatrix(new double[][] {{3, 4}, {5, 6}}, 1, 1); - expected = MatrixUtils.createRealMatrix - (new double[][] {{1, 2, 3, 4}, {5, 3, 4, 8}, {9, 5 ,6, 2}}); - assertEquals(expected, matrix); - // dimension overflow try { m.setSubMatrix(testData,1,1);