You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ps...@apache.org on 2005/09/04 02:38:27 UTC

svn commit: r267527 - in /jakarta/commons/proper/math/trunk: src/java/org/apache/commons/math/random/ src/test/org/apache/commons/math/fraction/ src/test/org/apache/commons/math/random/ xdocs/

Author: psteitz
Date: Sat Sep  3 17:38:15 2005
New Revision: 267527

URL: http://svn.apache.org/viewcvs?rev=267527&view=rev
Log:
Merged changes from MATH_1_1 branch, r240245:r267516

Modified:
    jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
    jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/RandomAdaptor.java
    jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java
    jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/AbstractRandomGeneratorTest.java
    jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/EmpiricalDistributionTest.java
    jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/RandomDataTest.java
    jakarta/commons/proper/math/trunk/xdocs/changes.xml

Modified: jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java (original)
+++ jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java Sat Sep  3 17:38:15 2005
@@ -250,8 +250,7 @@
             while ((str = inputStream.readLine()) != null) {
                 val = Double.parseDouble(str);
                 SummaryStatistics stats =
-                    (SummaryStatistics) binStats.get(
-                        Math.max((int) Math.ceil((val - min) / delta) - 1, 0));
+                    (SummaryStatistics) binStats.get(findBin(min, val, delta));
                 stats.addValue(val);
             }
 
@@ -316,8 +315,7 @@
             for (int i = 0; i < inputArray.length; i++) {
                 SummaryStatistics stats =
                     (SummaryStatistics) binStats.get(
-                        Math.max((int) Math.ceil(
-                                (inputArray[i] - min) / delta)- 1, 0));
+                            findBin(min, inputArray[i], delta));
                 stats.addValue(inputArray[i]);
             }
         }
@@ -375,6 +373,20 @@
         }
         upperBounds[binCount-1] = 1.0d;
     }
+    
+    /**
+     * Returns the index of the bin to which the given value belongs
+     * 
+     * @param min  the minimum value
+     * @param value  the value whose bin we are trying to find
+     * @param delta  the grid size
+     * @return
+     */
+    private int findBin(double min, double value, double delta) {
+        return Math.min(
+                Math.max((int) Math.ceil((value- min) / delta) - 1, 0), 
+                binCount - 1);
+        }
 
     /**
      * Generates a random value from this distribution.

Modified: jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/RandomAdaptor.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/RandomAdaptor.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/RandomAdaptor.java (original)
+++ jakarta/commons/proper/math/trunk/src/java/org/apache/commons/math/random/RandomAdaptor.java Sat Sep  3 17:38:15 2005
@@ -54,64 +54,118 @@
         return new RandomAdaptor(randomGenerator);
     }
     
-    /* (non-Javadoc)
-     * @see java.util.Random#nextBoolean()
+    /**
+     * Returns the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence.  
+     * 
+     * @return  the next pseudorandom, uniformly distributed
+     * <code>boolean</code> value from this random number generator's
+     * sequence
      */
     public boolean nextBoolean() {
         return randomGenerator.nextBoolean();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextBytes(byte[])
+     /**
+     * Generates random bytes and places them into a user-supplied 
+     * byte array.  The number of random bytes produced is equal to 
+     * the length of the byte array.
+     * 
+     * @param bytes the non-null byte array in which to put the 
+     * random bytes
      */
     public void nextBytes(byte[] bytes) {
         randomGenerator.nextBytes(bytes);
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextDouble()
-     */
+     /**
+     * Returns the next pseudorandom, uniformly distributed 
+     * <code>double</code> value between <code>0.0</code> and
+     * <code>1.0</code> from this random number generator's sequence.  
+     *
+     * @return  the next pseudorandom, uniformly distributed 
+     *  <code>double</code> value between <code>0.0</code> and
+     *  <code>1.0</code> from this random number generator's sequence
+     */  
     public double nextDouble() {
         return randomGenerator.nextDouble();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextFloat()
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this random
+     * number generator's sequence.  
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>float</code>
+     * value between <code>0.0</code> and <code>1.0</code> from this
+     * random number generator's sequence
      */
     public float nextFloat() {
         return randomGenerator.nextFloat();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextGaussian()
+    /**
+     * Returns the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and standard
+     * deviation <code>1.0</code> from this random number generator's sequence.
+     * 
+     * @return  the next pseudorandom, Gaussian ("normally") distributed
+     * <code>double</code> value with mean <code>0.0</code> and
+     * standard deviation <code>1.0</code> from this random number
+     *  generator's sequence
      */
     public double nextGaussian() {
         return randomGenerator.nextGaussian();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextInt()
+     /**
+     * Returns the next pseudorandom, uniformly distributed <code>int</code>
+     * value from this random number generator's sequence.  
+     * All 2<font size="-1"><sup>32</sup></font> possible <tt>int</tt> values
+     * should be produced with  (approximately) equal probability. 
+     *
+     * @return the next pseudorandom, uniformly distributed <code>int</code>
+     *  value from this random number generator's sequence
      */
     public int nextInt() {
         return randomGenerator.nextInt();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextInt(int)
+    /**
+     * Returns a pseudorandom, uniformly distributed <tt>int</tt> value
+     * between 0 (inclusive) and the specified value (exclusive), drawn from
+     * this random number generator's sequence.   
+     *
+     * @param n the bound on the random number to be returned.  Must be
+     * positive.
+     * @return  a pseudorandom, uniformly distributed <tt>int</tt>
+     * value between 0 (inclusive) and n (exclusive).
+     * @throws IllegalArgumentException  if n is not positive.
      */
     public int nextInt(int n) {
         return randomGenerator.nextInt(n);
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#nextLong()
+    /**
+     * Returns the next pseudorandom, uniformly distributed <code>long</code>
+     * value from this random number generator's sequence.  All 
+     * 2<font size="-1"><sup>64</sup></font> possible <tt>long</tt> values 
+     * should be produced with (approximately) equal probability. 
+     *
+     * @return  the next pseudorandom, uniformly distributed <code>long</code>
+     *value from this random number generator's sequence
      */
     public long nextLong() {
         return randomGenerator.nextLong();
     }
 
-    /* (non-Javadoc)
-     * @see java.util.Random#setSeed(long)
+    /**
+     * Sets the seed of the underyling random number generator using a 
+     * <code>long</code> seed.  Sequences of values generated starting with the
+     * same seeds should be identical.
+     *
+     * @param seed the seed value
      */
     public void setSeed(long seed) {
         if (randomGenerator != null) {  // required to avoid NPE in constructor

Modified: jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java (original)
+++ jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/fraction/FractionTest.java Sat Sep  3 17:38:15 2005
@@ -412,4 +412,34 @@
             fail("expecting ArithmeticException but got: " + f.toString());
         } catch (ArithmeticException ex) {}
     }
+    
+    public void testEqualsAndHashCode() {
+        Fraction zero  = new Fraction(0,1);
+        Fraction nullFraction = null;
+        int zeroHash = zero.hashCode();
+        assertTrue( zero.equals(zero));
+        assertFalse(zero.equals(nullFraction));
+        assertFalse(zero.equals(new Double(0)));
+        Fraction zero2 = new Fraction(0,2);
+        assertTrue(zero.equals(zero2));
+        assertEquals(zero.hashCode(), zero2.hashCode());
+        Fraction one = new Fraction(1,1);
+        assertFalse((one.equals(zero) ||zero.equals(one)));
+    }
+    
+    public void testGetReducedFraction() {
+        Fraction threeFourths = new Fraction(3, 4);
+        assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8)));
+        assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1)));
+        try {
+            Fraction f = Fraction.getReducedFraction(1, 0);
+            fail("expecting ArithmeticException");
+        } catch (ArithmeticException ex) {
+            // expected
+        }
+        assertEquals(Fraction.getReducedFraction
+                (2, Integer.MIN_VALUE).getNumerator(),-1);
+        assertEquals(Fraction.getReducedFraction
+                (1, -1).getNumerator(), -1);
+    }
 }

