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