private static StochasticSupplier<Double> normalVar(Optional<Double> min, Optional<Double> max, Optional<Double> mean, Optional<Double> std, Optional<Boolean> redraw) { checkArgument(min.isPresent(), "Min should be set."); checkArgument(max.isPresent(), "Max should be set."); checkArgument(mean.isPresent(), "Mean should be set."); checkArgument(std.isPresent(), "Std should be set."); checkArgument(redraw.isPresent(), "Redraw should be set."); final StochasticSuppliers.Builder builder = StochasticSuppliers.normal() .mean(mean.get()) .std(std.get()) .lowerBound(min.get()) .upperBound(max.get()); if (redraw.get()) { builder.redrawWhenOutOfBounds(); } else { builder.roundWhenOutOfBounds(); } return builder.buildDouble(); } }
/** * Creates a {@link TimeSeriesGenerator} that uses a truncated normal * distribution for the inter arrival times of events. The normal distribution * is truncated at a lower bound of <code>0</code> since it is not allowed (it * makes no sense) to have negative inter arrival times. For more information * about the normal distribution see {@link StochasticSuppliers#normal()}. * @param length The length of the time series, all generated times will be in * the interval [0,length). * @param numEvents The total number of events in the time series (on * average). * @param sd The standard deviation of the normal distribution. * @return A {@link TimeSeriesGenerator} based on a normal distribution. */ public static TimeSeriesGenerator normal(double length, int numEvents, double sd) { checkArgument(length > 0d); checkArgument(numEvents > 0); final double average = length / numEvents; return toTimeSeries(length, StochasticSuppliers.normal() .mean(average) .std(sd) .lowerBound(0d) .redrawWhenOutOfBounds() .scaleMean() .buildDouble()); }
/** * Tests whether the rescaling of the mean of a truncated normal distribution * is implemented correctly. */ @Test public void testNormalScaleMean() { final double[] means = new double[] {1d, 2d, 3d, 10d, 100d}; final double[] sds = new double[] {1d, 1d, 3d, 5d, 100d}; for (int i = 0; i < means.length; i++) { final StochasticSupplier<Double> ss = StochasticSuppliers.normal() .mean(means[i]) .std(sds[i]) .lowerBound(0) .scaleMean() .redrawWhenOutOfBounds() .buildDouble(); final RandomGenerator rng = new MersenneTwister(123); final SummaryStatistics stats = new SummaryStatistics(); for (int j = 0; j < 10000; j++) { stats.addValue(ss.get(rng.nextLong())); } // 1 % deviation from mean is acceptable final double allowedDeviation = 0.01 * means[i]; assertEquals(means[i], stats.getMean(), allowedDeviation); } } }