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  }