diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 689fa6868..6bd22ee6e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -55,6 +55,10 @@ This is a minor release: It combines bug fixes and new features.
Changes to existing features were made in a backwards-compatible
way such as to allow drop-in replacement of the v3.1[.1] JAR file.
">
+
+ AbstractRealMatrix will now check for rectangular input arrays in
+ its copySubMatrix methods.
+
Increment iteration counter in optimization algorithms.
diff --git a/src/main/java/org/apache/commons/math3/linear/AbstractRealMatrix.java b/src/main/java/org/apache/commons/math3/linear/AbstractRealMatrix.java
index 432d9ede8..c3c9c2d2a 100644
--- a/src/main/java/org/apache/commons/math3/linear/AbstractRealMatrix.java
+++ b/src/main/java/org/apache/commons/math3/linear/AbstractRealMatrix.java
@@ -353,6 +353,13 @@ public abstract class AbstractRealMatrix
rowsCount, columnsCount);
}
+ for (int i = 1; i < rowsCount; i++) {
+ if (destination[i].length != columnsCount) {
+ throw new MatrixDimensionMismatchException(destination.length, destination[i].length,
+ rowsCount, columnsCount);
+ }
+ }
+
walkInOptimizedOrder(new DefaultRealMatrixPreservingVisitor() {
/** Initial row index. */
@@ -385,14 +392,19 @@ public abstract class AbstractRealMatrix
throws OutOfRangeException, NullArgumentException, NoDataException,
MatrixDimensionMismatchException {
MatrixUtils.checkSubMatrixIndex(this, selectedRows, selectedColumns);
+ final int nCols = selectedColumns.length;
if ((destination.length < selectedRows.length) ||
- (destination[0].length < selectedColumns.length)) {
+ (destination[0].length < nCols)) {
throw new MatrixDimensionMismatchException(destination.length, destination[0].length,
selectedRows.length, selectedColumns.length);
}
for (int i = 0; i < selectedRows.length; i++) {
final double[] destinationI = destination[i];
+ if (destinationI.length != nCols) {
+ throw new MatrixDimensionMismatchException(destination.length, destinationI.length,
+ selectedRows.length, selectedColumns.length);
+ }
for (int j = 0; j < selectedColumns.length; j++) {
destinationI[j] = getEntry(selectedRows[i], selectedColumns[j]);
}
diff --git a/src/test/java/org/apache/commons/math3/linear/Array2DRowRealMatrixTest.java b/src/test/java/org/apache/commons/math3/linear/Array2DRowRealMatrixTest.java
index 880fa3b2f..19cad4991 100644
--- a/src/test/java/org/apache/commons/math3/linear/Array2DRowRealMatrixTest.java
+++ b/src/test/java/org/apache/commons/math3/linear/Array2DRowRealMatrixTest.java
@@ -537,6 +537,11 @@ public final class Array2DRowRealMatrixTest {
checkCopy(m, null, 1, 0, 2, 4, true);
checkCopy(m, null, new int[] {}, new int[] { 0 }, true);
checkCopy(m, null, new int[] { 0 }, new int[] { 4 }, true);
+
+ // rectangular check
+ double[][] copy = new double[][] { { 0, 0, 0 }, { 0, 0 } };
+ checkCopy(m, copy, 0, 1, 0, 2, true);
+ checkCopy(m, copy, new int[] { 0, 1 }, new int[] { 0, 2 }, true);
}
private void checkCopy(RealMatrix m, double[][] reference,
@@ -544,8 +549,7 @@ public final class Array2DRowRealMatrixTest {
boolean mustFail) {
try {
double[][] sub = (reference == null) ?
- new double[1][1] :
- new double[reference.length][reference[0].length];
+ new double[1][1] : createIdenticalCopy(reference);
m.copySubMatrix(startRow, endRow, startColumn, endColumn, sub);
Assert.assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub));
if (mustFail) {
@@ -563,6 +567,10 @@ public final class Array2DRowRealMatrixTest {
if (!mustFail) {
throw e;
}
+ } catch (MatrixDimensionMismatchException e) {
+ if (!mustFail) {
+ throw e;
+ }
}
}
@@ -571,8 +579,7 @@ public final class Array2DRowRealMatrixTest {
boolean mustFail) {
try {
double[][] sub = (reference == null) ?
- new double[1][1] :
- new double[reference.length][reference[0].length];
+ new double[1][1] : createIdenticalCopy(reference);
m.copySubMatrix(selectedRows, selectedColumns, sub);
Assert.assertEquals(new Array2DRowRealMatrix(reference), new Array2DRowRealMatrix(sub));
if (mustFail) {
@@ -590,9 +597,21 @@ public final class Array2DRowRealMatrixTest {
if (!mustFail) {
throw e;
}
+ } catch (MatrixDimensionMismatchException e) {
+ if (!mustFail) {
+ throw e;
+ }
}
}
+ private double[][] createIdenticalCopy(final double[][] matrix) {
+ final double[][] matrixCopy = new double[matrix.length][];
+ for (int i = 0; i < matrixCopy.length; i++) {
+ matrixCopy[i] = new double[matrix[i].length];
+ }
+ return matrixCopy;
+ }
+
@Test
public void testGetRowMatrix() {
RealMatrix m = new Array2DRowRealMatrix(subTestData);