Distributions.java

  1. package org.opentrafficsim.core.network.factory.xml.units;

  2. import org.djunits.unit.DurationUnit;
  3. import org.djunits.unit.LengthUnit;
  4. import org.djunits.unit.PositionUnit;
  5. import org.djunits.unit.SpeedUnit;
  6. import org.djunits.unit.TimeUnit;
  7. import org.djunits.value.vdouble.scalar.Duration;
  8. import org.djunits.value.vdouble.scalar.Length;
  9. import org.djunits.value.vdouble.scalar.Position;
  10. import org.djunits.value.vdouble.scalar.Speed;
  11. import org.djunits.value.vdouble.scalar.Time;
  12. import org.opentrafficsim.core.dsol.DistNormalTrunc;
  13. import org.opentrafficsim.core.network.NetworkException;
  14. import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;

  15. import nl.tudelft.simulation.jstats.distributions.DistBeta;
  16. import nl.tudelft.simulation.jstats.distributions.DistConstant;
  17. import nl.tudelft.simulation.jstats.distributions.DistContinuous;
  18. import nl.tudelft.simulation.jstats.distributions.DistErlang;
  19. import nl.tudelft.simulation.jstats.distributions.DistExponential;
  20. import nl.tudelft.simulation.jstats.distributions.DistGamma;
  21. import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
  22. import nl.tudelft.simulation.jstats.distributions.DistNormal;
  23. import nl.tudelft.simulation.jstats.distributions.DistPearson5;
  24. import nl.tudelft.simulation.jstats.distributions.DistPearson6;
  25. import nl.tudelft.simulation.jstats.distributions.DistTriangular;
  26. import nl.tudelft.simulation.jstats.distributions.DistUniform;
  27. import nl.tudelft.simulation.jstats.distributions.DistWeibull;
  28. import nl.tudelft.simulation.jstats.streams.MersenneTwister;
  29. import nl.tudelft.simulation.jstats.streams.StreamInterface;

  30. /**
  31.  * <p>
  32.  * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  33.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  34.  * <p>
  35.  * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
  36.  * initial version Jul 23, 2015 <br>
  37.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  38.  */
  39. public final class Distributions
  40. {
  41.     /** Utility class. */
  42.     private Distributions()
  43.     {
  44.         // do not instantiate
  45.     }

  46.     /** TODO include in GLOBAL tag. */
  47.     private static final StreamInterface STREAM = new MersenneTwister(2L);

  48.     /**
  49.      * parse a set of comma-separated values, e.g., <code>10.0, 4, 5.23</code>.
  50.      * @param s String; the string to parse.
  51.      * @return array of double values.
  52.      */
  53.     private static double[] parseDoubleArgs(final String s)
  54.     {
  55.         String[] ss = s.split(",");
  56.         double[] d = new double[ss.length];
  57.         for (int i = 0; i < ss.length; i++)
  58.         {
  59.             d[i] = Double.parseDouble(ss[i]);
  60.         }
  61.         return d;
  62.     }

  63.     /**
  64.      * Parse a continuous distribution.
  65.      * @param ds String; the name of the distribution, e.g. UNIF.
  66.      * @param args double[]; the parameters of the distribution, e.g. {1.0, 2.0}.
  67.      * @return the generated distribution.
  68.      * @throws NetworkException in case distribution unknown or parameter number does not match.
  69.      */
  70.     private static DistContinuous makeDistContinuous(final String ds, final double[] args) throws NetworkException
  71.     {
  72.         try
  73.         {
  74.             switch (ds)
  75.             {
  76.                 case "CONST":
  77.                 case "CONSTANT":
  78.                     return new DistConstant(STREAM, args[0]);

  79.                 case "EXPO":
  80.                 case "EXPONENTIAL":
  81.                     return new DistExponential(STREAM, args[0]);

  82.                 case "TRIA":
  83.                 case "TRIANGULAR":
  84.                     return new DistTriangular(STREAM, args[0], args[1], args[2]);

  85.                 case "NORM":
  86.                 case "NORMAL":
  87.                     return new DistNormal(STREAM, args[0], args[1]);

  88.                 case "NORMTRUNC":
  89.                 case "NORMALTRUNCATED":
  90.                     return new DistNormalTrunc(STREAM, args[0], args[1], args[2], args[3]);

  91.                 case "BETA":
  92.                     return new DistBeta(STREAM, args[0], args[1]);

  93.                 case "ERLANG":
  94.                     return new DistErlang(STREAM, (int) args[0], args[1]);

  95.                 case "GAMMA":
  96.                     return new DistGamma(STREAM, args[0], args[1]);

  97.                 case "LOGN":
  98.                 case "LOGNORMAL":
  99.                     return new DistLogNormal(STREAM, args[0], args[1]);

  100.                 case "PEARSON5":
  101.                     return new DistPearson5(STREAM, args[0], args[1]);

  102.                 case "PEARSON6":
  103.                     return new DistPearson6(STREAM, args[0], args[1], args[2]);

  104.                 case "UNIF":
  105.                 case "UNIFORM":
  106.                     return new DistUniform(STREAM, args[0], args[1]);

  107.                 case "WEIB":
  108.                 case "WEIBULL":
  109.                     return new DistWeibull(STREAM, args[0], args[1]);

  110.                 default:
  111.                     throw new NetworkException("makeDistContinuous - unknown distribution function " + ds);
  112.             }
  113.         }
  114.         catch (IndexOutOfBoundsException e)
  115.         {
  116.             throw new NetworkException("makeDistContinuous - wrong number of parameters for distribution function " + ds);
  117.         }
  118.     }

  119.     /**
  120.      * Parse a relative length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
  121.      * @param s String; the string to be parsed.
  122.      * @return a typed continuous random distribution.
  123.      * @throws NetworkException in case of a parse error.
  124.      */
  125.     public static ContinuousDistDoubleScalar.Rel<Length, LengthUnit> parseLengthDist(final String s) throws NetworkException
  126.     {
  127.         String[] s1 = s.split("\\(");
  128.         String ds = s1[0];
  129.         String[] s2 = s1[1].split("\\)");
  130.         String unit = LengthUnits.parseLengthUnit(s2[1]);
  131.         double[] args = parseDoubleArgs(s2[0]);
  132.         DistContinuous dist = makeDistContinuous(ds, args);
  133.         return new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(dist, LengthUnits.LENGTH_UNITS.get(unit));
  134.     }

  135.     /**
  136.      * Parse an absolute length distribution, e.g. <code>UNIFORM(1, 3) m</code>.
  137.      * @param s String; the string to be parsed.
  138.      * @return a typed continuous random distribution.
  139.      * @throws NetworkException in case of a parse error.
  140.      */
  141.     public static ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit> parsePositionDist(final String s)
  142.             throws NetworkException
  143.     {
  144.         String[] s1 = s.split("\\(");
  145.         String ds = s1[0];
  146.         String[] s2 = s1[1].split("\\)");
  147.         String unit = LengthUnits.parseLengthUnit(s2[1]);
  148.         double[] args = parseDoubleArgs(s2[0]);
  149.         DistContinuous dist = makeDistContinuous(ds, args);
  150.         return new ContinuousDistDoubleScalar.Abs<Position, PositionUnit, LengthUnit>(dist,
  151.                 PositionUnits.POSITION_UNITS.get(unit));
  152.     }

  153.     /**
  154.      * Parse a relative time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  155.      * @param s String; the string to be parsed.
  156.      * @return a typed continuous random distribution.
  157.      * @throws NetworkException in case of a parse error.
  158.      */
  159.     public static ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> parseDurationDist(final String s)
  160.             throws NetworkException
  161.     {
  162.         String[] s1 = s.split("\\(");
  163.         String ds = s1[0];
  164.         String[] s2 = s1[1].split("\\)");
  165.         String unit = DurationUnits.parseDurationUnit(s2[1]);
  166.         double[] args = parseDoubleArgs(s2[0]);
  167.         DistContinuous dist = makeDistContinuous(ds, args);
  168.         return new ContinuousDistDoubleScalar.Rel<Duration, DurationUnit>(dist, DurationUnits.DURATION_UNITS.get(unit));
  169.     }

  170.     /**
  171.      * Parse an absolute time distribution, e.g. <code>UNIFORM(1, 3) s</code>.
  172.      * @param s String; the string to be parsed.
  173.      * @return a typed continuous random distribution.
  174.      * @throws NetworkException in case of a parse error.
  175.      */
  176.     public static ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit> parseTimeDist(final String s)
  177.             throws NetworkException
  178.     {
  179.         String[] s1 = s.split("\\(");
  180.         String ds = s1[0];
  181.         String[] s2 = s1[1].split("\\)");
  182.         String unit = TimeUnits.parseTimeUnit(s2[1]);
  183.         double[] args = parseDoubleArgs(s2[0]);
  184.         DistContinuous dist = makeDistContinuous(ds, args);
  185.         return new ContinuousDistDoubleScalar.Abs<Time, TimeUnit, DurationUnit>(dist, TimeUnits.TIME_UNITS.get(unit));
  186.     }

  187.     /**
  188.      * Parse a relative speed distribution, e.g. <code>TRIANGULAR(80, 90, 110) km/h</code>.
  189.      * @param s String; the string to be parsed.
  190.      * @return a typed continuous random distribution.
  191.      * @throws NetworkException in case of a parse error.
  192.      */
  193.     public static ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> parseSpeedDist(final String s) throws NetworkException
  194.     {
  195.         String[] s1 = s.split("\\(");
  196.         String ds = s1[0];
  197.         String[] s2 = s1[1].split("\\)");
  198.         String unit = SpeedUnits.parseSpeedUnit(s2[1]);
  199.         double[] args = parseDoubleArgs(s2[0]);
  200.         DistContinuous dist = makeDistContinuous(ds, args);
  201.         return new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(dist, SpeedUnits.SPEED_UNITS.get(unit));
  202.     }

  203. }