SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
DistributionFactory.java
1/*
2 * Class: DistributionFactory
3 * Description: allows the creation of distribution objects from a string
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 java.lang.reflect.*;
28import java.util.StringTokenizer;
29
88 * @ingroup probdist_general
89 */
90public class DistributionFactory {
91 private DistributionFactory() {
92 } // ???? Utile?
93
94 public static Distribution getDistribution(String str) {
95 // Extracts the name of the distribution.
96 // If there is an open parenthesis, the name contains all the
97 // non-space characters preceeding it.If not,the name is the full string.
98
99 int i = 0;
100 str = str.trim();
101
102 int idx = str.indexOf('(', i);
103 String distName;
104 if (idx == -1)
105 distName = str.substring(i).trim();
106 else
107 distName = str.substring(i, idx).trim();
108
109 // Try to find the class in probdist package.
110 Class<?> distClass;
111 if (distName.equals("String"))
112 throw new IllegalArgumentException("Invalid distribution name: " + distName);
113 try {
114 distClass = Class.forName("umontreal.ssj.probdist." + distName);
115 } catch (ClassNotFoundException e) {
116 // Look for a fully qualified classname whose constructor
117 // matches this string.
118 try {
119 distClass = Class.forName(distName);
120 // We must check if the class implements Distribution
121 if (Distribution.class.isAssignableFrom(distClass) == false)
122 throw new IllegalArgumentException("The given class is not a Probdist distribution class.");
123 } catch (ClassNotFoundException ex) {
124 throw new IllegalArgumentException("Invalid distribution name: " + distName);
125 }
126 }
127
128 String paramStr = "";
129 if (idx != -1) {
130 // Get the parameters from the string.
131 int parFrom = idx;
132 int parTo = str.lastIndexOf(')');
133 // paramStr will contain the parameters without parentheses.
134 paramStr = str.substring(parFrom + 1, parTo).trim();
135 if (paramStr.indexOf('(') != -1 || paramStr.indexOf(')') != -1)
136 // All params are numerical,so parenthesis nesting is forbidden here
137 throw new IllegalArgumentException("Invalid parameter string: " + paramStr);
138 }
139
140 if (paramStr.equals("")) {
141 // No parameter is given to the constructor.
142 try {
143 return (Distribution) distClass.newInstance();
144 } catch (IllegalAccessException e) {
145 throw new IllegalArgumentException("Default parameters not available");
146 } catch (InstantiationException e) {
147 throw new IllegalArgumentException("Default parameters not available");
148 }
149 }
150
151 // Find the number of parameters and try to find a matching constructor.
152 // Within probdist, there are no constructors with the same
153 // number of arguments but with different types.
154 // This simplifies the constructor selection scheme.
155 StringTokenizer paramTok = new StringTokenizer(paramStr, ",");
156 int nparams = paramTok.countTokens();
157 Constructor[] cons = distClass.getConstructors();
158 Constructor<Distribution> distCons = null;
159 Class[] paramTypes = null;
160 // Find a public constructor with the correct number of parameters.
161 for (i = 0; i < cons.length; i++) {
162 if (Modifier.isPublic(cons[i].getModifiers())
163 && ((paramTypes = cons[i].getParameterTypes()).length == nparams)) {
164 distCons = cons[i];
165 break;
166 }
167 }
168 if (distCons == null)
169 throw new IllegalArgumentException("Invalid parameter number");
170
171 // Create the parameters for the selected constructor.
172 Object[] instParams = new Object[nparams];
173 for (i = 0; i < nparams; i++) {
174 String par = paramTok.nextToken().trim();
175 try {
176 // We only need a limited set of parameter types here.
177 if (paramTypes[i] == int.class)
178 instParams[i] = new Integer(par);
179 else if (paramTypes[i] == long.class)
180 instParams[i] = new Long(par);
181 else if (paramTypes[i] == float.class) {
182 if (par.equalsIgnoreCase("infinity") || par.equalsIgnoreCase("+infinity"))
183 instParams[i] = new Float(Float.POSITIVE_INFINITY);
184 else if (par.equalsIgnoreCase("-infinity"))
185 instParams[i] = new Float(Float.NEGATIVE_INFINITY);
186 else
187 instParams[i] = new Float(par);
188 } else if (paramTypes[i] == double.class) {
189 if (par.equalsIgnoreCase("infinity") || par.equalsIgnoreCase("+infinity"))
190 instParams[i] = new Double(Double.POSITIVE_INFINITY);
191 else if (par.equalsIgnoreCase("-infinity"))
192 instParams[i] = new Double(Double.NEGATIVE_INFINITY);
193 else
194 instParams[i] = new Double(par);
195 } else
196 throw new IllegalArgumentException(
197 "Parameter " + (i + 1) + " type " + paramTypes[i].getName() + "not supported");
198 } catch (NumberFormatException e) {
199 throw new IllegalArgumentException("Parameter " + (i + 1) + " of type " + paramTypes[i].getName()
200 + " could not be converted from String");
201 }
202 }
203
204 // Try to instantiate the distribution class.
205 try {
206 return (Distribution) distCons.newInstance(instParams);
207 } catch (IllegalAccessException e) {
208 return null;
209 } catch (InstantiationException e) {
210 return null;
211 } catch (InvocationTargetException e) {
212 return null;
213 }
214 }
215
239 */
240 @SuppressWarnings("unchecked")
241 public static ContinuousDistribution getDistributionMLE(String distName, double[] x, int n) {
242
243 Class<?> distClass;
244 try {
245 distClass = Class.forName("umontreal.ssj.probdist." + distName);
246 } catch (ClassNotFoundException e) {
247 try {
248 distClass = Class.forName(distName);
249 } catch (ClassNotFoundException ex) {
250 throw new IllegalArgumentException("Invalid distribution name: " + distName);
251 }
252 }
253
254 return getDistributionMLE((Class<? extends ContinuousDistribution>) distClass, x, n);
255 }
256
266 */
267 @SuppressWarnings("unchecked")
268 public static DiscreteDistributionInt getDistributionMLE(String distName, int[] x, int n) {
269
270 Class<?> distClass;
271 try {
272 distClass = Class.forName("umontreal.ssj.probdist." + distName);
273 } catch (ClassNotFoundException e) {
274 try {
275 distClass = Class.forName(distName);
276 } catch (ClassNotFoundException ex) {
277 throw new IllegalArgumentException("Invalid distribution name: " + distName);
278 }
279 }
280
281 return getDistributionMLE((Class<? extends DiscreteDistributionInt>) distClass, x, n);
282 }
283
293 */
294 @SuppressWarnings("unchecked")
295 public static <T extends ContinuousDistribution> T getDistributionMLE(Class<T> distClass, double[] x, int n) {
296 if (ContinuousDistribution.class.isAssignableFrom(distClass) == false)
297 throw new IllegalArgumentException("The given class is not a Probdist distribution class.");
298
299 Method m;
300 try {
301 m = distClass.getMethod("getInstanceFromMLE", double[].class, int.class);
302 } catch (NoSuchMethodException e) {
303 throw new IllegalArgumentException(
304 "The given class does not provide the static method getInstanceFromMLE (double[],int)");
305 }
306 if (!Modifier.isStatic(m.getModifiers()) || !distClass.isAssignableFrom(m.getReturnType()))
307 throw new IllegalArgumentException(
308 "The given class does not provide the static method getInstanceFromMLE (double[],int)");
309
310 try {
311 return (T) m.invoke(null, x, n);
312 } catch (IllegalAccessException e) {
313 return null;
314 } catch (IllegalArgumentException e) {
315 return null;
316 } catch (InvocationTargetException e) {
317 return null;
318 }
319 }
320
330 */
331 @SuppressWarnings("unchecked")
332 public static <T extends DiscreteDistributionInt> T getDistributionMLE(Class<T> distClass, int[] x, int n) {
333 if (DiscreteDistributionInt.class.isAssignableFrom(distClass) == false)
334 throw new IllegalArgumentException("The given class is not a discrete distribution class over integers.");
335
336 Method m;
337 try {
338 m = distClass.getMethod("getInstanceFromMLE", int[].class, int.class);
339 } catch (NoSuchMethodException e) {
340 throw new IllegalArgumentException(
341 "The given class does not provide the static method getInstanceFromMLE (int[],int)");
342 }
343 if (!Modifier.isStatic(m.getModifiers()) || !distClass.isAssignableFrom(m.getReturnType()))
344 throw new IllegalArgumentException(
345 "The given class does not provide the static method getInstanceFromMLE (int[],int)");
346
347 try {
348 return (T) m.invoke(null, x, n);
349 } catch (IllegalAccessException e) {
350 return null;
351 } catch (IllegalArgumentException e) {
352 return null;
353 } catch (InvocationTargetException e) {
354 return null;
355 }
356 }
357
375 * represent a continuous distribution
376 */
377 public static ContinuousDistribution getContinuousDistribution(String str) {
378 return (ContinuousDistribution) getDistribution(str);
379 }
380
393 * represent a discrete distribution
394 */
395 public static DiscreteDistribution getDiscreteDistribution(String str) {
396 return (DiscreteDistribution) getDistribution(str);
397 }
398
411 * represent a discrete distribution
412 */
413 public static DiscreteDistributionInt getDiscreteDistributionInt(String str) {
414 return (DiscreteDistributionInt) getDistribution(str);
415 }
416}
Classes implementing continuous distributions should inherit from this base class.
Classes implementing discrete distributions over the integers should inherit from this class.
This class implements discrete distributions over a finite set of real numbers (also over integers as...
static ContinuousDistribution getContinuousDistribution(String str)
Uses the Java Reflection API to construct a.
static ContinuousDistribution getDistributionMLE(String distName, double[] x, int n)
Uses the Java Reflection API to construct a ContinuousDistribution ,.
static DiscreteDistributionInt getDiscreteDistributionInt(String str)
Same as getContinuousDistribution, but for discrete distributions over the integers.
static DiscreteDistribution getDiscreteDistribution(String str)
Same as getContinuousDistribution, but for discrete distributions over the real numbers.
This interface should be implemented by all classes supporting discrete and continuous distributions.