1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.distribution.continuous;
23
24 import org.hipparchus.exception.LocalizedCoreFormats;
25 import org.hipparchus.exception.MathIllegalArgumentException;
26 import org.hipparchus.special.Beta;
27 import org.hipparchus.special.Gamma;
28 import org.hipparchus.util.FastMath;
29
30
31
32
33 public class TDistribution extends AbstractRealDistribution {
34
35 private static final long serialVersionUID = 20160320L;
36
37 private final double degreesOfFreedom;
38
39 private final double factor;
40
41
42
43
44
45
46
47 public TDistribution(double degreesOfFreedom)
48 throws MathIllegalArgumentException {
49 this(degreesOfFreedom, DEFAULT_SOLVER_ABSOLUTE_ACCURACY);
50 }
51
52
53
54
55
56
57
58
59
60
61
62 public TDistribution(double degreesOfFreedom, double inverseCumAccuracy)
63 throws MathIllegalArgumentException {
64 super(inverseCumAccuracy);
65
66 if (degreesOfFreedom <= 0) {
67 throw new MathIllegalArgumentException(LocalizedCoreFormats.DEGREES_OF_FREEDOM,
68 degreesOfFreedom);
69 }
70 this.degreesOfFreedom = degreesOfFreedom;
71
72 final double n = degreesOfFreedom;
73 final double nPlus1Over2 = (n + 1) / 2;
74 factor = Gamma.logGamma(nPlus1Over2) -
75 0.5 * (FastMath.log(FastMath.PI) + FastMath.log(n)) -
76 Gamma.logGamma(n / 2);
77 }
78
79
80
81
82
83
84 public double getDegreesOfFreedom() {
85 return degreesOfFreedom;
86 }
87
88
89 @Override
90 public double density(double x) {
91 return FastMath.exp(logDensity(x));
92 }
93
94
95 @Override
96 public double logDensity(double x) {
97 final double n = degreesOfFreedom;
98 final double nPlus1Over2 = (n + 1) / 2;
99 return factor - nPlus1Over2 * FastMath.log(1 + x * x / n);
100 }
101
102
103 @Override
104 public double cumulativeProbability(double x) {
105 double ret;
106 if (x == 0) {
107 ret = 0.5;
108 } else {
109 double t =
110 Beta.regularizedBeta(
111 degreesOfFreedom / (degreesOfFreedom + (x * x)),
112 0.5 * degreesOfFreedom,
113 0.5);
114 if (x < 0.0) {
115 ret = 0.5 * t;
116 } else {
117 ret = 1.0 - 0.5 * t;
118 }
119 }
120
121 return ret;
122 }
123
124
125
126
127
128
129
130
131
132
133 @Override
134 public double getNumericalMean() {
135 final double df = getDegreesOfFreedom();
136
137 if (df > 1) {
138 return 0;
139 }
140
141 return Double.NaN;
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155 @Override
156 public double getNumericalVariance() {
157 final double df = getDegreesOfFreedom();
158
159 if (df > 2) {
160 return df / (df - 2);
161 }
162
163 if (df > 1 && df <= 2) {
164 return Double.POSITIVE_INFINITY;
165 }
166
167 return Double.NaN;
168 }
169
170
171
172
173
174
175
176
177
178
179 @Override
180 public double getSupportLowerBound() {
181 return Double.NEGATIVE_INFINITY;
182 }
183
184
185
186
187
188
189
190
191
192
193 @Override
194 public double getSupportUpperBound() {
195 return Double.POSITIVE_INFINITY;
196 }
197
198
199
200
201
202
203
204
205 @Override
206 public boolean isSupportConnected() {
207 return true;
208 }
209 }