001package squidpony.squidmath;
002
003/**
004 * An IDistribution that produces results between -1.0 inclusive and 1.0 exclusive, but is much more likely to produce
005 * results near 0.0, and does not "round off" like a Gaussian curve around the midpoint.
006 * <br>
007 * Created by Tommy Ettinger on 11/23/2019.
008 */
009public class SpikeDistribution implements IDistribution {
010    public static final SpikeDistribution instance = new SpikeDistribution();
011    /**
012     * Gets a double between {@link #getLowerBound()} and {@link #getUpperBound()} that obeys this distribution.
013     *
014     * @param rng an IRNG, such as {@link RNG} or {@link GWTRNG}, that this will get one or more random numbers from
015     * @return a double within the range of {@link #getLowerBound()} and {@link #getUpperBound()}
016     */
017    @Override
018    public double nextDouble(IRNG rng) {
019        final double d = (rng.nextDouble() - 0.5) * 2.0;
020        return d * d * d;
021    }
022
023    /**
024     * Gets the lower bound of the distribution, which is -1, inclusive.
025     * @return the lower bound of the distribution
026     */
027    @Override
028    public double getLowerBound() {
029        return -1.0;
030    }
031
032    /**
033     * Gets the upper bound of the distribution, which is 1, exclusive.
034     *
035     * @return the upper bound of the distribution
036     */
037    @Override
038    public double getUpperBound() {
039        return 1.0;
040    }
041
042    /**
043     * A variant on SpikeDistribution that has its range shrunk and moved from {@code [-1,1)} to {@code [0,1)}. It is a
044     * {@link squidpony.squidmath.IDistribution.SimpleDistribution}, and the spike is centered on 0.5.
045     */
046    public static class SimpleSpikeDistribution extends SimpleDistribution implements IDistribution
047    {
048        /**
049         * Gets a double between {@link #getLowerBound()} and {@link #getUpperBound()} that obeys this distribution.
050         *
051         * @param rng an IRNG, such as {@link RNG} or {@link GWTRNG}, that this will get one or more random numbers from
052         * @return a double within the range of {@link #getLowerBound()} and {@link #getUpperBound()}
053         */
054        @Override
055        public double nextDouble(IRNG rng) {
056            final double d = (rng.nextDouble() - 0.5) * 2.0;
057            return d * d * d * 0.5 + 0.5;
058        }
059    }
060}