SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
FBar.java
1/*
2 * Class: FBar
3 * Description: Complementary empirical distributions
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.gof;
26
27import umontreal.ssj.probdist.*;
28
40public class FBar {
41 private FBar() {
42 }
43
44 private static final double EPSILONSCAN = 1.0E-7;
45
46 private static double scanGlaz(int n, double d, int m) {
47 int j, jmoy;
48 double temp;
49 double jr, jm1r, nr = n;
50 int signe;
51 double q = 1.0 - d;
52 double q4, q3, q2, q1;
53 double bin, binMoy;
54
55 jmoy = (int) ((n + 1) * d); // max term of the Binomial
56 if (jmoy < m - 1)
57 jmoy = m - 1;
58
59 /*---------------------------------------------------------
60 * Compute q1: formula (2.5) in Glaz (1989)
61 * Compute q2: formula (A.6) in Berman and Eagleson (1985)
62 * Compute q3, q4 : Theorem (3.2) in Glaz (1989)
63 *---------------------------------------------------------*/
64
65 // compute the probability of term j = jmoy
66 q1 = 0.0;
67 for (j = 1; j <= jmoy; j++) {
68 jr = j;
69 q1 += Math.log(nr - jr + 1.0) - Math.log(jr);
70 }
71 q1 += jmoy * Math.log(d) + (nr - jmoy) * Math.log(q);
72 binMoy = Math.exp(q1);
73 q1 = binMoy;
74 jm1r = jmoy - m + 1;
75 if (((jmoy - m + 1) & 1) != 0)
76 signe = -1;
77 else
78 signe = 1;
79 q2 = signe * binMoy;
80 q3 = signe * binMoy * (2.0 - jm1r * jm1r + jm1r);
81 q4 = signe * binMoy * (jm1r + 1.0) * (jm1r + 2.0) * (6.0 + jm1r * jm1r - 5.0 * jm1r);
82
83 // compute the probability of terms j > jmoy
84 if (((jmoy - m + 1) & 1) != 0)
85 signe = -1;
86 else
87 signe = 1;
88
89 jm1r = jmoy - m + 1;
90 bin = binMoy;
91 for (j = jmoy + 1; j <= n; j++) {
92 jr = j;
93 jm1r += 1.0;
94 signe = -signe;
95 bin = (bin * (nr - jr + 1.0) * d) / (jr * q);
96 if (bin < EPSILONSCAN)
97 break;
98 q1 += bin;
99 q2 += signe * bin;
100 q3 += signe * bin * (2.0 - jm1r * jm1r + jm1r);
101 q4 += signe * bin * (jm1r + 1.0) * (jm1r + 2.0) * (6.0 + jm1r * jm1r - 5.0 * jm1r);
102 }
103
104 q1 = 1.0 - q1;
105 q3 /= 2.0;
106 q4 /= 12.0;
107 if (m == 3) {
108 // Problem with this formula; I do not get the same results as Glaz
109 q4 = ((nr * (nr - 1.0) * d * d * Math.pow(q, nr - 2.0)) / 8.0
110 + nr * d * 2.0 * Math.pow(1.0 - 2.0 * d, nr - 1.0)) - 4.0 * Math.pow(1.0 - 2.0 * d, nr);
111 if (d < 1.0 / 3.0) {
112 q4 += nr * d * 2.0 * Math.pow(1.0 - 3.0 * d, nr - 1.0) + 4.0 * Math.pow(1.0 - 3.0 * d, nr);
113 }
114 }
115 // compute probability: Glaz, equations (3.2) and (3.3)
116 q3 = q1 - q2 - q3;
117 q4 = q3 - q4;
118 // when the approximation is bad, avoid overflow
119 temp = Math.log(q3) + (nr - m - 2.0) * Math.log(q4 / q3);
120 if (temp >= 0.0)
121 return 0.0;
122 if (temp < -30.0)
123 return 1.0;
124 q4 = Math.exp(temp);
125 return 1.0 - q4;
126 }
127
128 // -----------------------------------------------------------------
129
130 private static double scanWNeff(int n, double d, int m) {
131 double q = 1.0 - d;
132 double temp;
133 double bin;
134 double sum;
135 int j;
136
137 /*--------------------------------------
138 * Anderson-Titterington: equation (4)
139 *--------------------------------------*/
140
141 // compute the probability of term j = m
142 sum = 0.0;
143 for (j = 1; j <= m; j++)
144 sum += Math.log((double) (n - j + 1)) - Math.log((double) j);
145
146 sum += m * Math.log(d) + (n - m) * Math.log(q);
147 bin = Math.exp(sum);
148 temp = (m / d - n - 1.0) * bin;
149 sum = bin;
150
151 // compute the probability of terms j > m
152 for (j = m + 1; j <= n; j++) {
153 bin *= (n - j + 1) * d / (j * q);
154 if (bin < EPSILONSCAN)
155 break;
156 sum += bin;
157 }
158 sum = 2.0 * sum + temp;
159 return sum;
160 }
161
162 // ----------------------------------------------------------------
163
164 private static double scanAsympt(int n, double d, int m) {
165 double kappa;
166 double temp;
167 double theta;
168 double sum;
169
170 /*--------------------------------------------------------------
171 * Anderson-Titterington: asymptotic formula after equation (4)
172 *--------------------------------------------------------------*/
173
174 theta = Math.sqrt(d / (1.0 - d));
175 temp = Math.sqrt((double) n);
176 kappa = m / (d * temp) - temp;
177 temp = theta * kappa;
178 temp = temp * temp / 2.0;
179 sum = 2.0 * (1.0 - NormalDist.cdf01(theta * kappa))
180 + (kappa * theta * Math.exp(-temp)) / (d * Math.sqrt(2.0 * Math.PI));
181 return sum;
182 }
183
234 public static double scan(int n, double d, int m) {
235 double mu;
236 double prob;
237
238 if (n < 2)
239 throw new IllegalArgumentException("Calling scan with n < 2");
240 if (d <= 0.0 || d >= 1.0)
241 throw new IllegalArgumentException("Calling scan with " + "d outside (0,1)");
242
243 if (m > n)
244 return 0.0;
245 if (m <= 1)
246 return 1.0;
247 if (m <= 2) {
248 if ((n - 1) * d >= 1.0)
249 return 1.0;
250 return 1.0 - Math.pow(1.0 - (n - 1) * d, (double) n);
251 }
252 if (d >= 0.5 && m <= (n + 1) / 2.0)
253 return 1.0;
254 if (d > 0.5)
255 return -1.0; // Error
256 // util_Assert (d <= 0.5, "Calling fbar_Scan with d > 1/2");
257
258 mu = n * d; // mean of a binomial
259 if (m <= mu + d)
260 return 1.0;
261 if (mu <= 10.0)
262 return scanGlaz(n, d, m);
263 prob = scanAsympt(n, d, m);
264 if ((d >= 0.3 && n >= 50.0) || (n * d * d >= 250.0 && d < 0.3)) {
265 if (prob <= 0.4)
266 return prob;
267 }
268 prob = scanWNeff(n, d, m);
269 if (prob <= 0.4)
270 return prob;
271 prob = scanGlaz(n, d, m);
272 if (prob > 0.4 && prob <= 1.0)
273 return prob;
274 return 1.0;
275 }
276}
static double scan(int n, double d, int m)
Return , where is the scan statistic(see tgla89a, tgla01a  and GofStat.scan ), defined as.
Definition FBar.java:234
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
static double cdf01(double x)
Same as cdf(0, 1, x).