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 18 package org.apache.commons.math3.distribution; 19 20 import org.apache.commons.math3.exception.NumberIsTooLargeException; 21 import org.apache.commons.math3.exception.OutOfRangeException; 22 import org.apache.commons.math3.exception.util.LocalizedFormats; 23 import org.apache.commons.math3.random.RandomGenerator; 24 import org.apache.commons.math3.random.Well19937c; 25 26 /** 27 * Implementation of the uniform real distribution. 28 * 29 * @see <a href="http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)" 30 * >Uniform distribution (continuous), at Wikipedia</a> 31 * 32 * @since 3.0 33 */ 34 public class UniformRealDistribution extends AbstractRealDistribution { 35 /** Default inverse cumulative probability accuracy. 36 * @deprecated as of 3.2 not used anymore, will be removed in 4.0 37 */ 38 @Deprecated 39 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; 40 /** Serializable version identifier. */ 41 private static final long serialVersionUID = 20120109L; 42 /** Lower bound of this distribution (inclusive). */ 43 private final double lower; 44 /** Upper bound of this distribution (exclusive). */ 45 private final double upper; 46 47 /** 48 * Create a standard uniform real distribution with lower bound (inclusive) 49 * equal to zero and upper bound (exclusive) equal to one. 50 * <p> 51 * <b>Note:</b> this constructor will implicitly create an instance of 52 * {@link Well19937c} as random generator to be used for sampling only (see 53 * {@link #sample()} and {@link #sample(int)}). In case no sampling is 54 * needed for the created distribution, it is advised to pass {@code null} 55 * as random generator via the appropriate constructors to avoid the 56 * additional initialisation overhead. 57 */ 58 public UniformRealDistribution() { 59 this(0, 1); 60 } 61 62 /** 63 * Create a uniform real distribution using the given lower and upper 64 * bounds. 65 * <p> 66 * <b>Note:</b> this constructor will implicitly create an instance of 67 * {@link Well19937c} as random generator to be used for sampling only (see 68 * {@link #sample()} and {@link #sample(int)}). In case no sampling is 69 * needed for the created distribution, it is advised to pass {@code null} 70 * as random generator via the appropriate constructors to avoid the 71 * additional initialisation overhead. 72 * 73 * @param lower Lower bound of this distribution (inclusive). 74 * @param upper Upper bound of this distribution (exclusive). 75 * @throws NumberIsTooLargeException if {@code lower >= upper}. 76 */ 77 public UniformRealDistribution(double lower, double upper) 78 throws NumberIsTooLargeException { 79 this(new Well19937c(), lower, upper); 80 } 81 82 /** 83 * Create a uniform distribution. 84 * 85 * @param lower Lower bound of this distribution (inclusive). 86 * @param upper Upper bound of this distribution (exclusive). 87 * @param inverseCumAccuracy Inverse cumulative probability accuracy. 88 * @throws NumberIsTooLargeException if {@code lower >= upper}. 89 * @deprecated as of 3.2, inverse CDF is now calculated analytically, use 90 * {@link #UniformRealDistribution(double, double)} instead. 91 */ 92 @Deprecated 93 public UniformRealDistribution(double lower, double upper, double inverseCumAccuracy) 94 throws NumberIsTooLargeException { 95 this(new Well19937c(), lower, upper); 96 } 97 98 /** 99 * Creates a uniform distribution. 100 * 101 * @param rng Random number generator. 102 * @param lower Lower bound of this distribution (inclusive). 103 * @param upper Upper bound of this distribution (exclusive). 104 * @param inverseCumAccuracy Inverse cumulative probability accuracy. 105 * @throws NumberIsTooLargeException if {@code lower >= upper}. 106 * @since 3.1 107 * @deprecated as of 3.2, inverse CDF is now calculated analytically, use 108 * {@link #UniformRealDistribution(RandomGenerator, double, double)} 109 * instead. 110 */ 111 @Deprecated 112 public UniformRealDistribution(RandomGenerator rng, 113 double lower, 114 double upper, 115 double inverseCumAccuracy){ 116 this(rng, lower, upper); 117 } 118 119 /** 120 * Creates a uniform distribution. 121 * 122 * @param rng Random number generator. 123 * @param lower Lower bound of this distribution (inclusive). 124 * @param upper Upper bound of this distribution (exclusive). 125 * @throws NumberIsTooLargeException if {@code lower >= upper}. 126 * @since 3.1 127 */ 128 public UniformRealDistribution(RandomGenerator rng, 129 double lower, 130 double upper) 131 throws NumberIsTooLargeException { 132 super(rng); 133 if (lower >= upper) { 134 throw new NumberIsTooLargeException( 135 LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, 136 lower, upper, false); 137 } 138 139 this.lower = lower; 140 this.upper = upper; 141 } 142 143 /** {@inheritDoc} */ 144 public double density(double x) { 145 if (x < lower || x > upper) { 146 return 0.0; 147 } 148 return 1 / (upper - lower); 149 } 150 151 /** {@inheritDoc} */ 152 public double cumulativeProbability(double x) { 153 if (x <= lower) { 154 return 0; 155 } 156 if (x >= upper) { 157 return 1; 158 } 159 return (x - lower) / (upper - lower); 160 } 161 162 @Override 163 public double inverseCumulativeProbability(final double p) 164 throws OutOfRangeException { 165 if (p < 0.0 || p > 1.0) { 166 throw new OutOfRangeException(p, 0, 1); 167 } 168 return p * (upper - lower) + lower; 169 } 170 171 /** 172 * {@inheritDoc} 173 * 174 * For lower bound {@code lower} and upper bound {@code upper}, the mean is 175 * {@code 0.5 * (lower + upper)}. 176 */ 177 public double getNumericalMean() { 178 return 0.5 * (lower + upper); 179 } 180 181 /** 182 * {@inheritDoc} 183 * 184 * For lower bound {@code lower} and upper bound {@code upper}, the 185 * variance is {@code (upper - lower)^2 / 12}. 186 */ 187 public double getNumericalVariance() { 188 double ul = upper - lower; 189 return ul * ul / 12; 190 } 191 192 /** 193 * {@inheritDoc} 194 * 195 * The lower bound of the support is equal to the lower bound parameter 196 * of the distribution. 197 * 198 * @return lower bound of the support 199 */ 200 public double getSupportLowerBound() { 201 return lower; 202 } 203 204 /** 205 * {@inheritDoc} 206 * 207 * The upper bound of the support is equal to the upper bound parameter 208 * of the distribution. 209 * 210 * @return upper bound of the support 211 */ 212 public double getSupportUpperBound() { 213 return upper; 214 } 215 216 /** {@inheritDoc} */ 217 public boolean isSupportLowerBoundInclusive() { 218 return true; 219 } 220 221 /** {@inheritDoc} */ 222 public boolean isSupportUpperBoundInclusive() { 223 return true; 224 } 225 226 /** 227 * {@inheritDoc} 228 * 229 * The support of this distribution is connected. 230 * 231 * @return {@code true} 232 */ 233 public boolean isSupportConnected() { 234 return true; 235 } 236 237 /** {@inheritDoc} */ 238 @Override 239 public double sample() { 240 final double u = random.nextDouble(); 241 return u * upper + (1 - u) * lower; 242 } 243 }