1 package net.bmahe.genetics4j.core.util;
2
3 import java.util.Objects;
4 import java.util.function.Supplier;
5 import java.util.random.RandomGenerator;
6
7 import org.apache.commons.lang3.Validate;
8
9 import net.bmahe.genetics4j.core.spec.statistics.distributions.Distribution;
10 import net.bmahe.genetics4j.core.spec.statistics.distributions.NormalDistribution;
11 import net.bmahe.genetics4j.core.spec.statistics.distributions.UniformDistribution;
12
13 public class DistributionUtils {
14
15 public static Supplier<Double> distributionValueSupplier(final RandomGenerator randomGenerator,
16 final double minValue, final double maxValue, final Distribution distribution) {
17 Objects.requireNonNull(randomGenerator);
18 Objects.requireNonNull(distribution);
19 Validate.isTrue(minValue <= maxValue);
20
21 return switch (distribution) {
22 case UniformDistribution ud -> {
23 final double valueRange = maxValue - minValue;
24 yield () -> minValue + randomGenerator.nextDouble() * valueRange;
25 }
26 case NormalDistribution normalDistribution -> {
27 final double mean = normalDistribution.mean();
28 final double standardDeviation = normalDistribution.standardDeviation();
29
30 yield () -> {
31 final double value = mean + randomGenerator.nextGaussian() * standardDeviation;
32
33 if (value < minValue) {
34 return minValue;
35 } else if (value > maxValue) {
36 return maxValue;
37 }
38
39 return value;
40 };
41 }
42 default -> throw new IllegalArgumentException(String.format("Distribution not supported: %s", distribution));
43 };
44 }
45
46 public static Supplier<Float> distributionFloatValueSupplier(final RandomGenerator randomGenerator,
47 final float minValue, final float maxValue, final Distribution distribution) {
48 Objects.requireNonNull(randomGenerator);
49 Objects.requireNonNull(distribution);
50 Validate.isTrue(minValue <= maxValue);
51
52 return switch (distribution) {
53 case UniformDistribution ud -> {
54 final float valueRange = maxValue - minValue;
55
56 yield () -> minValue + randomGenerator.nextFloat() * valueRange;
57 }
58 case NormalDistribution normalDistribution -> {
59 final double mean = normalDistribution.mean();
60 final double standardDeviation = normalDistribution.standardDeviation();
61
62 yield () -> {
63 final float value = (float) (mean + randomGenerator.nextGaussian() * standardDeviation);
64
65 if (value < minValue) {
66 return minValue;
67 } else if (value > maxValue) {
68 return maxValue;
69 }
70
71 return value;
72 };
73 }
74 default -> throw new IllegalArgumentException(String.format("Distribution not supported: %s", distribution));
75 };
76 }
77 }