SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
CramerVonMisesDist.java
1/*
2 * Class: CramerVonMisesDist
3 * Description: Cramér-von Mises 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
47 protected int n;
48
49 private static class Function implements MathFunction {
50 protected int n;
51 protected double u;
52
53 public Function(int n, double u) {
54 this.n = n;
55 this.u = u;
56 }
57
58 public double evaluate(double x) {
59 return u - cdf(n, x);
60 }
61 }
62
67 public CramerVonMisesDist(int n) {
68 setN(n);
69 }
70
71 public double density(double x) {
72 return density(n, x);
73 }
74
75 public double cdf(double x) {
76 return cdf(n, x);
77 }
78
79 public double barF(double x) {
80 return barF(n, x);
81 }
82
83 public double inverseF(double u) {
84 return inverseF(n, u);
85 }
86
87 public double getMean() {
88 return CramerVonMisesDist.getMean(n);
89 }
90
91 public double getVariance() {
92 return CramerVonMisesDist.getVariance(n);
93 }
94
95 public double getStandardDeviation() {
96 return CramerVonMisesDist.getStandardDeviation(n);
97 }
98
103 public static double density(int n, double x) {
104 if (n <= 0)
105 throw new IllegalArgumentException("n <= 0");
106
107 if (x <= 1.0 / (12.0 * n) || x >= n / 3.0)
108 return 0.0;
109
110 if (n == 1)
111 return 1.0 / Math.sqrt(x - 1.0 / 12.0);
112
113 if (x <= 0.002 || x > 3.95)
114 return 0.0;
115
116 throw new UnsupportedOperationException("density not implemented.");
117 }
118
142 public static double cdf(int n, double x) {
143 if (n <= 0)
144 throw new IllegalArgumentException("n <= 0");
145
146 if (n == 1) {
147 if (x <= 1.0 / 12.0)
148 return 0.0;
149 if (x >= 1.0 / 3.0)
150 return 1.0;
151 return 2.0 * Math.sqrt(x - 1.0 / 12.0);
152 }
153
154 if (x <= 1.0 / (12.0 * n))
155 return 0.0;
156
157 if (x <= (n + 3.0) / (12.0 * n * n)) {
158 double t = Num.lnFactorial(n) - Num.lnGamma(1.0 + 0.5 * n)
159 + 0.5 * n * Math.log(Math.PI * (x - 1.0 / (12.0 * n)));
160 return Math.exp(t);
161 }
162
163 if (x <= 0.002)
164 return 0.0;
165 if (x > 3.95 || x >= n / 3.0)
166 return 1.0;
167
168 final double EPSILON = Num.DBL_EPSILON;
169 final int JMAX = 20;
170 int j = 0;
171 double Cor, Res, arg;
172 double termX, termS, termJ;
173
174 termX = 0.0625 / x; // 1 / (16x)
175 Res = 0.0;
176
177 final double A[] = { 1.0, 1.11803398875, 1.125, 1.12673477358, 1.1274116945, 1.12774323743, 1.1279296875,
178 1.12804477649, 1.12812074678, 1.12817350091 };
179
180 do {
181 termJ = 4 * j + 1;
182 arg = termJ * termJ * termX;
183 termS = A[j] * Math.exp(-arg) * Num.besselK025(arg);
184 Res += termS;
185 ++j;
186 } while (!(termS < EPSILON || j > JMAX));
187
188 if (j > JMAX)
189 System.err.println("cramerVonMises: iterations have not converged");
190 Res /= Math.PI * Math.sqrt(x);
191
192 // Empirical correction in 1/n
193 if (x < 0.0092)
194 Cor = 0.0;
195 else if (x < 0.03)
196 Cor = -0.0121763 + x * (2.56672 - 132.571 * x);
197 else if (x < 0.06)
198 Cor = 0.108688 + x * (-7.14677 + 58.0662 * x);
199 else if (x < 0.19)
200 Cor = -0.0539444 + x * (-2.22024 + x * (25.0407 - 64.9233 * x));
201 else if (x < 0.5)
202 Cor = -0.251455 + x * (2.46087 + x * (-8.92836 + x * (14.0988 - x * (5.5204 + 4.61784 * x))));
203 else if (x <= 1.1)
204 Cor = 0.0782122 + x * (-0.519924 + x * (1.75148 + x * (-2.72035 + x * (1.94487 - 0.524911 * x))));
205 else
206 Cor = Math.exp(-0.244889 - 4.26506 * x);
207
208 Res += Cor / n;
209 // This empirical correction is not very precise, so ...
210 if (Res <= 1.0)
211 return Res;
212 else
213 return 1.0;
214 }
215
220 public static double barF(int n, double x) {
221 return 1.0 - cdf(n, x);
222 }
223
228 public static double inverseF(int n, double u) {
229 if (n <= 0)
230 throw new IllegalArgumentException("n <= 0");
231 if (u < 0.0 || u > 1.0)
232 throw new IllegalArgumentException("u must be in [0,1]");
233
234 if (u >= 1.0)
235 return n / 3.0;
236 if (u <= 0.0)
237 return 1.0 / (12.0 * n);
238
239 if (n == 1)
240 return 1.0 / 12.0 + 0.25 * u * u;
241
242 Function f = new Function(n, u);
243 return RootFinder.brentDekker(0.0, 10.0, f, 1e-6);
244 }
245
251 public static double getMean(int n) {
252 return 1.0 / 6.0;
253 }
254
260 public static double getVariance(int n) {
261 return (4.0 * n - 3.0) / (180.0 * n);
262 }
263
269 public static double getStandardDeviation(int n) {
270 return Math.sqrt(getVariance(n));
271 }
272
276 public int getN() {
277 return n;
278 }
279
283 public void setN(int n) {
284 if (n <= 0)
285 throw new IllegalArgumentException("n <= 0");
286 this.n = n;
287 supportA = 1.0 / (12.0 * n);
288 supportB = n / 3.0;
289 }
290
294 public double[] getParams() {
295 double[] retour = { n };
296 return retour;
297 }
298
302 public String toString() {
303 return getClass().getSimpleName() + " : n = " + n;
304 }
305
306}
Classes implementing continuous distributions should inherit from this base class.
String toString()
Returns a String containing information about the current distribution.
static double cdf(int n, double x)
Computes the Cramér-von Mises distribution function with parameter.
double inverseF(double u)
Returns the inverse distribution function .
static double getStandardDeviation(int n)
Returns the standard deviation of the distribution with parameter.
int getN()
Returns the parameter of this object.
static double getMean(int n)
Returns the mean of the distribution with parameter .
void setN(int n)
Sets the parameter of this object.
static double getVariance(int n)
Returns the variance of the distribution with parameter .
double getStandardDeviation()
Returns the standard deviation.
static double inverseF(int n, double u)
Computes , where is the Cramér-von Mises distribution with parameter .
double barF(double x)
Returns the complementary distribution function.
static double density(int n, double x)
Computes the density function for a Cramér-von Mises distribution with parameter .
CramerVonMisesDist(int n)
Constructs a Cramér-von Mises distribution for a sample of size .
double[] getParams()
Return an array containing the parameter of this object.
double density(double x)
Returns , the density evaluated at .
double cdf(double x)
Returns the distribution function .
static double barF(int n, double x)
Computes the complementary distribution function with parameter .
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 DBL_EPSILON
Difference between 1.0 and the smallest double greater than 1.0.
Definition Num.java:90
static double lnFactorial(int n)
Returns the value of , the natural logarithm of factorial .
Definition Num.java:313
static double besselK025(double x)
Returns the value of , where.
Definition Num.java:863
This class provides numerical methods to solve non-linear equations.
static double brentDekker(double a, double b, MathFunction f, double tol)
Computes a root of the function in f using the Brent-Dekker method.
This interface should be implemented by classes which represent univariate mathematical functions.