001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.math3.distribution; 019 020import org.apache.commons.math3.exception.NumberIsTooLargeException; 021import org.apache.commons.math3.exception.OutOfRangeException; 022import org.apache.commons.math3.exception.util.LocalizedFormats; 023import org.apache.commons.math3.random.RandomGenerator; 024import org.apache.commons.math3.random.Well19937c; 025 026/** 027 * Implementation of the uniform real distribution. 028 * 029 * @see <a href="http://en.wikipedia.org/wiki/Uniform_distribution_(continuous)" 030 * >Uniform distribution (continuous), at Wikipedia</a> 031 * 032 * @since 3.0 033 */ 034public class UniformRealDistribution extends AbstractRealDistribution { 035 /** Default inverse cumulative probability accuracy. 036 * @deprecated as of 3.2 not used anymore, will be removed in 4.0 037 */ 038 @Deprecated 039 public static final double DEFAULT_INVERSE_ABSOLUTE_ACCURACY = 1e-9; 040 /** Serializable version identifier. */ 041 private static final long serialVersionUID = 20120109L; 042 /** Lower bound of this distribution (inclusive). */ 043 private final double lower; 044 /** Upper bound of this distribution (exclusive). */ 045 private final double upper; 046 047 /** 048 * Create a standard uniform real distribution with lower bound (inclusive) 049 * equal to zero and upper bound (exclusive) equal to one. 050 * <p> 051 * <b>Note:</b> this constructor will implicitly create an instance of 052 * {@link Well19937c} as random generator to be used for sampling only (see 053 * {@link #sample()} and {@link #sample(int)}). In case no sampling is 054 * needed for the created distribution, it is advised to pass {@code null} 055 * as random generator via the appropriate constructors to avoid the 056 * additional initialisation overhead. 057 */ 058 public UniformRealDistribution() { 059 this(0, 1); 060 } 061 062 /** 063 * Create a uniform real distribution using the given lower and upper 064 * bounds. 065 * <p> 066 * <b>Note:</b> this constructor will implicitly create an instance of 067 * {@link Well19937c} as random generator to be used for sampling only (see 068 * {@link #sample()} and {@link #sample(int)}). In case no sampling is 069 * needed for the created distribution, it is advised to pass {@code null} 070 * as random generator via the appropriate constructors to avoid the 071 * additional initialisation overhead. 072 * 073 * @param lower Lower bound of this distribution (inclusive). 074 * @param upper Upper bound of this distribution (exclusive). 075 * @throws NumberIsTooLargeException if {@code lower >= upper}. 076 */ 077 public UniformRealDistribution(double lower, double upper) 078 throws NumberIsTooLargeException { 079 this(new Well19937c(), lower, upper); 080 } 081 082 /** 083 * Create a uniform distribution. 084 * 085 * @param lower Lower bound of this distribution (inclusive). 086 * @param upper Upper bound of this distribution (exclusive). 087 * @param inverseCumAccuracy Inverse cumulative probability accuracy. 088 * @throws NumberIsTooLargeException if {@code lower >= upper}. 089 * @deprecated as of 3.2, inverse CDF is now calculated analytically, use 090 * {@link #UniformRealDistribution(double, double)} instead. 091 */ 092 @Deprecated 093 public UniformRealDistribution(double lower, double upper, double inverseCumAccuracy) 094 throws NumberIsTooLargeException { 095 this(new Well19937c(), lower, upper); 096 } 097 098 /** 099 * 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 /** {@inheritDoc} */ 163 @Override 164 public double inverseCumulativeProbability(final double p) 165 throws OutOfRangeException { 166 if (p < 0.0 || p > 1.0) { 167 throw new OutOfRangeException(p, 0, 1); 168 } 169 return p * (upper - lower) + lower; 170 } 171 172 /** 173 * {@inheritDoc} 174 * 175 * For lower bound {@code lower} and upper bound {@code upper}, the mean is 176 * {@code 0.5 * (lower + upper)}. 177 */ 178 public double getNumericalMean() { 179 return 0.5 * (lower + upper); 180 } 181 182 /** 183 * {@inheritDoc} 184 * 185 * For lower bound {@code lower} and upper bound {@code upper}, the 186 * variance is {@code (upper - lower)^2 / 12}. 187 */ 188 public double getNumericalVariance() { 189 double ul = upper - lower; 190 return ul * ul / 12; 191 } 192 193 /** 194 * {@inheritDoc} 195 * 196 * The lower bound of the support is equal to the lower bound parameter 197 * of the distribution. 198 * 199 * @return lower bound of the support 200 */ 201 public double getSupportLowerBound() { 202 return lower; 203 } 204 205 /** 206 * {@inheritDoc} 207 * 208 * The upper bound of the support is equal to the upper bound parameter 209 * of the distribution. 210 * 211 * @return upper bound of the support 212 */ 213 public double getSupportUpperBound() { 214 return upper; 215 } 216 217 /** {@inheritDoc} */ 218 public boolean isSupportLowerBoundInclusive() { 219 return true; 220 } 221 222 /** {@inheritDoc} */ 223 public boolean isSupportUpperBoundInclusive() { 224 return true; 225 } 226 227 /** 228 * {@inheritDoc} 229 * 230 * The support of this distribution is connected. 231 * 232 * @return {@code true} 233 */ 234 public boolean isSupportConnected() { 235 return true; 236 } 237 238 /** {@inheritDoc} */ 239 @Override 240 public double sample() { 241 final double u = random.nextDouble(); 242 return u * upper + (1 - u) * lower; 243 } 244}