ParseDistribution.java

  1. package org.opentrafficsim.road.network.factory.xml.utils;

  2. import java.util.Map;

  3. import org.djunits.unit.AccelerationUnit;
  4. import org.djunits.unit.DurationUnit;
  5. import org.djunits.unit.FrequencyUnit;
  6. import org.djunits.unit.LengthUnit;
  7. import org.djunits.unit.LinearDensityUnit;
  8. import org.djunits.unit.PositionUnit;
  9. import org.djunits.unit.SpeedUnit;
  10. import org.djunits.unit.TimeUnit;
  11. import org.djunits.value.vdouble.scalar.Acceleration;
  12. import org.djunits.value.vdouble.scalar.Duration;
  13. import org.djunits.value.vdouble.scalar.Frequency;
  14. import org.djunits.value.vdouble.scalar.Length;
  15. import org.djunits.value.vdouble.scalar.LinearDensity;
  16. import org.djunits.value.vdouble.scalar.Position;
  17. import org.djunits.value.vdouble.scalar.Speed;
  18. import org.djunits.value.vdouble.scalar.Time;
  19. import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
  20. import org.opentrafficsim.road.network.factory.xml.XmlParserException;
  21. import org.opentrafficsim.xml.generated.ACCELERATIONDISTTYPE;
  22. import org.opentrafficsim.xml.generated.CONTDISTTYPE;
  23. import org.opentrafficsim.xml.generated.DISCRETEDISTTYPE;
  24. import org.opentrafficsim.xml.generated.DURATIONDISTTYPE;
  25. import org.opentrafficsim.xml.generated.FREQUENCYDISTTYPE;
  26. import org.opentrafficsim.xml.generated.LENGTHDISTTYPE;
  27. import org.opentrafficsim.xml.generated.LINEARDENSITYDISTTYPE;
  28. import org.opentrafficsim.xml.generated.POSITIONDISTTYPE;
  29. import org.opentrafficsim.xml.generated.SPEEDDISTTYPE;
  30. import org.opentrafficsim.xml.generated.TIMEDISTTYPE;

  31. import nl.tudelft.simulation.jstats.distributions.DistBernoulli;
  32. import nl.tudelft.simulation.jstats.distributions.DistBeta;
  33. import nl.tudelft.simulation.jstats.distributions.DistBinomial;
  34. import nl.tudelft.simulation.jstats.distributions.DistConstant;
  35. import nl.tudelft.simulation.jstats.distributions.DistContinuous;
  36. import nl.tudelft.simulation.jstats.distributions.DistDiscrete;
  37. import nl.tudelft.simulation.jstats.distributions.DistDiscreteConstant;
  38. import nl.tudelft.simulation.jstats.distributions.DistDiscreteUniform;
  39. import nl.tudelft.simulation.jstats.distributions.DistErlang;
  40. import nl.tudelft.simulation.jstats.distributions.DistExponential;
  41. import nl.tudelft.simulation.jstats.distributions.DistGamma;
  42. import nl.tudelft.simulation.jstats.distributions.DistGeometric;
  43. import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
  44. import nl.tudelft.simulation.jstats.distributions.DistNegBinomial;
  45. import nl.tudelft.simulation.jstats.distributions.DistNormal;
  46. import nl.tudelft.simulation.jstats.distributions.DistPearson5;
  47. import nl.tudelft.simulation.jstats.distributions.DistPearson6;
  48. import nl.tudelft.simulation.jstats.distributions.DistPoisson;
  49. import nl.tudelft.simulation.jstats.distributions.DistTriangular;
  50. import nl.tudelft.simulation.jstats.distributions.DistUniform;
  51. import nl.tudelft.simulation.jstats.distributions.DistWeibull;
  52. import nl.tudelft.simulation.jstats.streams.StreamInterface;

  53. /**
  54.  * Parse a distribution from text to a distribution.
  55.  * <p>
  56.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  57.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  58.  * <p>
  59.  * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
  60.  * initial version Jul 23, 2015 <br>
  61.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  62.  */
  63. public final class ParseDistribution
  64. {
  65.     /** Utility class. */
  66.     private ParseDistribution()
  67.     {
  68.         // do not instantiate
  69.     }

  70.     /**
  71.      * Parse a discrete distribution.
  72.      * @param streamMap map with stream information
  73.      * @param distType the distribution to parse
  74.      * @return the generated distribution.
  75.      * @throws XmlParserException in case distribution unknown or parameter number does not match.
  76.      */
  77.     public static DistDiscrete makeDistDiscrete(final Map<String, StreamInformation> streamMap, final DISCRETEDISTTYPE distType)
  78.             throws XmlParserException
  79.     {
  80.         if (distType.getBERNOULLI() != null)
  81.         {
  82.             StreamInterface stream = findStream(streamMap, distType.getBERNOULLI().getRANDOMSTREAM());
  83.             return new DistBernoulli(stream, distType.getBERNOULLI().getP());
  84.         }
  85.         else if (distType.getBINOMIAL() != null)
  86.         {
  87.             StreamInterface stream = findStream(streamMap, distType.getBINOMIAL().getRANDOMSTREAM());
  88.             return new DistBinomial(stream, distType.getBINOMIAL().getN().longValue(), distType.getBINOMIAL().getP());
  89.         }
  90.         else if (distType.getCONSTANT() != null)
  91.         {
  92.             StreamInterface stream = findStream(streamMap, distType.getCONSTANT().getRANDOMSTREAM());
  93.             return new DistDiscreteConstant(stream, distType.getCONSTANT().getC());
  94.         }
  95.         else if (distType.getGEOMETRIC() != null)
  96.         {
  97.             StreamInterface stream = findStream(streamMap, distType.getGEOMETRIC().getRANDOMSTREAM());
  98.             return new DistGeometric(stream, distType.getGEOMETRIC().getP());
  99.         }
  100.         else if (distType.getNEGBINOMIAL() != null)
  101.         {
  102.             StreamInterface stream = findStream(streamMap, distType.getNEGBINOMIAL().getRANDOMSTREAM());
  103.             return new DistNegBinomial(stream, distType.getNEGBINOMIAL().getN().longValue(), distType.getGEOMETRIC().getP());
  104.         }
  105.         else if (distType.getPOISSON() != null)
  106.         {
  107.             StreamInterface stream = findStream(streamMap, distType.getPOISSON().getRANDOMSTREAM());
  108.             return new DistPoisson(stream, distType.getPOISSON().getLAMBDA());
  109.         }
  110.         else if (distType.getUNIFORM() != null)
  111.         {
  112.             StreamInterface stream = findStream(streamMap, distType.getUNIFORM().getRANDOMSTREAM());
  113.             return new DistDiscreteUniform(stream, distType.getUNIFORM().getMIN(), distType.getUNIFORM().getMAX());
  114.         }
  115.         throw new XmlParserException("makeDistDiscrete - unknown distribution function " + distType);
  116.     }

  117.     /**
  118.      * Parse a continuous distribution.
  119.      * @param streamMap map with stream information
  120.      * @param distType the distribution to parse
  121.      * @return the generated distribution.
  122.      * @throws XmlParserException in case distribution unknown or parameter number does not match.
  123.      */
  124.     public static DistContinuous makeDistContinuous(final Map<String, StreamInformation> streamMap, final CONTDISTTYPE distType)
  125.             throws XmlParserException
  126.     {
  127.         if (distType.getCONSTANT() != null)
  128.         {
  129.             StreamInterface stream = findStream(streamMap, distType.getCONSTANT().getRANDOMSTREAM());
  130.             return new DistConstant(stream, distType.getCONSTANT().getC());
  131.         }
  132.         else if (distType.getEXPONENTIAL() != null)
  133.         {
  134.             StreamInterface stream = findStream(streamMap, distType.getEXPONENTIAL().getRANDOMSTREAM());
  135.             return new DistExponential(stream, distType.getEXPONENTIAL().getLAMBDA());
  136.         }
  137.         else if (distType.getTRIANGULAR() != null)
  138.         {
  139.             StreamInterface stream = findStream(streamMap, distType.getTRIANGULAR().getRANDOMSTREAM());
  140.             return new DistTriangular(stream, distType.getTRIANGULAR().getMIN(), distType.getTRIANGULAR().getMODE(),
  141.                     distType.getTRIANGULAR().getMAX());
  142.         }
  143.         else if (distType.getNORMAL() != null)
  144.         {
  145.             StreamInterface stream = findStream(streamMap, distType.getNORMAL().getRANDOMSTREAM());
  146.             return new DistNormal(stream, distType.getNORMAL().getMU(), distType.getNORMAL().getSIGMA());
  147.         }
  148.         // TODO: NORMALTRUNC
  149.         else if (distType.getBETA() != null)
  150.         {
  151.             StreamInterface stream = findStream(streamMap, distType.getBETA().getRANDOMSTREAM());
  152.             return new DistBeta(stream, distType.getBETA().getALPHA1(), distType.getBETA().getALPHA2());
  153.         }
  154.         else if (distType.getERLANG() != null)
  155.         {
  156.             StreamInterface stream = findStream(streamMap, distType.getERLANG().getRANDOMSTREAM());
  157.             return new DistErlang(stream, distType.getERLANG().getK().intValue(), distType.getERLANG().getMEAN());
  158.         }
  159.         else if (distType.getGAMMA() != null)
  160.         {
  161.             StreamInterface stream = findStream(streamMap, distType.getGAMMA().getRANDOMSTREAM());
  162.             return new DistGamma(stream, distType.getGAMMA().getALPHA(), distType.getGAMMA().getBETA());
  163.         }
  164.         else if (distType.getLOGNORMAL() != null)
  165.         {
  166.             StreamInterface stream = findStream(streamMap, distType.getLOGNORMAL().getRANDOMSTREAM());
  167.             return new DistLogNormal(stream, distType.getLOGNORMAL().getMU(), distType.getLOGNORMAL().getSIGMA());
  168.         }
  169.         else if (distType.getPEARSON5() != null)
  170.         {
  171.             StreamInterface stream = findStream(streamMap, distType.getPEARSON5().getRANDOMSTREAM());
  172.             return new DistPearson5(stream, distType.getPEARSON5().getALPHA(), distType.getPEARSON5().getBETA());
  173.         }
  174.         else if (distType.getPEARSON6() != null)
  175.         {
  176.             StreamInterface stream = findStream(streamMap, distType.getPEARSON6().getRANDOMSTREAM());
  177.             return new DistPearson6(stream, distType.getPEARSON6().getALPHA1(), distType.getPEARSON6().getALPHA2(),
  178.                     distType.getPEARSON6().getBETA());
  179.         }
  180.         else if (distType.getUNIFORM() != null)
  181.         {
  182.             StreamInterface stream = findStream(streamMap, distType.getUNIFORM().getRANDOMSTREAM());
  183.             return new DistUniform(stream, distType.getUNIFORM().getMIN(), distType.getUNIFORM().getMAX());
  184.         }
  185.         else if (distType.getWEIBULL() != null)
  186.         {
  187.             StreamInterface stream = findStream(streamMap, distType.getWEIBULL().getRANDOMSTREAM());
  188.             return new DistWeibull(stream, distType.getWEIBULL().getALPHA(), distType.getWEIBULL().getBETA());
  189.         }
  190.         throw new XmlParserException("makeDistContinuous - unknown distribution function " + distType);
  191.     }

  192.     /**
  193.      * Find and return the stream belonging to te streamId.
  194.      * @param streamMap the map with streams from the RUN tag
  195.      * @param streamId the id to search for
  196.      * @return the stream belonging to te streamId
  197.      * @throws XmlParserException when the stream could not be found
  198.      */
  199.     private static StreamInterface findStream(final Map<String, StreamInformation> streamMap, final String streamId)
  200.             throws XmlParserException
  201.     {
  202.         StreamInformation streamInformation = streamMap.get(streamId);
  203.         if (streamInformation == null)
  204.         {
  205.             throw new XmlParserException("Could not find stream with ID=" + streamId);
  206.         }
  207.         return streamInformation.getStream();
  208.     }

  209.     /**
  210.      * Parse a relative length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
  211.      * @param streamMap the map with streams from the RUN tag
  212.      * @param lengthDist the tag to parse
  213.      * @return a typed continuous random distribution.
  214.      * @throws XmlParserException in case of a parse error.
  215.      */
  216.     public static ContinuousDistDoubleScalar.Rel<Length, LengthUnit> parseLengthDist(
  217.             final Map<String, StreamInformation> streamMap, final LENGTHDISTTYPE lengthDist) throws XmlParserException
  218.     {
  219.         DistContinuous dist = makeDistContinuous(streamMap, lengthDist);
  220.         for (LengthUnit unit : LengthUnit.BASE.getUnitsById().values())
  221.         {
  222.             if (unit.getAbbreviations().contains(lengthDist.getLENGTHUNIT()))
  223.             {
  224.                 return new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(dist, unit);
  225.             }
  226.         }
  227.         throw new XmlParserException(
  228.                 "Could not find LengthUnit " + lengthDist.getLENGTHUNIT() + " in tag of type LENGTHDISTTYPE");
  229.     }

  230.     /**
  231.      * Parse an absolute position distribution, e.g. <code>UNIFORM(1, 3) m</code>.
  232.      * @param streamMap the map with streams from the RUN tag
  233.      * @param positionDist the tag to parse
  234.      * @return a typed continuous random distribution.
  235.      * @throws XmlParserException in case of a parse error.
  236.      */
  237.     public static ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit> parsePositionDist(
  238.             final Map<String, StreamInformation> streamMap, final POSITIONDISTTYPE positionDist) throws XmlParserException
  239.     {
  240.         DistContinuous dist = makeDistContinuous(streamMap, positionDist);
  241.         for (PositionUnit unit : PositionUnit.BASE.getUnitsById().values())
  242.         {
  243.             if (unit.getAbbreviations().contains(positionDist.getPOSITIONUNIT()))
  244.             {
  245.                 return new ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit>(dist, unit);
  246.             }
  247.         }
  248.         throw new XmlParserException(
  249.                 "Could not find PositionUnit " + positionDist.getPOSITIONUNIT() + " in tag of type POSITIONDISTTYPE");
  250.     }

  251.     /**
  252.      * Parse a relative duration distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  253.      * @param streamMap the map with streams from the RUN tag
  254.      * @param durationDist the tag to parse
  255.      * @return a typed continuous random distribution.
  256.      * @throws XmlParserException in case of a parse error.
  257.      */
  258.     public static ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> parseDurationDist(
  259.             final Map<String, StreamInformation> streamMap, final DURATIONDISTTYPE durationDist) throws XmlParserException
  260.     {
  261.         DistContinuous dist = makeDistContinuous(streamMap, durationDist);
  262.         for (DurationUnit unit : DurationUnit.BASE.getUnitsById().values())
  263.         {
  264.             if (unit.getAbbreviations().contains(durationDist.getDURATIONUNIT()))
  265.             {
  266.                 return new ContinuousDistDoubleScalar.Rel<Duration, DurationUnit>(dist, unit);
  267.             }
  268.         }
  269.         throw new XmlParserException(
  270.                 "Could not find DurationUnit " + durationDist.getDURATIONUNIT() + " in tag of type DURATIONDISTTYPE");
  271.     }

  272.     /**
  273.      * Parse an absolute time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  274.      * @param streamMap the map with streams from the RUN tag
  275.      * @param timeDist the tag to parse
  276.      * @return a typed continuous random distribution.
  277.      * @throws XmlParserException in case of a parse error.
  278.      */
  279.     public static ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit> parseTimeDist(
  280.             final Map<String, StreamInformation> streamMap, final TIMEDISTTYPE timeDist) throws XmlParserException
  281.     {
  282.         DistContinuous dist = makeDistContinuous(streamMap, timeDist);
  283.         for (TimeUnit unit : TimeUnit.BASE.getUnitsById().values())
  284.         {
  285.             if (unit.getAbbreviations().contains(timeDist.getTIMEUNIT()))
  286.             {
  287.                 return new ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit>(dist, unit);
  288.             }
  289.         }
  290.         throw new XmlParserException("Could not find TimeUnit " + timeDist.getTIMEUNIT() + " in tag of type TIMEDISTTYPE");
  291.     }

  292.     /**
  293.      * Parse a relative speed distribution, e.g. <code>UNIFORM(1, 3) m/s</code>.
  294.      * @param streamMap the map with streams from the RUN tag
  295.      * @param speedDist the tag to parse
  296.      * @return a typed continuous random distribution.
  297.      * @throws XmlParserException in case of a parse error.
  298.      */
  299.     public static ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> parseSpeedDist(
  300.             final Map<String, StreamInformation> streamMap, final SPEEDDISTTYPE speedDist) throws XmlParserException
  301.     {
  302.         DistContinuous dist = makeDistContinuous(streamMap, speedDist);
  303.         for (SpeedUnit unit : SpeedUnit.BASE.getUnitsById().values())
  304.         {
  305.             if (unit.getAbbreviations().contains(speedDist.getSPEEDUNIT()))
  306.             {
  307.                 return new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(dist, unit);
  308.             }
  309.         }
  310.         throw new XmlParserException("Could not find SpeedUnit " + speedDist.getSPEEDUNIT() + " in tag of type SPEEDDISTTYPE");
  311.     }

  312.     /**
  313.      * Parse a relative acceleration distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  314.      * @param streamMap the map with streams from the RUN tag
  315.      * @param accelerationDist the tag to parse
  316.      * @return a typed continuous random distribution.
  317.      * @throws XmlParserException in case of a parse error.
  318.      */
  319.     public static ContinuousDistDoubleScalar.Rel<Acceleration, AccelerationUnit> parseAccelerationDist(
  320.             final Map<String, StreamInformation> streamMap, final ACCELERATIONDISTTYPE accelerationDist)
  321.             throws XmlParserException
  322.     {
  323.         DistContinuous dist = makeDistContinuous(streamMap, accelerationDist);
  324.         for (AccelerationUnit unit : AccelerationUnit.BASE.getUnitsById().values())
  325.         {
  326.             if (unit.getAbbreviations().contains(accelerationDist.getACCELERATIONUNIT()))
  327.             {
  328.                 return new ContinuousDistDoubleScalar.Rel<Acceleration, AccelerationUnit>(dist, unit);
  329.             }
  330.         }
  331.         throw new XmlParserException("Could not find AccelerationUnit " + accelerationDist.getACCELERATIONUNIT()
  332.                 + " in tag of type ACCELERATIONDISTTYPE");
  333.     }

  334.     /**
  335.      * Parse a relative frequency distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  336.      * @param streamMap the map with streams from the RUN tag
  337.      * @param frequencyDist the tag to parse
  338.      * @return a typed continuous random distribution.
  339.      * @throws XmlParserException in case of a parse error.
  340.      */
  341.     public static ContinuousDistDoubleScalar.Rel<Frequency, FrequencyUnit> parseFrequencyDist(
  342.             final Map<String, StreamInformation> streamMap, final FREQUENCYDISTTYPE frequencyDist) throws XmlParserException
  343.     {
  344.         DistContinuous dist = makeDistContinuous(streamMap, frequencyDist);
  345.         for (FrequencyUnit unit : FrequencyUnit.BASE.getUnitsById().values())
  346.         {
  347.             if (unit.getAbbreviations().contains(frequencyDist.getFREQUENCYUNIT()))
  348.             {
  349.                 return new ContinuousDistDoubleScalar.Rel<Frequency, FrequencyUnit>(dist, unit);
  350.             }
  351.         }
  352.         throw new XmlParserException(
  353.                 "Could not find FrequencyUnit " + frequencyDist.getFREQUENCYUNIT() + " in tag of type FREQUENCYDISTTYPE");
  354.     }

  355.     /**
  356.      * Parse a relative linear density distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  357.      * @param streamMap the map with streams from the RUN tag
  358.      * @param linearDensityDist the tag to parse
  359.      * @return a typed continuous random distribution.
  360.      * @throws XmlParserException in case of a parse error.
  361.      */
  362.     public static ContinuousDistDoubleScalar.Rel<LinearDensity, LinearDensityUnit> parseLinearDensityDist(
  363.             final Map<String, StreamInformation> streamMap, final LINEARDENSITYDISTTYPE linearDensityDist)
  364.             throws XmlParserException
  365.     {
  366.         DistContinuous dist = makeDistContinuous(streamMap, linearDensityDist);
  367.         for (LinearDensityUnit unit : LinearDensityUnit.BASE.getUnitsById().values())
  368.         {
  369.             if (unit.getAbbreviations().contains(linearDensityDist.getLINEARDENSITYUNIT()))
  370.             {
  371.                 return new ContinuousDistDoubleScalar.Rel<LinearDensity, LinearDensityUnit>(dist, unit);
  372.             }
  373.         }
  374.         throw new XmlParserException("Could not find FrequencyUnit " + linearDensityDist.getLINEARDENSITYUNIT()
  375.                 + " in tag of type FREQUENCYDISTTYPE");
  376.     }

  377. }