View Javadoc
1   package org.opentrafficsim.core.network.factory.xml.units;
2   
3   import org.djunits.unit.DurationUnit;
4   import org.djunits.unit.LengthUnit;
5   import org.djunits.unit.PositionUnit;
6   import org.djunits.unit.SpeedUnit;
7   import org.djunits.unit.TimeUnit;
8   import org.djunits.value.vdouble.scalar.Duration;
9   import org.djunits.value.vdouble.scalar.Length;
10  import org.djunits.value.vdouble.scalar.Position;
11  import org.djunits.value.vdouble.scalar.Speed;
12  import org.djunits.value.vdouble.scalar.Time;
13  import org.opentrafficsim.core.dsol.DistNormalTrunc;
14  import org.opentrafficsim.core.network.NetworkException;
15  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
16  
17  import nl.tudelft.simulation.jstats.distributions.DistBeta;
18  import nl.tudelft.simulation.jstats.distributions.DistConstant;
19  import nl.tudelft.simulation.jstats.distributions.DistContinuous;
20  import nl.tudelft.simulation.jstats.distributions.DistErlang;
21  import nl.tudelft.simulation.jstats.distributions.DistExponential;
22  import nl.tudelft.simulation.jstats.distributions.DistGamma;
23  import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
24  import nl.tudelft.simulation.jstats.distributions.DistNormal;
25  import nl.tudelft.simulation.jstats.distributions.DistPearson5;
26  import nl.tudelft.simulation.jstats.distributions.DistPearson6;
27  import nl.tudelft.simulation.jstats.distributions.DistTriangular;
28  import nl.tudelft.simulation.jstats.distributions.DistUniform;
29  import nl.tudelft.simulation.jstats.distributions.DistWeibull;
30  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
31  import nl.tudelft.simulation.jstats.streams.StreamInterface;
32  
33  /**
34   * <p>
35   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
36   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
37   * <p>
38   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
39   * initial version Jul 23, 2015 <br>
40   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
41   */
42  public final class Distributions
43  {
44      /** Utility class. */
45      private Distributions()
46      {
47          // do not instantiate
48      }
49  
50      /** TODO include in GLOBAL tag. */
51      private static final StreamInterface STREAM = new MersenneTwister(2L);
52  
53      /**
54       * parse a set of comma-separated values, e.g., <code>10.0, 4, 5.23</code>.
55       * @param s String; the string to parse.
56       * @return array of double values.
57       */
58      private static double[] parseDoubleArgs(final String s)
59      {
60          String[] ss = s.split(",");
61          double[] d = new double[ss.length];
62          for (int i = 0; i < ss.length; i++)
63          {
64              d[i] = Double.parseDouble(ss[i]);
65          }
66          return d;
67      }
68  
69      /**
70       * Parse a continuous distribution.
71       * @param ds String; the name of the distribution, e.g. UNIF.
72       * @param args double[]; the parameters of the distribution, e.g. {1.0, 2.0}.
73       * @return the generated distribution.
74       * @throws NetworkException in case distribution unknown or parameter number does not match.
75       */
76      private static DistContinuous makeDistContinuous(final String ds, final double[] args) throws NetworkException
77      {
78          try
79          {
80              switch (ds)
81              {
82                  case "CONST":
83                  case "CONSTANT":
84                      return new DistConstant(STREAM, args[0]);
85  
86                  case "EXPO":
87                  case "EXPONENTIAL":
88                      return new DistExponential(STREAM, args[0]);
89  
90                  case "TRIA":
91                  case "TRIANGULAR":
92                      return new DistTriangular(STREAM, args[0], args[1], args[2]);
93  
94                  case "NORM":
95                  case "NORMAL":
96                      return new DistNormal(STREAM, args[0], args[1]);
97  
98                  case "NORMTRUNC":
99                  case "NORMALTRUNCATED":
100                     return new DistNormalTrunc(STREAM, args[0], args[1], args[2], args[3]);
101 
102                 case "BETA":
103                     return new DistBeta(STREAM, args[0], args[1]);
104 
105                 case "ERLANG":
106                     return new DistErlang(STREAM, (int) args[0], args[1]);
107 
108                 case "GAMMA":
109                     return new DistGamma(STREAM, args[0], args[1]);
110 
111                 case "LOGN":
112                 case "LOGNORMAL":
113                     return new DistLogNormal(STREAM, args[0], args[1]);
114 
115                 case "PEARSON5":
116                     return new DistPearson5(STREAM, args[0], args[1]);
117 
118                 case "PEARSON6":
119                     return new DistPearson6(STREAM, args[0], args[1], args[2]);
120 
121                 case "UNIF":
122                 case "UNIFORM":
123                     return new DistUniform(STREAM, args[0], args[1]);
124 
125                 case "WEIB":
126                 case "WEIBULL":
127                     return new DistWeibull(STREAM, args[0], args[1]);
128 
129                 default:
130                     throw new NetworkException("makeDistContinuous - unknown distribution function " + ds);
131             }
132         }
133         catch (IndexOutOfBoundsException e)
134         {
135             throw new NetworkException("makeDistContinuous - wrong number of parameters for distribution function " + ds);
136         }
137     }
138 
139     /**
140      * Parse a relative length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
141      * @param s String; the string to be parsed.
142      * @return a typed continuous random distribution.
143      * @throws NetworkException in case of a parse error.
144      */
145     public static ContinuousDistDoubleScalar.Rel<Length, LengthUnit> parseLengthDist(final String s) throws NetworkException
146     {
147         String[] s1 = s.split("\\(");
148         String ds = s1[0];
149         String[] s2 = s1[1].split("\\)");
150         String unit = LengthUnits.parseLengthUnit(s2[1]);
151         double[] args = parseDoubleArgs(s2[0]);
152         DistContinuous dist = makeDistContinuous(ds, args);
153         return new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(dist, LengthUnits.LENGTH_UNITS.get(unit));
154     }
155 
156     /**
157      * Parse an absolute length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
158      * @param s String; the string to be parsed.
159      * @return a typed continuous random distribution.
160      * @throws NetworkException in case of a parse error.
161      */
162     public static ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit> parsePositionDist(final String s)
163             throws NetworkException
164     {
165         String[] s1 = s.split("\\(");
166         String ds = s1[0];
167         String[] s2 = s1[1].split("\\)");
168         String unit = LengthUnits.parseLengthUnit(s2[1]);
169         double[] args = parseDoubleArgs(s2[0]);
170         DistContinuous dist = makeDistContinuous(ds, args);
171         return new ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit>(dist,
172                 PositionUnits.POSITION_UNITS.get(unit));
173     }
174 
175     /**
176      * Parse a relative time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
177      * @param s String; the string to be parsed.
178      * @return a typed continuous random distribution.
179      * @throws NetworkException in case of a parse error.
180      */
181     public static ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> parseDurationDist(final String s)
182             throws NetworkException
183     {
184         String[] s1 = s.split("\\(");
185         String ds = s1[0];
186         String[] s2 = s1[1].split("\\)");
187         String unit = DurationUnits.parseDurationUnit(s2[1]);
188         double[] args = parseDoubleArgs(s2[0]);
189         DistContinuous dist = makeDistContinuous(ds, args);
190         return new ContinuousDistDoubleScalar.Rel<Duration, DurationUnit>(dist, DurationUnits.DURATION_UNITS.get(unit));
191     }
192 
193     /**
194      * Parse an absolute time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
195      * @param s String; the string to be parsed.
196      * @return a typed continuous random distribution.
197      * @throws NetworkException in case of a parse error.
198      */
199     public static ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit> parseTimeDist(final String s)
200             throws NetworkException
201     {
202         String[] s1 = s.split("\\(");
203         String ds = s1[0];
204         String[] s2 = s1[1].split("\\)");
205         String unit = TimeUnits.parseTimeUnit(s2[1]);
206         double[] args = parseDoubleArgs(s2[0]);
207         DistContinuous dist = makeDistContinuous(ds, args);
208         return new ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit>(dist, TimeUnits.TIME_UNITS.get(unit));
209     }
210 
211     /**
212      * Parse a relative speed distribution, e.g. <code>TRIANGULAR(80, 90, 110) km/h</code>.
213      * @param s String; the string to be parsed.
214      * @return a typed continuous random distribution.
215      * @throws NetworkException in case of a parse error.
216      */
217     public static ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> parseSpeedDist(final String s) throws NetworkException
218     {
219         String[] s1 = s.split("\\(");
220         String ds = s1[0];
221         String[] s2 = s1[1].split("\\)");
222         String unit = SpeedUnits.parseSpeedUnit(s2[1]);
223         double[] args = parseDoubleArgs(s2[0]);
224         DistContinuous dist = makeDistContinuous(ds, args);
225         return new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(dist, SpeedUnits.SPEED_UNITS.get(unit));
226     }
227 
228 }