Added normalizeArray method to MathUtils.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@809394 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ad6960636a
commit
e89db38df8
|
@ -987,6 +987,62 @@ public final class MathUtils {
|
|||
public static double normalizeAngle(double a, double center) {
|
||||
return a - TWO_PI * Math.floor((a + Math.PI - center) / TWO_PI);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Normalizes an array to make it sum to a specified value.
|
||||
* Returns the result of the transformation <pre>
|
||||
* x |-> x * normalizedSum / sum
|
||||
* </pre>
|
||||
* applied to each non-NaN element x of the input array, where sum is the
|
||||
* sum of the non-NaN entries in the input array.</p>
|
||||
*
|
||||
* <p>Throws IllegalArgumentException if <code>normalizedSum</code> is infinite
|
||||
* or NaN and ArithmeticException if the input array contains any infinite elements
|
||||
* or sums to 0</p>
|
||||
*
|
||||
* <p>Ignores (i.e., copies unchanged to the output array) NaNs in the input array.</p>
|
||||
*
|
||||
* @param values input array to be normalized
|
||||
* @param normalizedSum target sum for the normalized array
|
||||
* @return normalized array
|
||||
* @throws ArithmeticException if the input array contains infinite elements or sums to zero
|
||||
* @throws IllegalArgumentException if the target sum is infinite or NaN
|
||||
*/
|
||||
public static double[] normalizeArray(double[] values, double normalizedSum)
|
||||
throws ArithmeticException, IllegalArgumentException {
|
||||
if (Double.isInfinite(normalizedSum)) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"Cannot normalize to an infinite value");
|
||||
}
|
||||
if (Double.isNaN(normalizedSum)) {
|
||||
throw MathRuntimeException.createIllegalArgumentException(
|
||||
"Cannot normalize to NaN");
|
||||
}
|
||||
double sum = 0d;
|
||||
final int len = values.length;
|
||||
double[] out = new double[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (Double.isInfinite(values[i])) {
|
||||
throw MathRuntimeException.createArithmeticException(
|
||||
"Array contains an infinite element", values[i], i);
|
||||
}
|
||||
if (!Double.isNaN(values[i])) {
|
||||
sum += values[i];
|
||||
}
|
||||
}
|
||||
if (sum == 0) {
|
||||
throw MathRuntimeException.createArithmeticException(
|
||||
"Array sums to zero");
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (Double.isNaN(values[i])) {
|
||||
out[i] = Double.NaN;
|
||||
} else {
|
||||
out[i] = values[i] * normalizedSum / sum;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Round the given value to the specified number of decimal places. The
|
||||
|
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="2.1" date="TBD" description="TBD">
|
||||
<action dev="psteitz" type="add">
|
||||
Added normalizeArray method to MathUtils.
|
||||
</action>
|
||||
<action dev="luc" type="fix" issue="MATH-290" due-to="Benjamin McCann">
|
||||
Fixed a NullPointerException in simplex solver when no solution is possible
|
||||
and some constraints are negative.
|
||||
|
|
|
@ -796,6 +796,54 @@ public final class MathUtilsTest extends TestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testNormalizeArray() {
|
||||
double[] testValues1 = new double[] {1, 1, 2};
|
||||
TestUtils.assertEquals(
|
||||
new double[] {.25, .25, .5},
|
||||
MathUtils.normalizeArray(testValues1, 1),
|
||||
Double.MIN_VALUE);
|
||||
|
||||
double[] testValues2 = new double[] {-1, -1, 1};
|
||||
TestUtils.assertEquals(
|
||||
new double[] {1, 1, -1},
|
||||
MathUtils.normalizeArray(testValues2, 1),
|
||||
Double.MIN_VALUE);
|
||||
|
||||
// Ignore NaNs
|
||||
double[] testValues3 = new double[] {-1, -1, Double.NaN, 1, Double.NaN};
|
||||
TestUtils.assertEquals(
|
||||
new double[] {1, 1,Double.NaN, -1, Double.NaN},
|
||||
MathUtils.normalizeArray(testValues3, 1),
|
||||
Double.MIN_VALUE);
|
||||
|
||||
// Zero sum -> ArithmeticException
|
||||
double[] zeroSum = new double[] {-1, 1};
|
||||
try {
|
||||
MathUtils.normalizeArray(zeroSum, 1);
|
||||
fail("expecting ArithmeticException");
|
||||
} catch (ArithmeticException ex) {}
|
||||
|
||||
// Infinite elements -> ArithmeticException
|
||||
double[] hasInf = new double[] {1, 2, 1, Double.NEGATIVE_INFINITY};
|
||||
try {
|
||||
MathUtils.normalizeArray(hasInf, 1);
|
||||
fail("expecting ArithmeticException");
|
||||
} catch (ArithmeticException ex) {}
|
||||
|
||||
// Infinite target -> IllegalArgumentException
|
||||
try {
|
||||
MathUtils.normalizeArray(testValues1, Double.POSITIVE_INFINITY);
|
||||
fail("expecting IllegalArgumentException");
|
||||
} catch (IllegalArgumentException ex) {}
|
||||
|
||||
// NaN target -> IllegalArgumentException
|
||||
try {
|
||||
MathUtils.normalizeArray(testValues1, Double.NaN);
|
||||
fail("expecting IllegalArgumentException");
|
||||
} catch (IllegalArgumentException ex) {}
|
||||
|
||||
}
|
||||
|
||||
public void testRoundDouble() {
|
||||
double x = 1.234567890;
|
||||
|
|
Loading…
Reference in New Issue