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 */ 17dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 18dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpackage org.apache.commons.math.distribution; 19dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 20dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport java.io.Serializable; 21dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 22dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.MathRuntimeException; 23dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.exception.util.LocalizedFormats; 24dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.util.MathUtils; 25dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondimport org.apache.commons.math.util.FastMath; 26dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 27dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond/** 28dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * The default implementation of {@link HypergeometricDistribution}. 29dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 30dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @version $Revision: 1054524 $ $Date: 2011-01-03 05:59:18 +0100 (lun. 03 janv. 2011) $ 31dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 32dee0849a9704d532af0b550146cbafbaa6ee1d19Raymondpublic class HypergeometricDistributionImpl extends AbstractIntegerDistribution 33dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond implements HypergeometricDistribution, Serializable { 34dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 35dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** Serializable version identifier */ 36dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private static final long serialVersionUID = -436928820673516179L; 37dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 38dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** The number of successes in the population. */ 39dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int numberOfSuccesses; 40dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 41dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** The population size. */ 42dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int populationSize; 43dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 44dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** The sample size. */ 45dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int sampleSize; 46dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 47dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 48dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Construct a new hypergeometric distribution with the given the population 49dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * size, the number of successes in the population, and the sample size. 50dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 51dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param populationSize the population size. 52dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param numberOfSuccesses number of successes in the population. 53dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param sampleSize the sample size. 54dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 55dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public HypergeometricDistributionImpl(int populationSize, 56dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int numberOfSuccesses, int sampleSize) { 57dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond super(); 58dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (numberOfSuccesses > populationSize) { 59dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException 60dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond .createIllegalArgumentException( 61dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NUMBER_OF_SUCCESS_LARGER_THAN_POPULATION_SIZE, 62dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numberOfSuccesses, populationSize); 63dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 64dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (sampleSize > populationSize) { 65dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException 66dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond .createIllegalArgumentException( 67dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.SAMPLE_SIZE_LARGER_THAN_POPULATION_SIZE, 68dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sampleSize, populationSize); 69dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 70dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 71dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setPopulationSizeInternal(populationSize); 72dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setSampleSizeInternal(sampleSize); 73dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setNumberOfSuccessesInternal(numberOfSuccesses); 74dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 75dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 76dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 77dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For this distribution, X, this method returns P(X ≤ x). 78dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 79dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the PDF is evaluated. 80dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return PDF for this distribution. 81dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 82dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 83dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double cumulativeProbability(int x) { 84dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ret; 85dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 86dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); 87dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < domain[0]) { 88dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = 0.0; 89dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (x >= domain[1]) { 90dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = 1.0; 91dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 92dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = innerCumulativeProbability(domain[0], x, 1, populationSize, 93dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numberOfSuccesses, sampleSize); 94dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 95dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 96dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ret; 97dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 98dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 99dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 100dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Return the domain for the given hypergeometric distribution parameters. 101dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 102dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n the population size. 103dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param m number of successes in the population. 104dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param k the sample size. 105dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return a two element array containing the lower and upper bounds of the 106dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * hypergeometric distribution. 107dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 108dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int[] getDomain(int n, int m, int k) { 109dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return new int[] { getLowerDomain(n, m, k), getUpperDomain(m, k) }; 110dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 111dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 112dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 113dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the domain value lower bound, based on <code>p</code>, used to 114dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bracket a PDF root. 115dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 116dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p the desired probability for the critical value 117dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return domain value lower bound, i.e. P(X < <i>lower bound</i>) < 118dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>p</code> 119dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 120dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 121dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int getDomainLowerBound(double p) { 122dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getLowerDomain(populationSize, numberOfSuccesses, sampleSize); 123dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 124dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 125dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 126dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the domain value upper bound, based on <code>p</code>, used to 127dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * bracket a PDF root. 128dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 129dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param p the desired probability for the critical value 130dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return domain value upper bound, i.e. P(X < <i>upper bound</i>) > 131dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>p</code> 132dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 133dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Override 134dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected int getDomainUpperBound(double p) { 135dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return getUpperDomain(sampleSize, numberOfSuccesses); 136dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 137dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 138dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 139dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Return the lowest domain value for the given hypergeometric distribution 140dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameters. 141dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 142dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n the population size. 143dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param m number of successes in the population. 144dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param k the sample size. 145dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the lowest domain value of the hypergeometric distribution. 146dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 147dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int getLowerDomain(int n, int m, int k) { 148dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.max(0, m - (n - k)); 149dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 150dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 151dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 152dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the number of successes. 153dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 154dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the number of successes. 155dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 156dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getNumberOfSuccesses() { 157dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return numberOfSuccesses; 158dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 159dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 160dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 161dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the population size. 162dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 163dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the population size. 164dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 165dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getPopulationSize() { 166dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return populationSize; 167dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 168dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 169dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 170dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Access the sample size. 171dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 172dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the sample size. 173dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 174dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getSampleSize() { 175dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return sampleSize; 176dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 177dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 178dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 179dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Return the highest domain value for the given hypergeometric distribution 180dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameters. 181dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 182dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param m number of successes in the population. 183dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param k the sample size. 184dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the highest domain value of the hypergeometric distribution. 185dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 186dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private int getUpperDomain(int m, int k) { 187dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.min(k, m); 188dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 189dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 190dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 191dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For this distribution, X, this method returns P(X = x). 192dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 193dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the PMF is evaluated. 194dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return PMF for this distribution. 195dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 196dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double probability(int x) { 197dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ret; 198dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 199dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); 200dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < domain[0] || x > domain[1]) { 201dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = 0.0; 202dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 203dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p = (double) sampleSize / (double) populationSize; 204dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double q = (double) (populationSize - sampleSize) / (double) populationSize; 205dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p1 = SaddlePointExpansion.logBinomialProbability(x, 206dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numberOfSuccesses, p, q); 207dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p2 = 208dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SaddlePointExpansion.logBinomialProbability(sampleSize - x, 209dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond populationSize - numberOfSuccesses, p, q); 210dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double p3 = 211dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond SaddlePointExpansion.logBinomialProbability(sampleSize, populationSize, p, q); 212dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = FastMath.exp(p1 + p2 - p3); 213dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 214dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 215dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ret; 216dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 217dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 218dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 219dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For the distribution, X, defined by the given hypergeometric distribution 220dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * parameters, this method returns P(X = x). 221dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 222dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n the population size. 223dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param m number of successes in the population. 224dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param k the sample size. 225dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the PMF is evaluated. 226dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return PMF for the distribution. 227dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 228dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double probability(int n, int m, int k, int x) { 229dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.exp(MathUtils.binomialCoefficientLog(m, x) + 230dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond MathUtils.binomialCoefficientLog(n - m, k - x) - 231dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond MathUtils.binomialCoefficientLog(n, k)); 232dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 233dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 234dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 235dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the number of successes. 236dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 237dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param num the new number of successes. 238dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>num</code> is negative. 239dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @deprecated as of 2.1 (class will become immutable in 3.0) 240dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 241dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Deprecated 242dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setNumberOfSuccesses(int num) { 243dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setNumberOfSuccessesInternal(num); 244dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 245dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 246dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 247dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the number of successes. 248dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 249dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param num the new number of successes. 250dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>num</code> is negative. 251dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 252dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private void setNumberOfSuccessesInternal(int num) { 253dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (num < 0) { 254dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 255dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NEGATIVE_NUMBER_OF_SUCCESSES, num); 256dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 257dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond numberOfSuccesses = num; 258dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 259dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 260dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 261dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the population size. 262dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 263dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param size the new population size. 264dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>size</code> is not positive. 265dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @deprecated as of 2.1 (class will become immutable in 3.0) 266dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 267dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Deprecated 268dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setPopulationSize(int size) { 269dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setPopulationSizeInternal(size); 270dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 271dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 272dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 273dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the population size. 274dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 275dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param size the new population size. 276dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>size</code> is not positive. 277dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 278dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private void setPopulationSizeInternal(int size) { 279dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (size <= 0) { 280dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 281dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NOT_POSITIVE_POPULATION_SIZE, size); 282dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 283dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond populationSize = size; 284dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 285dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 286dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 287dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the sample size. 288dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 289dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param size the new sample size. 290dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>size</code> is negative. 291dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @deprecated as of 2.1 (class will become immutable in 3.0) 292dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 293dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond @Deprecated 294dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public void setSampleSize(int size) { 295dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond setSampleSizeInternal(size); 296dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 297dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 298dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Modify the sample size. 299dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 300dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param size the new sample size. 301dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @throws IllegalArgumentException if <code>size</code> is negative. 302dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 303dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private void setSampleSizeInternal(int size) { 304dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (size < 0) { 305dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond throw MathRuntimeException.createIllegalArgumentException( 306dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond LocalizedFormats.NOT_POSITIVE_SAMPLE_SIZE, size); 307dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 308dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond sampleSize = size; 309dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 310dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 311dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 312dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For this distribution, X, this method returns P(X ≥ x). 313dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 314dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x the value at which the CDF is evaluated. 315dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return upper tail CDF for this distribution. 316dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 1.1 317dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 318dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double upperCumulativeProbability(int x) { 319dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ret; 320dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 321dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize); 322dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond if (x < domain[0]) { 323dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = 1.0; 324dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else if (x > domain[1]) { 325dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = 0.0; 326dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } else { 327dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret = innerCumulativeProbability(domain[1], x, -1, populationSize, numberOfSuccesses, sampleSize); 328dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 329dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 330dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ret; 331dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 332dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 333dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 334dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For this distribution, X, this method returns P(x0 ≤ X ≤ x1). This 335dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * probability is computed by summing the point probabilities for the values 336dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * x0, x0 + 1, x0 + 2, ..., x1, in the order directed by dx. 337dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 338dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x0 the inclusive, lower bound 339dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param x1 the inclusive, upper bound 340dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param dx the direction of summation. 1 indicates summing from x0 to x1. 341dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 0 indicates summing from x1 to x0. 342dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param n the population size. 343dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param m number of successes in the population. 344dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @param k the sample size. 345dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return P(x0 ≤ X ≤ x1). 346dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 347dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond private double innerCumulativeProbability(int x0, int x1, int dx, int n, 348dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond int m, int k) { 349dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond double ret = probability(n, m, k, x0); 350dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond while (x0 != x1) { 351dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond x0 += dx; 352dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond ret += probability(n, m, k, x0); 353dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 354dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ret; 355dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 356dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 357dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 358dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the lower bound for the support for the distribution. 359dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 360dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For population size <code>N</code>, 361dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * number of successes <code>m</code>, and 362dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sample size <code>n</code>, 363dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the lower bound of the support is 364dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>max(0, n + m - N)</code> 365dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 366dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return lower bound of the support 367dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 368dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 369dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getSupportLowerBound() { 370dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.max(0, 371dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond getSampleSize() + getNumberOfSuccesses() - getPopulationSize()); 372dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 373dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 374dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 375dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the upper bound for the support of the distribution. 376dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 377dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For number of successes <code>m</code> and 378dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sample size <code>n</code>, 379dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * the upper bound of the support is 380dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>min(m, n)</code> 381dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 382dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return upper bound of the support 383dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 384dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 385dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public int getSupportUpperBound() { 386dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return FastMath.min(getNumberOfSuccesses(), getSampleSize()); 387dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 388dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 389dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 390dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the mean. 391dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 392dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For population size <code>N</code>, 393dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * number of successes <code>m</code>, and 394dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sample size <code>n</code>, the mean is 395dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>n * m / N</code> 396dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 397dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the mean 398dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 399dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 400dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond protected double getNumericalMean() { 401dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return (double)(getSampleSize() * getNumberOfSuccesses()) / (double)getPopulationSize(); 402dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 403dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond 404dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond /** 405dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * Returns the variance. 406dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 407dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * For population size <code>N</code>, 408dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * number of successes <code>m</code>, and 409dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * sample size <code>n</code>, the variance is 410dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * <code>[ n * m * (N - n) * (N - m) ] / [ N^2 * (N - 1) ]</code> 411dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * 412dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @return the variance 413dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond * @since 2.2 414dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond */ 415dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond public double getNumericalVariance() { 416dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double N = getPopulationSize(); 417dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double m = getNumberOfSuccesses(); 418dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond final double n = getSampleSize(); 419dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond return ( n * m * (N - n) * (N - m) ) / ( (N*N * (N - 1)) ); 420dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond } 421dee0849a9704d532af0b550146cbafbaa6ee1d19Raymond} 422