下面列出了org.openjdk.jmh.annotations.Threads#org.apache.commons.rng.UniformRandomProvider 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* @param rng Generator of uniformly distributed random numbers
* @param probabilityOfSuccess The probability of success (must be in the range
* {@code [0 < probabilityOfSuccess < 1]})
*/
GeometricExponentialSampler(UniformRandomProvider rng, double probabilityOfSuccess) {
this.rng = rng;
// Use a related exponential distribution:
// λ = −ln(1 − probabilityOfSuccess)
// exponential mean = 1 / λ
// --
// Note on validation:
// If probabilityOfSuccess == Math.nextDown(1.0) the exponential mean is >0 (valid).
// If probabilityOfSuccess == Double.MIN_VALUE the exponential mean is +Infinity
// and the sample will always be Integer.MAX_VALUE (the distribution is truncated). It
// is noted in the class Javadoc that the use of a small p leads to truncation so
// no checks are made for this case.
final double exponentialMean = 1.0 / (-Math.log1p(-probabilityOfSuccess));
exponentialSampler = AhrensDieterExponentialSampler.of(rng, exponentialMean);
}
/**
* Test the SharedStateSampler implementation throws if the underlying sampler is
* not a SharedStateSampler.
*/
@Test(expected = UnsupportedOperationException.class)
public void testSharedStateSamplerThrowsIfUnderlyingSamplerDoesNotShareState() {
final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
final NormalizedGaussianSampler gauss = new NormalizedGaussianSampler() {
@Override
public double sample() {
return 0;
}
};
final double mean = 1.23;
final double standardDeviation = 4.56;
final SharedStateContinuousSampler sampler1 =
GaussianSampler.of(gauss, mean, standardDeviation);
sampler1.withUniformRandomProvider(rng2);
}
/**
* Creates the task.
*
* @param randomSource The random source.
* @param rng RNG to be tested.
* @param seed The seed used to create the RNG.
* @param output Output report file.
* @param command The sub-process command to run.
* @param cmd The run command.
* @param progressTracker The progress tracker.
*/
StressTestTask(RandomSource randomSource,
UniformRandomProvider rng,
byte[] seed,
File output,
List<String> command,
StressTestCommand cmd,
ProgressTracker progressTracker) {
this.randomSource = randomSource;
this.rng = rng;
this.seed = seed;
this.output = output;
this.command = command;
this.cmd = cmd;
this.progressTracker = progressTracker;
}
@Test
void testGoodnessOfFit() {
final UniformRandomProvider rng = RandomSource.create(RandomSource.WELL_19937_A,
123456789L);
final int numSamples = 1000;
final double level = 0.01;
for (final double alpha : ALPHA_BETAS) {
for (final double beta : ALPHA_BETAS) {
final BetaDistribution betaDistribution = new BetaDistribution(alpha, beta);
final ContinuousDistribution.Sampler sampler = betaDistribution.createSampler(rng);
final double[] observed = AbstractContinuousDistribution.sample(numSamples, sampler);
final double gT = gTest(betaDistribution, observed);
Assertions.assertFalse(gT < level,
() -> "G goodness-of-fit (" + gT + ") test rejected null at alpha = " + level);
}
}
}
@Test
public void testMultiply_numericalStability() {
// arrange
int slices = 1024;
double delta = (8.0 * PlaneAngleRadians.PI / 3.0) / slices;
QuaternionRotation q = QuaternionRotation.identity();
UniformRandomProvider rand = RandomSource.create(RandomSource.JDK, 2L);
// act
for (int i = 0; i < slices; ++i) {
double angle = rand.nextDouble();
QuaternionRotation forward = QuaternionRotation.fromAxisAngle(PLUS_DIAGONAL, angle);
QuaternionRotation backward = QuaternionRotation.fromAxisAngle(PLUS_DIAGONAL, delta - angle);
q = q.multiply(forward).multiply(backward);
}
// assert
Assert.assertTrue(q.getQuaternion().getW() > 0);
Assert.assertEquals(1.0, q.getQuaternion().norm(), EPS);
assertRotationEquals(StandardRotations.PLUS_DIAGONAL_TWO_THIRDS_PI, q);
}
@Test
public void testUnrestorable() {
// Create two generators of the same type as the one being tested.
final UniformRandomProvider rng1 = RandomSource.create(originalSource, originalSeed, originalArgs);
final UniformRandomProvider rng2 = RandomSource.unrestorable(RandomSource.create(originalSource, originalSeed, originalArgs));
// Ensure that they generate the same values.
RandomAssert.assertProduceSameSequence(rng1, rng2);
// Cast must work.
final RestorableUniformRandomProvider restorable = (RestorableUniformRandomProvider) rng1;
// Cast must fail.
try {
final RestorableUniformRandomProvider dummy = (RestorableUniformRandomProvider) rng2;
Assert.fail("Cast should have failed");
} catch (ClassCastException e) {
// Expected.
}
}
/**
* Assert the shuffle matches {@link PermutationSampler#shuffle(UniformRandomProvider, int[])}.
*
* @param list Array whose entries will be shuffled (in-place).
*/
private static void assertShuffleMatchesPermutationSamplerShuffle(List<Integer> list) {
final int[] array = new int[list.size()];
ListIterator<Integer> it = list.listIterator();
for (int i = 0; i < array.length; i++) {
array[i] = it.next();
}
// Identical RNGs
final long seed = RandomSource.createLong();
final UniformRandomProvider rng1 = RandomSource.create(RandomSource.SPLIT_MIX_64, seed);
final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, seed);
ListSampler.shuffle(rng1, list);
PermutationSampler.shuffle(rng2, array);
final String msg = "Type=" + list.getClass().getSimpleName();
it = list.listIterator();
for (int i = 0; i < array.length; i++) {
Assert.assertEquals(msg, array[i], it.next().intValue());
}
}
/**
* Test the SharedStateSampler implementation.
*/
@Test
public void testSharedStateSampler() {
final UniformRandomProvider rng1 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
final int n = 17;
final int k = 13;
final PermutationSampler sampler1 =
new PermutationSampler(rng1, n, k);
final PermutationSampler sampler2 = sampler1.withUniformRandomProvider(rng2);
RandomAssert.assertProduceSameSequence(
new RandomAssert.Sampler<int[]>() {
@Override
public int[] sample() {
return sampler1.sample();
}
},
new RandomAssert.Sampler<int[]>() {
@Override
public int[] sample() {
return sampler2.sample();
}
});
}
/**
* Test the abs and log functions are consistent. The definition of log uses abs and
* the result should be computed using the same representation of the complex number's
* magnitude (abs). If the log function uses a simple representation
* {@code sqrt(x^2 + y^2)} then this may have a 1 ulp or more difference from the high
* accuracy result computed by abs. This will propagate to create differences in log.
*
* <p>Note: This test is separated from the similar test for sqrt to allow testing
* different numbers.
*/
@Test
void testAbsVsLog() {
final UniformRandomProvider rng = RandomSource.create(RandomSource.XO_RO_SHI_RO_128_PP);
// Note: All methods implement scaling to ensure the magnitude can be computed.
// Try very large or small numbers that will over/underflow to test that the
// scaling
// is consistent. Note that:
// - log will set the real component using log(|z|). This will massively reduce
// the magnitude when |z| >> 1. Highest accuracy will be when |z| is as large
// as possible before computing the log.
// No test around |z| == 1 as a high accuracy computation is required:
// Math.log1p(x*x+y*y-1)
// Each sample fails approximately 25% of the time if using a standard x^2+y^2 in
// log()
// and high accuracy representation in abs(). Use 100 samples to ensure the
// behavior is OK.
assertAbsVsLog(100,
() -> Complex.ofCartesian(createFixedExponentNumber(rng, 1022), createFixedExponentNumber(rng, 1022)));
assertAbsVsLog(100,
() -> Complex.ofCartesian(createFixedExponentNumber(rng, -1022), createFixedExponentNumber(rng, -1022)));
}
/**
* ISO C Standard G.6 (7).
*/
@Test
void testImplicitTrig() {
final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64);
for (int i = 0; i < 100; i++) {
final double re = next(rng);
final double im = next(rng);
final Complex z = complex(re, im);
final Complex iz = z.multiplyImaginary(1);
assertComplex(z.asin(), iz.asinh().multiplyImaginary(-1));
assertComplex(z.atan(), iz.atanh().multiplyImaginary(-1));
assertComplex(z.cos(), iz.cosh());
assertComplex(z.sin(), iz.sinh().multiplyImaginary(-1));
assertComplex(z.tan(), iz.tanh().multiplyImaginary(-1));
}
}
/**
* @param sources Source of randomness.
* @param range The range.
* @param bh Data sink.
*/
@Benchmark
public void runPoissonSampler(Sources sources,
MeanRange range,
Blackhole bh) {
final UniformRandomProvider r = sources.getGenerator();
final PoissonSamplerFactory factory = new PoissonSamplerFactory() {
@Override
public DiscreteSampler createPoissonSampler(double mean) {
return PoissonSampler.of(r, mean);
}
};
runSample(factory, range, bh);
}
/**
* @param rng Generator of uniformly distributed random numbers.
* @param function Inverse cumulative probability function.
*/
public InverseTransformContinuousSampler(UniformRandomProvider rng,
ContinuousInverseCumulativeProbabilityFunction function) {
super(null);
this.rng = rng;
this.function = function;
}
/**
* @param rng Generator of uniformly distributed random numbers.
* @param source Source to copy.
*/
private PermutationSampler(UniformRandomProvider rng,
PermutationSampler source) {
// Do not clone the domain. This ensures:
// 1. Thread safety as the domain may be shuffled during the clone
// and an incomplete shuffle swap step can result in duplicates and
// missing elements in the array.
// 2. If the argument RNG is an exact match for the RNG in the source
// then the output sequence will differ unless the domain is currently
// in natural order.
domain = PermutationSampler.natural(source.domain.length);
size = source.size;
this.rng = rng;
}
/**
* Creates the Poisson distribution by computing probabilities recursively from {@code X=0}.
*
* @param rng Generator of uniformly distributed random numbers.
* @param mean Mean.
* @return Sampler.
*/
private static SharedStateDiscreteSampler createPoissonDistributionFromX0(
UniformRandomProvider rng, double mean) {
final double p0 = Math.exp(-mean);
// Recursive update of Poisson probability until the value is too small
// p(x + 1) = p(x) * mean / (x + 1)
double p = p0;
int i = 1;
while (p * DOUBLE_31 >= 1) {
p *= mean / i++;
}
// Probabilities are 30-bit integers, assumed denominator 2^30
final int size = i - 1;
final int[] prob = new int[size];
p = p0;
prob[0] = toUnsignedInt30(p);
// The sum must exceed 2^30. In edges cases this is false due to round-off.
int sum = prob[0];
for (i = 1; i < prob.length; i++) {
p *= mean / i;
prob[i] = toUnsignedInt30(p);
sum += prob[i];
}
// If the sum is < 2^30 add the remaining sum to the mode (floor(mean)).
prob[(int) mean] += Math.max(0, INT_30 - sum);
// Note: offset = 0
return createSampler(rng, POISSON_NAME, prob, 0);
}
/**
* Test to demonstrate that any probability of success under one produces a valid
* mean for the exponential distribution.
*/
@Test
public void testProbabilityOfSuccessUnderOneIsValid() {
// The sampler explicitly handles probabilityOfSuccess == 1 as an edge case.
// Anything under it should be valid for sampling from an ExponentialDistribution.
final double probabilityOfSuccess = Math.nextAfter(1, -1);
// Map to the mean
final double exponentialMean = 1.0 / (-Math.log1p(-probabilityOfSuccess));
// As long as this is finite positive then the sampler is valid
Assert.assertTrue(exponentialMean > 0 && exponentialMean <= Double.MAX_VALUE);
// The internal exponential sampler validates the mean so demonstrate creating a
// geometric sampler does not throw.
final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64);
GeometricSampler.of(rng, probabilityOfSuccess);
}
/**
* Test the edge case where the pair of samples are rejected. This occurs when the distance
* of the pair is outside the unit circle or lies on the origin.
*/
@Test
public void testSamplePairIsRejected() {
final double value = 0.25;
final UniformRandomProvider rng = new IntProvider() {
private int i;
@Override
public int next() {
// Not used
return 0;
}
@Override
public double nextDouble() {
i++;
if (i <= 2) {
// First two samples are one.
// This is outside the unit circle.
return 1.0;
}
if (i <= 4) {
// Next two samples are 0.5.
// The pair lies at the origin.
return 0.5;
}
return value;
}
};
final MarsagliaNormalizedGaussianSampler sampler = new MarsagliaNormalizedGaussianSampler(rng);
// Compute as per the algorithm
final double x = 2 * value - 1;
final double r2 = x * x + x * x;
final double expected = x * Math.sqrt(-2 * Math.log(r2) / r2);
Assert.assertEquals(expected, sampler.sample(), 0);
}
/**
* Perform a Fischer-Yates shuffle.
*
* @param array the array
* @param rng the random generator
*/
private static void shuffle(int[] array, UniformRandomProvider rng) {
for (int i = array.length - 1; i > 0; i--) {
// Swap index with any position down to 0
final int j = rng.nextInt(i);
final int tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
}
@Test
public void testToTree_randomSpheres() {
// arrange
UniformRandomProvider rand = RandomSource.create(RandomSource.XO_RO_SHI_RO_128_PP, 1L);
DoublePrecisionContext precision = new EpsilonDoublePrecisionContext(1e-10);
double min = 1e-1;
double max = 1e2;
DoubleSupplier randDouble = () -> (rand.nextDouble() * (max - min)) + min;
int count = 10;
for (int i = 0; i < count; ++i) {
Vector3D center = Vector3D.of(
randDouble.getAsDouble(),
randDouble.getAsDouble(),
randDouble.getAsDouble());
double radius = randDouble.getAsDouble();
Sphere sphere = Sphere.from(center, radius, precision);
for (int s = 0; s < 7; ++s) {
// act
RegionBSPTree3D tree = sphere.toTree(s);
// assert
Assert.assertEquals((int)(8 * Math.pow(4, s)), tree.getBoundaries().size());
Assert.assertTrue(tree.isFinite());
Assert.assertFalse(tree.isEmpty());
Assert.assertTrue(tree.getSize() < sphere.getSize());
}
}
}
@Test
void testCGrammar() {
final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64);
for (int i = 0; i < 10; i++) {
final Complex z = Complex.ofCartesian(rng.nextDouble(), rng.nextDouble());
Assertions.assertEquals(z.getReal(), z.real(), "real");
Assertions.assertEquals(z.getImaginary(), z.imag(), "imag");
}
}
/**
* Test the sampler with a probability that requires inversion has the same name for
* {@link Object#toString()}.
*/
@Test
public void testBinomialSamplerToString() {
final UniformRandomProvider rng = new FixedRNG();
final int trials = 10;
final double p1 = 0.4;
final double p2 = 1 - p1;
final DiscreteSampler sampler1 = MarsagliaTsangWangDiscreteSampler.Binomial.of(rng, trials, p1);
final DiscreteSampler sampler2 = MarsagliaTsangWangDiscreteSampler.Binomial.of(rng, trials, p2);
Assert.assertEquals(sampler1.toString(), sampler2.toString());
}
/**
* @param sources Source of randomness.
* @return the result
*/
@Benchmark
@Threads(4)
public long threadLocalRandomSourceCurrent(Sources sources) {
final UniformRandomProvider rng = ThreadLocalRandomSource.current(sources.getRandomSource());
long result = 0;
for (int i = 0; i < numValues; i++) {
result = result ^ rng.nextLong();
}
return result;
}
/**
* @param sources Source of randomness.
* @param sizes Size of the seed.
* @return the seed
*/
@Benchmark
@Threads(4)
public int[] Threads4_createIntArraySeed_UnfairLock(SeedRandomSources sources, SeedSizes sizes) {
final UniformRandomProvider rng = sources.getGenerator();
final int[] seed = new int[sizes.getSize()];
for (int i = 0; i < seed.length; i++) {
seed[i] = nextInt(UNFAIR_LOCK, rng);
}
return seed;
}
/**
* Test the SharedStateSampler implementation.
*/
@Test
public void testSharedStateSampler() {
final UniformRandomProvider rng1 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
final double[] probabilities = {0.1, 0, 0.2, 0.3, 0.1, 0.3, 0};
final SharedStateDiscreteSampler sampler1 =
GuideTableDiscreteSampler.of(rng1, probabilities);
final SharedStateDiscreteSampler sampler2 = sampler1.withUniformRandomProvider(rng2);
RandomAssert.assertProduceSameSequence(sampler1, sampler2);
}
@Test
public void testSamplesWithRangeOf1() {
final int upper = 99;
final int lower = upper;
final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64);
final SharedStateDiscreteSampler sampler = DiscreteUniformSampler.of(rng, lower, upper);
for (int i = 0; i < 5; i++) {
Assert.assertEquals(lower, sampler.sample());
}
}
/**
* @param sources Source of randomness.
* @param sizes Size of the seed.
* @return the seed
*/
@Benchmark
@Threads(4)
public int[] Threads4_createIntArraySeed_FairLock(SeedRandomSources sources, SeedSizes sizes) {
final UniformRandomProvider rng = sources.getGenerator();
final int[] seed = new int[sizes.getSize()];
for (int i = 0; i < seed.length; i++) {
seed[i] = nextInt(FAIR_LOCK, rng);
}
return seed;
}
/**
* Tests uniformity of the distribution produced by {@code nextInt(int)}.
*
* @param rng Generator.
* @param max Upper bound.
* @param sampleSize Number of random values generated.
*/
private void checkNextIntegerInRange(final UniformRandomProvider rng,
final int max,
int sampleSize) {
final Callable<Integer> nextMethod = new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return rng.nextInt(max);
}
};
checkNextInRange(max, sampleSize, nextMethod);
}
/**
* @param rng Generator of uniformly distributed random numbers.
* @param source Source to copy.
*/
private GaussianSampler(UniformRandomProvider rng,
GaussianSampler source) {
this.mean = source.mean;
this.standardDeviation = source.standardDeviation;
this.normalized = InternalUtils.newNormalizedGaussianSampler(source.normalized, rng);
}
/**
* @param sources Source of randomness.
* @param sizes Size of the seed and compute blocks.
* @return the seed
*/
@Benchmark
@Threads(4)
public int[] Threads4_createIntArraySeedBlocks_FairLock(SeedRandomSources sources, TestSizes sizes) {
final UniformRandomProvider rng = sources.getGenerator();
final int[] seed = new int[sizes.getSize()];
for (int i = 0; i < seed.length; i += sizes.getBlockSize()) {
nextInt(FAIR_LOCK, rng, seed, i, Math.min(i + sizes.getBlockSize(), seed.length));
}
return seed;
}
/**
* Instantiates a sampler using a precomputed state.
*
* @param rng Generator of uniformly distributed random numbers.
* @param state The state for {@code lambda = (int)Math.floor(mean)}.
* @param lambdaFractional The lambda fractional value
* ({@code mean - (int)Math.floor(mean))}.
* @throws IllegalArgumentException
* if {@code lambdaFractional < 0 || lambdaFractional >= 1}.
*/
LargeMeanPoissonSampler(UniformRandomProvider rng,
LargeMeanPoissonSamplerState state,
double lambdaFractional) {
if (lambdaFractional < 0 || lambdaFractional >= 1) {
throw new IllegalArgumentException(
"lambdaFractional must be in the range 0 (inclusive) to 1 (exclusive): " + lambdaFractional);
}
this.rng = rng;
gaussian = new ZigguratNormalizedGaussianSampler(rng);
exponential = AhrensDieterExponentialSampler.of(rng, 1);
// Plain constructor uses the uncached function.
factorialLog = NO_CACHE_FACTORIAL_LOG;
// Use the state to initialise the algorithm
lambda = state.getLambdaRaw();
logLambda = state.getLogLambda();
logLambdaFactorial = state.getLogLambdaFactorial();
delta = state.getDelta();
halfDelta = state.getHalfDelta();
twolpd = state.getTwolpd();
p1 = state.getP1();
p2 = state.getP2();
c1 = state.getC1();
// The algorithm requires a Poisson sample from the remaining lambda fraction.
smallMeanPoissonSampler = (lambdaFractional < Double.MIN_VALUE) ?
NO_SMALL_MEAN_POISSON_SAMPLER : // Not used.
KempSmallMeanPoissonSampler.of(rng, lambdaFractional);
}
/**
* Test the constructor with a bad mean.
*/
@Test(expected = IllegalArgumentException.class)
public void testConstructorThrowsWithMeanThatSetsProbabilityP0ToZero() {
final UniformRandomProvider rng =
RandomSource.create(RandomSource.SPLIT_MIX_64);
final double p0 = Double.MIN_VALUE;
// Note: p0 = Math.exp(-mean) => mean = -Math.log(p0).
// Add to the limit on the mean to cause p0 to be zero.
final double mean = -Math.log(p0) + 1;
SmallMeanPoissonSampler.of(rng, mean);
}