SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
StudentDistQuick.java
1/*
2 * Class: StudentDistQuick
3 * Description: Student t-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.Num;
28// import umontreal.ssj.functions.MathFunction;
29
40public class StudentDistQuick extends StudentDist {
41 private static final int STUDENT_N1 = 20;
42 private static final double STUDENT_X1 = 8.01;
43 private static final int STUDENT_KMAX = 200;
44 private static final double STUDENT_EPS = 0.5E-16;
45
49 public StudentDistQuick(int n) {
50 super(n);
51 }
52
53 /*
54 * These public methods are necessary so that the methods cdf, barF and inverseF
55 * used are those of the present class and not those of the mother class.
56 */
57
58 public double cdf(double x) {
59 return cdf(n, x);
60 }
61
62 public double barF(double x) {
63 return barF(n, x);
64 }
65
66 public double inverseF(double u) {
67 return inverseF(n, u);
68 }
69
75 public static double cdf(int n, double x) {
76 if (n <= 2)
77 return StudentDist.cdf(n, x);
78 if (x == Double.NEGATIVE_INFINITY)
79 return 0.0;
80 if (x == Double.POSITIVE_INFINITY)
81 return 1.0;
82 double b, y, z, z2, prec, v;
83 int k;
84
85 // first case: small n and small x
86 if (n <= STUDENT_N1 && x <= STUDENT_X1) {
87 b = 1.0 + x * x / n;
88 y = x / Math.sqrt((double) n);
89 z = 1.0;
90 for (k = n - 2; k >= 2; k -= 2)
91 z = 1.0 + z * (k - 1) / (k * b);
92 if (n % 2 == 0) {
93 v = (1.0 + z * y / Math.sqrt(b)) / 2.0;
94 } else {
95 if (y > -1.0)
96 v = (0.5 + (Math.atan(y) + z * y / b) / Math.PI);
97 else
98 v = (Math.atan(-1.0 / y) + z * y / b) / Math.PI;
99 }
100 if (v > 1.0e-18)
101 return v;
102 else
103 return 0.0;
104 }
105
106 // second case: large n and small x
107 else if (x < STUDENT_X1) {
108 double a = n - 0.5;
109 b = 48.0 * a * a;
110 z2 = a * Math.log1p(x * x / n);
111 z = Math.sqrt(z2);
112 y = (((((64.0 * z2 + 788.0) * z2 + 9801.0) * z2 + 89775.0) * z2 + 543375.0) * z2 + 1788885.0) * z
113 / (210.0 * b * b * b);
114 y -= (((4.0 * z2 + 33.0) * z2 + 240.0) * z2 + 855.0) * z / (10.0 * b * b);
115 y += z + (z2 + 3.0) * z / b;
116 if (x >= 0.0)
117 return NormalDist.barF01(-y);
118 else
119 return NormalDist.barF01(y);
120 }
121
122 // third case: large x
123 else {
124 // Compute the Student probability density
125 b = 1.0 + x * x / n;
126 y = Num.gammaRatioHalf(n / 2.0);
127 y *= 1.0 / (Math.sqrt(Math.PI * n) * Math.pow(b, (n + 1) / 2.0));
128
129 y *= 2.0 * Math.sqrt(n * b);
130 z = y / n;
131 k = 2;
132 z2 = prec = 10.0;
133 while (k < STUDENT_KMAX && prec > STUDENT_EPS) {
134 y *= (k - 1) / (k * b);
135 z += y / (n + k);
136 prec = Math.abs(z - z2);
137 z2 = z;
138 k += 2;
139 }
140 if (k >= STUDENT_KMAX)
141 System.err.println("student: k >= STUDENT_KMAX");
142 if (x >= 0.0)
143 return 1.0 - z / 2.0;
144 else
145 return z / 2.0;
146 }
147 }
148
152 public static double barF(int n, double x) {
153 if (n <= 2)
154 return StudentDist.barF(n, x);
155 return cdf(n, -x);
156 }
157
166 public static double inverseF(int n, double u) {
167 if (n <= 2)
168 return StudentDist.inverseF(n, u);
169 final double PI = Math.PI;
170 double a, b, c, d, e, p, t, x, y;
171
172 e = (double) n;
173 if (u > 0.5)
174 p = 2.0 * (1.0 - u);
175 else
176 p = 2.0 * u;
177
178 a = 1. / (e - 0.5);
179 b = 48. / (a * a);
180 c = ((20700. / b * a - 98.) * a - 16.) * a + 96.36;
181 d = e * Math.sqrt(a * PI / 2.) * ((94.5 / (b + c) - 3.) / b + 1.);
182 y = Math.pow((d * p), (2.0 / e));
183 if (y > (a + 0.05)) {
184 if (p == 1.0)
185 x = 0.0;
186 else
187 x = NormalDist.inverseF01(p * 0.5);
188 y = x * x;
189 if (n < 5)
190 c = c + 0.3 * (e - 4.5) * (x + 0.6);
191
192 c = (((0.05 * d * x - 5.) * x - 7.) * x - 2.) * x + b + c;
193 y = (((((0.4 * y + 6.3) * y + 36.) * y + 94.5) / c - y - 3.) / b + 1.) * x;
194 y = a * (y * y);
195 y = Math.expm1(y);
196
197 } else {
198 y = ((1. / (((e + 6.) / (e * y) - 0.089 * d - 0.822) * (e + 2.) * 3.) + 0.5 / (e + 4.)) * y - 1.) * (e + 1.)
199 / (e + 2.) + 1. / y;
200 }
201
202 t = Math.sqrt(e * y);
203 if (u < 0.5)
204 return -t;
205 else
206 return t;
207 }
208
209}
Extends the class ContinuousDistribution for the normal distribution (e.g., tjoh95a  (page 80)).
static double inverseF01(double u)
Same as inverseF(0, 1, u).
static double barF01(double x)
Same as barF(0, 1, x).
static double cdf(int n, double x)
Returns the approximation of tken80a  (page 96) of the Student -distribution function with degrees o...
double inverseF(double u)
Returns the inverse distribution function .
StudentDistQuick(int n)
Constructs a StudentDistQuick object with n degrees of freedom.
double cdf(double x)
Returns the distribution function .
static double inverseF(int n, double u)
Returns an approximation of , where is the Student -distribution function with degrees of freedom.
static double barF(int n, double x)
Computes the complementary distribution function .
double barF(double x)
Returns the complementary distribution function.
StudentDist(int n)
Constructs a StudentDist object with n degrees of freedom.
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static double gammaRatioHalf(double x)
Returns the value of the ratio of two gamma functions.
Definition Num.java:635