diff --git a/src/changes/changes.xml b/src/changes/changes.xml index e201c3b4e..83d03e1d9 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces! + + Added mapping functions to MathArrays. These methods allow to map + any univariate or bivariate functions to arrays. + "KolmogorovSmirnovTest#ksSum(...)" returned wrong result in case the provided t-parameters was zero. This affected the calculation of "approximateP(...)" for 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 f4e7f4e4e..a6784a6d2 100644 --- a/src/main/java/org/apache/commons/math4/util/MathArrays.java +++ b/src/main/java/org/apache/commons/math4/util/MathArrays.java @@ -25,6 +25,8 @@ import java.util.Comparator; import java.util.List; import org.apache.commons.math4.Field; +import org.apache.commons.math4.analysis.BivariateFunction; +import org.apache.commons.math4.analysis.UnivariateFunction; import org.apache.commons.math4.distribution.UniformIntegerDistribution; import org.apache.commons.math4.exception.DimensionMismatchException; import org.apache.commons.math4.exception.MathArithmeticException; @@ -107,6 +109,75 @@ public class MathArrays { } } + /** + * Creates an array whose contents will be the element-by-element + * mapping of the function to argument. + * + * @param f function to map on elements + * @param a array of function parameters. + * @return a new array {@code r} where {@code r[i] = f(a[i])}. + * @since 4.0 + */ + public static double[] map(final UnivariateFunction f, final double[] a) { + + final double[] result = new double[a.length]; + for (int i = 0; i < result.length; ++i) { + result[i] = f.value(a[i]); + } + + return result; + + } + + /** + * Creates an array whose contents will be the element-by-element + * mapping of the function to arguments. + * + * @param f function to map on elements + * @param a array of first parameters of the function. + * @param b array of second parameters of the function. + * @return a new array {@code r} where {@code r[i] = f(a[i], b[i])}. + * @throws DimensionMismatchException if the array lengths differ. + * @since 4.0 + */ + public static double[] map(final BivariateFunction f, + final double[] a, final double[] b) { + + if (a.length != b.length) { + throw new DimensionMismatchException(a.length, b.length); + } + + final double[] result = new double[a.length]; + for (int i = 0; i < result.length; ++i) { + result[i] = f.value(a[i], b[i]); + } + + return result; + + } + + /** + * Creates an array whose contents will be the element-by-element + * mapping of the function to arguments. + * + * @param f function to map on elements + * @param a array of first parameters of the function. + * @param b fixed value for second function parameter. + * @return a new array {@code r} where {@code r[i] = f(a[i])}. + * @since 4.0 + */ + public static double[] map(final BivariateFunction f, + final double[] a, final double b) { + + final double[] result = new double[a.length]; + for (int i = 0; i < result.length; ++i) { + result[i] = f.value(a[i], b); + } + + return result; + + } + /** * Creates an array whose contents will be the element-by-element * addition of the arguments. 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 3abd0cd13..fedd11c93 100644 --- a/src/test/java/org/apache/commons/math4/util/MathArraysTest.java +++ b/src/test/java/org/apache/commons/math4/util/MathArraysTest.java @@ -16,6 +16,8 @@ package org.apache.commons.math4.util; import java.util.Arrays; import org.apache.commons.math4.TestUtils; +import org.apache.commons.math4.analysis.function.Abs; +import org.apache.commons.math4.analysis.function.Add; import org.apache.commons.math4.exception.DimensionMismatchException; import org.apache.commons.math4.exception.MathArithmeticException; import org.apache.commons.math4.exception.MathIllegalArgumentException; @@ -74,7 +76,37 @@ public class MathArraysTest { Assert.assertEquals(correctScaled[i], test[i], 0); } } - + + @Test + public void testMapUnivariate() { + final double[] expected = new double[] { 1, 2, 4, 8 }; + final double[] observed = + MathArrays.map(new Abs(), new double[] { 1, -2, -4, 8}); + TestUtils.assertEquals(expected, observed, 1.0e-15); + } + + @Test + public void testMapBivariateTwoArrays() { + final double[] expected = new double[] { 1, 3, 6, 11 }; + final double[] observed = + MathArrays.map(new Add(), + new double[] { 1, 2, 4, 8}, new double[] { 0, 1, 2, 3}); + TestUtils.assertEquals(expected, observed, 1.0e-15); + } + + @Test + public void testMapBivariateOneArray() { + final double[] expected = new double[] { 3.5, 4.5, 6.5, 10.5 }; + final double[] observed = + MathArrays.map(new Add(), new double[] { 1, 2, 4, 8}, 2.5); + TestUtils.assertEquals(expected, observed, 1.0e-15); + } + + @Test(expected=DimensionMismatchException.class) + public void testMapBivariatePrecondition() { + MathArrays.map(new Add(), new double[3], new double[4]); + } + @Test(expected=DimensionMismatchException.class) public void testEbeAddPrecondition() { MathArrays.ebeAdd(new double[3], new double[4]);