Merged changes from MATH_1_1 branch, r240245:r267516

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@267527 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2005-09-04 00:38:15 +00:00
parent e1062a38bb
commit fe3ac4361e
7 changed files with 250 additions and 28 deletions

View File

@ -250,8 +250,7 @@ public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistrib
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 @@ public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistrib
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 @@ public class EmpiricalDistributionImpl implements Serializable, EmpiricalDistrib
}
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.

View File

@ -54,64 +54,118 @@ public class RandomAdaptor extends Random implements RandomGenerator {
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

View File

@ -412,4 +412,34 @@ public class FractionTest extends TestCase {
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);
}
}

View File

@ -17,6 +17,9 @@ package org.apache.commons.math.random;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.commons.math.stat.Frequency;
/**
* Test cases for the AbstractRandomGenerator class
*
@ -24,9 +27,12 @@ import junit.framework.TestSuite;
*/
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() {
@ -34,4 +40,110 @@ public class AbstractRandomGeneratorTest extends RandomDataTest {
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);
}
}

View File

@ -160,6 +160,14 @@ public final class EmpiricalDistributionTest extends RetryTestCase {
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();

View File

@ -39,14 +39,14 @@ public class RandomDataTest extends RetryTestCase {
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() {
}

View File

@ -50,6 +50,12 @@ Commons Math Release Notes</title>
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>