Modified: jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/AbstractRandomGeneratorTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/AbstractRandomGeneratorTest.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/AbstractRandomGeneratorTest.java (original)
+++ jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/AbstractRandomGeneratorTest.java Sat Sep  3 17:38:15 2005
@@ -17,6 +17,9 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.apache.commons.math.stat.Frequency;
+ 
+
 /**
  * Test cases for the AbstractRandomGenerator class
  *
@@ -24,14 +27,123 @@
  */
 
 public class AbstractRandomGeneratorTest extends RandomDataTest {
+    
+    protected TestRandomGenerator testGenerator = new TestRandomGenerator();
+    
     public AbstractRandomGeneratorTest(String name) {
         super(name);
-        randomData = new RandomDataImpl(new TestRandomGenerator());
+        randomData = new RandomDataImpl(testGenerator);
     } 
     
     public static Test suite() {
         TestSuite suite = new TestSuite(AbstractRandomGeneratorTest.class);
         suite.setName("AbstractRandomGenerator Tests");
         return suite;
+    }
+    
+    public void testNextInt() {
+        try {
+            int x = testGenerator.nextInt(-1);
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException ex) {
+            ;
+        }
+        Frequency freq = new Frequency();
+        int value = 0;
+        for (int i=0; i<smallSampleSize; i++) {
+            value = testGenerator.nextInt(4);
+            assertTrue("nextInt range",(value >= 0) && (value <= 3));
+            freq.addValue(value);  
+        }
+        long[] observed = new long[4];
+        for (int i=0; i<4; i++) {
+            observed[i] = freq.getCount(i);
+        } 
+        
+        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
+         * Change to 11.34 for alpha = .01
+         */
+        assertTrue("chi-square test -- will fail about 1 in 1000 times",
+                testStatistic.chiSquare(expected,observed) < 16.27);    
+    }
+    
+    public void testNextLong() {
+        long q1 = Long.MAX_VALUE/4;
+        long q2 = 2 *  q1;
+        long q3 = 3 * q1;
+        
+        Frequency freq = new Frequency();
+        long val = 0;
+        int value = 0;
+        for (int i=0; i<smallSampleSize; i++) {
+            val = testGenerator.nextLong();
+            if (val < q1) {
+                value = 0;
+            } else if (val < q2) {
+                value = 1;
+            } else if (val < q3) {
+                value = 2;
+            } else {
+                value = 3;
+            }
+            freq.addValue(value);  
+        }
+        long[] observed = new long[4];
+        for (int i=0; i<4; i++) {
+            observed[i] = freq.getCount(i);
+        } 
+        
+        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
+         * Change to 11.34 for alpha = .01
+         */
+        assertTrue("chi-square test -- will fail about 1 in 1000 times",
+                testStatistic.chiSquare(expected,observed) < 16.27);    
+    }
+    
+    public void testNextBoolean() {
+        long halfSampleSize = smallSampleSize / 2; 
+        double[] expected = {halfSampleSize, halfSampleSize};
+        long[] observed = new long[2];
+        for (int i=0; i<smallSampleSize; i++) {
+            if (testGenerator.nextBoolean()) {
+                observed[0]++;
+            } else {
+                observed[1]++;
+            }
+        }
+        /* Use ChiSquare dist with df = 2-1 = 1, alpha = .001
+         * Change to 6.635 for alpha = .01
+         */
+        assertTrue("chi-square test -- will fail about 1 in 1000 times",
+                testStatistic.chiSquare(expected,observed) < 10.828);    
+    }
+    
+    public void testNextFloat() {
+        Frequency freq = new Frequency();
+        float val = 0;
+        int value = 0;
+        for (int i=0; i<smallSampleSize; i++) {
+            val = testGenerator.nextFloat();
+            if (val < 0.25) {
+                value = 0;
+            } else if (val < 0.5) {
+                value = 1;
+            } else if (val < 0.75) {
+                value = 2;
+            } else {
+                value = 3;
+            }
+            freq.addValue(value);  
+        }
+        long[] observed = new long[4];
+        for (int i=0; i<4; i++) {
+            observed[i] = freq.getCount(i);
+        } 
+        
+        /* Use ChiSquare dist with df = 4-1 = 3, alpha = .001
+         * Change to 11.34 for alpha = .01
+         */
+        assertTrue("chi-square test -- will fail about 1 in 1000 times",
+                testStatistic.chiSquare(expected,observed) < 16.27);    
     }
 }

