added copySubmatrix methods

use matrix visitors to implement some existing methods more efficiently

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@731231 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2009-01-04 12:07:43 +00:00
parent 49cea9feed
commit 1336db1d5c
2 changed files with 124 additions and 22 deletions

View File

@ -285,23 +285,105 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable {
}
/** {@inheritDoc} */
public RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
public RealMatrix getSubMatrix(final int[] selectedRows, final int[] selectedColumns)
throws MatrixIndexException {
// safety checks
checkSubMatrixIndex(selectedRows, selectedColumns);
// copy entries
final RealMatrix subMatrix =
createMatrix(selectedRows.length, selectedColumns.length);
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]));
subMatrix.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() {
/** Serializable version identifier. */
private static final long serialVersionUID = 4572851009041214720L;
/** {@inheritDoc} */
public double visit(final int row, final int column, final double value) {
return getEntry(selectedRows[row], selectedColumns[column]);
}
}
});
return subMatrix;
}
/** {@inheritDoc} */
public void copySubMatrix(final int startRow, final int endRow,
final int startColumn, final int endColumn,
final double[][] destination)
throws MatrixIndexException, IllegalArgumentException {
// safety checks
checkSubMatrixIndex(startRow, endRow, startColumn, endColumn);
final int rowsCount = endRow + 1 - startRow;
final int columnsCount = endColumn + 1 - startColumn;
if ((destination.length < rowsCount) || (destination[0].length < columnsCount)) {
throw MathRuntimeException.createIllegalArgumentException(
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
new Object[] {
destination.length, destination[0].length,
rowsCount, columnsCount
});
}
// copy entries
walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
/** Serializable version identifier. */
private static final long serialVersionUID = -6302162622577015104L;
/** Initial row index. */
private int startRow;
/** Initial column index. */
private int startColumn;
/** {@inheritDoc} */
public void start(final int rows, final int columns,
final int startRow, final int endRow,
final int startColumn, final int endColumn) {
this.startRow = startRow;
this.startColumn = startColumn;
}
/** {@inheritDoc} */
public void visit(final int row, final int column, final double value) {
destination[row - startRow][column - startColumn] = value;
}
}, startRow, endRow, startColumn, endColumn);
}
/** {@inheritDoc} */
public void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination)
throws MatrixIndexException, IllegalArgumentException {
// safety checks
checkSubMatrixIndex(selectedRows, selectedColumns);
if ((destination.length < selectedRows.length) ||
(destination[0].length < selectedColumns.length)) {
throw MathRuntimeException.createIllegalArgumentException(
"dimensions mismatch: got {0}x{1} but expected {2}x{3}",
new Object[] {
destination.length, destination[0].length,
selectedRows.length, selectedColumns.length
});
}
// copy entries
for (int i = 0; i < selectedRows.length; i++) {
final double[] destinationI = destination[i];
for (int j = 0; j < selectedColumns.length; j++) {
destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
}
}
}
/** {@inheritDoc} */
public void setSubMatrix(final double[][] subMatrix, final int row, final int column)
throws MatrixIndexException {
@ -554,27 +636,16 @@ public abstract class AbstractRealMatrix implements RealMatrix, Serializable {
final int nRows = getRowDimension();
final int nCols = getColumnDimension();
final RealMatrix out = createMatrix(nCols, nRows);
walkInOptimizedOrder(new RealMatrixPreservingVisitor() {
walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
/** Serializable version identifier */
private static final long serialVersionUID = 3807296710038754174L;
/** {@inheritDoc} */
public void start(final int rows, final int columns,
final int startRow, final int endRow,
final int startColumn, final int endColumn) {
}
/** Serializable version identifier. */
private static final long serialVersionUID = 2482589609486637597L;
/** {@inheritDoc} */
public void visit(final int row, final int column, final double value) {
out.setEntry(column, row, value);
}
/** {@inheritDoc} */
public double end() {
return 0;
}
});
return out;

View File

@ -136,8 +136,8 @@ public interface RealMatrix extends Serializable {
* specified rows and columns
* @exception MatrixIndexException if the indices are not valid
*/
RealMatrix getSubMatrix(int startRow, int endRow, int startColumn,
int endColumn) throws MatrixIndexException;
RealMatrix getSubMatrix(int startRow, int endRow, int startColumn, int endColumn)
throws MatrixIndexException;
/**
* Gets a submatrix. Rows and columns are indicated
@ -150,8 +150,39 @@ public interface RealMatrix extends Serializable {
* @exception MatrixIndexException if row or column selections are not valid
*/
RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
throws MatrixIndexException;
throws MatrixIndexException;
/**
* Copy a submatrix. Rows and columns are indicated
* counting from 0 to n-1.
*
* @param startRow Initial row index
* @param endRow Final row index (inclusive)
* @param startColumn Initial column index
* @param endColumn Final column index (inclusive)
* @param destination The arrays where the submatrix data should be copied
* (if larger than rows/columns counts, only the upper-left part will be used)
* @exception MatrixIndexException if the indices are not valid
* @exception IllegalArgumentException if the destination array is too small
*/
void copySubMatrix(int startRow, int endRow, int startColumn, int endColumn,
double[][] destination)
throws MatrixIndexException, IllegalArgumentException;
/**
* Copy a submatrix. Rows and columns are indicated
* counting from 0 to n-1.
*
* @param selectedRows Array of row indices.
* @param selectedColumns Array of column indices.
* @param destination The arrays where the submatrix data should be copied
* (if larger than rows/columns counts, only the upper-left part will be used)
* @exception MatrixIndexException if the indices are not valid
* @exception IllegalArgumentException if the destination array is too small
*/
void copySubMatrix(int[] selectedRows, int[] selectedColumns, double[][] destination)
throws MatrixIndexException, IllegalArgumentException;
/**
* Replace the submatrix starting at <code>row, column</code> using data in
* the input <code>subMatrix</code> array. Indexes are 0-based.