1 package nl.tudelft.simulation.jstats.distributions;
2
3 import org.djutils.exceptions.Throw;
4
5 import nl.tudelft.simulation.jstats.math.ProbMath;
6 import nl.tudelft.simulation.jstats.streams.StreamInterface;
7
8 /**
9 * The Pearson6 distribution. For more information on this distribution see
10 * <a href="https://mathworld.wolfram.com/Pearson6Distribution.html"> https://mathworld.wolfram.com/Pearson6Distribution.html
11 * </a>
12 * <p>
13 * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
14 * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
15 * project is distributed under a three-clause BSD-style license, which can be found at
16 * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
17 * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
18 * </p>
19 * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
20 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
21 */
22 public class DistPearson6 extends DistContinuous
23 {
24 /** */
25 private static final long serialVersionUID = 1L;
26
27 /** dist1 is the first gamma distribution. */
28 private final DistGamma dist1;
29
30 /** dist2 is the second gamma distribution. */
31 private final DistGamma dist2;
32
33 /** alpha1 is the first shape parameter. */
34 private final double alpha1;
35
36 /** alpha2 is the second shape parameter. */
37 private final double alpha2;
38
39 /** beta is the scale parameter. */
40 private final double beta;
41
42 /**
43 * constructs a new Pearson6 distribution.
44 * @param stream StreamInterface; the random number stream
45 * @param alpha1 double; the first shape parameter
46 * @param alpha2 double; the second shape parameter
47 * @param beta double; the scale parameter
48 * @throws IllegalArgumentException when alpha1 <= 0 or alpha2 <= 0 or beta <= 0
49 */
50 public DistPearson6(final StreamInterface stream, final double alpha1, final double alpha2, final double beta)
51 {
52 super(stream);
53 Throw.when(alpha1 <= 0.0 || alpha2 <= 0.0 || beta <= 0.0, IllegalArgumentException.class,
54 "Pearson6 distribution cannot be created with alpha1 <= 0.0 or alpha2 <= 0 or beta <= 0.0");
55 this.alpha1 = alpha1;
56 this.alpha2 = alpha2;
57 this.beta = beta;
58 this.dist1 = new DistGamma(super.stream, this.alpha1, this.beta);
59 this.dist2 = new DistGamma(super.stream, this.alpha2, this.beta);
60 }
61
62 /** {@inheritDoc} */
63 @Override
64 public double draw()
65 {
66 // according to Law and Kelton, Simulation Modeling and Analysis, 1991, page 494.
67 // but since dist1 and dist2 are both scaled by beta, the result is beta/beta = 1, without the scale parameter
68 // So, in contrast with Law & Kelton and Banks (2000), a multiplication with beta is added
69 return this.beta * this.dist1.draw() / this.dist2.draw();
70 }
71
72 /** {@inheritDoc} */
73 @Override
74 public double getProbabilityDensity(final double x)
75 {
76 if (x > 0)
77 {
78 return Math.pow(x / this.beta, this.alpha1 - 1) / (this.beta * ProbMath.beta(this.alpha1, this.alpha2)
79 * Math.pow(1 + x / this.beta, this.alpha1 + this.alpha2));
80 }
81 return 0;
82 }
83
84 /**
85 * Return the first shape parameter α1.
86 * @return double; the first shape parameter α1
87 */
88 public double getAlpha1()
89 {
90 return this.alpha1;
91 }
92
93 /**
94 * Return the second shape parameter α2.
95 * @return double; the second shape parameter α2
96 */
97 public double getAlpha2()
98 {
99 return this.alpha2;
100 }
101
102 /**
103 * Return the scale parameter β.
104 * @return double; the scale parameter β
105 */
106 public double getBeta()
107 {
108 return this.beta;
109 }
110
111 /** {@inheritDoc} */
112 @Override
113 public void setStream(final StreamInterface stream)
114 {
115 super.setStream(stream);
116 this.dist1.setStream(stream);
117 this.dist2.setStream(stream);
118 }
119
120 /** {@inheritDoc} */
121 @Override
122 public String toString()
123 {
124 return "Pearson6(" + this.alpha1 + "," + this.alpha2 + "," + this.beta + ")";
125 }
126
127 }