View Javadoc
1   package org.opentrafficsim.road.network.factory.xml.utils;
2   
3   import java.util.Map;
4   
5   import org.djunits.unit.AccelerationUnit;
6   import org.djunits.unit.DurationUnit;
7   import org.djunits.unit.FrequencyUnit;
8   import org.djunits.unit.LengthUnit;
9   import org.djunits.unit.LinearDensityUnit;
10  import org.djunits.unit.PositionUnit;
11  import org.djunits.unit.SpeedUnit;
12  import org.djunits.unit.TimeUnit;
13  import org.djunits.unit.Unit;
14  import org.djunits.value.vdouble.scalar.Acceleration;
15  import org.djunits.value.vdouble.scalar.Duration;
16  import org.djunits.value.vdouble.scalar.Frequency;
17  import org.djunits.value.vdouble.scalar.Length;
18  import org.djunits.value.vdouble.scalar.LinearDensity;
19  import org.djunits.value.vdouble.scalar.Position;
20  import org.djunits.value.vdouble.scalar.Speed;
21  import org.djunits.value.vdouble.scalar.Time;
22  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
23  import org.opentrafficsim.road.network.factory.xml.XmlParserException;
24  import org.opentrafficsim.xml.generated.ACCELERATIONDISTTYPE;
25  import org.opentrafficsim.xml.generated.CONTDISTTYPE;
26  import org.opentrafficsim.xml.generated.DISCRETEDISTTYPE;
27  import org.opentrafficsim.xml.generated.DURATIONDISTTYPE;
28  import org.opentrafficsim.xml.generated.FREQUENCYDISTTYPE;
29  import org.opentrafficsim.xml.generated.LENGTHDISTTYPE;
30  import org.opentrafficsim.xml.generated.LINEARDENSITYDISTTYPE;
31  import org.opentrafficsim.xml.generated.POSITIONDISTTYPE;
32  import org.opentrafficsim.xml.generated.SPEEDDISTTYPE;
33  import org.opentrafficsim.xml.generated.TIMEDISTTYPE;
34  
35  import nl.tudelft.simulation.jstats.distributions.DistBernoulli;
36  import nl.tudelft.simulation.jstats.distributions.DistBeta;
37  import nl.tudelft.simulation.jstats.distributions.DistBinomial;
38  import nl.tudelft.simulation.jstats.distributions.DistConstant;
39  import nl.tudelft.simulation.jstats.distributions.DistContinuous;
40  import nl.tudelft.simulation.jstats.distributions.DistDiscrete;
41  import nl.tudelft.simulation.jstats.distributions.DistDiscreteConstant;
42  import nl.tudelft.simulation.jstats.distributions.DistDiscreteUniform;
43  import nl.tudelft.simulation.jstats.distributions.DistErlang;
44  import nl.tudelft.simulation.jstats.distributions.DistExponential;
45  import nl.tudelft.simulation.jstats.distributions.DistGamma;
46  import nl.tudelft.simulation.jstats.distributions.DistGeometric;
47  import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
48  import nl.tudelft.simulation.jstats.distributions.DistNegBinomial;
49  import nl.tudelft.simulation.jstats.distributions.DistNormal;
50  import nl.tudelft.simulation.jstats.distributions.DistPearson5;
51  import nl.tudelft.simulation.jstats.distributions.DistPearson6;
52  import nl.tudelft.simulation.jstats.distributions.DistPoisson;
53  import nl.tudelft.simulation.jstats.distributions.DistTriangular;
54  import nl.tudelft.simulation.jstats.distributions.DistUniform;
55  import nl.tudelft.simulation.jstats.distributions.DistWeibull;
56  import nl.tudelft.simulation.jstats.streams.StreamInterface;
57  
58  /**
59   * Parse a distribution from text to a distribution.
60   * <p>
61   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
62   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
63   * <p>
64   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
65   * initial version Jul 23, 2015 <br>
66   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
67   */
68  public final class ParseDistribution
69  {
70      /** Utility class. */
71      private ParseDistribution()
72      {
73          // do not instantiate
74      }
75  
76      /**
77       * Parse a discrete distribution.
78       * @param streamMap map with stream information
79       * @param distType the distribution to parse
80       * @return the generated distribution.
81       * @throws XmlParserException in case distribution unknown or parameter number does not match.
82       */
83      public static DistDiscrete makeDistDiscrete(final Map<String, StreamInformation> streamMap, final DISCRETEDISTTYPE distType)
84              throws XmlParserException
85      {
86          if (distType.getBERNOULLI() != null)
87          {
88              StreamInterface stream = findStream(streamMap, distType.getBERNOULLI().getRANDOMSTREAM());
89              return new DistBernoulli(stream, distType.getBERNOULLI().getP());
90          }
91          else if (distType.getBINOMIAL() != null)
92          {
93              StreamInterface stream = findStream(streamMap, distType.getBINOMIAL().getRANDOMSTREAM());
94              return new DistBinomial(stream, distType.getBINOMIAL().getN().longValue(), distType.getBINOMIAL().getP());
95          }
96          else if (distType.getCONSTANT() != null)
97          {
98              StreamInterface stream = findStream(streamMap, distType.getCONSTANT().getRANDOMSTREAM());
99              return new DistDiscreteConstant(stream, distType.getCONSTANT().getC());
100         }
101         else if (distType.getGEOMETRIC() != null)
102         {
103             StreamInterface stream = findStream(streamMap, distType.getGEOMETRIC().getRANDOMSTREAM());
104             return new DistGeometric(stream, distType.getGEOMETRIC().getP());
105         }
106         else if (distType.getNEGBINOMIAL() != null)
107         {
108             StreamInterface stream = findStream(streamMap, distType.getNEGBINOMIAL().getRANDOMSTREAM());
109             return new DistNegBinomial(stream, distType.getNEGBINOMIAL().getN().longValue(), distType.getGEOMETRIC().getP());
110         }
111         else if (distType.getPOISSON() != null)
112         {
113             StreamInterface stream = findStream(streamMap, distType.getPOISSON().getRANDOMSTREAM());
114             return new DistPoisson(stream, distType.getPOISSON().getLAMBDA());
115         }
116         else if (distType.getUNIFORM() != null)
117         {
118             StreamInterface stream = findStream(streamMap, distType.getUNIFORM().getRANDOMSTREAM());
119             return new DistDiscreteUniform(stream, distType.getUNIFORM().getMIN(), distType.getUNIFORM().getMAX());
120         }
121         throw new XmlParserException("makeDistDiscrete - unknown distribution function " + distType);
122     }
123 
124     /**
125      * Parse a continuous distribution.
126      * @param streamMap map with stream information
127      * @param distType the distribution to parse
128      * @return the generated distribution.
129      * @throws XmlParserException in case distribution unknown or parameter number does not match.
130      */
131     public static DistContinuous makeDistContinuous(final Map<String, StreamInformation> streamMap, final CONTDISTTYPE distType)
132             throws XmlParserException
133     {
134         if (distType.getCONSTANT() != null)
135         {
136             StreamInterface stream = findStream(streamMap, distType.getCONSTANT().getRANDOMSTREAM());
137             return new DistConstant(stream, distType.getCONSTANT().getC());
138         }
139         else if (distType.getEXPONENTIAL() != null)
140         {
141             StreamInterface stream = findStream(streamMap, distType.getEXPONENTIAL().getRANDOMSTREAM());
142             return new DistExponential(stream, distType.getEXPONENTIAL().getLAMBDA());
143         }
144         else if (distType.getTRIANGULAR() != null)
145         {
146             StreamInterface stream = findStream(streamMap, distType.getTRIANGULAR().getRANDOMSTREAM());
147             return new DistTriangular(stream, distType.getTRIANGULAR().getMIN(), distType.getTRIANGULAR().getMODE(),
148                     distType.getTRIANGULAR().getMAX());
149         }
150         else if (distType.getNORMAL() != null)
151         {
152             StreamInterface stream = findStream(streamMap, distType.getNORMAL().getRANDOMSTREAM());
153             return new DistNormal(stream, distType.getNORMAL().getMU(), distType.getNORMAL().getSIGMA());
154         }
155         // TODO: NORMALTRUNC
156         else if (distType.getBETA() != null)
157         {
158             StreamInterface stream = findStream(streamMap, distType.getBETA().getRANDOMSTREAM());
159             return new DistBeta(stream, distType.getBETA().getALPHA1(), distType.getBETA().getALPHA2());
160         }
161         else if (distType.getERLANG() != null)
162         {
163             StreamInterface stream = findStream(streamMap, distType.getERLANG().getRANDOMSTREAM());
164             return new DistErlang(stream, distType.getERLANG().getK().intValue(), distType.getERLANG().getMEAN());
165         }
166         else if (distType.getGAMMA() != null)
167         {
168             StreamInterface stream = findStream(streamMap, distType.getGAMMA().getRANDOMSTREAM());
169             return new DistGamma(stream, distType.getGAMMA().getALPHA(), distType.getGAMMA().getBETA());
170         }
171         else if (distType.getLOGNORMAL() != null)
172         {
173             StreamInterface stream = findStream(streamMap, distType.getLOGNORMAL().getRANDOMSTREAM());
174             return new DistLogNormal(stream, distType.getLOGNORMAL().getMU(), distType.getLOGNORMAL().getSIGMA());
175         }
176         else if (distType.getPEARSON5() != null)
177         {
178             StreamInterface stream = findStream(streamMap, distType.getPEARSON5().getRANDOMSTREAM());
179             return new DistPearson5(stream, distType.getPEARSON5().getALPHA(), distType.getPEARSON5().getBETA());
180         }
181         else if (distType.getPEARSON6() != null)
182         {
183             StreamInterface stream = findStream(streamMap, distType.getPEARSON6().getRANDOMSTREAM());
184             return new DistPearson6(stream, distType.getPEARSON6().getALPHA1(), distType.getPEARSON6().getALPHA2(),
185                     distType.getPEARSON6().getBETA());
186         }
187         else if (distType.getUNIFORM() != null)
188         {
189             StreamInterface stream = findStream(streamMap, distType.getUNIFORM().getRANDOMSTREAM());
190             return new DistUniform(stream, distType.getUNIFORM().getMIN(), distType.getUNIFORM().getMAX());
191         }
192         else if (distType.getWEIBULL() != null)
193         {
194             StreamInterface stream = findStream(streamMap, distType.getWEIBULL().getRANDOMSTREAM());
195             return new DistWeibull(stream, distType.getWEIBULL().getALPHA(), distType.getWEIBULL().getBETA());
196         }
197         throw new XmlParserException("makeDistContinuous - unknown distribution function " + distType);
198     }
199 
200     /**
201      * Find and return the stream belonging to te streamId.
202      * @param streamMap the map with streams from the RUN tag
203      * @param streamId the id to search for
204      * @return the stream belonging to te streamId
205      * @throws XmlParserException when the stream could not be found
206      */
207     private static StreamInterface findStream(final Map<String, StreamInformation> streamMap, final String streamId)
208             throws XmlParserException
209     {
210         StreamInformation streamInformation = streamMap.get(streamId);
211         if (streamInformation == null)
212         {
213             throw new XmlParserException("Could not find stream with ID=" + streamId);
214         }
215         return streamInformation.getStream();
216     }
217 
218     /**
219      * Parse a relative length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
220      * @param streamMap the map with streams from the RUN tag
221      * @param lengthDist the tag to parse
222      * @return a typed continuous random distribution.
223      * @throws XmlParserException in case of a parse error.
224      */
225     public static ContinuousDistDoubleScalar.Rel<Length, LengthUnit> parseLengthDist(
226             final Map<String, StreamInformation> streamMap, final LENGTHDISTTYPE lengthDist) throws XmlParserException
227     {
228         DistContinuous dist = makeDistContinuous(streamMap, lengthDist);
229         for (LengthUnit unit : Unit.getUnits(LengthUnit.class))
230         {
231             if (unit.getDefaultLocaleTextualRepresentations().contains(lengthDist.getLENGTHUNIT()))
232             {
233                 return new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(dist, unit);
234             }
235         }
236         throw new XmlParserException(
237                 "Could not find LengthUnit " + lengthDist.getLENGTHUNIT() + " in tag of type LENGTHDISTTYPE");
238     }
239 
240     /**
241      * Parse an absolute position distribution, e.g. <code>UNIFORM(1, 3) m</code>.
242      * @param streamMap the map with streams from the RUN tag
243      * @param positionDist the tag to parse
244      * @return a typed continuous random distribution.
245      * @throws XmlParserException in case of a parse error.
246      */
247     public static ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit> parsePositionDist(
248             final Map<String, StreamInformation> streamMap, final POSITIONDISTTYPE positionDist) throws XmlParserException
249     {
250         DistContinuous dist = makeDistContinuous(streamMap, positionDist);
251         for (PositionUnit unit : Unit.getUnits(PositionUnit.class))
252         {
253             if (unit.getDefaultLocaleTextualRepresentations().contains(positionDist.getPOSITIONUNIT()))
254             {
255                 return new ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit>(dist, unit);
256             }
257         }
258         throw new XmlParserException(
259                 "Could not find PositionUnit " + positionDist.getPOSITIONUNIT() + " in tag of type POSITIONDISTTYPE");
260     }
261 
262     /**
263      * Parse a relative duration distribution, e.g. <code>UNIFORM(1, 3) s</code>.
264      * @param streamMap the map with streams from the RUN tag
265      * @param durationDist the tag to parse
266      * @return a typed continuous random distribution.
267      * @throws XmlParserException in case of a parse error.
268      */
269     public static ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> parseDurationDist(
270             final Map<String, StreamInformation> streamMap, final DURATIONDISTTYPE durationDist) throws XmlParserException
271     {
272         DistContinuous dist = makeDistContinuous(streamMap, durationDist);
273         for (DurationUnit unit : Unit.getUnits(DurationUnit.class))
274         {
275             if (unit.getDefaultLocaleTextualRepresentations().contains(durationDist.getDURATIONUNIT()))
276             {
277                 return new ContinuousDistDoubleScalar.Rel<Duration, DurationUnit>(dist, unit);
278             }
279         }
280         throw new XmlParserException(
281                 "Could not find DurationUnit " + durationDist.getDURATIONUNIT() + " in tag of type DURATIONDISTTYPE");
282     }
283 
284     /**
285      * Parse an absolute time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
286      * @param streamMap the map with streams from the RUN tag
287      * @param timeDist the tag to parse
288      * @return a typed continuous random distribution.
289      * @throws XmlParserException in case of a parse error.
290      */
291     public static ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit> parseTimeDist(
292             final Map<String, StreamInformation> streamMap, final TIMEDISTTYPE timeDist) throws XmlParserException
293     {
294         DistContinuous dist = makeDistContinuous(streamMap, timeDist);
295         for (TimeUnit unit : Unit.getUnits(TimeUnit.class))
296         {
297             if (unit.getDefaultLocaleTextualRepresentations().contains(timeDist.getTIMEUNIT()))
298             {
299                 return new ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit>(dist, unit);
300             }
301         }
302         throw new XmlParserException("Could not find TimeUnit " + timeDist.getTIMEUNIT() + " in tag of type TIMEDISTTYPE");
303     }
304 
305     /**
306      * Parse a relative speed distribution, e.g. <code>UNIFORM(1, 3) m/s</code>.
307      * @param streamMap the map with streams from the RUN tag
308      * @param speedDist the tag to parse
309      * @return a typed continuous random distribution.
310      * @throws XmlParserException in case of a parse error.
311      */
312     public static ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> parseSpeedDist(
313             final Map<String, StreamInformation> streamMap, final SPEEDDISTTYPE speedDist) throws XmlParserException
314     {
315         DistContinuous dist = makeDistContinuous(streamMap, speedDist);
316         for (SpeedUnit unit : Unit.getUnits(SpeedUnit.class))
317         {
318             if (unit.getDefaultLocaleTextualRepresentations().contains(speedDist.getSPEEDUNIT()))
319             {
320                 return new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(dist, unit);
321             }
322         }
323         throw new XmlParserException("Could not find SpeedUnit " + speedDist.getSPEEDUNIT() + " in tag of type SPEEDDISTTYPE");
324     }
325 
326     /**
327      * Parse a relative acceleration distribution, e.g. <code>UNIFORM(1, 3) s</code>.
328      * @param streamMap the map with streams from the RUN tag
329      * @param accelerationDist the tag to parse
330      * @return a typed continuous random distribution.
331      * @throws XmlParserException in case of a parse error.
332      */
333     public static ContinuousDistDoubleScalar.Rel<Acceleration, AccelerationUnit> parseAccelerationDist(
334             final Map<String, StreamInformation> streamMap, final ACCELERATIONDISTTYPE accelerationDist)
335             throws XmlParserException
336     {
337         DistContinuous dist = makeDistContinuous(streamMap, accelerationDist);
338         for (AccelerationUnit unit : Unit.getUnits(AccelerationUnit.class))
339         {
340             if (unit.getDefaultLocaleTextualRepresentations().contains(accelerationDist.getACCELERATIONUNIT()))
341             {
342                 return new ContinuousDistDoubleScalar.Rel<Acceleration, AccelerationUnit>(dist, unit);
343             }
344         }
345         throw new XmlParserException("Could not find AccelerationUnit " + accelerationDist.getACCELERATIONUNIT()
346                 + " in tag of type ACCELERATIONDISTTYPE");
347     }
348 
349     /**
350      * Parse a relative frequency distribution, e.g. <code>UNIFORM(1, 3) s</code>.
351      * @param streamMap the map with streams from the RUN tag
352      * @param frequencyDist the tag to parse
353      * @return a typed continuous random distribution.
354      * @throws XmlParserException in case of a parse error.
355      */
356     public static ContinuousDistDoubleScalar.Rel<Frequency, FrequencyUnit> parseFrequencyDist(
357             Map<String, StreamInformation> streamMap, FREQUENCYDISTTYPE frequencyDist) throws XmlParserException
358     {
359         DistContinuous dist = makeDistContinuous(streamMap, frequencyDist);
360         for (FrequencyUnit unit : Unit.getUnits(FrequencyUnit.class))
361         {
362             if (unit.getDefaultLocaleTextualRepresentations().contains(frequencyDist.getFREQUENCYUNIT()))
363             {
364                 return new ContinuousDistDoubleScalar.Rel<Frequency, FrequencyUnit>(dist, unit);
365             }
366         }
367         throw new XmlParserException(
368                 "Could not find FrequencyUnit " + frequencyDist.getFREQUENCYUNIT() + " in tag of type FREQUENCYDISTTYPE");
369     }
370 
371     /**
372      * Parse a relative linear density distribution, e.g. <code>UNIFORM(1, 3) s</code>.
373      * @param streamMap the map with streams from the RUN tag
374      * @param linearDensityDist the tag to parse
375      * @return a typed continuous random distribution.
376      * @throws XmlParserException in case of a parse error.
377      */
378     public static ContinuousDistDoubleScalar.Rel<LinearDensity, LinearDensityUnit> parseLinearDensityDist(
379             Map<String, StreamInformation> streamMap, LINEARDENSITYDISTTYPE linearDensityDist) throws XmlParserException
380     {
381         DistContinuous dist = makeDistContinuous(streamMap, linearDensityDist);
382         for (LinearDensityUnit unit : Unit.getUnits(LinearDensityUnit.class))
383         {
384             if (unit.getDefaultLocaleTextualRepresentations().contains(linearDensityDist.getLINEARDENSITYUNIT()))
385             {
386                 return new ContinuousDistDoubleScalar.Rel<LinearDensity, LinearDensityUnit>(dist, unit);
387             }
388         }
389         throw new XmlParserException("Could not find FrequencyUnit " + linearDensityDist.getLINEARDENSITYUNIT()
390                 + " in tag of type FREQUENCYDISTTYPE");
391     }
392 
393 }