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
34
35 public class BetaDistribution extends AbstractRealDistribution {
36
37 private static final long serialVersionUID = 20160320L;
38
39 private final double alpha;
40
41 private final double beta;
42
43 private final double z;
44
45
46
47
48
49
50
51 public BetaDistribution(double alpha, double beta) {
52 this(alpha, beta, DEFAULT_SOLVER_ABSOLUTE_ACCURACY);
53 }
54
55
56
57
58
59
60
61
62
63
64 public BetaDistribution(double alpha, double beta, double inverseCumAccuracy) {
65 super(inverseCumAccuracy);
66
67 this.alpha = alpha;
68 this.beta = beta;
69 this.z = Gamma.logGamma(alpha) +
70 Gamma.logGamma(beta) -
71 Gamma.logGamma(alpha + beta);
72 }
73
74
75
76
77
78
79 public double getAlpha() {
80 return alpha;
81 }
82
83
84
85
86
87
88 public double getBeta() {
89 return beta;
90 }
91
92
93 @Override
94 public double density(double x) {
95 final double logDensity = logDensity(x);
96 return logDensity == Double.NEGATIVE_INFINITY ? 0 : FastMath.exp(logDensity);
97 }
98
99
100 @Override
101 public double logDensity(double x) {
102 if (x < 0 || x > 1) {
103 return Double.NEGATIVE_INFINITY;
104 } else if (x == 0) {
105 if (alpha < 1) {
106 throw new MathIllegalArgumentException(LocalizedCoreFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA,
107 alpha, 1, false);
108 }
109 return Double.NEGATIVE_INFINITY;
110 } else if (x == 1) {
111 if (beta < 1) {
112 throw new MathIllegalArgumentException(LocalizedCoreFormats.CANNOT_COMPUTE_BETA_DENSITY_AT_1_FOR_SOME_BETA,
113 beta, 1, false);
114 }
115 return Double.NEGATIVE_INFINITY;
116 } else {
117 double logX = FastMath.log(x);
118 double log1mX = FastMath.log1p(-x);
119 return (alpha - 1) * logX + (beta - 1) * log1mX - z;
120 }
121 }
122
123
124 @Override
125 public double cumulativeProbability(double x) {
126 if (x <= 0) {
127 return 0;
128 } else if (x >= 1) {
129 return 1;
130 } else {
131 return Beta.regularizedBeta(x, alpha, beta);
132 }
133 }
134
135
136
137
138
139
140
141 @Override
142 public double getNumericalMean() {
143 final double a = getAlpha();
144 return a / (a + getBeta());
145 }
146
147
148
149
150
151
152
153
154 @Override
155 public double getNumericalVariance() {
156 final double a = getAlpha();
157 final double b = getBeta();
158 final double alphabetasum = a + b;
159 return (a * b) / ((alphabetasum * alphabetasum) * (alphabetasum + 1));
160 }
161
162
163
164
165
166
167
168
169 @Override
170 public double getSupportLowerBound() {
171 return 0;
172 }
173
174
175
176
177
178
179
180
181 @Override
182 public double getSupportUpperBound() {
183 return 1;
184 }
185
186
187
188
189
190
191
192
193 @Override
194 public boolean isSupportConnected() {
195 return true;
196 }
197 }