Modified: jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/EmpiricalDistributionTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/EmpiricalDistributionTest.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/EmpiricalDistributionTest.java (original)
+++ jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/EmpiricalDistributionTest.java Sat Sep  3 17:38:15 2005
@@ -160,6 +160,14 @@
         tstDoubleGen(5);           
     }
     
+    /**
+     * Test bin index overflow problem (BZ 36450)
+     */
+    public void testBinIndexOverflow() throws Exception {
+        double[] x = new double[] {9474.94326071674, 2080107.8865462579};
+        new EmpiricalDistributionImpl().load(x);
+    }
+    
     public void testSerialization() {
         // Empty
         EmpiricalDistribution dist = new EmpiricalDistributionImpl();

Modified: jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/RandomDataTest.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/RandomDataTest.java?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/RandomDataTest.java (original)
+++ jakarta/commons/proper/math/trunk/src/test/org/apache/commons/math/random/RandomDataTest.java Sat Sep  3 17:38:15 2005
@@ -39,14 +39,14 @@
         randomData = new RandomDataImpl();
     }
 
-    private long smallSampleSize = 1000;
-    private double[] expected = {250,250,250,250};
-    private int largeSampleSize = 10000;
+    protected long smallSampleSize = 1000;
+    protected double[] expected = {250,250,250,250};
+    protected int largeSampleSize = 10000;
     private int tolerance = 50;
     private String[] hex = 
         {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}; 
     protected RandomDataImpl randomData = null; 
-    private ChiSquareTestImpl testStatistic = new ChiSquareTestImpl();
+    protected ChiSquareTestImpl testStatistic = new ChiSquareTestImpl();
     
     public void setUp() { 
     }

Modified: jakarta/commons/proper/math/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/math/trunk/xdocs/changes.xml?rev=267527&r1=267526&r2=267527&view=diff
==============================================================================
--- jakarta/commons/proper/math/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/math/trunk/xdocs/changes.xml Sat Sep  3 17:38:15 2005
@@ -50,6 +50,12 @@
        and numerical utilities, and a PRNG pluggability framework making it
        possible to replace the JDK-supplied random number generator in
        commons-math (and elsewhere) with alternative PRNG implementations.">
+          <action dev="psteitz" type="fix" issue="36450" due-to="Keith McDonald">
+		Fixed bin index overflow problem in EmpiricalDistributionImpl.
+	  </action>
+          <action dev="brentworden" type="fix" issue="36232" due-to="Xiaogang Zhang">
+		Added protection against numerical overflow and underflow in the isBracketing method.
+	  </action>
 	  <action dev="brentworden" type="fix" issue="36300" due-to="Nikhil Gupte">
 		Fixed division by zero error in rounding methods.
 	  </action>



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org