UniformRealDistribution.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.math3.distribution;

  18. import org.apache.commons.math3.exception.NumberIsTooLargeException;
  19. import org.apache.commons.math3.exception.OutOfRangeException;
  20. import org.apache.commons.math3.exception.util.LocalizedFormats;
  21. import org.apache.commons.math3.random.RandomGenerator;
  22. import org.apache.commons.math3.random.Well19937c;

  23. /**
  24.  * Implementation of the uniform real distribution.
  25.  *
  26.  * @see <a href="http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)"
  27.  * >Uniform distribution (continuous), at Wikipedia</a>
  28.  *
  29.  * @since 3.0
  30.  */
  31. public class UniformRealDistribution extends AbstractRealDistribution {
  32.     /** Default inverse cumulative probability accuracy.
  33.      * @deprecated as of 3.2 not used anymore, will be removed in 4.0
  34.      */
  35.     @Deprecated
  36.     public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9;
  37.     /** Serializable version identifier. */
  38.     private static final long serialVersionUID = 20120109L;
  39.     /** Lower bound of this distribution (inclusive). */
  40.     private final double lower;
  41.     /** Upper bound of this distribution (exclusive). */
  42.     private final double upper;

  43.     /**
  44.      * Create a standard uniform real distribution with lower bound (inclusive)
  45.      * equal to zero and upper bound (exclusive) equal to one.
  46.      * <p>
  47.      * <b>Note:</b> this constructor will implicitly create an instance of
  48.      * {@link Well19937c} as random generator to be used for sampling only (see
  49.      * {@link #sample()} and {@link #sample(int)}). In case no sampling is
  50.      * needed for the created distribution, it is advised to pass {@code null}
  51.      * as random generator via the appropriate constructors to avoid the
  52.      * additional initialisation overhead.
  53.      */
  54.     public UniformRealDistribution() {
  55.         this(0, 1);
  56.     }

  57.     /**
  58.      * Create a uniform real distribution using the given lower and upper
  59.      * bounds.
  60.      * <p>
  61.      * <b>Note:</b> this constructor will implicitly create an instance of
  62.      * {@link Well19937c} as random generator to be used for sampling only (see
  63.      * {@link #sample()} and {@link #sample(int)}). In case no sampling is
  64.      * needed for the created distribution, it is advised to pass {@code null}
  65.      * as random generator via the appropriate constructors to avoid the
  66.      * additional initialisation overhead.
  67.      *
  68.      * @param lower Lower bound of this distribution (inclusive).
  69.      * @param upper Upper bound of this distribution (exclusive).
  70.      * @throws NumberIsTooLargeException if {@code lower >= upper}.
  71.      */
  72.     public UniformRealDistribution(double lower, double upper)
  73.         throws NumberIsTooLargeException {
  74.         this(new Well19937c(), lower, upper);
  75.     }

  76.     /**
  77.      * Create a uniform distribution.
  78.      *
  79.      * @param lower Lower bound of this distribution (inclusive).
  80.      * @param upper Upper bound of this distribution (exclusive).
  81.      * @param inverseCumAccuracy Inverse cumulative probability accuracy.
  82.      * @throws NumberIsTooLargeException if {@code lower >= upper}.
  83.      * @deprecated as of 3.2, inverse CDF is now calculated analytically, use
  84.      *             {@link #UniformRealDistribution(double, double)} instead.
  85.      */
  86.     @Deprecated
  87.     public UniformRealDistribution(double lower, double upper, double inverseCumAccuracy)
  88.         throws NumberIsTooLargeException {
  89.         this(new Well19937c(), lower, upper);
  90.     }

  91.     /**
  92.      * Creates a uniform distribution.
  93.      *
  94.      * @param rng Random number generator.
  95.      * @param lower Lower bound of this distribution (inclusive).
  96.      * @param upper Upper bound of this distribution (exclusive).
  97.      * @param inverseCumAccuracy Inverse cumulative probability accuracy.
  98.      * @throws NumberIsTooLargeException if {@code lower >= upper}.
  99.      * @since 3.1
  100.      * @deprecated as of 3.2, inverse CDF is now calculated analytically, use
  101.      *             {@link #UniformRealDistribution(RandomGenerator, double, double)}
  102.      *             instead.
  103.      */
  104.     @Deprecated
  105.     public UniformRealDistribution(RandomGenerator rng,
  106.                                    double lower,
  107.                                    double upper,
  108.                                    double inverseCumAccuracy){
  109.         this(rng, lower, upper);
  110.     }

  111.     /**
  112.      * Creates a uniform distribution.
  113.      *
  114.      * @param rng Random number generator.
  115.      * @param lower Lower bound of this distribution (inclusive).
  116.      * @param upper Upper bound of this distribution (exclusive).
  117.      * @throws NumberIsTooLargeException if {@code lower >= upper}.
  118.      * @since 3.1
  119.      */
  120.     public UniformRealDistribution(RandomGenerator rng,
  121.                                    double lower,
  122.                                    double upper)
  123.         throws NumberIsTooLargeException {
  124.         super(rng);
  125.         if (lower >= upper) {
  126.             throw new NumberIsTooLargeException(
  127.                             LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
  128.                             lower, upper, false);
  129.         }

  130.         this.lower = lower;
  131.         this.upper = upper;
  132.     }

  133.     /** {@inheritDoc} */
  134.     public double density(double x) {
  135.         if (x < lower || x > upper) {
  136.             return 0.0;
  137.         }
  138.         return 1 / (upper - lower);
  139.     }

  140.     /** {@inheritDoc} */
  141.     public double cumulativeProbability(double x)  {
  142.         if (x <= lower) {
  143.             return 0;
  144.         }
  145.         if (x >= upper) {
  146.             return 1;
  147.         }
  148.         return (x - lower) / (upper - lower);
  149.     }

  150.     @Override
  151.     public double inverseCumulativeProbability(final double p)
  152.             throws OutOfRangeException {
  153.         if (p < 0.0 || p > 1.0) {
  154.             throw new OutOfRangeException(p, 0, 1);
  155.         }
  156.         return p * (upper - lower) + lower;
  157.     }

  158.     /**
  159.      * {@inheritDoc}
  160.      *
  161.      * For lower bound {@code lower} and upper bound {@code upper}, the mean is
  162.      * {@code 0.5 * (lower + upper)}.
  163.      */
  164.     public double getNumericalMean() {
  165.         return 0.5 * (lower + upper);
  166.     }

  167.     /**
  168.      * {@inheritDoc}
  169.      *
  170.      * For lower bound {@code lower} and upper bound {@code upper}, the
  171.      * variance is {@code (upper - lower)^2 / 12}.
  172.      */
  173.     public double getNumericalVariance() {
  174.         double ul = upper - lower;
  175.         return ul * ul / 12;
  176.     }

  177.     /**
  178.      * {@inheritDoc}
  179.      *
  180.      * The lower bound of the support is equal to the lower bound parameter
  181.      * of the distribution.
  182.      *
  183.      * @return lower bound of the support
  184.      */
  185.     public double getSupportLowerBound() {
  186.         return lower;
  187.     }

  188.     /**
  189.      * {@inheritDoc}
  190.      *
  191.      * The upper bound of the support is equal to the upper bound parameter
  192.      * of the distribution.
  193.      *
  194.      * @return upper bound of the support
  195.      */
  196.     public double getSupportUpperBound() {
  197.         return upper;
  198.     }

  199.     /** {@inheritDoc} */
  200.     public boolean isSupportLowerBoundInclusive() {
  201.         return true;
  202.     }

  203.     /** {@inheritDoc} */
  204.     public boolean isSupportUpperBoundInclusive() {
  205.         return true;
  206.     }

  207.     /**
  208.      * {@inheritDoc}
  209.      *
  210.      * The support of this distribution is connected.
  211.      *
  212.      * @return {@code true}
  213.      */
  214.     public boolean isSupportConnected() {
  215.         return true;
  216.     }

  217.     /** {@inheritDoc} */
  218.     @Override
  219.     public double sample()  {
  220.         final double u = random.nextDouble();
  221.         return u * upper + (1 - u) * lower;
  222.     }
  223. }