SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
WeibullDist.java
1/*
2 * Class: WeibullDist
3 * Description: Weibull 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;
28import umontreal.ssj.util.RootFinder;
29import umontreal.ssj.functions.MathFunction;
30
49public class WeibullDist extends ContinuousDistribution {
50 private double alpha;
51 private double lambda;
52 private double delta;
53
54 private static class Function implements MathFunction {
55 private int n;
56 private double xi[];
57 private double lnXi[];
58 private double sumLnXi = 0.0;
59 private final double LN_EPS = Num.LN_DBL_MIN - Num.LN2;
60
61 public Function(double x[], int n) {
62 this.n = n;
63 this.xi = new double[n];
64 this.lnXi = new double[n];
65
66 for (int i = 0; i < n; i++) {
67 this.xi[i] = x[i];
68 if (x[i] > 0.0)
69 this.lnXi[i] = Math.log(x[i]);
70 else
71 this.lnXi[i] = LN_EPS;
72 sumLnXi += this.lnXi[i];
73 }
74 }
75
76 public double evaluate(double x) {
77 if (x <= 0.0)
78 return 1.0e200;
79 double sumXiLnXi = 0.0;
80 double sumXi = 0.0;
81 double xalpha;
82
83 for (int i = 0; i < n; i++) {
84 xalpha = Math.pow(this.xi[i], x);
85 sumXiLnXi += xalpha * lnXi[i];
86 sumXi += xalpha;
87 }
88
89 return (x * (n * sumXiLnXi - sumLnXi * sumXi) - n * sumXi);
90 }
91 }
92
97 public WeibullDist(double alpha) {
98 setParams(alpha, 1.0, 0.0);
99 }
100
105 public WeibullDist(double alpha, double lambda, double delta) {
106 setParams(alpha, lambda, delta);
107 }
108
109 public double density(double x) {
110 return density(alpha, lambda, delta, x);
111 }
112
113 public double cdf(double x) {
114 return cdf(alpha, lambda, delta, x);
115 }
116
117 public double barF(double x) {
118 return barF(alpha, lambda, delta, x);
119 }
120
121 public double inverseF(double u) {
122 return inverseF(alpha, lambda, delta, u);
123 }
124
125 public double getMean() {
126 return WeibullDist.getMean(alpha, lambda, delta);
127 }
128
129 public double getVariance() {
130 return WeibullDist.getVariance(alpha, lambda, delta);
131 }
132
133 public double getStandardDeviation() {
134 return WeibullDist.getStandardDeviation(alpha, lambda, delta);
135 }
136
140 public static double density(double alpha, double lambda, double delta, double x) {
141 if (alpha <= 0.0)
142 throw new IllegalArgumentException("alpha <= 0");
143 if (lambda <= 0.0)
144 throw new IllegalArgumentException("lambda <= 0");
145 if (x <= delta)
146 return 0.0;
147 double y = Math.log(lambda * (x - delta)) * alpha;
148 if (y >= 7.0)
149 return 0.0;
150 y = Math.exp(y);
151
152 return alpha * (y / (x - delta)) * Math.exp(-y);
153 }
154
158 public static double density(double alpha, double x) {
159 return density(alpha, 1.0, 0.0, x);
160 }
161
165 public static double cdf(double alpha, double lambda, double delta, double x) {
166 if (alpha <= 0.0)
167 throw new IllegalArgumentException("alpha <= 0");
168 if (lambda <= 0.0)
169 throw new IllegalArgumentException("lambda <= 0");
170 if (x <= delta)
171 return 0.0;
172 if ((lambda * (x - delta) >= XBIG) && (alpha >= 1.0))
173 return 1.0;
174 double y = Math.log(lambda * (x - delta)) * alpha;
175 if (y >= 3.65)
176 return 1.0;
177 y = Math.exp(y);
178 return -Math.expm1(-y); // in JDK-1.5
179 }
180
184 public static double cdf(double alpha, double x) {
185 return cdf(alpha, 1.0, 0.0, x);
186 }
187
191 public static double barF(double alpha, double lambda, double delta, double x) {
192 if (alpha <= 0)
193 throw new IllegalArgumentException("alpha <= 0");
194 if (lambda <= 0)
195 throw new IllegalArgumentException("lambda <= 0");
196 if (x <= delta)
197 return 1.0;
198 if (alpha >= 1.0 && x >= Num.DBL_MAX_EXP * 2)
199 return 0.0;
200
201 double temp = Math.log(lambda * (x - delta)) * alpha;
202 if (temp >= Num.DBL_MAX_EXP * Num.LN2)
203 return 0.0;
204 temp = Math.exp(temp);
205 return Math.exp(-temp);
206 }
207
211 public static double barF(double alpha, double x) {
212 return barF(alpha, 1.0, 0.0, x);
213 }
214
218 public static double inverseF(double alpha, double lambda, double delta, double u) {
219 double t;
220 if (alpha <= 0.0)
221 throw new IllegalArgumentException("alpha <= 0");
222 if (lambda <= 0.0)
223 throw new IllegalArgumentException("lambda <= 0");
224
225 if (u < 0.0 || u > 1.0)
226 throw new IllegalArgumentException("u not in [0, 1]");
227 if (u <= 0.0)
228 return 0.0;
229 if (u >= 1.0)
230 return Double.POSITIVE_INFINITY;
231
232 t = -Math.log1p(-u);
233 if (Math.log(t) / Math.log(10) >= alpha * Num.DBL_MAX_10_EXP)
234 throw new ArithmeticException("inverse function cannot be positive infinity");
235
236 return Math.pow(t, 1.0 / alpha) / lambda + delta;
237 }
238
242 public static double inverseF(double alpha, double x) {
243 return inverseF(alpha, 1.0, 0.0, x);
244 }
245
246 private static double[] getMaximumLikelihoodEstimate(double[] x, int n, double delta) {
247 if (n <= 0)
248 throw new IllegalArgumentException("n <= 0");
249 if (delta != 0.0)
250 throw new IllegalArgumentException("delta must be equal to 0");
251// Verifier cette fonction si delta != 0.
252
253 final double LN_EPS = Num.LN_DBL_MIN - Num.LN2;
254 double sumLn = 0.0;
255 double sumLn2 = 0.0;
256 double lnxi;
257 for (int i = 0; i < n; i++) {
258 if (x[i] <= delta)
259 lnxi = LN_EPS;
260 else
261 lnxi = Math.log(x[i]);
262 sumLn += lnxi;
263 sumLn2 += lnxi * lnxi;
264 }
265
266 double alpha0 = Math.sqrt((double) n / ((6.0 / (Math.PI * Math.PI)) * (sumLn2 - sumLn * sumLn / (double) n)));
267 double a = alpha0 - 20.0;
268 if (a <= delta)
269 a = delta + 1.0e-5;
270
271 double param[] = new double[3];
272 param[2] = 0.0;
273 Function f = new Function(x, n);
274 param[0] = RootFinder.brentDekker(a, alpha0 + 20.0, f, 1e-5);
275
276 double sumXalpha = 0.0;
277 for (int i = 0; i < n; i++)
278 sumXalpha += Math.pow(x[i], param[0]);
279 param[1] = Math.pow((double) n / sumXalpha, 1.0 / param[0]);
280
281 return param;
282 }
283
303 public static double[] getMLE(double[] x, int n) {
304 return getMaximumLikelihoodEstimate(x, n, 0.0);
305 }
306
316 public static WeibullDist getInstanceFromMLE(double[] x, int n) {
317 double param[] = getMLE(x, n);
318 return new WeibullDist(param[0], param[1], param[2]);
319 }
320
330 public static double getMean(double alpha, double lambda, double delta) {
331 if (alpha <= 0.0)
332 throw new IllegalArgumentException("alpha <= 0");
333 if (lambda <= 0.0)
334 throw new IllegalArgumentException("lambda <= 0");
335
336 return (delta + Math.exp(Num.lnGamma(1.0 + 1.0 / alpha)) / lambda);
337 }
338
349 public static double getVariance(double alpha, double lambda, double delta) {
350 double gAlpha;
351
352 if (alpha <= 0.0)
353 throw new IllegalArgumentException("alpha <= 0");
354 if (lambda <= 0.0)
355 throw new IllegalArgumentException("lambda <= 0");
356
357 gAlpha = Math.exp(Num.lnGamma(1.0 / alpha + 1.0));
358
359 return (Math.abs(Math.exp(Num.lnGamma(2 / alpha + 1)) - gAlpha * gAlpha) / (lambda * lambda));
360 }
361
368 public static double getStandardDeviation(double alpha, double lambda, double delta) {
369 return Math.sqrt(WeibullDist.getVariance(alpha, lambda, delta));
370 }
371
375 public double getAlpha() {
376 return alpha;
377 }
378
382 public double getLambda() {
383 return lambda;
384 }
385
389 public double getDelta() {
390 return delta;
391 }
392
397 public void setParams(double alpha, double lambda, double delta) {
398 if (alpha <= 0.0)
399 throw new IllegalArgumentException("alpha <= 0");
400 if (lambda <= 0.0)
401 throw new IllegalArgumentException("lambda <= 0");
402
403 this.alpha = alpha;
404 this.lambda = lambda;
405 this.delta = delta;
406 supportA = delta;
407 }
408
413 public double[] getParams() {
414 double[] retour = { alpha, lambda, delta };
415 return retour;
416 }
417
421 public String toString() {
422 return getClass().getSimpleName() + " : alpha = " + alpha + ", lambda = " + lambda + ", delta = " + delta;
423 }
424
425}
Classes implementing continuous distributions should inherit from this base class.
WeibullDist(double alpha)
Constructs a WeibullDist object with parameters = alpha, = 1, and = 0.
double getStandardDeviation()
Returns the standard deviation.
String toString()
Returns a String containing information about the current distribution.
static double getMean(double alpha, double lambda, double delta)
Computes and returns the mean of the Weibull distribution with parameters ,.
double getMean()
Returns the mean.
static double barF(double alpha, double x)
Same as barF (alpha, 1, 0, x).
WeibullDist(double alpha, double lambda, double delta)
Constructs a WeibullDist object with parameters alpha, = lambda, and = delta.
static double inverseF(double alpha, double lambda, double delta, double u)
Computes the inverse of the distribution function.
static WeibullDist getInstanceFromMLE(double[] x, int n)
Creates a new instance of a Weibull distribution with parameters.
static double barF(double alpha, double lambda, double delta, double x)
Computes the complementary distribution function.
double inverseF(double u)
Returns the inverse distribution function .
double getAlpha()
Returns the parameter .
static double getVariance(double alpha, double lambda, double delta)
Computes and returns the variance.
static double inverseF(double alpha, double x)
Same as inverseF (alpha, 1, 0, x).
double density(double x)
Returns , the density evaluated at .
double getVariance()
Returns the variance.
static double getStandardDeviation(double alpha, double lambda, double delta)
Computes and returns the standard deviation of the Weibull distribution with parameters ,...
static double[] getMLE(double[] x, int n)
Estimates the parameters of the Weibull distribution, assuming that , using the maximum likelihood m...
static double density(double alpha, double x)
Same as density (alpha, 1, 0, x).
double getDelta()
Returns the parameter .
double barF(double x)
Returns the complementary distribution function.
static double density(double alpha, double lambda, double delta, double x)
Computes the density function.
double getLambda()
Returns the parameter .
double cdf(double x)
Returns the distribution function .
double[] getParams()
Return a table containing the parameters of the current distribution.
static double cdf(double alpha, double x)
Same as cdf (alpha, 1, 0, x).
static double cdf(double alpha, double lambda, double delta, double x)
Computes the distribution function.
void setParams(double alpha, double lambda, double delta)
Sets the parameters , and for this object.
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static final double LN_DBL_MIN
Natural logarithm of DBL_MIN.
Definition Num.java:118
static double lnGamma(double x)
Returns the natural logarithm of the gamma function evaluated at x.
Definition Num.java:417
static final int DBL_MAX_10_EXP
Largest int such that is representable (approximately) as a double.
Definition Num.java:108
static final int DBL_MAX_EXP
Largest int such that is representable (approximately) as a double.
Definition Num.java:96
static final double LN2
The values of .
Definition Num.java:148
This interface should be implemented by classes which represent univariate mathematical functions.