added the addToentry and multiplyEntry methods

to allow in-place operation for matrices

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@728184 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2008-12-19 23:53:11 +00:00
parent da40b8373a
commit 4826123478
4 changed files with 130 additions and 41 deletions

View File

@ -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

View File

@ -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.
* <p>
* Row and column indices start at 0 and must satisfy
* <ul>
* <li><code>0 <= row < rowDimension</code></li>
* <li><code> 0 <= column < columnDimension</code></li>
* </ul>
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
*
* @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.
* <p>
* Row and column indices start at 0 and must satisfy
* <ul>
* <li><code>0 <= row < rowDimension</code></li>
* <li><code> 0 <= column < columnDimension</code></li>
* </ul>
* otherwise a <code>MatrixIndexException</code> is thrown.</p>
*
* @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.
*

View File

@ -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;

View File

@ -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);