MATH-1610: Functionality moved to "Commons RNG" (cf. RNG-145).
This commit is contained in:
parent
ee73d636de
commit
b509678e95
|
@ -97,89 +97,5 @@ public class RandomUtils {
|
|||
return lower + rng.nextLong(max);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a uniformly distributed random value from the open interval
|
||||
* {@code (lower, upper)} (i.e., endpoints excluded).
|
||||
* <p>
|
||||
* <strong>Definition</strong>:
|
||||
* <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
|
||||
* Uniform Distribution</a> {@code lower} and {@code upper - lower} are the
|
||||
* <a href = "http://www.itl.nist.gov/div898/handbook/eda/section3/eda364.htm">
|
||||
* location and scale parameters</a>, respectively.</p>
|
||||
* <p>
|
||||
* <strong>Algorithm Description</strong>: scales the output of
|
||||
* Random.nextDouble(), but rejects 0 values (i.e., will generate another
|
||||
* random double if Random.nextDouble() returns 0). This is necessary to
|
||||
* provide a symmetric output interval (both endpoints excluded).
|
||||
* </p>
|
||||
*
|
||||
* @param lower Lower bound of the support (excluded).
|
||||
* @param upper Upper bound of the support (excluded).
|
||||
* @return a uniformly distributed random value between lower and upper
|
||||
* (both excluded).
|
||||
* @throws NumberIsTooLargeException if {@code lower >= upper}.
|
||||
* @throws NotFiniteNumberException if one of the bounds is infinite.
|
||||
* @throws NotANumberException if one of the bounds is NaN.
|
||||
*/
|
||||
public double nextUniform(double lower, double upper) {
|
||||
return nextUniform(lower, upper, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a uniformly distributed random value from the interval
|
||||
* {@code (lower, upper)} or the interval {@code [lower, upper)}. The lower
|
||||
* bound is thus optionally included, while the upper bound is always
|
||||
* excluded.
|
||||
* <p>
|
||||
* <strong>Definition</strong>:
|
||||
* <a href="http://www.itl.nist.gov/div898/handbook/eda/section3/eda3662.htm">
|
||||
* Uniform Distribution</a> {@code lower} and {@code upper - lower} are the
|
||||
* <a href = "http://www.itl.nist.gov/div898/handbook/eda/section3/eda364.htm">
|
||||
* location and scale parameters</a>, respectively.</p>
|
||||
* <p>
|
||||
* <strong>Algorithm Description</strong>: if the lower bound is excluded,
|
||||
* scales the output of "nextDouble()", but rejects 0 values (i.e. it
|
||||
* will generate another random double if "nextDouble()" returns 0).
|
||||
* This is necessary to provide a symmetric output interval (both
|
||||
* endpoints excluded).
|
||||
* </p>
|
||||
*
|
||||
* @param lower Lower bound of the support.
|
||||
* @param upper Exclusive upper bound of the support.
|
||||
* @param lowerInclusive {@code true} if the lower bound is inclusive.
|
||||
* @return a uniformly distributed random value in the {@code (lower, upper)}
|
||||
* interval, if {@code lowerInclusive} is {@code false}, or in the
|
||||
* {@code [lower, upper)} interval, if {@code lowerInclusive} is
|
||||
* {@code true}.
|
||||
* @throws NumberIsTooLargeException if {@code lower >= upper}.
|
||||
* @throws NotFiniteNumberException if one of the bounds is infinite.
|
||||
* @throws NotANumberException if one of the bounds is NaN.
|
||||
*/
|
||||
public double nextUniform(double lower,
|
||||
double upper,
|
||||
boolean lowerInclusive) {
|
||||
if (lower >= upper) {
|
||||
throw new NumberIsTooLargeException(LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
|
||||
lower, upper, false);
|
||||
}
|
||||
if (Double.isInfinite(lower)) {
|
||||
throw new NotFiniteNumberException(LocalizedFormats.INFINITE_BOUND, lower);
|
||||
}
|
||||
if (Double.isInfinite(upper)) {
|
||||
throw new NotFiniteNumberException(LocalizedFormats.INFINITE_BOUND, upper);
|
||||
}
|
||||
if (Double.isNaN(lower) || Double.isNaN(upper)) {
|
||||
throw new NotANumberException();
|
||||
}
|
||||
|
||||
// Ensure nextDouble() isn't 0.0
|
||||
double u = rng.nextDouble();
|
||||
while (!lowerInclusive && u <= 0.0) {
|
||||
u = rng.nextDouble();
|
||||
}
|
||||
|
||||
return u * upper + (1.0 - u) * lower;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,17 +51,6 @@ public abstract class RandomUtilsDataGeneratorAbstractTest {
|
|||
Assert.assertFalse(x == y);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformExtremeValues() {
|
||||
double x = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
double y = randomData.nextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
Assert.assertFalse(x == y);
|
||||
Assert.assertFalse(Double.isNaN(x));
|
||||
Assert.assertFalse(Double.isNaN(y));
|
||||
Assert.assertFalse(Double.isInfinite(x));
|
||||
Assert.assertFalse(Double.isInfinite(y));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextLongIAE() {
|
||||
try {
|
||||
|
@ -136,109 +125,4 @@ public abstract class RandomUtilsDataGeneratorAbstractTest {
|
|||
(((double) upper) - ((double) lower));
|
||||
Assert.assertTrue(ratio > 0.99999);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformIAE() {
|
||||
try {
|
||||
randomData.nextUniform(4, 3);
|
||||
Assert.fail("MathIllegalArgumentException expected");
|
||||
} catch (MathIllegalArgumentException ex) {
|
||||
// ignored
|
||||
}
|
||||
try {
|
||||
randomData.nextUniform(0, Double.POSITIVE_INFINITY);
|
||||
Assert.fail("MathIllegalArgumentException expected");
|
||||
} catch (MathIllegalArgumentException ex) {
|
||||
// ignored
|
||||
}
|
||||
try {
|
||||
randomData.nextUniform(Double.NEGATIVE_INFINITY, 0);
|
||||
Assert.fail("MathIllegalArgumentException expected");
|
||||
} catch (MathIllegalArgumentException ex) {
|
||||
// ignored
|
||||
}
|
||||
try {
|
||||
randomData.nextUniform(0, Double.NaN);
|
||||
Assert.fail("MathIllegalArgumentException expected");
|
||||
} catch (MathIllegalArgumentException ex) {
|
||||
// ignored
|
||||
}
|
||||
try {
|
||||
randomData.nextUniform(Double.NaN, 0);
|
||||
Assert.fail("MathIllegalArgumentException expected");
|
||||
} catch (MathIllegalArgumentException ex) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformPositiveBounds() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
checkNextUniform(0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformNegativeToPositiveBounds() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
checkNextUniform(-3, 5);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformNegativeBounds() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
checkNextUniform(-7, -3);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNextUniformMaximalInterval() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
checkNextUniform(-Double.MAX_VALUE, Double.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNextUniform(double min, double max) {
|
||||
// Set up bin bounds - min, binBound[0], ..., binBound[binCount-2], max
|
||||
final int binCount = 5;
|
||||
final double binSize = max / binCount - min/binCount; // Prevent overflow in extreme value case
|
||||
final double[] binBounds = new double[binCount - 1];
|
||||
binBounds[0] = min + binSize;
|
||||
for (int i = 1; i < binCount - 1; i++) {
|
||||
binBounds[i] = binBounds[i - 1] + binSize; // + instead of * to avoid overflow in extreme case
|
||||
}
|
||||
|
||||
final Frequency<Integer> freq = new Frequency<>();
|
||||
for (int i = 0; i < smallSampleSize; i++) {
|
||||
final double value = randomData.nextUniform(min, max);
|
||||
Assert.assertTrue("nextUniform range", (value > min) && (value < max));
|
||||
// Find bin
|
||||
int j = 0;
|
||||
while (j < binCount - 1 && value > binBounds[j]) {
|
||||
j++;
|
||||
}
|
||||
freq.addValue(j);
|
||||
}
|
||||
|
||||
final long[] observed = new long[binCount];
|
||||
for (int i = 0; i < binCount; i++) {
|
||||
observed[i] = freq.getCount(i);
|
||||
}
|
||||
final double[] expected = new double[binCount];
|
||||
for (int i = 0; i < binCount; i++) {
|
||||
expected[i] = 1d / binCount;
|
||||
}
|
||||
|
||||
TestUtils.assertChiSquareAccept(expected, observed, 0.01);
|
||||
}
|
||||
|
||||
/** test exclusive endpoints of nextUniform **/
|
||||
@Test
|
||||
public void testNextUniformExclusiveEndpoints() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
double u = randomData.nextUniform(0.99, 1);
|
||||
Assert.assertTrue(u > 0.99 && u < 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue