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