commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pste...@apache.org
Subject svn commit: r809394 - in /commons/proper/math/trunk/src: main/java/org/apache/commons/math/util/MathUtils.java site/xdoc/changes.xml test/java/org/apache/commons/math/util/MathUtilsTest.java
Date Sun, 30 Aug 2009 18:10:16 GMT
Author: psteitz
Date: Sun Aug 30 18:10:16 2009
New Revision: 809394

URL: http://svn.apache.org/viewvc?rev=809394&view=rev
Log:
Added normalizeArray method to MathUtils.

Modified:
    commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
    commons/proper/math/trunk/src/site/xdoc/changes.xml
    commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java

Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java?rev=809394&r1=809393&r2=809394&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math/util/MathUtils.java Sun
Aug 30 18:10:16 2009
@@ -987,6 +987,62 @@
      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

Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=809394&r1=809393&r2=809394&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Sun Aug 30 18:10:16 2009
@@ -39,6 +39,9 @@
   </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.

Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java?rev=809394&r1=809393&r2=809394&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
(original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math/util/MathUtilsTest.java
Sun Aug 30 18:10:16 2009
@@ -796,6 +796,54 @@
             }
         }
     }
+    
+    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;



Mime
View raw message