gonum.org/v1/gonum@v0.14.0/stat/distuv/lognormal.go (about) 1 // Copyright ©2015 The Gonum 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 distuv 6 7 import ( 8 "math" 9 10 "golang.org/x/exp/rand" 11 ) 12 13 // LogNormal represents a random variable whose log is normally distributed. 14 // The probability density function is given by 15 // 16 // 1/(x σ √2π) exp(-(ln(x)-μ)^2)/(2σ^2)) 17 type LogNormal struct { 18 Mu float64 19 Sigma float64 20 Src rand.Source 21 } 22 23 // CDF computes the value of the cumulative density function at x. 24 func (l LogNormal) CDF(x float64) float64 { 25 return 0.5 * math.Erfc(-(math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma)) 26 } 27 28 // Entropy returns the differential entropy of the distribution. 29 func (l LogNormal) Entropy() float64 { 30 return 0.5 + 0.5*math.Log(2*math.Pi*l.Sigma*l.Sigma) + l.Mu 31 } 32 33 // ExKurtosis returns the excess kurtosis of the distribution. 34 func (l LogNormal) ExKurtosis() float64 { 35 s2 := l.Sigma * l.Sigma 36 return math.Exp(4*s2) + 2*math.Exp(3*s2) + 3*math.Exp(2*s2) - 6 37 } 38 39 // LogProb computes the natural logarithm of the value of the probability density function at x. 40 func (l LogNormal) LogProb(x float64) float64 { 41 if x < 0 { 42 return math.Inf(-1) 43 } 44 logx := math.Log(x) 45 normdiff := (logx - l.Mu) / l.Sigma 46 return -0.5*normdiff*normdiff - logx - math.Log(l.Sigma) - logRoot2Pi 47 } 48 49 // Mean returns the mean of the probability distribution. 50 func (l LogNormal) Mean() float64 { 51 return math.Exp(l.Mu + 0.5*l.Sigma*l.Sigma) 52 } 53 54 // Median returns the median of the probability distribution. 55 func (l LogNormal) Median() float64 { 56 return math.Exp(l.Mu) 57 } 58 59 // Mode returns the mode of the probability distribution. 60 func (l LogNormal) Mode() float64 { 61 return math.Exp(l.Mu - l.Sigma*l.Sigma) 62 } 63 64 // NumParameters returns the number of parameters in the distribution. 65 func (LogNormal) NumParameters() int { 66 return 2 67 } 68 69 // Prob computes the value of the probability density function at x. 70 func (l LogNormal) Prob(x float64) float64 { 71 return math.Exp(l.LogProb(x)) 72 } 73 74 // Quantile returns the inverse of the cumulative probability distribution. 75 func (l LogNormal) Quantile(p float64) float64 { 76 if p < 0 || p > 1 { 77 panic(badPercentile) 78 } 79 // Formula from http://www.math.uah.edu/stat/special/LogNormal.html. 80 return math.Exp(l.Mu + l.Sigma*UnitNormal.Quantile(p)) 81 } 82 83 // Rand returns a random sample drawn from the distribution. 84 func (l LogNormal) Rand() float64 { 85 var rnd float64 86 if l.Src == nil { 87 rnd = rand.NormFloat64() 88 } else { 89 rnd = rand.New(l.Src).NormFloat64() 90 } 91 return math.Exp(rnd*l.Sigma + l.Mu) 92 } 93 94 // Skewness returns the skewness of the distribution. 95 func (l LogNormal) Skewness() float64 { 96 s2 := l.Sigma * l.Sigma 97 return (math.Exp(s2) + 2) * math.Sqrt(math.Exp(s2)-1) 98 } 99 100 // StdDev returns the standard deviation of the probability distribution. 101 func (l LogNormal) StdDev() float64 { 102 return math.Sqrt(l.Variance()) 103 } 104 105 // Survival returns the survival function (complementary CDF) at x. 106 func (l LogNormal) Survival(x float64) float64 { 107 return 0.5 * (1 - math.Erf((math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma))) 108 } 109 110 // Variance returns the variance of the probability distribution. 111 func (l LogNormal) Variance() float64 { 112 s2 := l.Sigma * l.Sigma 113 return (math.Exp(s2) - 1) * math.Exp(2*l.Mu+s2) 114 }