SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
HypoExponentialDistQuick.java
1/*
2 * Class: HypoExponentialDistQuick
3 * Description: Hypo-exponential 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 Richard Simard
9 * @since January 2011
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 java.util.Formatter;
28import java.util.Locale;
29import umontreal.ssj.util.*;
30import umontreal.ssj.functions.MathFunction;
31
83 private double[] m_H;
84
85 private static double[] computeH(double[] lambda) {
86 int k = lambda.length;
87 double[] H = new double[k];
88 double tem;
89 int j;
90 for (int i = 0; i < k; i++) {
91 tem = 1.0;
92 for (j = 0; j < i; j++)
93 tem *= lambda[j] / (lambda[j] - lambda[i]);
94 for (j = i + 1; j < k; j++)
95 tem *= lambda[j] / (lambda[j] - lambda[i]);
96 H[i] = tem;
97 }
98 return H;
99 }
100
101 private static double m_density(double[] lambda, double[] H, double x) {
102 if (x < 0)
103 return 0;
104
105 int k = lambda.length;
106 double tem;
107 double prob = 0;
108 for (int j = 0; j < k; j++) {
109 tem = Math.exp(-lambda[j] * x);
110 if (tem > 0)
111 prob += lambda[j] * H[j] * tem;
112 }
113
114 return prob;
115 }
116
117 private static double m_barF(double[] lambda, double[] H, double x) {
118 if (x <= 0.)
119 return 1.;
120
121 int k = lambda.length;
122 double tem;
123 double prob = 0; // probability
124 for (int j = 0; j < k; j++) {
125 tem = Math.exp(-lambda[j] * x);
126 if (tem > 0)
127 prob += H[j] * tem;
128 }
129 return prob;
130 }
131
132 private static double m_cdf(double[] lambda, double[] H, double x) {
133 if (x <= 0.)
134 return 0.;
135
136 int k = lambda.length;
137 double tem = Math.exp(-lambda[0] * x);
138 if (tem <= 0)
139 return 1.0 - HypoExponentialDistQuick.m_barF(lambda, H, x);
140
141 double prob = 0; // cumulative probability
142 for (int j = 0; j < k; j++) {
143 tem = Math.expm1(-lambda[j] * x);
144 prob += H[j] * tem;
145 }
146 return -prob;
147 }
148
149 private static class myFunc implements MathFunction {
150 // For inverseF
151 private double[] m_lam;
152 private double m_u;
153
154 public myFunc(double[] lam, double u) {
155 m_lam = lam;
156 m_u = u;
157 }
158
159 public double evaluate(double x) {
160 return m_u - HypoExponentialDistQuick.cdf(m_lam, x);
161 }
162 }
163
170 public HypoExponentialDistQuick(double[] lambda) {
171 super(lambda);
172 }
173
174 /*
175 * These public methods are necessary so that methods cdf, barF and inverseF
176 * used are those of the present class and not those of the mother class.
177 */
178 public double density(double x) {
179 return m_density(m_lambda, m_H, x);
180 }
181
182 public double cdf(double x) {
183 return m_cdf(m_lambda, m_H, x);
184 }
185
186 public double barF(double x) {
187 return m_barF(m_lambda, m_H, x);
188 }
189
190 public double inverseF(double u) {
191 return m_inverseF(m_lambda, m_H, u);
192 }
193
202 public static double density(double[] lambda, double x) {
203 testLambda(lambda);
204 double[] H = computeH(lambda);
205 return m_density(lambda, H, x);
206 }
207
216 public static double cdf(double[] lambda, double x) {
217 testLambda(lambda);
218 double[] H = computeH(lambda);
219 return m_cdf(lambda, H, x);
220 }
221
230 public static double barF(double[] lambda, double x) {
231 testLambda(lambda);
232 double[] H = computeH(lambda);
233 return m_barF(lambda, H, x);
234 }
235
244 public static double inverseF(double[] lambda, double u) {
245 testLambda(lambda);
246 double[] H = computeH(lambda);
247 return m_inverseF(lambda, H, u);
248 }
249
250 private static double m_inverseF(double[] lambda, double[] H, double u) {
251 if (u < 0.0 || u > 1.0)
252 throw new IllegalArgumentException("u not in [0,1]");
253 if (u >= 1.0)
254 return Double.POSITIVE_INFINITY;
255 if (u <= 0.0)
256 return 0.0;
257
258 final double EPS = 1.0e-12;
259 myFunc fonc = new myFunc(lambda, u);
260 double x1 = getMean(lambda);
261 double v = m_cdf(lambda, H, x1);
262 if (u <= v)
263 return RootFinder.brentDekker(0, x1, fonc, EPS);
264
265 // u > v
266 double x2 = 4.0 * x1 + 1.0;
267 v = m_cdf(lambda, H, x2);
268 while (v < u) {
269 x1 = x2;
270 x2 = 4.0 * x2;
271 v = m_cdf(lambda, H, x2);
272 }
273 return RootFinder.brentDekker(x1, x2, fonc, EPS);
274 }
275
276 public void setLambda(double[] lambda) {
277 if (lambda == null)
278 return;
279 super.setLambda(lambda);
280 m_H = computeH(lambda);
281 }
282
283 public String toString() {
284 StringBuilder sb = new StringBuilder();
285 Formatter formatter = new Formatter(sb, Locale.US);
286 formatter.format(getClass().getSimpleName() + " : lambda = {" + PrintfFormat.NEWLINE);
287 int k = m_lambda.length;
288 for (int i = 0; i < k; i++) {
289 formatter.format(" %f%n", m_lambda[i]);
290 }
291 formatter.format("}%n");
292 return sb.toString();
293 }
294}
String toString()
Returns a String containing information about the current distribution.
static double inverseF(double[] lambda, double u)
Computes the inverse distribution function , with.
double inverseF(double u)
Returns the inverse distribution function .
double density(double x)
Returns , the density evaluated at .
double cdf(double x)
Returns the distribution function .
static double density(double[] lambda, double x)
Computes the density function , with lambda[ ], .
double barF(double x)
Returns the complementary distribution function.
static double cdf(double[] lambda, double x)
Computes the distribution function , with lambda[ ], .
void setLambda(double[] lambda)
Sets the values lambda[ ], for this object.
static double barF(double[] lambda, double x)
Computes the complementary distribution , with.
HypoExponentialDistQuick(double[] lambda)
Constructs a HypoExponentialDistQuick object, with rates.
HypoExponentialDist(double[] lambda)
Constructs a HypoExponentialDist object, with rates lambda[ ], .
This class acts like a StringBuffer which defines new types of append methods.
static final String NEWLINE
End-of-line symbol or line separator.
This class provides numerical methods to solve non-linear equations.
static double brentDekker(double a, double b, MathFunction f, double tol)
Computes a root of the function in f using the Brent-Dekker method.
This interface should be implemented by classes which represent univariate mathematical functions.