diff --git a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java index 26434a98a..023648de1 100644 --- a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java +++ b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java @@ -292,6 +292,58 @@ public abstract class AbstractRealVector implements RealVector { return d; } + /** Get the index of the minimum entry. + * @return index of the minimum entry or -1 if vector length is 0 + * or all entries are NaN + */ + public int getMinIndex() { + int minIndex = -1; + double minValue = Double.POSITIVE_INFINITY; + Iterator iterator = iterator(); + while (iterator.hasNext()) { + final Entry entry = iterator.next(); + if (entry.getValue() <= minValue) { + minIndex = entry.getIndex(); + minValue = entry.getValue(); + } + } + return minIndex; + } + + /** Get the value of the minimum entry. + * @return value of the minimum entry or NaN if all entries are NaN + */ + public double getMinValue() { + final int minIndex = getMinIndex(); + return minIndex < 0 ? Double.NaN : getEntry(minIndex); + } + + /** Get the index of the maximum entry. + * @return index of the maximum entry or -1 if vector length is 0 + * or all entries are NaN + */ + public int getMaxIndex() { + int maxIndex = -1; + double maxValue = Double.NEGATIVE_INFINITY; + Iterator iterator = iterator(); + while (iterator.hasNext()) { + final Entry entry = iterator.next(); + if (entry.getValue() >= maxValue) { + maxIndex = entry.getIndex(); + maxValue = entry.getValue(); + } + } + return maxIndex; + } + + /** Get the value of the maximum entry. + * @return value of the maximum entry or NaN if all entries are NaN + */ + public double getMaxValue() { + final int maxIndex = getMaxIndex(); + return maxIndex < 0 ? Double.NaN : getEntry(maxIndex); + } + /** {@inheritDoc} */ public RealVector mapAbs() { return copy().mapAbsToSelf(); diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index c1a0ee33e..545d8dbc8 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -39,6 +39,10 @@ The type attribute can be add,update,fix,remove. + + Added min/max getters for real vectors (not yet in the RealVector interface for + compatibility purposes, but in the AbstractRealVector abstract class). + Fixed automatic step initialization in embedded Runge-Kutta integrators. The relative tolerance setting was never used, only the absolute tolerance diff --git a/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java b/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java index 9f52044a8..5cfdb93b3 100644 --- a/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java +++ b/src/test/java/org/apache/commons/math/linear/ArrayRealVectorTest.java @@ -1308,6 +1308,30 @@ public class ArrayRealVectorTest extends TestCase { } + public void testMinMax() { + ArrayRealVector v1 = new ArrayRealVector(new double[] { 0, -6, 4, 12, 7 }); + assertEquals(1, v1.getMinIndex()); + assertEquals(-6, v1.getMinValue(), 1.0e-12); + assertEquals(3, v1.getMaxIndex()); + assertEquals(12, v1.getMaxValue(), 1.0e-12); + ArrayRealVector v2 = new ArrayRealVector(new double[] { Double.NaN, 3, Double.NaN, -2 }); + assertEquals(3, v2.getMinIndex()); + assertEquals(-2, v2.getMinValue(), 1.0e-12); + assertEquals(1, v2.getMaxIndex()); + assertEquals(3, v2.getMaxValue(), 1.0e-12); + ArrayRealVector v3 = new ArrayRealVector(new double[] { Double.NaN, Double.NaN }); + assertEquals(-1, v3.getMinIndex()); + assertTrue(Double.isNaN(v3.getMinValue())); + assertEquals(-1, v3.getMaxIndex()); + assertTrue(Double.isNaN(v3.getMaxValue())); + ArrayRealVector v4 = new ArrayRealVector(new double[0]); + assertEquals(-1, v4.getMinIndex()); + assertTrue(Double.isNaN(v4.getMinValue())); + assertEquals(-1, v4.getMaxIndex()); + assertTrue(Double.isNaN(v4.getMaxValue())); + } + + /** verifies that two vectors are close (sup norm) */ protected void assertClose(String msg, double[] m, double[] n, double tolerance) {