1dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/* 2dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Licensed to the Apache Software Foundation (ASF) under one or more 3dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * contributor license agreements. See the NOTICE file distributed with 4dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this work for additional information regarding copyright ownership. 5dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The ASF licenses this file to You under the Apache License, Version 2.0 6dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * (the "License"); you may not use this file except in compliance with 7dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the License. You may obtain a copy of the License at 8dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 9dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * http://www.apache.org/licenses/LICENSE-2.0 10dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 11dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Unless required by applicable law or agreed to in writing, software 12dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distributed under the License is distributed on an "AS IS" BASIS, 13dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * See the License for the specific language governing permissions and 15dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * limitations under the License. 16dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.distribution; 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable; 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathException; 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.random.RandomDataImpl; 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.util.FastMath; 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Base class for integer-valued discrete distributions. Default 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * implementations are provided for some of the methods that do not vary 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * from distribution to distribution. 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1067494 $ $Date: 2011-02-05 20:49:07 +0100 (sam. 05 févr. 2011) $ 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic abstract class AbstractIntegerDistribution extends AbstractDistribution 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond implements IntegerDistribution, Serializable { 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Serializable version identifier */ 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long serialVersionUID = -1146319659338487221L; 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * RandomData instance used to generate samples from the distribution 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected final RandomDataImpl randomData = new RandomDataImpl(); 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Default constructor. 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected AbstractIntegerDistribution() { 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond super(); 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns P(X ≤ x). In other words, 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this method represents the (cumulative) distribution function, or 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * CDF, for this distribution. 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If <code>x</code> does not represent an integer value, the CDF is 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * evaluated at the greatest integer less than x. 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the distribution function is evaluated. 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cumulative probability that a random variable with this 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * distribution takes a value less than or equal to <code>x</code> 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the cumulative probability can not be 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computed due to convergence or other numerical errors. 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double cumulativeProbability(double x) throws MathException { 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cumulativeProbability((int) FastMath.floor(x)); 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns P(x0 ≤ X ≤ x1). 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x0 the (inclusive) lower bound 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x1 the (inclusive) upper bound 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the probability that a random variable with this distribution 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * will take a value between <code>x0</code> and <code>x1</code>, 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * including the endpoints. 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the cumulative probability can not be 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computed due to convergence or other numerical errors. 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>x0 > x1</code> 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double cumulativeProbability(double x0, double x1) 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throws MathException { 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x0 > x1) { 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1); 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (FastMath.floor(x0) < x0) { 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cumulativeProbability(((int) FastMath.floor(x0)) + 1, 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (int) FastMath.floor(x1)); // don't want to count mass below x0 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { // x0 is mathematical integer, so use as is 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cumulativeProbability((int) FastMath.floor(x0), 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond (int) FastMath.floor(x1)); 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns P(X ≤ x). In other words, 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * this method represents the probability distribution function, or PDF, 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * for this distribution. 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the PDF is evaluated. 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return PDF for this distribution. 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the cumulative probability can not be 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computed due to convergence or other numerical errors. 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public abstract double cumulativeProbability(int x) throws MathException; 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns P(X = x). In other words, this 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * method represents the probability mass function, or PMF, for the distribution. 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <p> 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * If <code>x</code> does not represent an integer value, 0 is returned. 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the probability density function is evaluated 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the value of the probability density function at x 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double probability(double x) { 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double fl = FastMath.floor(x); 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (fl == x) { 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return this.probability((int) x); 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return 0; 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns P(x0 ≤ X ≤ x1). 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x0 the inclusive, lower bound 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x1 the inclusive, upper bound 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the cumulative probability. 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the cumulative probability can not be 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computed due to convergence or other numerical errors. 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if x0 > x1 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double cumulativeProbability(int x0, int x1) throws MathException { 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x0 > x1) { 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.LOWER_ENDPOINT_ABOVE_UPPER_ENDPOINT, x0, x1); 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return cumulativeProbability(x1) - cumulativeProbability(x0 - 1); 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For a random variable X whose values are distributed according 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * to this distribution, this method returns the largest x, such 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * that P(X ≤ x) ≤ <code>p</code>. 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p the desired probability 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the largest x such that P(X ≤ x) <= p 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the inverse cumulative probability can not be 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * computed due to convergence or other numerical errors. 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if p < 0 or p > 1 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int inverseCumulativeProbability(final double p) throws MathException{ 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (p < 0.0 || p > 1.0) { 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.OUT_OF_RANGE_SIMPLE, p, 0.0, 1.0); 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // by default, do simple bisection. 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // subclasses can override if there is a better method. 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int x0 = getDomainLowerBound(p); 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int x1 = getDomainUpperBound(p); 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double pm; 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (x0 < x1) { 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int xm = x0 + (x1 - x0) / 2; 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pm = checkedCumulativeProbability(xm); 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (pm > p) { 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // update x1 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xm == x1) { 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // this can happen with integer division 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // simply decrement x1 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond --x1; 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // update x1 normally 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x1 = xm; 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // update x0 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (xm == x0) { 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // this can happen with integer division 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // simply increment x0 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ++x0; 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // update x0 normally 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x0 = xm; 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond // insure x0 is the correct critical point 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pm = checkedCumulativeProbability(x0); 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (pm > p) { 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond --x0; 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond pm = checkedCumulativeProbability(x0); 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return x0; 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Reseeds the random generator used to generate samples. 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param seed the new seed 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void reseedRandomGenerator(long seed) { 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond randomData.reSeed(seed); 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Generates a random value sampled from this distribution. The default 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * implementation uses the 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <a href="http://en.wikipedia.org/wiki/Inverse_transform_sampling"> inversion method.</a> 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return random value 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if an error occurs generating the random value 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int sample() throws MathException { 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return randomData.nextInversionDeviate(this); 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Generates a random sample from the distribution. The default implementation 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * generates the sample by calling {@link #sample()} in a loop. 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param sampleSize number of random values to generate 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return an array representing the random sample 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if an error occurs generating the sample 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if sampleSize is not positive 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int[] sample(int sampleSize) throws MathException { 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (sampleSize <= 0) { 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond MathRuntimeException.createIllegalArgumentException(LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, sampleSize); 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int[] out = new int[sampleSize]; 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond for (int i = 0; i < sampleSize; i++) { 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond out[i] = sample(); 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return out; 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Computes the cumulative probability function and checks for NaN values returned. 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Throws MathException if the value is NaN. Rethrows any MathException encountered 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * evaluating the cumulative probability function. Throws 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * MathException if the cumulative probability function returns NaN. 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param argument input value 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return cumulative probability 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws MathException if the cumulative probability is NaN 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double checkedCumulativeProbability(int argument) throws MathException { 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double result = Double.NaN; 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond result = cumulativeProbability(argument); 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (Double.isNaN(result)) { 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw new MathException(LocalizedFormats.DISCRETE_CUMULATIVE_PROBABILITY_RETURNED_NAN, argument); 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return result; 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the domain value lower bound, based on <code>p</code>, used to 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bracket a PDF root. This method is used by 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link #inverseCumulativeProbability(double)} to find critical values. 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p the desired probability for the critical value 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return domain value lower bound, i.e. 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * P(X < <i>lower bound</i>) < <code>p</code> 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected abstract int getDomainLowerBound(double p); 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the domain value upper bound, based on <code>p</code>, used to 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bracket a PDF root. This method is used by 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * {@link #inverseCumulativeProbability(double)} to find critical values. 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p the desired probability for the critical value 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return domain value upper bound, i.e. 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * P(X < <i>upper bound</i>) > <code>p</code> 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected abstract int getDomainUpperBound(double p); 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use this method to get information about whether the lower bound 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the support is inclusive or not. For discrete support, 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * only true here is meaningful. 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true (always but at Integer.MIN_VALUE because of the nature of discrete support) 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public boolean isSupportLowerBoundInclusive() { 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Use this method to get information about whether the upper bound 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * of the support is inclusive or not. For discrete support, 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * only true here is meaningful. 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return true (always but at Integer.MAX_VALUE because of the nature of discrete support) 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public boolean isSupportUpperBoundInclusive() { 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return true; 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 320