github.com/gopherd/gonum@v0.0.4/stat/distuv/chi.go (about) 1 // Copyright ©2021 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 "math/rand" 11 12 "github.com/gopherd/gonum/mathext" 13 ) 14 15 // Chi implements the χ distribution, a one parameter distribution 16 // with support on the positive numbers. 17 // 18 // The density function is given by 19 // 1/(2^{k/2-1} * Γ(k/2)) * x^{k - 1} * e^{-x^2/2} 20 // 21 // For more information, see https://en.wikipedia.org/wiki/Chi_distribution. 22 type Chi struct { 23 // K is the shape parameter, corresponding to the degrees of freedom. Must 24 // be greater than 0. 25 K float64 26 27 Src rand.Source 28 } 29 30 // CDF computes the value of the cumulative density function at x. 31 func (c Chi) CDF(x float64) float64 { 32 return mathext.GammaIncReg(c.K/2, (x*x)/2) 33 } 34 35 // Entropy returns the differential entropy of the distribution. 36 func (c Chi) Entropy() float64 { 37 lg, _ := math.Lgamma(c.K / 2) 38 return lg + 0.5*(c.K-math.Ln2-(c.K-1)*mathext.Digamma(c.K/2)) 39 } 40 41 // ExKurtosis returns the excess kurtosis of the distribution. 42 func (c Chi) ExKurtosis() float64 { 43 v := c.Variance() 44 s := math.Sqrt(v) 45 return 2 / v * (1 - c.Mean()*s*c.Skewness() - v) 46 } 47 48 // LogProb computes the natural logarithm of the value of the probability 49 // density function at x. 50 func (c Chi) LogProb(x float64) float64 { 51 if x < 0 { 52 return math.Inf(-1) 53 } 54 lg, _ := math.Lgamma(c.K / 2) 55 return (c.K-1)*math.Log(x) - (x*x)/2 - (c.K/2-1)*math.Ln2 - lg 56 } 57 58 // Mean returns the mean of the probability distribution. 59 func (c Chi) Mean() float64 { 60 lg1, _ := math.Lgamma((c.K + 1) / 2) 61 lg, _ := math.Lgamma(c.K / 2) 62 return math.Sqrt2 * math.Exp(lg1-lg) 63 } 64 65 // Median returns the median of the distribution. 66 func (c Chi) Median() float64 { 67 return c.Quantile(0.5) 68 } 69 70 // Mode returns the mode of the distribution. 71 // 72 // Mode returns NaN if K is less than one. 73 func (c Chi) Mode() float64 { 74 return math.Sqrt(c.K - 1) 75 } 76 77 // NumParameters returns the number of parameters in the distribution. 78 func (c Chi) NumParameters() int { 79 return 1 80 } 81 82 // Prob computes the value of the probability density function at x. 83 func (c Chi) Prob(x float64) float64 { 84 return math.Exp(c.LogProb(x)) 85 } 86 87 // Rand returns a random sample drawn from the distribution. 88 func (c Chi) Rand() float64 { 89 return math.Sqrt(Gamma{c.K / 2, 0.5, c.Src}.Rand()) 90 } 91 92 // Quantile returns the inverse of the cumulative distribution function. 93 func (c Chi) Quantile(p float64) float64 { 94 if p < 0 || 1 < p { 95 panic(badPercentile) 96 } 97 return math.Sqrt(2 * mathext.GammaIncRegInv(0.5*c.K, p)) 98 } 99 100 // Skewness returns the skewness of the distribution. 101 func (c Chi) Skewness() float64 { 102 v := c.Variance() 103 s := math.Sqrt(v) 104 return c.Mean() / (s * v) * (1 - 2*v) 105 } 106 107 // StdDev returns the standard deviation of the probability distribution. 108 func (c Chi) StdDev() float64 { 109 return math.Sqrt(c.Variance()) 110 } 111 112 // Survival returns the survival function (complementary CDF) at x. 113 func (c Chi) Survival(x float64) float64 { 114 if x < 0 { 115 return 1 116 } 117 return mathext.GammaIncRegComp(0.5*c.K, 0.5*(x*x)) 118 } 119 120 // Variance returns the variance of the probability distribution. 121 func (c Chi) Variance() float64 { 122 m := c.Mean() 123 return math.Max(0, c.K-m*m) 124 }