1 16 17 package org.apache.commons.math.distribution; 18 19 import java.io.Serializable ; 20 21 import org.apache.commons.math.MathException; 22 import org.apache.commons.math.util.MathUtils; 23 24 29 public class HypergeometricDistributionImpl extends AbstractIntegerDistribution 30 implements HypergeometricDistribution, Serializable 31 { 32 33 34 static final long serialVersionUID = -436928820673516179L; 35 36 37 private int numberOfSuccesses; 38 39 40 private int populationSize; 41 42 43 private int sampleSize; 44 45 52 public HypergeometricDistributionImpl(int populationSize, 53 int numberOfSuccesses, int sampleSize) { 54 super(); 55 if (numberOfSuccesses > populationSize) { 56 throw new IllegalArgumentException ( 57 "number of successes must be less than or equal to population size"); 58 } 59 if (sampleSize > populationSize) { 60 throw new IllegalArgumentException ( 61 "sample size must be less than or equal to population size"); 62 } 63 setPopulationSize(populationSize); 64 setSampleSize(sampleSize); 65 setNumberOfSuccesses(numberOfSuccesses); 66 } 67 68 75 public double cumulativeProbability(int x) throws MathException{ 76 double ret; 77 78 int n = getPopulationSize(); 79 int m = getNumberOfSuccesses(); 80 int k = getSampleSize(); 81 82 int[] domain = getDomain(n, m, k); 83 if (x < domain[0]) { 84 ret = 0.0; 85 } else if(x >= domain[1]) { 86 ret = 1.0; 87 } else { 88 ret = 0.0; 89 for (int i = domain[0]; i <= x; ++i){ 90 ret += probability(n, m, k, i); 91 } 92 } 93 94 return ret; 95 } 96 97 105 private int[] getDomain(int n, int m, int k){ 106 return new int[]{ 107 getLowerDomain(n, m, k), 108 getUpperDomain(m, k) 109 }; 110 } 111 112 120 protected int getDomainLowerBound(double p) { 121 return getLowerDomain(getPopulationSize(), getNumberOfSuccesses(), 122 getSampleSize()); 123 } 124 125 133 protected int getDomainUpperBound(double p) { 134 return getUpperDomain(getSampleSize(), getNumberOfSuccesses()); 135 } 136 137 145 private int getLowerDomain(int n, int m, int k) { 146 return Math.max(0, m - (n - k)); 147 } 148 149 153 public int getNumberOfSuccesses() { 154 return numberOfSuccesses; 155 } 156 157 161 public int getPopulationSize() { 162 return populationSize; 163 } 164 165 169 public int getSampleSize() { 170 return sampleSize; 171 } 172 173 180 private int getUpperDomain(int m, int k){ 181 return Math.min(k, m); 182 } 183 184 190 public double probability(int x) { 191 double ret; 192 193 int n = getPopulationSize(); 194 int m = getNumberOfSuccesses(); 195 int k = getSampleSize(); 196 197 int[] domain = getDomain(n, m, k); 198 if(x < domain[0] || x > domain[1]){ 199 ret = 0.0; 200 } else { 201 ret = probability(n, m, k, x); 202 } 203 204 return ret; 205 } 206 207 217 private double probability(int n, int m, int k, int x) { 218 return Math.exp(MathUtils.binomialCoefficientLog(m, x) + 219 MathUtils.binomialCoefficientLog(n - m, k - x) - 220 MathUtils.binomialCoefficientLog(n, k)); 221 } 222 223 228 public void setNumberOfSuccesses(int num) { 229 if(num < 0){ 230 throw new IllegalArgumentException ( 231 "number of successes must be non-negative."); 232 } 233 numberOfSuccesses = num; 234 } 235 236 241 public void setPopulationSize(int size) { 242 if(size <= 0){ 243 throw new IllegalArgumentException ( 244 "population size must be positive."); 245 } 246 populationSize = size; 247 } 248 249 254 public void setSampleSize(int size) { 255 if (size < 0) { 256 throw new IllegalArgumentException ( 257 "sample size must be non-negative."); 258 } 259 sampleSize = size; 260 } 261 } 262 | Popular Tags |