SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
ChiSquareDist.java
1/*
2 * Class: ChiSquareDist
3 * Description: chi-square distribution
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.probdist;
26
27import umontreal.ssj.util.*;
28import umontreal.ssj.functions.MathFunction;
29
52 protected int n;
53 protected double C1;
54
55 private static class Function implements MathFunction {
56 protected int n;
57 protected double sumLog;
58
59 public Function(double s, int n) {
60 this.n = n;
61 this.sumLog = s;
62 }
63
64 public double evaluate(double k) {
65 if (k < 1.0)
66 return 1.0e200;
67 return (sumLog + n * (Num.lnGamma(k / 2.0) - 0.5 * Num.LN2 - Num.lnGamma((k + 1.0) / 2.0)));
68 }
69 }
70
74 public ChiSquareDist(int n) {
75 setN(n);
76 }
77
78 public double density(double x) {
79 if (x <= 0)
80 return 0.0;
81 return Math.exp((n / 2.0 - 1) * Math.log(x) - x / 2.0 - C1);
82 }
83
84 public double cdf(double x) {
85 return cdf(n, decPrec, x);
86 }
87
88 public double barF(double x) {
89 return barF(n, decPrec, x);
90 }
91
92 public double inverseF(double u) {
93 return inverseF(n, u);
94 }
95
96 public double getMean() {
97 return ChiSquareDist.getMean(n);
98 }
99
100 public double getVariance() {
101 return ChiSquareDist.getVariance(n);
102 }
103
104 public double getStandardDeviation() {
105 return ChiSquareDist.getStandardDeviation(n);
106 }
107
112 public static double density(int n, double x) {
113 if (x <= 0)
114 return 0.0;
115 return Math.exp((n / 2.0 - 1) * Math.log(x) - x / 2.0 - (n / 2.0) * Num.LN2 - Num.lnGamma(n / 2.0));
116 }
117
123 public static double cdf(int n, int d, double x) {
124 if (n <= 0)
125 throw new IllegalArgumentException("n <= 0");
126 if (x <= 0.0)
127 return 0.0;
128 if (x >= XBIG * n)
129 return 1.0;
130 return GammaDist.cdf(n / 2.0, d, x / 2.0);
131 }
132
140 public static double barF(int n, int d, double x) {
141 if (n <= 0)
142 throw new IllegalArgumentException("n <= 0");
143 if (x <= 0.0)
144 return 1.0;
145 return GammaDist.barF(n / 2.0, d, x / 2.0);
146 }
147
163 public static double inverseF(int n, double u) {
164 /*
165 * Returns an approximation of the inverse of Chi square cdf with n degrees of
166 * freedom. As in Figure L.23 of P.Bratley, B.L.Fox, and L.E.Schrage. A Guide to
167 * Simulation Springer-Verlag, New York, second edition, 1987.
168 */
169 if (n <= 0)
170 throw new IllegalArgumentException("n <= 0");
171 if (u < 0.0 || u > 1.0)
172 throw new IllegalArgumentException("u must be in [0,1]");
173 if (u == 1.0)
174 return Double.POSITIVE_INFINITY;
175 if (u == 0.0)
176 return 0.0;
177
178 final double E = 0.5e-5; // Precision of this approximation
179 final double AA = 0.6931471805;
180 double A, XX, X, C, G, CH, Q, P1, P2, T, B, S1, S2, S3, S4, S5, S6;
181
182 if (u < 0.00001 || u > 1.0 - 1.0e-5)
183 return 2.0 * GammaDist.inverseF(n / 2.0, 7, u);
184 if (u >= 1.0)
185 return n * XBIG;
186 if (u >= 0.999998)
187 return (n + 4.0 * Math.sqrt(2.0 * n));
188
189 G = Num.lnGamma(n / 2.0);
190 XX = 0.5 * n;
191 C = XX - 1.0;
192
193 if (n >= -1.24 * Math.log(u)) {
194 X = NormalDist.inverseF01(u);
195 P1 = 0.222222 / n;
196 Q = X * Math.sqrt(P1) + 1.0 - P1;
197 CH = n * Q * Q * Q;
198 if (CH > 2.2 * n + 6.0)
199 CH = -2.0 * (Math.log1p(-u) - C * Math.log(0.5 * CH) + G);
200
201 } else {
202 CH = Math.pow(u * XX * Math.exp(G + XX * AA), 1.0 / XX);
203 if (CH - E < 0)
204 return CH;
205 }
206
207 Q = CH;
208 P1 = 0.5 * CH;
209 P2 = u - GammaDist.cdf(XX, 5, P1);
210 if (GammaDist.cdf(XX, 5, P1) == -1.0)
211 throw new IllegalArgumentException("RESULT = -1");
212
213 T = P2 * Math.exp(XX * AA + G + P1 - C * Math.log(CH));
214 B = T / CH;
215 A = 0.5 * T - B * C;
216 S1 = (210.0 + A * (140.0 + A * (105.0 + A * (84.0 + A * (70.0 + 60.0 * A))))) / 420.0;
217 S2 = (420.0 + A * (735.0 + A * (966.0 + A * (1141.0 + 1278.0 * A)))) / 2520.0;
218 S3 = (210.0 + A * (462.0 + A * (707.0 + 932.0 * A))) / 2520.0;
219 S4 = (252.0 + A * (672.0 + 1182.0 * A) + C * (294.0 + A * (889.0 + 1740.0 * A))) / 5040.0;
220 S5 = (84.0 + 264.0 * A + C * (175.0 + 606.0 * A)) / 2520.0;
221 S6 = (120.0 + C * (346.0 + 127.0 * C)) / 5040.0;
222 CH = CH + T * (1.0 + 0.5 * T * S1 - B * C * (S1 - B * (S2 - B * (S3 - B * (S4 - B * (S5 - B * S6))))));
223
224 double temp;
225 while (Math.abs(Q / CH - 1.0) > E) {
226 Q = CH;
227 P1 = 0.5 * CH;
228 temp = GammaDist.cdf(XX, 6, P1);
229 P2 = u - temp;
230
231 if (temp == -1.0)
232 return -1.0;
233
234 T = P2 * Math.exp(XX * AA + G + P1 - C * Math.log(CH));
235 B = T / CH;
236 A = 0.5 * T - B * C;
237 S1 = (210.0 + A * (140.0 + A * (105.0 + A * (84.0 + A * (70.0 + 60.0 * A))))) / 420.0;
238 S2 = (420.0 + A * (735.0 + A * (966.0 + A * (1141.0 + 1278.0 * A)))) / 2520.0;
239 S3 = (210.0 + A * (462.0 + A * (707.0 + 932.0 * A))) / 2520.0;
240 S4 = (252.0 + A * (672.0 + 1182.0 * A) + C * (294.0 + A * (889.0 + 1740.0 * A))) / 5040.0;
241 S5 = (84.0 + 264.0 * A + C * (175.0 + 606.0 * A)) / 2520.0;
242 S6 = (120.0 + C * (346.0 + 127.0 * C)) / 5040.0;
243 CH = CH + T * (1.0 + 0.5 * T * S1 - B * C * (S1 - B * (S2 - B * (S3 - B * (S4 - B * (S5 - B * S6))))));
244 }
245 return CH;
246 }
247
258 public static double[] getMLE(double[] x, int m) {
259 if (m <= 0)
260 throw new IllegalArgumentException("m <= 0");
261
262 double[] parameters;
263
264 parameters = getMomentsEstimate(x, m);
265 double k = Math.round(parameters[0]) - 5.0;
266 if (k < 1.0)
267 k = 1.0;
268
269 double sum = 0.0;
270 for (int i = 0; i < m; i++) {
271 if (x[i] > 0.0)
272 sum += 0.5 * Math.log(x[i]);
273 else
274 sum -= 709.0;
275 }
276
277 Function f = new Function(sum, m);
278 while (f.evaluate(k) > 0.0)
279 k++;
280 parameters[0] = k;
281
282 return parameters;
283 }
284
293 public static ChiSquareDist getInstanceFromMLE(double[] x, int m) {
294 double parameters[] = getMLE(x, m);
295 return new ChiSquareDist((int) parameters[0]);
296 }
297
304 public static double getMean(int n) {
305 if (n <= 0)
306 throw new IllegalArgumentException("degrees of freedom " + "must be non-null and positive.");
307
308 return n;
309 }
310
320 public static double[] getMomentsEstimate(double[] x, int m) {
321 double[] parameters = new double[1];
322
323 double sum = 0.0;
324 for (int i = 0; i < m; i++)
325 sum += x[i];
326 parameters[0] = sum / (double) m;
327
328 return parameters;
329 }
330
337 public static double getVariance(int n) {
338 if (n <= 0)
339 throw new IllegalArgumentException("degrees of freedom " + "must be non-null and positive.");
340
341 return (2 * n);
342 }
343
350 public static double getStandardDeviation(int n) {
351 if (n <= 0)
352 throw new IllegalArgumentException("degrees of freedom " + "must be non-null and positive.");
353
354 return Math.sqrt(2 * n);
355 }
356
360 public int getN() {
361 return n;
362 }
363
367 public void setN(int n) {
368 if (n <= 0)
369 throw new IllegalArgumentException("degrees of freedom " + "must be non-null and positive.");
370
371 this.n = n;
372 supportA = 0.0;
373 C1 = 0.5 * n * Num.LN2 + Num.lnGamma(n / 2.0);
374 }
375
379 public double[] getParams() {
380 double[] retour = { n };
381 return retour;
382 }
383
387 public String toString() {
388 return getClass().getSimpleName() + " : n = " + n;
389 }
390
391}
ChiSquareDist(int n)
Constructs a chi-square distribution with n degrees of freedom.
double[] getParams()
Return a table containing the parameters of the current distribution.
static double density(int n, double x)
Computes the density function ( Fchi2 ) for a chi-square distribution with degrees of freedom.
double cdf(double x)
Returns the distribution function .
String toString()
Returns a String containing information about the current distribution.
double getVariance()
Returns the variance.
static double getStandardDeviation(int n)
Returns the standard deviation of the chi-square distribution with parameter .
static ChiSquareDist getInstanceFromMLE(double[] x, int m)
Creates a new instance of a chi-square distribution with parameter.
double density(double x)
Returns , the density evaluated at .
static double getMean(int n)
Computes and returns the mean of the chi-square distribution with parameter .
double barF(double x)
Returns the complementary distribution function.
double getStandardDeviation()
Returns the standard deviation.
static double[] getMLE(double[] x, int m)
Estimates the parameter of the chi-square distribution using the maximum likelihood method,...
static double barF(int n, int d, double x)
Computes the complementary chi-square distribution function with.
double inverseF(double u)
Returns the inverse distribution function .
static double getVariance(int n)
Returns the variance of the chi-square distribution with parameter .
void setN(int n)
Sets the parameter of this object.
static double inverseF(int n, double u)
Computes an approximation of , where is the chi-square distribution with degrees of freedom.
double getMean()
Returns the mean.
int getN()
Returns the parameter of this object.
static double[] getMomentsEstimate(double[] x, int m)
Estimates and returns the parameter [ ] of the chi-square distribution using the moments method based...
static double cdf(int n, int d, double x)
Computes the chi-square distribution function with degrees of freedom, evaluated at .
Classes implementing continuous distributions should inherit from this base class.
Extends the class ContinuousDistribution for the gamma distribution tjoh95a  (page 337) with shape pa...
double inverseF(double u)
Returns the inverse distribution function .
double cdf(double x)
Returns the distribution function .
double barF(double x)
Returns the complementary distribution function.
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
static double inverseF01(double u)
Same as inverseF(0, 1, u).
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static double lnGamma(double x)
Returns the natural logarithm of the gamma function evaluated at x.
Definition Num.java:417
static final double LN2
The values of .
Definition Num.java:148
This interface should be implemented by classes which represent univariate mathematical functions.