1 package nl.tudelft.simulation.jstats.distributions;
2
3 import org.djutils.exceptions.Throw;
4
5 import nl.tudelft.simulation.jstats.streams.StreamInterface;
6
7 /**
8 * The Triangular distribution. For more information on this distribution see
9 * <a href="https://mathworld.wolfram.com/TriangularDistribution.html">
10 * https://mathworld.wolfram.com/TriangularDistribution.html </a>
11 * <p>
12 * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
13 * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
14 * project is distributed under a three-clause BSD-style license, which can be found at
15 * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
16 * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
17 * </p>
18 * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
19 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
20 */
21 public class DistTriangular extends DistContinuous
22 {
23 /** */
24 private static final long serialVersionUID = 1L;
25
26 /** the minimum. */
27 private final double min;
28
29 /** the mode. */
30 private final double mode;
31
32 /** the maximum. */
33 private final double max;
34
35 /**
36 * constructs a new triangular distribution with a minimum, mode, and maximum.
37 * @param stream StreamInterface; the random number stream
38 * @param min double; the minimum
39 * @param mode double; the mode
40 * @param max double; the maximum
41 * @throws IllegalArgumentException when mode < min or mode > max or min == max
42 */
43 public DistTriangular(final StreamInterface stream, final double min, final double mode, final double max)
44 {
45 super(stream);
46 Throw.when(mode < min || mode > max || min == max, IllegalArgumentException.class,
47 "Triangular distribution, mode < min or mode > max or min == max");
48 this.min = min;
49 this.mode = mode;
50 this.max = max;
51 }
52
53 /** {@inheritDoc} */
54 @Override
55 public double draw()
56 {
57 double u = this.stream.nextDouble();
58 if (u <= ((this.mode - this.min) / (this.max - this.min)))
59 {
60 return this.min + Math.sqrt((this.mode - this.min) * (this.max - this.min) * u);
61 }
62 return this.max - Math.sqrt((this.max - this.min) * (this.max - this.mode) * (1.0d - u));
63 }
64
65 /** {@inheritDoc} */
66 @Override
67 public double getProbabilityDensity(final double x)
68 {
69 if (x >= this.min && x <= this.mode)
70 {
71 return 2.0 * (x - this.min) / ((this.max - this.min) * (this.mode - this.min));
72 }
73 if (x >= this.mode && x <= this.max)
74 {
75 return 2.0 * (this.max - x) / ((this.max - this.min) * (this.max - this.mode));
76 }
77 return 0.0;
78 }
79
80 /**
81 * Return the minimum value of the distribution.
82 * @return double; the minimum value of the distribution
83 */
84 public double getMin()
85 {
86 return this.min;
87 }
88
89 /**
90 * Return the mode of the distribution.
91 * @return double; the mode of the distribution
92 */
93 public double getMode()
94 {
95 return this.mode;
96 }
97
98 /**
99 * Return the maximum value of the distribution.
100 * @return double; the maximum value of the distribution.
101 */
102 public double getMax()
103 {
104 return this.max;
105 }
106
107 /** {@inheritDoc} */
108 @Override
109 public String toString()
110 {
111 return "Triangular(" + this.min + "," + this.mode + "," + this.max + ")";
112 }
113 }