Repository: commons-math Updated Branches: refs/heads/feature-MATH-1372 [created] 0ca1b7449
MATH-1372 Methods for locating the minimum (or maximum) in an array. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/0ca1b744 Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/0ca1b744 Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/0ca1b744 Branch: refs/heads/feature-MATH-1372 Commit: 0ca1b7449402394ee2b44d67208b09ea7bc1aa59 Parents: fc9d93d Author: Gilles <[email protected]> Authored: Wed Jun 1 14:19:19 2016 +0200 Committer: Gilles <[email protected]> Committed: Wed Jun 1 14:19:19 2016 +0200 ---------------------------------------------------------------------- .../apache/commons/math4/util/MathArrays.java | 69 +++++++++++++++ .../commons/math4/util/MathArraysTest.java | 90 ++++++++++++++++++++ 2 files changed, 159 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/0ca1b744/src/main/java/org/apache/commons/math4/util/MathArrays.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/util/MathArrays.java b/src/main/java/org/apache/commons/math4/util/MathArrays.java index e1e4478..cb9e39a 100644 --- a/src/main/java/org/apache/commons/math4/util/MathArrays.java +++ b/src/main/java/org/apache/commons/math4/util/MathArrays.java @@ -1931,4 +1931,73 @@ public class MathArrays { } return out; } + + /** + * Retrieves the index of the minimum among the values + * stored in the given {@code array}. + * In case of several occurrences of the smallest value, + * the index of the first one is returned. + * + * @param array Data. + * @return the index of the minimum or -1 if the array is + * {@code null} or has zero length. + */ + public static int argMin(final double[] array) { + return argMinOrMax(array, true); + } + + /** + * Retrieves the index of the maximum among the values + * stored in the given {@code array}. + * In case of several occurrences of the largest value, + * the index of the first one is returned. + * + * @param array Data. + * @return the index of the maximum or -1 if the array is + * {@code null} or has zero length. + */ + public static int argMax(final double[] array) { + return argMinOrMax(array, false); + } + + /** + * Retrieves the location of the requested element (either + * min or max value). + * + * @param data Array. + * @param isMin If {@code true}, the minimum is searched for, + * otherwise the maximum. + * @return the index of the element that satisfies the condition + * or -1 if the array is {@code null} or has zero length. + */ + private static int argMinOrMax(final double[] data, + boolean isMin) { + if (data == null || + data.length == 0) { + return -1; + } + + int index = 0; + double selected = data[0]; + + if (isMin) { + for (int i = 1; i < data.length; i++) { + final double current = data[i]; + if (current < selected) { + index = i; + selected = current; + } + } + } else { + for (int i = 1; i < data.length; i++) { + final double current = data[i]; + if (current > selected) { + index = i; + selected = current; + } + } + } + + return index; + } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/0ca1b744/src/test/java/org/apache/commons/math4/util/MathArraysTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/util/MathArraysTest.java b/src/test/java/org/apache/commons/math4/util/MathArraysTest.java index 05de1b0..8056119 100644 --- a/src/test/java/org/apache/commons/math4/util/MathArraysTest.java +++ b/src/test/java/org/apache/commons/math4/util/MathArraysTest.java @@ -1338,4 +1338,94 @@ public class MathArraysTest { public void testUniqueNullArgument() { MathArrays.unique(null); } + + @Test + public void testArgMinPrecondition1() { + Assert.assertEquals(-1, MathArrays.argMin(null)); + } + + @Test + public void testArgMinPrecondition2() { + Assert.assertEquals(-1, MathArrays.argMin(new double[0])); + } + + @Test + public void testArgMin() { + final double[] data = { 1, 0, -8, 10, 17, 11, -15}; + final int index = MathArrays.argMin(data); + Assert.assertEquals(6, index); + } + + @Test + public void testArgMinNegativeOnlyValues() { + final double[] data = { -1, 0, -8, -10, -17, -11, -15}; + final int index = MathArrays.argMin(data); + Assert.assertEquals(4, index); + } + + @Test + public void testArgMinPositiveOnlyValues() { + final double[] data = { 5, 3, 8, 2, 17, 11, 15}; + final int index = MathArrays.argMin(data); + Assert.assertEquals(3, index); + } + + @Test + public void testArgMinRepeatedValues() { + final double[] data = { -1, -17, -8, -10, -17, -11, -15}; + final int index = MathArrays.argMin(data); + Assert.assertEquals(1, index); + } + + @Test + public void testArgMinInfinity() { + final double[] data = { -Double.MAX_VALUE, Double.NEGATIVE_INFINITY, -1e100}; + final int index = MathArrays.argMin(data); + Assert.assertEquals(1, index); + } + + @Test + public void testArgMaxPrecondition1() { + Assert.assertEquals(-1, MathArrays.argMin(null)); + } + + @Test + public void testArgMaxPrecondition2() { + Assert.assertEquals(-1, MathArrays.argMin(new double[0])); + } + + @Test + public void testArgMax() { + final double[] data = { 23, 10, -8, 1, 39, 7, -15}; + final int index = MathArrays.argMax(data); + Assert.assertEquals(4, index); + } + + @Test + public void testArgMaxNegativeOnlyValues() { + final double[] data = { -1, -Double.MIN_VALUE, -8, -10, -17, -11, -15}; + final int index = MathArrays.argMax(data); + Assert.assertEquals(1, index); + } + + @Test + public void testArgMaxPositiveOnlyValues() { + final double[] data = { 5, 3, 8, 2, 17, Double.MAX_VALUE, 15}; + final int index = MathArrays.argMax(data); + Assert.assertEquals(5, index); + } + + @Test + public void testArgMaxRepeatedValues() { + final double[] data = { 11, 7, 3, -6, -7, 11, -5}; + final int index = MathArrays.argMax(data); + Assert.assertEquals(0, index); + } + + @Test + public void testArgMaxInfinity() { + final double[] data = { Double.MAX_VALUE, Double.POSITIVE_INFINITY, 1e100}; + final int index = MathArrays.argMax(data); + Assert.assertEquals(1, index); + } }
