github.com/aclements/go-misc@v0.0.0-20240129233631-2f6ede80790c/findflakes/geodist.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "math" 9 "math/rand" 10 ) 11 12 // GeometricDist is a geometric distribution with success probability 13 // P. 14 type GeometricDist struct { 15 P float64 16 17 // Start is the start of the distribution's support. There are 18 // two conventional definitions of the geometric distribution: 19 // 20 // For Start=0, the distribution gives the number of failures 21 // before the first success in a Bernoulli process with 22 // success probability P. 23 // 24 // For Start=1, the distribution gives the number of trials 25 // needed to get one success. This is often called the 26 // "shifted geometric distribution." 27 // 28 // Other values of Start are allowed, but have no conventional 29 // meaning. 30 Start int 31 } 32 33 func (d *GeometricDist) PMF(k int) float64 { 34 if k < d.Start { 35 return 0 36 } 37 return math.Pow(1-d.P, float64(k-d.Start)) * d.P 38 } 39 40 func (d *GeometricDist) CDF(k int) float64 { 41 if k < d.Start { 42 return 0 43 } 44 return 1 - math.Pow(1-d.P, float64(k-d.Start+1)) 45 } 46 47 func (d *GeometricDist) SF(k int) float64 { 48 if k < d.Start { 49 return 1 50 } 51 return math.Pow(1-d.P, float64(k-d.Start+1)) 52 } 53 54 func (d *GeometricDist) InvCDF(y float64) int { 55 return int(math.Ceil(math.Log(1-y)/math.Log(1-d.P)-1)) + d.Start 56 } 57 58 func (d *GeometricDist) Rand() int { 59 u := 1 - rand.Float64() 60 return int(math.Log(u)/math.Log(1-d.P)) + d.Start 61 }