package io.vivarium.util;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import com.johnuckele.vtest.Tester;
import io.vivarium.test.FastTest;
import io.vivarium.test.UnitTest;
public class RandTest
{
@Test
@Category({ FastTest.class, UnitTest.class })
public void testRandSeedForLCGMethods()
{
// Test with LCG based java.util.Random generated numbers
// Set a seed
Rand.getInstance().setRandomSeed(1);
Tester.equal("1st random with seed of 1", Rand.getInstance().getRandomPositiveDouble(), 0.7308781907032909,
0.0);
Tester.equal("2nd random with seed of 1", Rand.getInstance().getRandomPositiveDouble(), 0.41008081149220166,
0.0);
Tester.equal("3rd random with seed of 1", Rand.getInstance().getRandomPositiveDouble(), 0.20771484130971707,
0.0);
Tester.equal("4th random with seed of 1", Rand.getInstance().getRandomPositiveDouble(), 0.3327170559595112,
0.0);
// Set the seed again
Rand.getInstance().setRandomSeed(1);
Tester.equal("1st random with seed of 1", Rand.getInstance().getRandomPositiveDouble(), 0.7308781907032909,
0.0);
// Clear the seed
Rand.getInstance().setRandomSeed();
Tester.notEqual("1st random with generated seed", Rand.getInstance().getRandomPositiveDouble(),
0.7308781907032909, 0.0);
Rand.getInstance().setRandomSeed(10);
double randFromSeed1 = Rand.getInstance().getRandomPositiveDouble();
Rand.getInstance().setRandomSeed(20);
double randFromSeed2 = Rand.getInstance().getRandomPositiveDouble();
Tester.notEqual("Two randoms with different seeds don't match", randFromSeed1, randFromSeed2, 0.0);
Rand.getInstance().setRandomSeed(30);
double randFromSeed3 = Rand.getInstance().getRandomPositiveDouble();
Rand.getInstance().setRandomSeed(30);
double randFromSeed4 = Rand.getInstance().getRandomPositiveDouble();
Tester.equal("Two randoms with matching seeds do match", randFromSeed3, randFromSeed4, 0.0);
// Clear the seed
Rand.getInstance().setRandomSeed();
}
@Test
@Category({ FastTest.class, UnitTest.class })
public void testRandSeedForXorshiftMethods()
{
// Test with Xorshift based
// io.vivarium.core.UtilityFunctions generated numbers
// Set a seed
Rand.getInstance().setRandomSeed(1);
Tester.equal("1st random with seed of 1", Rand.getInstance().getRandomLong(), 35651601L);
Tester.equal("2nd random with seed of 1", Rand.getInstance().getRandomLong(), 1130297953386881L);
Tester.equal("3rd random with seed of 1", Rand.getInstance().getRandomLong(), -9204155794254196429L);
Tester.equal("4th random with seed of 1", Rand.getInstance().getRandomLong(), 144132848981442561L);
// Set the seed again
Rand.getInstance().setRandomSeed(1);
Tester.equal("1st random with seed of 1", Rand.getInstance().getRandomLong(), 35651601L);
Tester.equal("2nd random with seed of 1", Rand.getInstance().getRandomDouble(), 0.00012254714966179758, 0.0001);
Tester.equal("3rd random with seed of 1", Rand.getInstance().getRandomLong(), -9204155794254196429L);
// Clear the seed
Rand.getInstance().setRandomSeed();
Tester.notEqual("1st random with generated seed", Rand.getInstance().getRandomLong(), 1130297953386881L);
Rand.getInstance().setRandomSeed(10);
long randFromSeed1 = Rand.getInstance().getRandomLong();
Rand.getInstance().setRandomSeed(20);
long randFromSeed2 = Rand.getInstance().getRandomLong();
Tester.notEqual("Two randoms with different seeds don't match", randFromSeed1, randFromSeed2);
Rand.getInstance().setRandomSeed(30);
long randFromSeed3 = Rand.getInstance().getRandomLong();
Rand.getInstance().setRandomSeed(30);
long randFromSeed4 = Rand.getInstance().getRandomLong();
Tester.equal("Two randoms with matching seeds do match", randFromSeed3, randFromSeed4);
// Clear the seed
Rand.getInstance().setRandomSeed();
}
@Test
@Category({ FastTest.class, UnitTest.class })
public void testGetRandomPositiveDouble()
{
// Statistical distribution tests, all statistical tests are 4 sigma
double fourSigmaZScore = 4;
double allowedError = 0.01;
int samples = (int) (Math.pow(fourSigmaZScore, 2) / (4 * Math.pow(allowedError, 2)));
int heads = 0;
for (int i = 0; i < samples; i++)
{
if (Rand.getInstance().getRandomPositiveDouble() > 0.5)
{
heads++;
}
}
double observedProbability = ((double) heads) / samples;
double error = Math.abs(observedProbability - 0.5);
Tester.lessOrEqual("Above or below 0.5 should behave like an unbiased coin", error, allowedError);
// Clear the seed
Rand.getInstance().setRandomSeed();
}
@Test
@Category({ FastTest.class, UnitTest.class })
public void testGetRandomLong()
{
// Statistical distribution tests, all statistical tests are 4 sigma
double fourSigmaZScore = 4;
double allowedError = 0.01;
int samples = (int) (Math.pow(fourSigmaZScore, 2) / (4 * Math.pow(allowedError, 2)));
int heads = 0;
for (int i = 0; i < samples; i++)
{
if (Rand.getInstance().getRandomLong() > 0)
{
heads++;
}
}
double observedProbability = ((double) heads) / samples;
double error = Math.abs(observedProbability - 0.5);
Tester.lessOrEqual("Above or below 0 should be an unbiased coin", error, allowedError);
// Clear the seed
Rand.getInstance().setRandomSeed();
}
}