Added setSubMatrix methods to RealMatrix, BigMatrix.

Modified copyIn methods to use setSubMatrix and moved array argument checking
from constructors and copyIn to setSubMatrix.
PR # 35007
Base implementation contributed by Rodrigo di Lorenzo Lopes


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@178982 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2005-05-29 20:26:11 +00:00
parent 2e21b43df8
commit f6da77e2bc
8 changed files with 339 additions and 57 deletions

View File

@ -120,6 +120,9 @@
<contributor>
<name>C. Scott Ananian</name>
</contributor>
<contributor>
<name>Rodrigo di Lorenzo Lopes</name>
</contributor>
<contributor>
<name>Ken Geis</name>
</contributor>

View File

@ -145,6 +145,34 @@ public interface BigMatrix {
BigMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
throws MatrixIndexException;
/**
* Replace the submatrix starting at <code>row, column</code> using data in
* the input <code>subMatrix</code> array. Indexes are 0-based.
* <p>
* Example:<br>
* Starting with <pre>
* 1 2 3 4
* 5 6 7 8
* 9 0 1 2
* </pre>
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
* 1 2 3 4
* 5 3 4 8
* 9 5 6 2
* </pre>
*
* @param subMatrix array containing the submatrix replacement data
* @param row row coordinate of the top, left element to be replaced
* @param column column coordinate of the top, left element to be replaced
* @throws MatrixIndexException if subMatrix does not fit into this
* matrix from element in (row, column)
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
* (not all rows have the same length) or empty
* @throws NullPointerException if <code>subMatrix</code> is null
*/
public void setSubMatrix(BigDecimal subMatrix[][], int row, int column) throws MatrixIndexException;
/**
* Returns the entries in row number <code>row</code>
* as a row matrix. Row indices start at 0.

View File

@ -113,22 +113,6 @@ public class BigMatrixImpl implements BigMatrix, Serializable {
* @throws NullPointerException if <code>d</code> is null
*/
public BigMatrixImpl(BigDecimal[][] d) {
int nRows = d.length;
if (nRows == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one row.");
}
int nCols = d[0].length;
if (nCols == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one column.");
}
for (int row = 1; row < nRows; row++) {
if (d[row].length != nCols) {
throw new IllegalArgumentException(
"All input rows must have the same length.");
}
}
this.copyIn(d);
lu = null;
}
@ -503,6 +487,70 @@ public class BigMatrixImpl implements BigMatrix, Serializable {
return subMatrix;
}
/**
* Replace the submatrix starting at <code>row, column</code> using data in
* the input <code>subMatrix</code> array. Indexes are 0-based.
* <p>
* Example:<br>
* Starting with <pre>
* 1 2 3 4
* 5 6 7 8
* 9 0 1 2
* </pre>
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
* 1 2 3 4
* 5 3 4 8
* 9 5 6 2
* </pre>
*
* @param subMatrix array containing the submatrix replacement data
* @param row row coordinate of the top, left element to be replaced
* @param column column coordinate of the top, left element to be replaced
* @throws MatrixIndexException if subMatrix does not fit into this
* matrix from element in (row, column)
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
* (not all rows have the same length) or empty
* @throws NullPointerException if <code>subMatrix</code> is null
*/
public void setSubMatrix(BigDecimal[][] subMatrix, int row, int column)
throws MatrixIndexException {
if ((row < 0) || (column < 0)){
throw new MatrixIndexException
("invalid row or column index selection");
}
int nRows = subMatrix.length;
if (nRows == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one row.");
}
int nCols = subMatrix[0].length;
if (nCols == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one column.");
}
for (int r = 1; r < nRows; r++) {
if (subMatrix[r].length != nCols) {
throw new IllegalArgumentException(
"All input rows must have the same length.");
}
}
if (data == null) {
if ((row > 0)||(column > 0)) throw new MatrixIndexException
("matrix must be initialized to perfom this method");
data = new BigDecimal[nRows][nCols];
System.arraycopy(subMatrix, 0, data, 0, subMatrix.length);
}
if (((nRows + row) > this.getRowDimension())
|| (nCols + column > this.getColumnDimension()))
throw new MatrixIndexException(
"invalid row or column index selection");
for (int i = 0; i < nRows; i++) {
System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
}
lu = null;
}
/**
* Returns the entries in row number <code>row</code>
* as a row matrix. Row indices start at 0.
@ -1205,18 +1253,16 @@ public class BigMatrixImpl implements BigMatrix, Serializable {
/**
* Replaces data with a fresh copy of the input array.
* <p>
* Verifies that the input array is rectangular and non-empty.
*
* @param in data to copy in
* @throws IllegalArgumentException if input array is emtpy or not
* rectangular
* @throws NullPointerException if input array is null
*/
private void copyIn(BigDecimal[][] in) {
int nRows = in.length;
int nCols = in[0].length;
data = new BigDecimal[nRows][nCols];
System.arraycopy(in, 0, data, 0, in.length);
for (int i = 0; i < nRows; i++) {
System.arraycopy(in[i], 0, data[i], 0, nCols);
}
lu = null;
setSubMatrix(in,0,0);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2004 The Apache Software Foundation.
* Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,7 +25,6 @@ package org.apache.commons.math.linear;
* @version $Revision$ $Date$
*/
public interface RealMatrix {
/**
* Returns a (deep) copy of this.
*
@ -129,6 +128,35 @@ public interface RealMatrix {
RealMatrix getSubMatrix(int[] selectedRows, int[] selectedColumns)
throws MatrixIndexException;
/**
* Replace the submatrix starting at <code>row, column</code> using data in
* the input <code>subMatrix</code> array. Indexes are 0-based.
* <p>
* Example:<br>
* Starting with <pre>
* 1 2 3 4
* 5 6 7 8
* 9 0 1 2
* </pre>
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
* 1 2 3 4
* 5 3 4 8
* 9 5 6 2
* </pre>
*
* @param subMatrix array containing the submatrix replacement data
* @param row row coordinate of the top, left element to be replaced
* @param column column coordinate of the top, left element to be replaced
* @throws MatrixIndexException if subMatrix does not fit into this
* matrix from element in (row, column)
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
* (not all rows have the same length) or empty
* @throws NullPointerException if <code>subMatrix</code> is null
*/
public void setSubMatrix(double subMatrix[][], int row, int column) throws MatrixIndexException;
/**
* Returns the entries in row number <code>row</code>
* as a row matrix. Row indices start at 0.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2004 The Apache Software Foundation.
* Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -104,22 +104,6 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
* @throws NullPointerException if <code>data</code> is null
*/
public RealMatrixImpl(double[][] d) {
int nRows = d.length;
if (nRows == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one row.");
}
int nCols = d[0].length;
if (nCols == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one column.");
}
for (int row = 1; row < nRows; row++) {
if (d[row].length != nCols) {
throw new IllegalArgumentException(
"All input rows must have the same length.");
}
}
this.copyIn(d);
lu = null;
}
@ -371,12 +355,76 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
}
return subMatrix;
}
/**
* Replace the submatrix starting at <code>row, column</code> using data in
* the input <code>subMatrix</code> array. Indexes are 0-based.
* <p>
* Example:<br>
* Starting with <pre>
* 1 2 3 4
* 5 6 7 8
* 9 0 1 2
* </pre>
* and <code>subMatrix = {{3, 4} {5,6}}</code>, invoking
* <code>setSubMatrix(subMatrix,1,1))</code> will result in <pre>
* 1 2 3 4
* 5 3 4 8
* 9 5 6 2
* </pre>
*
* @param subMatrix array containing the submatrix replacement data
* @param row row coordinate of the top, left element to be replaced
* @param column column coordinate of the top, left element to be replaced
* @throws MatrixIndexException if subMatrix does not fit into this
* matrix from element in (row, column)
* @throws IllegalArgumentException if <code>subMatrix</code> is not rectangular
* (not all rows have the same length) or empty
* @throws NullPointerException if <code>subMatrix</code> is null
*/
public void setSubMatrix(double[][] subMatrix, int row, int column)
throws MatrixIndexException {
if ((row < 0) || (column < 0)){
throw new MatrixIndexException
("invalid row or column index selection");
}
int nRows = subMatrix.length;
if (nRows == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one row.");
}
int nCols = subMatrix[0].length;
if (nCols == 0) {
throw new IllegalArgumentException(
"Matrix must have at least one column.");
}
for (int r = 1; r < nRows; r++) {
if (subMatrix[r].length != nCols) {
throw new IllegalArgumentException(
"All input rows must have the same length.");
}
}
if (data == null) {
if ((row > 0)||(column > 0)) throw new MatrixIndexException
("matrix must be initialized to perfom this method");
data = new double[nRows][nCols];
System.arraycopy(subMatrix, 0, data, 0, subMatrix.length);
}
if (((nRows + row) > this.getRowDimension())
|| (nCols + column > this.getColumnDimension()))
throw new MatrixIndexException(
"invalid row or column index selection");
for (int i = 0; i < nRows; i++) {
System.arraycopy(subMatrix[i], 0, data[row + i], column, nCols);
}
lu = null;
}
/**
* Returns the entries in row number <code>row</code>
* as a row matrix. Row indices start at 0.
*
* @param row the row to be fetched
* Returns the entries in row number <code>row</code> as a row matrix.
* Row indices start at 0.
*
* @param row the row to be fetched
* @return row matrix
* @throws MatrixIndexException if the specified row index is invalid
*/
@ -955,18 +1003,16 @@ public class RealMatrixImpl implements RealMatrix, Serializable {
/**
* Replaces data with a fresh copy of the input array.
* <p>
* Verifies that the input array is rectangular and non-empty
*
* @param in data to copy in
* @throws IllegalArgumentException if input array is emtpy or not
* rectangular
* @throws NullPointerException if input array is null
*/
private void copyIn(double[][] in) {
int nRows = in.length;
int nCols = in[0].length;
data = new double[nRows][nCols];
System.arraycopy(in, 0, data, 0, in.length);
for (int i = 0; i < nRows; i++) {
System.arraycopy(in[i], 0, data[i], 0, nCols);
}
lu = null;
setSubMatrix(in,0,0);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2004 The Apache Software Foundation.
* Copyright 2004-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -636,6 +636,75 @@ public final class BigMatrixImplTest extends TestCase {
m.toString());
}
public void testSetSubMatrix() throws Exception {
BigDecimal[][] detData3 =
MatrixUtils.createBigMatrix(detData2).getData();
BigMatrixImpl m = new BigMatrixImpl(testData);
m.setSubMatrix(detData3,1,1);
BigMatrix expected = MatrixUtils.createBigMatrix
(new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}});
assertEquals(expected, m);
m.setSubMatrix(detData3,0,0);
expected = MatrixUtils.createBigMatrix
(new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}});
assertEquals(expected, m);
BigDecimal[][] testDataPlus3 =
MatrixUtils.createBigMatrix(testDataPlus2).getData();
m.setSubMatrix(testDataPlus3,0,0);
expected = MatrixUtils.createBigMatrix
(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
BigMatrix matrix = MatrixUtils.createBigMatrix
(new double[][] {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 0, 1 , 2}});
matrix.setSubMatrix(new BigDecimal[][] {{new BigDecimal(3),
new BigDecimal(4)}, {new BigDecimal(5), new BigDecimal(6)}}, 1, 1);
expected = MatrixUtils.createBigMatrix
(new BigDecimal[][] {{new BigDecimal(1), new BigDecimal(2),
new BigDecimal(3), new BigDecimal(4)}, {new BigDecimal(5),
new BigDecimal(3), new BigDecimal(4), new BigDecimal(8)},
{new BigDecimal(9), new BigDecimal(5) , new BigDecimal(6),
new BigDecimal(2)}});
assertEquals(expected, matrix);
// dimension overflow
try {
m.setSubMatrix(matrix.getData(),1,1);
fail("expecting MatrixIndexException");
} catch (MatrixIndexException e) {
// expected
}
// null
try {
m.setSubMatrix(null,1,1);
fail("expecting NullPointerException");
} catch (NullPointerException e) {
// expected
}
// ragged
try {
m.setSubMatrix(new BigDecimal[][] {{new BigDecimal(1)},
{new BigDecimal(2), new BigDecimal(3)}}, 0, 0);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
// empty
try {
m.setSubMatrix(new BigDecimal[][] {{}}, 0, 0);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
//--------------- -----------------Protected methods
/** verifies that two matrices are close (1-norm) */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2004 The Apache Software Foundation.
* Copyright 2003-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -610,6 +610,65 @@ public final class RealMatrixImplTest extends TestCase {
m.toString());
}
public void testSetSubMatrix() throws Exception {
RealMatrixImpl m = new RealMatrixImpl(testData);
m.setSubMatrix(detData2,1,1);
RealMatrix expected = MatrixUtils.createRealMatrix
(new double[][] {{1.0,2.0,3.0},{2.0,1.0,3.0},{1.0,2.0,4.0}});
assertEquals(expected, m);
m.setSubMatrix(detData2,0,0);
expected = MatrixUtils.createRealMatrix
(new double[][] {{1.0,3.0,3.0},{2.0,4.0,3.0},{1.0,2.0,4.0}});
assertEquals(expected, m);
m.setSubMatrix(testDataPlus2,0,0);
expected = MatrixUtils.createRealMatrix
(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
RealMatrix matrix = 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);
fail("expecting MatrixIndexException");
} catch (MatrixIndexException e) {
// expected
}
// null
try {
m.setSubMatrix(null,1,1);
fail("expecting NullPointerException");
} catch (NullPointerException e) {
// expected
}
// ragged
try {
m.setSubMatrix(new double[][] {{1}, {2, 3}}, 0, 0);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
// empty
try {
m.setSubMatrix(new double[][] {{}}, 0, 0);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected
}
}
//--------------- -----------------Protected methods
/** verifies that two matrices are close (1-norm) */

View File

@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
<body>
<release version="1.1" date="In Development"
description="Jakarta Commons Math 1.1 - Development">
<action dev="psteitz" type="update" issue="35007" due-to="Rodrigo di Lorenzo Lopes">
Added setSubMatrix methods to RealMatrix, BigMatrix.
</action>
<action dev="psteitz" type="update">
Added createXIdentityMatrix methods to MatrixUtils and deprecated
getIdentity methods in RealMatrixImpl, BigMatrixImpl.