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 Geometric distribution. The geometric distribution is the only discrete memoryless random distribution. It is a discrete 9 * analog of the exponential distribution. There are two variants, one that indicates the number of Bernoulli trials to get the 10 * first success (1, 2, 3, ...), and one that indicates the number of failures before the first success (0, 1, 2, ...). In line 11 * with Law & Kelton, the version of the number of failures before the first success is modeled here, so X ={0, 1, 2, ...}. 12 * For more information on this distribution see <a href="https://mathworld.wolfram.com/GeometricDistribution.html"> 13 * https://mathworld.wolfram.com/GeometricDistribution.html </a> 14 * <p> 15 * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See 16 * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL 17 * project is distributed under a three-clause BSD-style license, which can be found at 18 * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank"> 19 * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>. 20 * </p> 21 * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a> 22 * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a> 23 */ 24 public class DistGeometric extends DistDiscrete 25 { 26 /** */ 27 private static final long serialVersionUID = 1L; 28 29 /** p is the the probability of success for each individual trial. */ 30 private final double p; 31 32 /** lnp is a helper variable with value ln(1-p) to avoid repetitive calculation. */ 33 private final double lnp; 34 35 /** 36 * Construct a new geometric distribution for a repeated set of Bernoulli trials, indicating the number of failures before 37 * the first success. 38 * @param stream StreamInterface; the random number stream 39 * @param p double; the probability of success for each individual trial 40 * @throws IllegalArgumentException when p <= 0 or p >= 1 41 */ 42 public DistGeometric(final StreamInterface stream, final double p) 43 { 44 super(stream); 45 Throw.when(p <= 0.0 || p >= 1.0, IllegalArgumentException.class, "Error Geometric - p <= 0 or p >= 1"); 46 this.p = p; 47 this.lnp = Math.log(1.0 - this.p); 48 } 49 50 /** {@inheritDoc} */ 51 @Override 52 public long draw() 53 { 54 double u = this.stream.nextDouble(); 55 return (long) (Math.floor(Math.log(u) / this.lnp)); 56 } 57 58 /** {@inheritDoc} */ 59 @Override 60 public double probability(final long observation) 61 { 62 if (observation >= 0) 63 { 64 return this.p * Math.pow(1 - this.p, observation); 65 } 66 return 0.0; 67 } 68 69 /** 70 * Return the probability of success for each individual trial. 71 * @return double; the probability of success for each individual trial 72 */ 73 public double getP() 74 { 75 return this.p; 76 } 77 78 /** {@inheritDoc} */ 79 @Override 80 public String toString() 81 { 82 return "Geometric(" + this.p + ")"; 83 } 84 }