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