Distributions
- added all distributions required - introduced tests
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"java.configuration.updateBuildConfiguration": "automatic"
|
||||||
|
}
|
||||||
14
pom.xml
14
pom.xml
@@ -13,4 +13,18 @@
|
|||||||
<maven.compiler.target>23</maven.compiler.target>
|
<maven.compiler.target>23</maven.compiler.target>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>5.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.platform</groupId>
|
||||||
|
<artifactId>junit-platform-runner</artifactId>
|
||||||
|
<version>1.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -10,7 +10,7 @@ public interface Distribution {
|
|||||||
* Represents an exponential distribution.
|
* Represents an exponential distribution.
|
||||||
*/
|
*/
|
||||||
public static class Exponential implements Distribution {
|
public static class Exponential implements Distribution {
|
||||||
private final double lambda;
|
public final double lambda;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new exponential distribution with the given rate.
|
* Creates a new exponential distribution with the given rate.
|
||||||
@@ -31,8 +31,8 @@ public interface Distribution {
|
|||||||
* Represents a normal distribution.
|
* Represents a normal distribution.
|
||||||
*/
|
*/
|
||||||
public static class Normal implements Distribution {
|
public static class Normal implements Distribution {
|
||||||
private final double mean;
|
public final double mean;
|
||||||
private final double sigma;
|
public final double sigma;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new normal distribution with the given mean and standard deviation.
|
* Creates a new normal distribution with the given mean and standard deviation.
|
||||||
@@ -56,8 +56,8 @@ public interface Distribution {
|
|||||||
* Represents a normal distribution using the Box-Muller transform.
|
* Represents a normal distribution using the Box-Muller transform.
|
||||||
*/
|
*/
|
||||||
public static class NormalBoxMuller implements Distribution {
|
public static class NormalBoxMuller implements Distribution {
|
||||||
private final double mean;
|
public final double mean;
|
||||||
private final double sigma;
|
public final double sigma;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new normal distribution with the given mean and standard deviation.
|
* Creates a new normal distribution with the given mean and standard deviation.
|
||||||
@@ -74,9 +74,102 @@ public interface Distribution {
|
|||||||
public double sample(Rng rng) {
|
public double sample(Rng rng) {
|
||||||
var sample1 = rng.random();
|
var sample1 = rng.random();
|
||||||
var sample2 = rng.random();
|
var sample2 = rng.random();
|
||||||
//remove the other value for thread safety
|
// remove the other value for thread safety
|
||||||
//next = mean + sigma * Math.sqrt(-2 * Math.log(sample1)) * Math.sin(2 * Math.PI * sample2);
|
// next = mean + sigma * Math.sqrt(-2 * Math.log(sample1)) * Math.sin(2 *
|
||||||
|
// Math.PI * sample2);
|
||||||
return mean + sigma * Math.sqrt(-2 * Math.log(sample1)) * Math.cos(2 * Math.PI * sample2);
|
return mean + sigma * Math.sqrt(-2 * Math.log(sample1)) * Math.cos(2 * Math.PI * sample2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a uniform distribution.
|
||||||
|
*/
|
||||||
|
public static class Uniform implements Distribution {
|
||||||
|
public final double min;
|
||||||
|
public final double max;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new uniform distribution with the given min value and max value.
|
||||||
|
*
|
||||||
|
* @param min the minimum value possible
|
||||||
|
* @param max the maximum value possible
|
||||||
|
*/
|
||||||
|
public Uniform(double min, double max) {
|
||||||
|
this.min = min;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double sample(Rng rng) {
|
||||||
|
return min + rng.random() * (max - min);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent an Erlang distribution.
|
||||||
|
*/
|
||||||
|
public static class Erlang implements Distribution {
|
||||||
|
public final int k;
|
||||||
|
public final double lambda;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new erlang distribution with the given K exponentials, all with the
|
||||||
|
* same lambda.
|
||||||
|
*
|
||||||
|
* @param k the number of exponentials
|
||||||
|
* @param lambda the lambda of the exponentials
|
||||||
|
*/
|
||||||
|
public Erlang(int k, double lambda) {
|
||||||
|
this.k = k;
|
||||||
|
this.lambda = lambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double sample(Rng rng) {
|
||||||
|
var product = 1.0;
|
||||||
|
for (int i = 0; i < this.k; i++) {
|
||||||
|
product *= rng.random();
|
||||||
|
}
|
||||||
|
return -Math.log(product) / this.lambda;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a HyperExponential distribution.
|
||||||
|
*/
|
||||||
|
public static class HyperExponential implements Distribution {
|
||||||
|
private final double[] lambdas;
|
||||||
|
private final double[] probabilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new hyperexponential distribution with the given lambdas and their
|
||||||
|
* corresponding probabilities.
|
||||||
|
*
|
||||||
|
* @param lambdas the array of lambda values for the exponential
|
||||||
|
* distributions
|
||||||
|
* @param probabilities the array of probabilities for each lambda
|
||||||
|
*/
|
||||||
|
public HyperExponential(double[] lambdas, double[] probabilities) {
|
||||||
|
if (lambdas.length != probabilities.length) {
|
||||||
|
throw new IllegalArgumentException("Lambdas and probabilities must have the same length");
|
||||||
|
}
|
||||||
|
this.lambdas = lambdas;
|
||||||
|
this.probabilities = probabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double sample(Rng rng) {
|
||||||
|
var randomValue = rng.random();
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
while (i < probabilities.length) {
|
||||||
|
randomValue -= probabilities[i];
|
||||||
|
if (randomValue <= 0.0d)
|
||||||
|
break;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -Math.log(rng.random()) / lambdas[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class Statistics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
*
|
||||||
*
|
*
|
||||||
* @param save
|
* @param save
|
||||||
* @param val1
|
* @param val1
|
||||||
|
|||||||
29
src/test/java/net/berack/upo/valpre/rand/TestRandom.java
Normal file
29
src/test/java/net/berack/upo/valpre/rand/TestRandom.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package net.berack.upo.valpre.rand;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TestRandom {
|
||||||
|
@Test
|
||||||
|
public void testRng() {
|
||||||
|
var numbers = new int[5000];
|
||||||
|
var rng = new Rng(4656);
|
||||||
|
|
||||||
|
for (var i = 0; i < 1000000; i++) {
|
||||||
|
var sample = rng.random();
|
||||||
|
var index = (int) (sample * numbers.length);
|
||||||
|
numbers[index] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var avg = (double) Arrays.stream(numbers).sum() / numbers.length;
|
||||||
|
var variance = Arrays.stream(numbers).mapToDouble(num -> Math.pow(num - avg, 2)).sum() / numbers.length;
|
||||||
|
var stdDev = Math.sqrt(variance);
|
||||||
|
var expected = Math.sqrt((double) numbers.length / 12);
|
||||||
|
expected *= 1.1; // adding a bit of margin
|
||||||
|
|
||||||
|
assertTrue("Standard Dev must be less than [" + expected + "] -> [" + stdDev + "]", stdDev < expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user