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 + *
0 <= row < rowDimension
0 <= column < columnDimension
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 + *
0 <= row < rowDimension
0 <= column < columnDimension
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);