fixed dependencies

This commit is contained in:
nuknal
2024-10-24 15:46:01 +08:00
parent d16a5bd9c0
commit 1161e8d054
2005 changed files with 690883 additions and 0 deletions

113
vendor/gonum.org/v1/gonum/stat/distuv/alphastable.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
// Copyright ©2020 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// AlphaStable represents an α-stable distribution with four parameters.
// See https://en.wikipedia.org/wiki/Stable_distribution for more information.
type AlphaStable struct {
// Alpha is the stability parameter.
// It is valid within the range 0 < α ≤ 2.
Alpha float64
// Beta is the skewness parameter.
// It is valid within the range -1 ≤ β ≤ 1.
Beta float64
// C is the scale parameter.
// It is valid when positive.
C float64
// Mu is the location parameter.
Mu float64
Src rand.Source
}
// ExKurtosis returns the excess kurtosis of the distribution.
// ExKurtosis returns NaN when Alpha != 2.
func (a AlphaStable) ExKurtosis() float64 {
if a.Alpha == 2 {
return 0
}
return math.NaN()
}
// Mean returns the mean of the probability distribution.
// Mean returns NaN when Alpha <= 1.
func (a AlphaStable) Mean() float64 {
if a.Alpha > 1 {
return a.Mu
}
return math.NaN()
}
// Median returns the median of the distribution.
// Median panics when Beta != 0, because then the mode is not analytically
// expressible.
func (a AlphaStable) Median() float64 {
if a.Beta == 0 {
return a.Mu
}
panic("distuv: cannot compute Median for Beta != 0")
}
// Mode returns the mode of the distribution.
// Mode panics when Beta != 0, because then the mode is not analytically
// expressible.
func (a AlphaStable) Mode() float64 {
if a.Beta == 0 {
return a.Mu
}
panic("distuv: cannot compute Mode for Beta != 0")
}
// NumParameters returns the number of parameters in the distribution.
func (a AlphaStable) NumParameters() int {
return 4
}
// Rand returns a random sample drawn from the distribution.
func (a AlphaStable) Rand() float64 {
// From https://en.wikipedia.org/wiki/Stable_distribution#Simulation_of_stable_variables
const halfPi = math.Pi / 2
u := Uniform{-halfPi, halfPi, a.Src}.Rand()
w := Exponential{1, a.Src}.Rand()
if a.Alpha == 1 {
f := halfPi + a.Beta*u
x := (f*math.Tan(u) - a.Beta*math.Log(halfPi*w*math.Cos(u)/f)) / halfPi
return a.C*(x+a.Beta*math.Log(a.C)/halfPi) + a.Mu
}
zeta := -a.Beta * math.Tan(halfPi*a.Alpha)
xi := math.Atan(-zeta) / a.Alpha
f := a.Alpha * (u + xi)
g := math.Sqrt(1+zeta*zeta) * math.Pow(math.Cos(u-f)/w, 1-a.Alpha) / math.Cos(u)
x := math.Pow(g, 1/a.Alpha) * math.Sin(f)
return a.C*x + a.Mu
}
// Skewness returns the skewness of the distribution.
// Skewness returns NaN when Alpha != 2.
func (a AlphaStable) Skewness() float64 {
if a.Alpha == 2 {
return 0
}
return math.NaN()
}
// StdDev returns the standard deviation of the probability distribution.
func (a AlphaStable) StdDev() float64 {
return math.Sqrt(a.Variance())
}
// Variance returns the variance of the probability distribution.
// Variance returns +Inf when Alpha != 2.
func (a AlphaStable) Variance() float64 {
if a.Alpha == 2 {
return 2 * a.C * a.C
}
return math.Inf(1)
}

141
vendor/gonum.org/v1/gonum/stat/distuv/bernoulli.go generated vendored Normal file
View File

@@ -0,0 +1,141 @@
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// Bernoulli represents a random variable whose value is 1 with probability p and
// value of zero with probability 1-P. The value of P must be between 0 and 1.
// More information at https://en.wikipedia.org/wiki/Bernoulli_distribution.
type Bernoulli struct {
P float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (b Bernoulli) CDF(x float64) float64 {
if x < 0 {
return 0
}
if x < 1 {
return 1 - b.P
}
return 1
}
// Entropy returns the entropy of the distribution.
func (b Bernoulli) Entropy() float64 {
if b.P == 0 || b.P == 1 {
return 0
}
q := 1 - b.P
return -b.P*math.Log(b.P) - q*math.Log(q)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (b Bernoulli) ExKurtosis() float64 {
pq := b.P * (1 - b.P)
return (1 - 6*pq) / pq
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (b Bernoulli) LogProb(x float64) float64 {
if x == 0 {
return math.Log(1 - b.P)
}
if x == 1 {
return math.Log(b.P)
}
return math.Inf(-1)
}
// Mean returns the mean of the probability distribution.
func (b Bernoulli) Mean() float64 {
return b.P
}
// Median returns the median of the probability distribution.
func (b Bernoulli) Median() float64 {
p := b.P
switch {
case p < 0.5:
return 0
case p > 0.5:
return 1
default:
return 0.5
}
}
// NumParameters returns the number of parameters in the distribution.
func (Bernoulli) NumParameters() int {
return 1
}
// Prob computes the value of the probability distribution at x.
func (b Bernoulli) Prob(x float64) float64 {
if x == 0 {
return 1 - b.P
}
if x == 1 {
return b.P
}
return 0
}
// Quantile returns the minimum value of x from amongst all those values whose CDF value exceeds or equals p.
func (b Bernoulli) Quantile(p float64) float64 {
if p < 0 || 1 < p {
panic(badPercentile)
}
if p <= 1-b.P {
return 0
}
return 1
}
// Rand returns a random sample drawn from the distribution.
func (b Bernoulli) Rand() float64 {
var rnd float64
if b.Src == nil {
rnd = rand.Float64()
} else {
rnd = rand.New(b.Src).Float64()
}
if rnd < b.P {
return 1
}
return 0
}
// Skewness returns the skewness of the distribution.
func (b Bernoulli) Skewness() float64 {
return (1 - 2*b.P) / math.Sqrt(b.P*(1-b.P))
}
// StdDev returns the standard deviation of the probability distribution.
func (b Bernoulli) StdDev() float64 {
return math.Sqrt(b.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (b Bernoulli) Survival(x float64) float64 {
if x < 0 {
return 1
}
if x < 1 {
return b.P
}
return 0
}
// Variance returns the variance of the probability distribution.
func (b Bernoulli) Variance() float64 {
return b.P * (1 - b.P)
}

152
vendor/gonum.org/v1/gonum/stat/distuv/beta.go generated vendored Normal file
View File

@@ -0,0 +1,152 @@
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// Beta implements the Beta distribution, a two-parameter continuous distribution
// with support between 0 and 1.
//
// The beta distribution has density function
//
// x^(α-1) * (1-x)^(β-1) * Γ(α+β) / (Γ(α)*Γ(β))
//
// For more information, see https://en.wikipedia.org/wiki/Beta_distribution
type Beta struct {
// Alpha is the left shape parameter of the distribution. Alpha must be greater
// than 0.
Alpha float64
// Beta is the right shape parameter of the distribution. Beta must be greater
// than 0.
Beta float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (b Beta) CDF(x float64) float64 {
if x <= 0 {
return 0
}
if x >= 1 {
return 1
}
return mathext.RegIncBeta(b.Alpha, b.Beta, x)
}
// Entropy returns the differential entropy of the distribution.
func (b Beta) Entropy() float64 {
if b.Alpha <= 0 || b.Beta <= 0 {
panic("beta: negative parameters")
}
return mathext.Lbeta(b.Alpha, b.Beta) - (b.Alpha-1)*mathext.Digamma(b.Alpha) -
(b.Beta-1)*mathext.Digamma(b.Beta) + (b.Alpha+b.Beta-2)*mathext.Digamma(b.Alpha+b.Beta)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (b Beta) ExKurtosis() float64 {
num := 6 * ((b.Alpha-b.Beta)*(b.Alpha-b.Beta)*(b.Alpha+b.Beta+1) - b.Alpha*b.Beta*(b.Alpha+b.Beta+2))
den := b.Alpha * b.Beta * (b.Alpha + b.Beta + 2) * (b.Alpha + b.Beta + 3)
return num / den
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (b Beta) LogProb(x float64) float64 {
if x < 0 || x > 1 {
return math.Inf(-1)
}
if b.Alpha <= 0 || b.Beta <= 0 {
panic("beta: negative parameters")
}
lab, _ := math.Lgamma(b.Alpha + b.Beta)
la, _ := math.Lgamma(b.Alpha)
lb, _ := math.Lgamma(b.Beta)
var lx float64
if b.Alpha != 1 {
lx = (b.Alpha - 1) * math.Log(x)
}
var l1mx float64
if b.Beta != 1 {
l1mx = (b.Beta - 1) * math.Log(1-x)
}
return lab - la - lb + lx + l1mx
}
// Mean returns the mean of the probability distribution.
func (b Beta) Mean() float64 {
return b.Alpha / (b.Alpha + b.Beta)
}
// Mode returns the mode of the distribution.
//
// Mode returns NaN if both parameters are less than or equal to 1 as a special case,
// 0 if only Alpha <= 1 and 1 if only Beta <= 1.
func (b Beta) Mode() float64 {
if b.Alpha <= 1 {
if b.Beta <= 1 {
return math.NaN()
}
return 0
}
if b.Beta <= 1 {
return 1
}
return (b.Alpha - 1) / (b.Alpha + b.Beta - 2)
}
// NumParameters returns the number of parameters in the distribution.
func (b Beta) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (b Beta) Prob(x float64) float64 {
return math.Exp(b.LogProb(x))
}
// Quantile returns the inverse of the cumulative distribution function.
func (b Beta) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return mathext.InvRegIncBeta(b.Alpha, b.Beta, p)
}
// Rand returns a random sample drawn from the distribution.
func (b Beta) Rand() float64 {
ga := Gamma{Alpha: b.Alpha, Beta: 1, Src: b.Src}.Rand()
gb := Gamma{Alpha: b.Beta, Beta: 1, Src: b.Src}.Rand()
return ga / (ga + gb)
}
// StdDev returns the standard deviation of the probability distribution.
func (b Beta) StdDev() float64 {
return math.Sqrt(b.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (b Beta) Survival(x float64) float64 {
switch {
case x <= 0:
return 1
case x >= 1:
return 0
}
return mathext.RegIncBeta(b.Beta, b.Alpha, 1-x)
}
// Variance returns the variance of the probability distribution.
func (b Beta) Variance() float64 {
return b.Alpha * b.Beta / ((b.Alpha + b.Beta) * (b.Alpha + b.Beta) * (b.Alpha + b.Beta + 1))
}

190
vendor/gonum.org/v1/gonum/stat/distuv/binomial.go generated vendored Normal file
View File

@@ -0,0 +1,190 @@
// Copyright ©2018 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
"gonum.org/v1/gonum/stat/combin"
)
// Binomial implements the binomial distribution, a discrete probability distribution
// that expresses the probability of a given number of successful Bernoulli trials
// out of a total of n, each with success probability p.
// The binomial distribution has the density function:
//
// f(k) = (n choose k) p^k (1-p)^(n-k)
//
// For more information, see https://en.wikipedia.org/wiki/Binomial_distribution.
type Binomial struct {
// N is the total number of Bernoulli trials. N must be greater than 0.
N float64
// P is the probability of success in any given trial. P must be in [0, 1].
P float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (b Binomial) CDF(x float64) float64 {
if x < 0 {
return 0
}
if x >= b.N {
return 1
}
x = math.Floor(x)
return mathext.RegIncBeta(b.N-x, x+1, 1-b.P)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (b Binomial) ExKurtosis() float64 {
v := b.P * (1 - b.P)
return (1 - 6*v) / (b.N * v)
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (b Binomial) LogProb(x float64) float64 {
if x < 0 || x > b.N || math.Floor(x) != x {
return math.Inf(-1)
}
lb := combin.LogGeneralizedBinomial(b.N, x)
return lb + x*math.Log(b.P) + (b.N-x)*math.Log(1-b.P)
}
// Mean returns the mean of the probability distribution.
func (b Binomial) Mean() float64 {
return b.N * b.P
}
// NumParameters returns the number of parameters in the distribution.
func (Binomial) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (b Binomial) Prob(x float64) float64 {
return math.Exp(b.LogProb(x))
}
// Rand returns a random sample drawn from the distribution.
func (b Binomial) Rand() float64 {
// NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5)
// p. 295-6
// http://www.aip.de/groups/soe/local/numres/bookcpdf/c7-3.pdf
runif := rand.Float64
rexp := rand.ExpFloat64
if b.Src != nil {
rnd := rand.New(b.Src)
runif = rnd.Float64
rexp = rnd.ExpFloat64
}
p := b.P
if p > 0.5 {
p = 1 - p
}
am := b.N * p
if b.N < 25 {
// Use direct method.
bnl := 0.0
for i := 0; i < int(b.N); i++ {
if runif() < p {
bnl++
}
}
if p != b.P {
return b.N - bnl
}
return bnl
}
if am < 1 {
// Use rejection method with Poisson proposal.
const logM = 2.6e-2 // constant for rejection sampling (https://en.wikipedia.org/wiki/Rejection_sampling)
var bnl float64
z := -p
pclog := (1 + 0.5*z) * z / (1 + (1+1.0/6*z)*z) // Padé approximant of log(1 + x)
for {
bnl = 0.0
t := 0.0
for i := 0; i < int(b.N); i++ {
t += rexp()
if t >= am {
break
}
bnl++
}
bnlc := b.N - bnl
z = -bnl / b.N
log1p := (1 + 0.5*z) * z / (1 + (1+1.0/6*z)*z)
t = (bnlc+0.5)*log1p + bnl - bnlc*pclog + 1/(12*bnlc) - am + logM // Uses Stirling's expansion of log(n!)
if rexp() >= t {
break
}
}
if p != b.P {
return b.N - bnl
}
return bnl
}
// Original algorithm samples from a Poisson distribution with the
// appropriate expected value. However, the Poisson approximation is
// asymptotic such that the absolute deviation in probability is O(1/n).
// Rejection sampling produces exact variates with at worst less than 3%
// rejection with minimal additional computation.
// Use rejection method with Cauchy proposal.
g, _ := math.Lgamma(b.N + 1)
plog := math.Log(p)
pclog := math.Log1p(-p)
sq := math.Sqrt(2 * am * (1 - p))
for {
var em, y float64
for {
y = math.Tan(math.Pi * runif())
em = sq*y + am
if em >= 0 && em < b.N+1 {
break
}
}
em = math.Floor(em)
lg1, _ := math.Lgamma(em + 1)
lg2, _ := math.Lgamma(b.N - em + 1)
t := 1.2 * sq * (1 + y*y) * math.Exp(g-lg1-lg2+em*plog+(b.N-em)*pclog)
if runif() <= t {
if p != b.P {
return b.N - em
}
return em
}
}
}
// Skewness returns the skewness of the distribution.
func (b Binomial) Skewness() float64 {
return (1 - 2*b.P) / b.StdDev()
}
// StdDev returns the standard deviation of the probability distribution.
func (b Binomial) StdDev() float64 {
return math.Sqrt(b.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (b Binomial) Survival(x float64) float64 {
return 1 - b.CDF(x)
}
// Variance returns the variance of the probability distribution.
func (b Binomial) Variance() float64 {
return b.N * b.P * (1 - b.P)
}

185
vendor/gonum.org/v1/gonum/stat/distuv/categorical.go generated vendored Normal file
View File

@@ -0,0 +1,185 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// Categorical is an extension of the Bernoulli distribution where x takes
// values {0, 1, ..., len(w)-1} where w is the weight vector. Categorical must
// be initialized with NewCategorical.
type Categorical struct {
weights []float64
// heap is a weight heap.
//
// It keeps a heap-organised sum of remaining
// index weights that are available to be taken
// from.
//
// Each element holds the sum of weights for
// the corresponding index, plus the sum of
// its children's weights; the children of
// an element i can be found at positions
// 2*(i+1)-1 and 2*(i+1). The root of the
// weight heap is at element 0.
//
// See comments in container/heap for an
// explanation of the layout of a heap.
heap []float64
src rand.Source
}
// NewCategorical constructs a new categorical distribution where the probability
// that x equals i is proportional to w[i]. All of the weights must be
// nonnegative, and at least one of the weights must be positive.
func NewCategorical(w []float64, src rand.Source) Categorical {
c := Categorical{
weights: make([]float64, len(w)),
heap: make([]float64, len(w)),
src: src,
}
c.ReweightAll(w)
return c
}
// CDF computes the value of the cumulative density function at x.
func (c Categorical) CDF(x float64) float64 {
var cdf float64
for i, w := range c.weights {
if x < float64(i) {
break
}
cdf += w
}
return cdf / c.heap[0]
}
// Entropy returns the entropy of the distribution.
func (c Categorical) Entropy() float64 {
var ent float64
for _, w := range c.weights {
if w == 0 {
continue
}
p := w / c.heap[0]
ent += p * math.Log(p)
}
return -ent
}
// Len returns the number of values x could possibly take (the length of the
// initial supplied weight vector).
func (c Categorical) Len() int {
return len(c.weights)
}
// Mean returns the mean of the probability distribution.
func (c Categorical) Mean() float64 {
var mean float64
for i, v := range c.weights {
mean += float64(i) * v
}
return mean / c.heap[0]
}
// Prob computes the value of the probability density function at x.
func (c Categorical) Prob(x float64) float64 {
xi := int(x)
if float64(xi) != x {
return 0
}
if xi < 0 || xi > len(c.weights)-1 {
return 0
}
return c.weights[xi] / c.heap[0]
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (c Categorical) LogProb(x float64) float64 {
return math.Log(c.Prob(x))
}
// Rand returns a random draw from the categorical distribution.
func (c Categorical) Rand() float64 {
var r float64
if c.src == nil {
r = c.heap[0] * rand.Float64()
} else {
r = c.heap[0] * rand.New(c.src).Float64()
}
i := 1
last := -1
left := len(c.weights)
for {
if r -= c.weights[i-1]; r <= 0 {
break // Fall within item i-1.
}
i <<= 1 // Move to left child.
if d := c.heap[i-1]; r > d {
r -= d
// If enough r to pass left child,
// move to right child state will
// be caught at break above.
i++
}
if i == last || left < 0 {
panic("categorical: bad sample")
}
last = i
left--
}
return float64(i - 1)
}
// Reweight sets the weight of item idx to w. The input weight must be
// non-negative, and after reweighting at least one of the weights must be
// positive.
func (c Categorical) Reweight(idx int, w float64) {
if w < 0 {
panic("categorical: negative weight")
}
w, c.weights[idx] = c.weights[idx]-w, w
idx++
for idx > 0 {
c.heap[idx-1] -= w
idx >>= 1
}
if c.heap[0] <= 0 {
panic("categorical: sum of the weights non-positive")
}
}
// ReweightAll resets the weights of the distribution. ReweightAll panics if
// len(w) != c.Len. All of the weights must be nonnegative, and at least one of
// the weights must be positive.
func (c Categorical) ReweightAll(w []float64) {
if len(w) != c.Len() {
panic("categorical: length of the slices do not match")
}
for _, v := range w {
if v < 0 {
panic("categorical: negative weight")
}
}
copy(c.weights, w)
c.reset()
}
func (c Categorical) reset() {
copy(c.heap, c.weights)
for i := len(c.heap) - 1; i > 0; i-- {
// Sometimes 1-based counting makes sense.
c.heap[((i+1)>>1)-1] += c.heap[i]
}
// TODO(btracey): Renormalization for weird weights?
if c.heap[0] <= 0 {
panic("categorical: sum of the weights non-positive")
}
}

125
vendor/gonum.org/v1/gonum/stat/distuv/chi.go generated vendored Normal file
View File

@@ -0,0 +1,125 @@
// Copyright ©2021 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// Chi implements the χ distribution, a one parameter distribution
// with support on the positive numbers.
//
// The density function is given by
//
// 1/(2^{k/2-1} * Γ(k/2)) * x^{k - 1} * e^{-x^2/2}
//
// For more information, see https://en.wikipedia.org/wiki/Chi_distribution.
type Chi struct {
// K is the shape parameter, corresponding to the degrees of freedom. Must
// be greater than 0.
K float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (c Chi) CDF(x float64) float64 {
return mathext.GammaIncReg(c.K/2, (x*x)/2)
}
// Entropy returns the differential entropy of the distribution.
func (c Chi) Entropy() float64 {
lg, _ := math.Lgamma(c.K / 2)
return lg + 0.5*(c.K-math.Ln2-(c.K-1)*mathext.Digamma(c.K/2))
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (c Chi) ExKurtosis() float64 {
v := c.Variance()
s := math.Sqrt(v)
return 2 / v * (1 - c.Mean()*s*c.Skewness() - v)
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (c Chi) LogProb(x float64) float64 {
if x < 0 {
return math.Inf(-1)
}
lg, _ := math.Lgamma(c.K / 2)
return (c.K-1)*math.Log(x) - (x*x)/2 - (c.K/2-1)*math.Ln2 - lg
}
// Mean returns the mean of the probability distribution.
func (c Chi) Mean() float64 {
lg1, _ := math.Lgamma((c.K + 1) / 2)
lg, _ := math.Lgamma(c.K / 2)
return math.Sqrt2 * math.Exp(lg1-lg)
}
// Median returns the median of the distribution.
func (c Chi) Median() float64 {
return c.Quantile(0.5)
}
// Mode returns the mode of the distribution.
//
// Mode returns NaN if K is less than one.
func (c Chi) Mode() float64 {
return math.Sqrt(c.K - 1)
}
// NumParameters returns the number of parameters in the distribution.
func (c Chi) NumParameters() int {
return 1
}
// Prob computes the value of the probability density function at x.
func (c Chi) Prob(x float64) float64 {
return math.Exp(c.LogProb(x))
}
// Rand returns a random sample drawn from the distribution.
func (c Chi) Rand() float64 {
return math.Sqrt(Gamma{c.K / 2, 0.5, c.Src}.Rand())
}
// Quantile returns the inverse of the cumulative distribution function.
func (c Chi) Quantile(p float64) float64 {
if p < 0 || 1 < p {
panic(badPercentile)
}
return math.Sqrt(2 * mathext.GammaIncRegInv(0.5*c.K, p))
}
// Skewness returns the skewness of the distribution.
func (c Chi) Skewness() float64 {
v := c.Variance()
s := math.Sqrt(v)
return c.Mean() / (s * v) * (1 - 2*v)
}
// StdDev returns the standard deviation of the probability distribution.
func (c Chi) StdDev() float64 {
return math.Sqrt(c.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (c Chi) Survival(x float64) float64 {
if x < 0 {
return 1
}
return mathext.GammaIncRegComp(0.5*c.K, 0.5*(x*x))
}
// Variance returns the variance of the probability distribution.
func (c Chi) Variance() float64 {
m := c.Mean()
return math.Max(0, c.K-m*m)
}

102
vendor/gonum.org/v1/gonum/stat/distuv/chisquared.go generated vendored Normal file
View File

@@ -0,0 +1,102 @@
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// ChiSquared implements the χ² distribution, a one parameter distribution
// with support on the positive numbers.
//
// The density function is given by
//
// 1/(2^{k/2} * Γ(k/2)) * x^{k/2 - 1} * e^{-x/2}
//
// It is a special case of the Gamma distribution, Γ(k/2, 1/2).
//
// For more information, see https://en.wikipedia.org/wiki/Chi-squared_distribution.
type ChiSquared struct {
// K is the shape parameter, corresponding to the degrees of freedom. Must
// be greater than 0.
K float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (c ChiSquared) CDF(x float64) float64 {
return mathext.GammaIncReg(c.K/2, x/2)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (c ChiSquared) ExKurtosis() float64 {
return 12 / c.K
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (c ChiSquared) LogProb(x float64) float64 {
if x < 0 {
return math.Inf(-1)
}
lg, _ := math.Lgamma(c.K / 2)
return (c.K/2-1)*math.Log(x) - x/2 - (c.K/2)*math.Ln2 - lg
}
// Mean returns the mean of the probability distribution.
func (c ChiSquared) Mean() float64 {
return c.K
}
// Mode returns the mode of the distribution.
func (c ChiSquared) Mode() float64 {
return math.Max(c.K-2, 0)
}
// NumParameters returns the number of parameters in the distribution.
func (c ChiSquared) NumParameters() int {
return 1
}
// Prob computes the value of the probability density function at x.
func (c ChiSquared) Prob(x float64) float64 {
return math.Exp(c.LogProb(x))
}
// Rand returns a random sample drawn from the distribution.
func (c ChiSquared) Rand() float64 {
return Gamma{c.K / 2, 0.5, c.Src}.Rand()
}
// Quantile returns the inverse of the cumulative distribution function.
func (c ChiSquared) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return mathext.GammaIncRegInv(0.5*c.K, p) * 2
}
// StdDev returns the standard deviation of the probability distribution.
func (c ChiSquared) StdDev() float64 {
return math.Sqrt(c.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (c ChiSquared) Survival(x float64) float64 {
if x < 0 {
return 1
}
return mathext.GammaIncRegComp(0.5*c.K, 0.5*x)
}
// Variance returns the variance of the probability distribution.
func (c ChiSquared) Variance() float64 {
return 2 * c.K
}

28
vendor/gonum.org/v1/gonum/stat/distuv/constants.go generated vendored Normal file
View File

@@ -0,0 +1,28 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
const (
// oneOverRoot2Pi is the value of 1/(2Pi)^(1/2)
// http://www.wolframalpha.com/input/?i=1%2F%282+*+pi%29%5E%281%2F2%29
oneOverRoot2Pi = 0.39894228040143267793994605993438186847585863116493465766592582967065792589930183850125233390730693643030255886263518268
//LogRoot2Pi is the value of log(sqrt(2*Pi))
logRoot2Pi = 0.91893853320467274178032973640561763986139747363778341281715154048276569592726039769474329863595419762200564662463433744
negLogRoot2Pi = -logRoot2Pi
log2Pi = 1.8378770664093454835606594728112352797227949472755668
ln2 = 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754200148102057068573368552023
// EulerMascheroni constant.
eulerGamma = 0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495146314472498070824809605
// sqrt3 is the value of sqrt(3)
// https://www.wolframalpha.com/input/?i=sqrt%283%29
sqrt3 = 1.7320508075688772935274463415058723669428052538103806280558069794519330169088000370811461867572485756756261414154067030299699450
)
const (
panicNameMismatch = "parameter name mismatch"
)

6
vendor/gonum.org/v1/gonum/stat/distuv/doc.go generated vendored Normal file
View File

@@ -0,0 +1,6 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package distuv provides univariate random distribution types.
package distuv // import "gonum.org/v1/gonum/stat/distuv"

267
vendor/gonum.org/v1/gonum/stat/distuv/exponential.go generated vendored Normal file
View File

@@ -0,0 +1,267 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/stat"
)
// Exponential represents the exponential distribution (https://en.wikipedia.org/wiki/Exponential_distribution).
type Exponential struct {
Rate float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (e Exponential) CDF(x float64) float64 {
if x < 0 {
return 0
}
return -math.Expm1(-e.Rate * x)
}
// ConjugateUpdate updates the parameters of the distribution from the sufficient
// statistics of a set of samples. The sufficient statistics, suffStat, have been
// observed with nSamples observations. The prior values of the distribution are those
// currently in the distribution, and have been observed with priorStrength samples.
//
// For the exponential distribution, the sufficient statistic is the inverse of
// the mean of the samples.
// The prior is having seen priorStrength[0] samples with inverse mean Exponential.Rate
// As a result of this function, Exponential.Rate is updated based on the weighted
// samples, and priorStrength is modified to include the new number of samples observed.
//
// This function panics if len(suffStat) != e.NumSuffStat() or
// len(priorStrength) != e.NumSuffStat().
func (e *Exponential) ConjugateUpdate(suffStat []float64, nSamples float64, priorStrength []float64) {
if len(suffStat) != e.NumSuffStat() {
panic("exponential: incorrect suffStat length")
}
if len(priorStrength) != e.NumSuffStat() {
panic("exponential: incorrect priorStrength length")
}
totalSamples := nSamples + priorStrength[0]
totalSum := nSamples / suffStat[0]
if !(priorStrength[0] == 0) {
totalSum += priorStrength[0] / e.Rate
}
e.Rate = totalSamples / totalSum
priorStrength[0] = totalSamples
}
// Entropy returns the entropy of the distribution.
func (e Exponential) Entropy() float64 {
return 1 - math.Log(e.Rate)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (Exponential) ExKurtosis() float64 {
return 6
}
// Fit sets the parameters of the probability distribution from the
// data samples x with relative weights w.
// If weights is nil, then all the weights are 1.
// If weights is not nil, then the len(weights) must equal len(samples).
func (e *Exponential) Fit(samples, weights []float64) {
suffStat := make([]float64, e.NumSuffStat())
nSamples := e.SuffStat(suffStat, samples, weights)
e.ConjugateUpdate(suffStat, nSamples, make([]float64, e.NumSuffStat()))
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (e Exponential) LogProb(x float64) float64 {
if x < 0 {
return math.Inf(-1)
}
return math.Log(e.Rate) - e.Rate*x
}
// Mean returns the mean of the probability distribution.
func (e Exponential) Mean() float64 {
return 1 / e.Rate
}
// Median returns the median of the probability distribution.
func (e Exponential) Median() float64 {
return math.Ln2 / e.Rate
}
// Mode returns the mode of the probability distribution.
func (Exponential) Mode() float64 {
return 0
}
// NumParameters returns the number of parameters in the distribution.
func (Exponential) NumParameters() int {
return 1
}
// NumSuffStat returns the number of sufficient statistics for the distribution.
func (Exponential) NumSuffStat() int {
return 1
}
// Prob computes the value of the probability density function at x.
func (e Exponential) Prob(x float64) float64 {
return math.Exp(e.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (e Exponential) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return -math.Log(1-p) / e.Rate
}
// Rand returns a random sample drawn from the distribution.
func (e Exponential) Rand() float64 {
var rnd float64
if e.Src == nil {
rnd = rand.ExpFloat64()
} else {
rnd = rand.New(e.Src).ExpFloat64()
}
return rnd / e.Rate
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂Rate].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
//
// Special cases:
//
// Score(0) = [NaN]
func (e Exponential) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, e.NumParameters())
}
if len(deriv) != e.NumParameters() {
panic(badLength)
}
if x > 0 {
deriv[0] = 1/e.Rate - x
return deriv
}
if x < 0 {
deriv[0] = 0
return deriv
}
deriv[0] = math.NaN()
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
//
// Special cases:
//
// ScoreInput(0) = NaN
func (e Exponential) ScoreInput(x float64) float64 {
if x > 0 {
return -e.Rate
}
if x < 0 {
return 0
}
return math.NaN()
}
// Skewness returns the skewness of the distribution.
func (Exponential) Skewness() float64 {
return 2
}
// StdDev returns the standard deviation of the probability distribution.
func (e Exponential) StdDev() float64 {
return 1 / e.Rate
}
// SuffStat computes the sufficient statistics of set of samples to update
// the distribution. The sufficient statistics are stored in place, and the
// effective number of samples are returned.
//
// The exponential distribution has one sufficient statistic, the average rate
// of the samples.
//
// If weights is nil, the weights are assumed to be 1, otherwise panics if
// len(samples) != len(weights). Panics if len(suffStat) != NumSuffStat().
func (Exponential) SuffStat(suffStat, samples, weights []float64) (nSamples float64) {
if len(weights) != 0 && len(samples) != len(weights) {
panic(badLength)
}
if len(suffStat) != (Exponential{}).NumSuffStat() {
panic(badSuffStat)
}
if len(weights) == 0 {
nSamples = float64(len(samples))
} else {
nSamples = floats.Sum(weights)
}
mean := stat.Mean(samples, weights)
suffStat[0] = 1 / mean
return nSamples
}
// Survival returns the survival function (complementary CDF) at x.
func (e Exponential) Survival(x float64) float64 {
if x < 0 {
return 1
}
return math.Exp(-e.Rate * x)
}
// setParameters modifies the parameters of the distribution.
func (e *Exponential) setParameters(p []Parameter) {
if len(p) != e.NumParameters() {
panic("exponential: incorrect number of parameters to set")
}
if p[0].Name != "Rate" {
panic("exponential: " + panicNameMismatch)
}
e.Rate = p[0].Value
}
// Variance returns the variance of the probability distribution.
func (e Exponential) Variance() float64 {
return 1 / (e.Rate * e.Rate)
}
// parameters returns the parameters of the distribution.
func (e Exponential) parameters(p []Parameter) []Parameter {
nParam := e.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic("exponential: improper parameter length")
}
p[0].Name = "Rate"
p[0].Value = e.Rate
return p
}

135
vendor/gonum.org/v1/gonum/stat/distuv/f.go generated vendored Normal file
View File

@@ -0,0 +1,135 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// F implements the F-distribution, a two-parameter continuous distribution
// with support over the positive real numbers.
//
// The F-distribution has density function
//
// sqrt(((d1*x)^d1) * d2^d2 / ((d1*x+d2)^(d1+d2))) / (x * B(d1/2,d2/2))
//
// where B is the beta function.
//
// For more information, see https://en.wikipedia.org/wiki/F-distribution
type F struct {
D1 float64 // Degrees of freedom for the numerator
D2 float64 // Degrees of freedom for the denominator
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (f F) CDF(x float64) float64 {
return mathext.RegIncBeta(f.D1/2, f.D2/2, f.D1*x/(f.D1*x+f.D2))
}
// ExKurtosis returns the excess kurtosis of the distribution.
//
// ExKurtosis returns NaN if the D2 parameter is less or equal to 8.
func (f F) ExKurtosis() float64 {
if f.D2 <= 8 {
return math.NaN()
}
return (12 / (f.D2 - 6)) * ((5*f.D2-22)/(f.D2-8) + ((f.D2-4)/f.D1)*((f.D2-2)/(f.D2-8))*((f.D2-2)/(f.D1+f.D2-2)))
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (f F) LogProb(x float64) float64 {
return 0.5*(f.D1*math.Log(f.D1*x)+f.D2*math.Log(f.D2)-(f.D1+f.D2)*math.Log(f.D1*x+f.D2)) - math.Log(x) - mathext.Lbeta(f.D1/2, f.D2/2)
}
// Mean returns the mean of the probability distribution.
//
// Mean returns NaN if the D2 parameter is less than or equal to 2.
func (f F) Mean() float64 {
if f.D2 <= 2 {
return math.NaN()
}
return f.D2 / (f.D2 - 2)
}
// Mode returns the mode of the distribution.
//
// Mode returns NaN if the D1 parameter is less than or equal to 2.
func (f F) Mode() float64 {
if f.D1 <= 2 {
return math.NaN()
}
return ((f.D1 - 2) / f.D1) * (f.D2 / (f.D2 + 2))
}
// NumParameters returns the number of parameters in the distribution.
func (f F) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (f F) Prob(x float64) float64 {
return math.Exp(f.LogProb(x))
}
// Quantile returns the inverse of the cumulative distribution function.
func (f F) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
y := mathext.InvRegIncBeta(0.5*f.D1, 0.5*f.D2, p)
return f.D2 * y / (f.D1 * (1 - y))
}
// Rand returns a random sample drawn from the distribution.
func (f F) Rand() float64 {
u1 := ChiSquared{f.D1, f.Src}.Rand()
u2 := ChiSquared{f.D2, f.Src}.Rand()
return (u1 / f.D1) / (u2 / f.D2)
}
// Skewness returns the skewness of the distribution.
//
// Skewness returns NaN if the D2 parameter is less than or equal to 6.
func (f F) Skewness() float64 {
if f.D2 <= 6 {
return math.NaN()
}
num := (2*f.D1 + f.D2 - 2) * math.Sqrt(8*(f.D2-4))
den := (f.D2 - 6) * math.Sqrt(f.D1*(f.D1+f.D2-2))
return num / den
}
// StdDev returns the standard deviation of the probability distribution.
//
// StdDev returns NaN if the D2 parameter is less than or equal to 4.
func (f F) StdDev() float64 {
if f.D2 <= 4 {
return math.NaN()
}
return math.Sqrt(f.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (f F) Survival(x float64) float64 {
return 1 - f.CDF(x)
}
// Variance returns the variance of the probability distribution.
//
// Variance returns NaN if the D2 parameter is less than or equal to 4.
func (f F) Variance() float64 {
if f.D2 <= 4 {
return math.NaN()
}
num := 2 * f.D2 * f.D2 * (f.D1 + f.D2 - 2)
den := f.D1 * (f.D2 - 2) * (f.D2 - 2) * (f.D2 - 4)
return num / den
}

201
vendor/gonum.org/v1/gonum/stat/distuv/gamma.go generated vendored Normal file
View File

@@ -0,0 +1,201 @@
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// Gamma implements the Gamma distribution, a two-parameter continuous distribution
// with support over the positive real numbers.
//
// The gamma distribution has density function
//
// β^α / Γ(α) x^(α-1)e^(-βx)
//
// For more information, see https://en.wikipedia.org/wiki/Gamma_distribution
type Gamma struct {
// Alpha is the shape parameter of the distribution. Alpha must be greater
// than 0. If Alpha == 1, this is equivalent to an exponential distribution.
Alpha float64
// Beta is the rate parameter of the distribution. Beta must be greater than 0.
// If Beta == 2, this is equivalent to a Chi-Squared distribution.
Beta float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (g Gamma) CDF(x float64) float64 {
if x < 0 {
return 0
}
return mathext.GammaIncReg(g.Alpha, g.Beta*x)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (g Gamma) ExKurtosis() float64 {
return 6 / g.Alpha
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (g Gamma) LogProb(x float64) float64 {
if x <= 0 {
return math.Inf(-1)
}
a := g.Alpha
b := g.Beta
lg, _ := math.Lgamma(a)
return a*math.Log(b) - lg + (a-1)*math.Log(x) - b*x
}
// Mean returns the mean of the probability distribution.
func (g Gamma) Mean() float64 {
return g.Alpha / g.Beta
}
// Mode returns the mode of the normal distribution.
//
// The mode is NaN in the special case where the Alpha (shape) parameter
// is less than 1.
func (g Gamma) Mode() float64 {
if g.Alpha < 1 {
return math.NaN()
}
return (g.Alpha - 1) / g.Beta
}
// NumParameters returns the number of parameters in the distribution.
func (Gamma) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (g Gamma) Prob(x float64) float64 {
return math.Exp(g.LogProb(x))
}
// Quantile returns the inverse of the cumulative distribution function.
func (g Gamma) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return mathext.GammaIncRegInv(g.Alpha, p) / g.Beta
}
// Rand returns a random sample drawn from the distribution.
//
// Rand panics if either alpha or beta is <= 0.
func (g Gamma) Rand() float64 {
const (
// The 0.2 threshold is from https://www4.stat.ncsu.edu/~rmartin/Codes/rgamss.R
// described in detail in https://arxiv.org/abs/1302.1884.
smallAlphaThresh = 0.2
)
if g.Beta <= 0 {
panic("gamma: beta <= 0")
}
unifrnd := rand.Float64
exprnd := rand.ExpFloat64
normrnd := rand.NormFloat64
if g.Src != nil {
rnd := rand.New(g.Src)
unifrnd = rnd.Float64
exprnd = rnd.ExpFloat64
normrnd = rnd.NormFloat64
}
a := g.Alpha
b := g.Beta
switch {
case a <= 0:
panic("gamma: alpha <= 0")
case a == 1:
// Generate from exponential
return exprnd() / b
case a < smallAlphaThresh:
// Generate using
// Liu, Chuanhai, Martin, Ryan and Syring, Nick. "Simulating from a
// gamma distribution with small shape parameter"
// https://arxiv.org/abs/1302.1884
// use this reference: http://link.springer.com/article/10.1007/s00180-016-0692-0
// Algorithm adjusted to work in log space as much as possible.
lambda := 1/a - 1
lr := -math.Log1p(1 / lambda / math.E)
for {
e := exprnd()
var z float64
if e >= -lr {
z = e + lr
} else {
z = -exprnd() / lambda
}
eza := math.Exp(-z / a)
lh := -z - eza
var lEta float64
if z >= 0 {
lEta = -z
} else {
lEta = -1 + lambda*z
}
if lh-lEta > -exprnd() {
return eza / b
}
}
case a >= smallAlphaThresh:
// Generate using:
// Marsaglia, George, and Wai Wan Tsang. "A simple method for generating
// gamma variables." ACM Transactions on Mathematical Software (TOMS)
// 26.3 (2000): 363-372.
d := a - 1.0/3
m := 1.0
if a < 1 {
d += 1.0
m = math.Pow(unifrnd(), 1/a)
}
c := 1 / (3 * math.Sqrt(d))
for {
x := normrnd()
v := 1 + x*c
if v <= 0.0 {
continue
}
v = v * v * v
u := unifrnd()
if u < 1.0-0.0331*(x*x)*(x*x) {
return m * d * v / b
}
if math.Log(u) < 0.5*x*x+d*(1-v+math.Log(v)) {
return m * d * v / b
}
}
}
panic("unreachable")
}
// Survival returns the survival function (complementary CDF) at x.
func (g Gamma) Survival(x float64) float64 {
if x < 0 {
return 1
}
return mathext.GammaIncRegComp(g.Alpha, g.Beta*x)
}
// StdDev returns the standard deviation of the probability distribution.
func (g Gamma) StdDev() float64 {
return math.Sqrt(g.Alpha) / g.Beta
}
// Variance returns the variance of the probability distribution.
func (g Gamma) Variance() float64 {
return g.Alpha / g.Beta / g.Beta
}

24
vendor/gonum.org/v1/gonum/stat/distuv/general.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
// Parameter represents a parameter of a probability distribution
type Parameter struct {
Name string
Value float64
}
const (
badPercentile = "distuv: percentile out of bounds"
badLength = "distuv: slice length mismatch"
badSuffStat = "distuv: wrong suffStat length"
errNoSamples = "distuv: must have at least one sample"
)
const (
expNegOneHalf = 0.6065306597126334236037995349911804534419 // https://oeis.org/A092605
eulerMascheroni = 0.5772156649015328606065120900824024310421 // https://oeis.org/A001620
apery = 1.2020569031595942853997381615114499907649 // https://oeis.org/A002117
)

119
vendor/gonum.org/v1/gonum/stat/distuv/gumbel.go generated vendored Normal file
View File

@@ -0,0 +1,119 @@
// Copyright ©2018 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// GumbelRight implements the right-skewed Gumbel distribution, a two-parameter
// continuous distribution with support over the real numbers. The right-skewed
// Gumbel distribution is also sometimes known as the Extreme Value distribution.
//
// The right-skewed Gumbel distribution has density function
//
// 1/beta * exp(-(z + exp(-z)))
// z = (x - mu)/beta
//
// Beta must be greater than 0.
//
// For more information, see https://en.wikipedia.org/wiki/Gumbel_distribution.
type GumbelRight struct {
Mu float64
Beta float64
Src rand.Source
}
func (g GumbelRight) z(x float64) float64 {
return (x - g.Mu) / g.Beta
}
// CDF computes the value of the cumulative density function at x.
func (g GumbelRight) CDF(x float64) float64 {
z := g.z(x)
return math.Exp(-math.Exp(-z))
}
// Entropy returns the differential entropy of the distribution.
func (g GumbelRight) Entropy() float64 {
return math.Log(g.Beta) + eulerMascheroni + 1
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (g GumbelRight) ExKurtosis() float64 {
return 12.0 / 5
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (g GumbelRight) LogProb(x float64) float64 {
z := g.z(x)
return -math.Log(g.Beta) - z - math.Exp(-z)
}
// Mean returns the mean of the probability distribution.
func (g GumbelRight) Mean() float64 {
return g.Mu + g.Beta*eulerMascheroni
}
// Median returns the median of the Gumbel distribution.
func (g GumbelRight) Median() float64 {
return g.Mu - g.Beta*math.Log(math.Ln2)
}
// Mode returns the mode of the normal distribution.
func (g GumbelRight) Mode() float64 {
return g.Mu
}
// NumParameters returns the number of parameters in the distribution.
func (GumbelRight) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (g GumbelRight) Prob(x float64) float64 {
return math.Exp(g.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (g GumbelRight) Quantile(p float64) float64 {
if p < 0 || 1 < p {
panic(badPercentile)
}
return g.Mu - g.Beta*math.Log(-math.Log(p))
}
// Rand returns a random sample drawn from the distribution.
func (g GumbelRight) Rand() float64 {
var rnd float64
if g.Src == nil {
rnd = rand.ExpFloat64()
} else {
rnd = rand.New(g.Src).ExpFloat64()
}
return g.Mu - g.Beta*math.Log(rnd)
}
// Skewness returns the skewness of the distribution.
func (GumbelRight) Skewness() float64 {
return 12 * math.Sqrt(6) * apery / (math.Pi * math.Pi * math.Pi)
}
// StdDev returns the standard deviation of the probability distribution.
func (g GumbelRight) StdDev() float64 {
return (math.Pi / math.Sqrt(6)) * g.Beta
}
// Survival returns the survival function (complementary CDF) at x.
func (g GumbelRight) Survival(x float64) float64 {
return 1 - g.CDF(x)
}
// Variance returns the variance of the probability distribution.
func (g GumbelRight) Variance() float64 {
return math.Pi * math.Pi * g.Beta * g.Beta / 6
}

32
vendor/gonum.org/v1/gonum/stat/distuv/interfaces.go generated vendored Normal file
View File

@@ -0,0 +1,32 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
// LogProber wraps the LogProb method.
type LogProber interface {
// LogProb returns the natural logarithm of the
// value of the probability density or probability
// mass function at x.
LogProb(x float64) float64
}
// Rander wraps the Rand method.
type Rander interface {
// Rand returns a random sample drawn from the distribution.
Rand() float64
}
// RandLogProber is the interface that groups the Rander and LogProber methods.
type RandLogProber interface {
Rander
LogProber
}
// Quantiler wraps the Quantile method.
type Quantiler interface {
// Quantile returns the minimum value of x from amongst
// all those values whose CDF value exceeds or equals p.
Quantile(p float64) float64
}

124
vendor/gonum.org/v1/gonum/stat/distuv/inversegamma.go generated vendored Normal file
View File

@@ -0,0 +1,124 @@
// Copyright ©2018 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// InverseGamma implements the inverse gamma distribution, a two-parameter
// continuous distribution with support over the positive real numbers. The
// inverse gamma distribution is the same as the distribution of the reciprocal
// of a gamma distributed random variable.
//
// The inverse gamma distribution has density function
//
// β^α / Γ(α) x^(-α-1)e^(-β/x)
//
// For more information, see https://en.wikipedia.org/wiki/Inverse-gamma_distribution
type InverseGamma struct {
// Alpha is the shape parameter of the distribution. Alpha must be greater than 0.
Alpha float64
// Beta is the scale parameter of the distribution. Beta must be greater than 0.
Beta float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (g InverseGamma) CDF(x float64) float64 {
if x < 0 {
return 0
}
// TODO(btracey): Replace this with a direct call to the upper regularized
// gamma function if mathext gets it.
//return 1 - mathext.GammaInc(g.Alpha, g.Beta/x)
return mathext.GammaIncRegComp(g.Alpha, g.Beta/x)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (g InverseGamma) ExKurtosis() float64 {
if g.Alpha <= 4 {
return math.Inf(1)
}
return (30*g.Alpha - 66) / (g.Alpha - 3) / (g.Alpha - 4)
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (g InverseGamma) LogProb(x float64) float64 {
if x <= 0 {
return math.Inf(-1)
}
a := g.Alpha
b := g.Beta
lg, _ := math.Lgamma(a)
return a*math.Log(b) - lg + (-a-1)*math.Log(x) - b/x
}
// Mean returns the mean of the probability distribution.
func (g InverseGamma) Mean() float64 {
if g.Alpha <= 1 {
return math.Inf(1)
}
return g.Beta / (g.Alpha - 1)
}
// Mode returns the mode of the distribution.
func (g InverseGamma) Mode() float64 {
return g.Beta / (g.Alpha + 1)
}
// NumParameters returns the number of parameters in the distribution.
func (InverseGamma) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (g InverseGamma) Prob(x float64) float64 {
return math.Exp(g.LogProb(x))
}
// Quantile returns the inverse of the cumulative distribution function.
func (g InverseGamma) Quantile(p float64) float64 {
if p < 0 || 1 < p {
panic(badPercentile)
}
return (1 / (mathext.GammaIncRegCompInv(g.Alpha, p))) * g.Beta
}
// Rand returns a random sample drawn from the distribution.
//
// Rand panics if either alpha or beta is <= 0.
func (g InverseGamma) Rand() float64 {
// TODO(btracey): See if there is a more direct way to sample.
return 1 / Gamma(g).Rand()
}
// Survival returns the survival function (complementary CDF) at x.
func (g InverseGamma) Survival(x float64) float64 {
if x < 0 {
return 1
}
return mathext.GammaIncReg(g.Alpha, g.Beta/x)
}
// StdDev returns the standard deviation of the probability distribution.
func (g InverseGamma) StdDev() float64 {
return math.Sqrt(g.Variance())
}
// Variance returns the variance of the probability distribution.
func (g InverseGamma) Variance() float64 {
if g.Alpha <= 2 {
return math.Inf(1)
}
v := g.Beta / (g.Alpha - 1)
return v * v / (g.Alpha - 2)
}

267
vendor/gonum.org/v1/gonum/stat/distuv/laplace.go generated vendored Normal file
View File

@@ -0,0 +1,267 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"sort"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/stat"
)
// Laplace represents the Laplace distribution (https://en.wikipedia.org/wiki/Laplace_distribution).
type Laplace struct {
Mu float64 // Mean of the Laplace distribution
Scale float64 // Scale of the Laplace distribution
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (l Laplace) CDF(x float64) float64 {
if x < l.Mu {
return 0.5 * math.Exp((x-l.Mu)/l.Scale)
}
return 1 - 0.5*math.Exp(-(x-l.Mu)/l.Scale)
}
// Entropy returns the entropy of the distribution.
func (l Laplace) Entropy() float64 {
return 1 + math.Log(2*l.Scale)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (l Laplace) ExKurtosis() float64 {
return 3
}
// Fit sets the parameters of the probability distribution from the
// data samples x with relative weights w.
// If weights is nil, then all the weights are 1.
// If weights is not nil, then the len(weights) must equal len(samples).
//
// Note: Laplace distribution has no FitPrior because it has no sufficient
// statistics.
func (l *Laplace) Fit(samples, weights []float64) {
if weights != nil && len(samples) != len(weights) {
panic(badLength)
}
if len(samples) == 0 {
panic(errNoSamples)
}
if len(samples) == 1 {
l.Mu = samples[0]
l.Scale = 0
return
}
var (
sortedSamples []float64
sortedWeights []float64
)
if sort.Float64sAreSorted(samples) {
sortedSamples = samples
sortedWeights = weights
} else {
// Need to copy variables so the input variables aren't effected by the sorting
sortedSamples = make([]float64, len(samples))
copy(sortedSamples, samples)
sortedWeights := make([]float64, len(samples))
copy(sortedWeights, weights)
stat.SortWeighted(sortedSamples, sortedWeights)
}
// The (weighted) median of the samples is the maximum likelihood estimate
// of the mean parameter
// TODO: Rethink quantile type when stat has more options
l.Mu = stat.Quantile(0.5, stat.Empirical, sortedSamples, sortedWeights)
// The scale parameter is the average absolute distance
// between the sample and the mean
var absError float64
var sumWeights float64
if weights != nil {
for i, v := range samples {
absError += weights[i] * math.Abs(l.Mu-v)
sumWeights += weights[i]
}
l.Scale = absError / sumWeights
} else {
for _, v := range samples {
absError += math.Abs(l.Mu - v)
}
l.Scale = absError / float64(len(samples))
}
}
// LogProb computes the natural logarithm of the value of the probability density
// function at x.
func (l Laplace) LogProb(x float64) float64 {
return -math.Ln2 - math.Log(l.Scale) - math.Abs(x-l.Mu)/l.Scale
}
// parameters returns the parameters of the distribution.
func (l Laplace) parameters(p []Parameter) []Parameter {
nParam := l.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic(badLength)
}
p[0].Name = "Mu"
p[0].Value = l.Mu
p[1].Name = "Scale"
p[1].Value = l.Scale
return p
}
// Mean returns the mean of the probability distribution.
func (l Laplace) Mean() float64 {
return l.Mu
}
// Median returns the median of the LaPlace distribution.
func (l Laplace) Median() float64 {
return l.Mu
}
// Mode returns the mode of the LaPlace distribution.
func (l Laplace) Mode() float64 {
return l.Mu
}
// NumParameters returns the number of parameters in the distribution.
func (l Laplace) NumParameters() int {
return 2
}
// Quantile returns the inverse of the cumulative probability distribution.
func (l Laplace) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
if p < 0.5 {
return l.Mu + l.Scale*math.Log(1+2*(p-0.5))
}
return l.Mu - l.Scale*math.Log(1-2*(p-0.5))
}
// Prob computes the value of the probability density function at x.
func (l Laplace) Prob(x float64) float64 {
return math.Exp(l.LogProb(x))
}
// Rand returns a random sample drawn from the distribution.
func (l Laplace) Rand() float64 {
var rnd float64
if l.Src == nil {
rnd = rand.Float64()
} else {
rnd = rand.New(l.Src).Float64()
}
u := rnd - 0.5
if u < 0 {
return l.Mu + l.Scale*math.Log(1+2*u)
}
return l.Mu - l.Scale*math.Log(1-2*u)
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Scale].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
//
// Special cases:
//
// Score(l.Mu) = [NaN, -1/l.Scale]
func (l Laplace) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, l.NumParameters())
}
if len(deriv) != l.NumParameters() {
panic(badLength)
}
diff := x - l.Mu
if diff > 0 {
deriv[0] = 1 / l.Scale
} else if diff < 0 {
deriv[0] = -1 / l.Scale
} else {
// must be NaN
deriv[0] = math.NaN()
}
deriv[1] = math.Abs(diff)/(l.Scale*l.Scale) - 1/l.Scale
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
//
// Special cases:
//
// ScoreInput(l.Mu) = NaN
func (l Laplace) ScoreInput(x float64) float64 {
diff := x - l.Mu
if diff == 0 {
return math.NaN()
}
if diff > 0 {
return -1 / l.Scale
}
return 1 / l.Scale
}
// Skewness returns the skewness of the distribution.
func (Laplace) Skewness() float64 {
return 0
}
// StdDev returns the standard deviation of the distribution.
func (l Laplace) StdDev() float64 {
return math.Sqrt2 * l.Scale
}
// Survival returns the survival function (complementary CDF) at x.
func (l Laplace) Survival(x float64) float64 {
if x < l.Mu {
return 1 - 0.5*math.Exp((x-l.Mu)/l.Scale)
}
return 0.5 * math.Exp(-(x-l.Mu)/l.Scale)
}
// setParameters modifies the parameters of the distribution.
func (l *Laplace) setParameters(p []Parameter) {
if len(p) != l.NumParameters() {
panic(badLength)
}
if p[0].Name != "Mu" {
panic("laplace: " + panicNameMismatch)
}
if p[1].Name != "Scale" {
panic("laplace: " + panicNameMismatch)
}
l.Mu = p[0].Value
l.Scale = p[1].Value
}
// Variance returns the variance of the probability distribution.
func (l Laplace) Variance() float64 {
return 2 * l.Scale * l.Scale
}

98
vendor/gonum.org/v1/gonum/stat/distuv/logistic.go generated vendored Normal file
View File

@@ -0,0 +1,98 @@
// Copyright ©2021 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
)
// Logistic implements the Logistic distribution, a two-parameter distribution with support on the real axis.
// Its cumulative distribution function is the logistic function.
//
// General form of probability density function for Logistic distribution is
//
// E(x) / (s * (1 + E(x))^2)
// where E(x) = exp(-(x-μ)/s)
//
// For more information, see https://en.wikipedia.org/wiki/Logistic_distribution.
type Logistic struct {
Mu float64 // Mean value
S float64 // Scale parameter proportional to standard deviation
}
// CDF computes the value of the cumulative density function at x.
func (l Logistic) CDF(x float64) float64 {
return 1 / (1 + math.Exp(-(x-l.Mu)/l.S))
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (l Logistic) ExKurtosis() float64 {
return 6.0 / 5.0
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (l Logistic) LogProb(x float64) float64 {
return x - 2*math.Log(math.Exp(x)+1)
}
// Mean returns the mean of the probability distribution.
func (l Logistic) Mean() float64 {
return l.Mu
}
// Mode returns the mode of the distribution.
//
// It is same as Mean for Logistic distribution.
func (l Logistic) Mode() float64 {
return l.Mu
}
// Median returns the median of the distribution.
//
// It is same as Mean for Logistic distribution.
func (l Logistic) Median() float64 {
return l.Mu
}
// NumParameters returns the number of parameters in the distribution.
//
// Always returns 2.
func (l Logistic) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (l Logistic) Prob(x float64) float64 {
E := math.Exp(-(x - l.Mu) / l.S)
return E / (l.S * math.Pow(1+E, 2))
}
// Quantile returns the inverse of the cumulative distribution function.
func (l Logistic) Quantile(p float64) float64 {
return l.Mu + l.S*math.Log(p/(1-p))
}
// Skewness returns the skewness of the distribution.
//
// Always 0 for Logistic distribution.
func (l Logistic) Skewness() float64 {
return 0
}
// StdDev returns the standard deviation of the probability distribution.
func (l Logistic) StdDev() float64 {
return l.S * math.Pi / sqrt3
}
// Survival returns the survival function (complementary CDF) at x.
func (l Logistic) Survival(x float64) float64 {
return 1 - l.CDF(x)
}
// Variance returns the variance of the probability distribution.
func (l Logistic) Variance() float64 {
return l.S * l.S * math.Pi * math.Pi / 3
}

114
vendor/gonum.org/v1/gonum/stat/distuv/lognormal.go generated vendored Normal file
View File

@@ -0,0 +1,114 @@
// Copyright ©2015 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// LogNormal represents a random variable whose log is normally distributed.
// The probability density function is given by
//
// 1/(x σ √2π) exp(-(ln(x)-μ)^2)/(2σ^2))
type LogNormal struct {
Mu float64
Sigma float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (l LogNormal) CDF(x float64) float64 {
return 0.5 * math.Erfc(-(math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma))
}
// Entropy returns the differential entropy of the distribution.
func (l LogNormal) Entropy() float64 {
return 0.5 + 0.5*math.Log(2*math.Pi*l.Sigma*l.Sigma) + l.Mu
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (l LogNormal) ExKurtosis() float64 {
s2 := l.Sigma * l.Sigma
return math.Exp(4*s2) + 2*math.Exp(3*s2) + 3*math.Exp(2*s2) - 6
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (l LogNormal) LogProb(x float64) float64 {
if x < 0 {
return math.Inf(-1)
}
logx := math.Log(x)
normdiff := (logx - l.Mu) / l.Sigma
return -0.5*normdiff*normdiff - logx - math.Log(l.Sigma) - logRoot2Pi
}
// Mean returns the mean of the probability distribution.
func (l LogNormal) Mean() float64 {
return math.Exp(l.Mu + 0.5*l.Sigma*l.Sigma)
}
// Median returns the median of the probability distribution.
func (l LogNormal) Median() float64 {
return math.Exp(l.Mu)
}
// Mode returns the mode of the probability distribution.
func (l LogNormal) Mode() float64 {
return math.Exp(l.Mu - l.Sigma*l.Sigma)
}
// NumParameters returns the number of parameters in the distribution.
func (LogNormal) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (l LogNormal) Prob(x float64) float64 {
return math.Exp(l.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (l LogNormal) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
// Formula from http://www.math.uah.edu/stat/special/LogNormal.html.
return math.Exp(l.Mu + l.Sigma*UnitNormal.Quantile(p))
}
// Rand returns a random sample drawn from the distribution.
func (l LogNormal) Rand() float64 {
var rnd float64
if l.Src == nil {
rnd = rand.NormFloat64()
} else {
rnd = rand.New(l.Src).NormFloat64()
}
return math.Exp(rnd*l.Sigma + l.Mu)
}
// Skewness returns the skewness of the distribution.
func (l LogNormal) Skewness() float64 {
s2 := l.Sigma * l.Sigma
return (math.Exp(s2) + 2) * math.Sqrt(math.Exp(s2)-1)
}
// StdDev returns the standard deviation of the probability distribution.
func (l LogNormal) StdDev() float64 {
return math.Sqrt(l.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (l LogNormal) Survival(x float64) float64 {
return 0.5 * (1 - math.Erf((math.Log(x)-l.Mu)/(math.Sqrt2*l.Sigma)))
}
// Variance returns the variance of the probability distribution.
func (l LogNormal) Variance() float64 {
s2 := l.Sigma * l.Sigma
return (math.Exp(s2) - 1) * math.Exp(2*l.Mu+s2)
}

264
vendor/gonum.org/v1/gonum/stat/distuv/norm.go generated vendored Normal file
View File

@@ -0,0 +1,264 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/floats"
"gonum.org/v1/gonum/mathext"
"gonum.org/v1/gonum/stat"
)
// UnitNormal is an instantiation of the normal distribution with Mu = 0 and Sigma = 1.
var UnitNormal = Normal{Mu: 0, Sigma: 1}
// Normal represents a normal (Gaussian) distribution (https://en.wikipedia.org/wiki/Normal_distribution).
type Normal struct {
Mu float64 // Mean of the normal distribution
Sigma float64 // Standard deviation of the normal distribution
Src rand.Source
// Needs to be Mu and Sigma and not Mean and StdDev because Normal has functions
// Mean and StdDev
}
// CDF computes the value of the cumulative density function at x.
func (n Normal) CDF(x float64) float64 {
return 0.5 * math.Erfc(-(x-n.Mu)/(n.Sigma*math.Sqrt2))
}
// ConjugateUpdate updates the parameters of the distribution from the sufficient
// statistics of a set of samples. The sufficient statistics, suffStat, have been
// observed with nSamples observations. The prior values of the distribution are those
// currently in the distribution, and have been observed with priorStrength samples.
//
// For the normal distribution, the sufficient statistics are the mean and
// uncorrected standard deviation of the samples.
// The prior is having seen strength[0] samples with mean Normal.Mu
// and strength[1] samples with standard deviation Normal.Sigma. As a result of
// this function, Normal.Mu and Normal.Sigma are updated based on the weighted
// samples, and strength is modified to include the new number of samples observed.
//
// This function panics if len(suffStat) != n.NumSuffStat() or
// len(priorStrength) != n.NumSuffStat().
func (n *Normal) ConjugateUpdate(suffStat []float64, nSamples float64, priorStrength []float64) {
// TODO: Support prior strength with math.Inf(1) to allow updating with
// a known mean/standard deviation
if len(suffStat) != n.NumSuffStat() {
panic("norm: incorrect suffStat length")
}
if len(priorStrength) != n.NumSuffStat() {
panic("norm: incorrect priorStrength length")
}
totalMeanSamples := nSamples + priorStrength[0]
totalSum := suffStat[0]*nSamples + n.Mu*priorStrength[0]
totalVarianceSamples := nSamples + priorStrength[1]
// sample variance
totalVariance := nSamples * suffStat[1] * suffStat[1]
// add prior variance
totalVariance += priorStrength[1] * n.Sigma * n.Sigma
// add cross variance from the difference of the means
meanDiff := (suffStat[0] - n.Mu)
totalVariance += priorStrength[0] * nSamples * meanDiff * meanDiff / totalMeanSamples
n.Mu = totalSum / totalMeanSamples
n.Sigma = math.Sqrt(totalVariance / totalVarianceSamples)
floats.AddConst(nSamples, priorStrength)
}
// Entropy returns the differential entropy of the distribution.
func (n Normal) Entropy() float64 {
return 0.5 * (log2Pi + 1 + 2*math.Log(n.Sigma))
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (Normal) ExKurtosis() float64 {
return 0
}
// Fit sets the parameters of the probability distribution from the
// data samples x with relative weights w. If weights is nil, then all the weights
// are 1. If weights is not nil, then the len(weights) must equal len(samples).
func (n *Normal) Fit(samples, weights []float64) {
suffStat := make([]float64, n.NumSuffStat())
nSamples := n.SuffStat(suffStat, samples, weights)
n.ConjugateUpdate(suffStat, nSamples, make([]float64, n.NumSuffStat()))
}
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (n Normal) LogProb(x float64) float64 {
return negLogRoot2Pi - math.Log(n.Sigma) - (x-n.Mu)*(x-n.Mu)/(2*n.Sigma*n.Sigma)
}
// Mean returns the mean of the probability distribution.
func (n Normal) Mean() float64 {
return n.Mu
}
// Median returns the median of the normal distribution.
func (n Normal) Median() float64 {
return n.Mu
}
// Mode returns the mode of the normal distribution.
func (n Normal) Mode() float64 {
return n.Mu
}
// NumParameters returns the number of parameters in the distribution.
func (Normal) NumParameters() int {
return 2
}
// NumSuffStat returns the number of sufficient statistics for the distribution.
func (Normal) NumSuffStat() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (n Normal) Prob(x float64) float64 {
return math.Exp(n.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (n Normal) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return n.Mu + n.Sigma*mathext.NormalQuantile(p)
}
// Rand returns a random sample drawn from the distribution.
func (n Normal) Rand() float64 {
var rnd float64
if n.Src == nil {
rnd = rand.NormFloat64()
} else {
rnd = rand.New(n.Src).NormFloat64()
}
return rnd*n.Sigma + n.Mu
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Sigma].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
func (n Normal) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, n.NumParameters())
}
if len(deriv) != n.NumParameters() {
panic(badLength)
}
deriv[0] = (x - n.Mu) / (n.Sigma * n.Sigma)
deriv[1] = 1 / n.Sigma * (-1 + ((x-n.Mu)/n.Sigma)*((x-n.Mu)/n.Sigma))
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
func (n Normal) ScoreInput(x float64) float64 {
return -(1 / (2 * n.Sigma * n.Sigma)) * 2 * (x - n.Mu)
}
// Skewness returns the skewness of the distribution.
func (Normal) Skewness() float64 {
return 0
}
// StdDev returns the standard deviation of the probability distribution.
func (n Normal) StdDev() float64 {
return n.Sigma
}
// SuffStat computes the sufficient statistics of a set of samples to update
// the distribution. The sufficient statistics are stored in place, and the
// effective number of samples are returned.
//
// The normal distribution has two sufficient statistics, the mean of the samples
// and the standard deviation of the samples.
//
// If weights is nil, the weights are assumed to be 1, otherwise panics if
// len(samples) != len(weights). Panics if len(suffStat) != NumSuffStat().
func (Normal) SuffStat(suffStat, samples, weights []float64) (nSamples float64) {
lenSamp := len(samples)
if len(weights) != 0 && len(samples) != len(weights) {
panic(badLength)
}
if len(suffStat) != (Normal{}).NumSuffStat() {
panic(badSuffStat)
}
if len(weights) == 0 {
nSamples = float64(lenSamp)
} else {
nSamples = floats.Sum(weights)
}
mean := stat.Mean(samples, weights)
suffStat[0] = mean
// Use Moment and not StdDev because we want it to be uncorrected
variance := stat.MomentAbout(2, samples, mean, weights)
suffStat[1] = math.Sqrt(variance)
return nSamples
}
// Survival returns the survival function (complementary CDF) at x.
func (n Normal) Survival(x float64) float64 {
return 0.5 * (1 - math.Erf((x-n.Mu)/(n.Sigma*math.Sqrt2)))
}
// setParameters modifies the parameters of the distribution.
func (n *Normal) setParameters(p []Parameter) {
if len(p) != n.NumParameters() {
panic("normal: incorrect number of parameters to set")
}
if p[0].Name != "Mu" {
panic("normal: " + panicNameMismatch)
}
if p[1].Name != "Sigma" {
panic("normal: " + panicNameMismatch)
}
n.Mu = p[0].Value
n.Sigma = p[1].Value
}
// Variance returns the variance of the probability distribution.
func (n Normal) Variance() float64 {
return n.Sigma * n.Sigma
}
// parameters returns the parameters of the distribution.
func (n Normal) parameters(p []Parameter) []Parameter {
nParam := n.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic("normal: improper parameter length")
}
p[0].Name = "Mu"
p[0].Value = n.Mu
p[1].Name = "Sigma"
p[1].Value = n.Sigma
return p
}

131
vendor/gonum.org/v1/gonum/stat/distuv/pareto.go generated vendored Normal file
View File

@@ -0,0 +1,131 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// Pareto implements the Pareto (Type I) distribution, a one parameter distribution
// with support above the scale parameter.
//
// The density function is given by
//
// (α x_m^{α})/(x^{α+1}) for x >= x_m.
//
// For more information, see https://en.wikipedia.org/wiki/Pareto_distribution.
type Pareto struct {
// Xm is the scale parameter.
// Xm must be greater than 0.
Xm float64
// Alpha is the shape parameter.
// Alpha must be greater than 0.
Alpha float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (p Pareto) CDF(x float64) float64 {
if x < p.Xm {
return 0
}
return -math.Expm1(p.Alpha * math.Log(p.Xm/x))
}
// Entropy returns the differential entropy of the distribution.
func (p Pareto) Entropy() float64 {
return math.Log(p.Xm) - math.Log(p.Alpha) + (1 + 1/p.Alpha)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (p Pareto) ExKurtosis() float64 {
if p.Alpha <= 4 {
return math.NaN()
}
return 6 * (p.Alpha*p.Alpha*p.Alpha + p.Alpha*p.Alpha - 6*p.Alpha - 2) / (p.Alpha * (p.Alpha - 3) * (p.Alpha - 4))
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (p Pareto) LogProb(x float64) float64 {
if x < p.Xm {
return math.Inf(-1)
}
return math.Log(p.Alpha) + p.Alpha*math.Log(p.Xm) - (p.Alpha+1)*math.Log(x)
}
// Mean returns the mean of the probability distribution.
func (p Pareto) Mean() float64 {
if p.Alpha <= 1 {
return math.Inf(1)
}
return p.Alpha * p.Xm / (p.Alpha - 1)
}
// Median returns the median of the pareto distribution.
func (p Pareto) Median() float64 {
return p.Quantile(0.5)
}
// Mode returns the mode of the distribution.
func (p Pareto) Mode() float64 {
return p.Xm
}
// NumParameters returns the number of parameters in the distribution.
func (p Pareto) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (p Pareto) Prob(x float64) float64 {
return math.Exp(p.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (p Pareto) Quantile(prob float64) float64 {
if prob < 0 || 1 < prob {
panic(badPercentile)
}
return p.Xm / math.Pow(1-prob, 1/p.Alpha)
}
// Rand returns a random sample drawn from the distribution.
func (p Pareto) Rand() float64 {
var rnd float64
if p.Src == nil {
rnd = rand.ExpFloat64()
} else {
rnd = rand.New(p.Src).ExpFloat64()
}
return p.Xm * math.Exp(rnd/p.Alpha)
}
// StdDev returns the standard deviation of the probability distribution.
func (p Pareto) StdDev() float64 {
return math.Sqrt(p.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (p Pareto) Survival(x float64) float64 {
if x < p.Xm {
return 1
}
return math.Pow(p.Xm/x, p.Alpha)
}
// Variance returns the variance of the probability distribution.
func (p Pareto) Variance() float64 {
if p.Alpha <= 2 {
return math.Inf(1)
}
am1 := p.Alpha - 1
return p.Xm * p.Xm * p.Alpha / (am1 * am1 * (p.Alpha - 2))
}

145
vendor/gonum.org/v1/gonum/stat/distuv/poisson.go generated vendored Normal file
View File

@@ -0,0 +1,145 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
// Poisson implements the Poisson distribution, a discrete probability distribution
// that expresses the probability of a given number of events occurring in a fixed
// interval.
// The poisson distribution has density function:
//
// f(k) = λ^k / k! e^(-λ)
//
// For more information, see https://en.wikipedia.org/wiki/Poisson_distribution.
type Poisson struct {
// Lambda is the average number of events in an interval.
// Lambda must be greater than 0.
Lambda float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (p Poisson) CDF(x float64) float64 {
if x < 0 {
return 0
}
return mathext.GammaIncRegComp(math.Floor(x+1), p.Lambda)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (p Poisson) ExKurtosis() float64 {
return 1 / p.Lambda
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (p Poisson) LogProb(x float64) float64 {
if x < 0 || math.Floor(x) != x {
return math.Inf(-1)
}
lg, _ := math.Lgamma(math.Floor(x) + 1)
return x*math.Log(p.Lambda) - p.Lambda - lg
}
// Mean returns the mean of the probability distribution.
func (p Poisson) Mean() float64 {
return p.Lambda
}
// NumParameters returns the number of parameters in the distribution.
func (Poisson) NumParameters() int {
return 1
}
// Prob computes the value of the probability density function at x.
func (p Poisson) Prob(x float64) float64 {
return math.Exp(p.LogProb(x))
}
// Rand returns a random sample drawn from the distribution.
func (p Poisson) Rand() float64 {
// NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING (ISBN 0-521-43108-5)
// p. 294
// <http://www.aip.de/groups/soe/local/numres/bookcpdf/c7-3.pdf>
rnd := rand.ExpFloat64
var rng *rand.Rand
if p.Src != nil {
rng = rand.New(p.Src)
rnd = rng.ExpFloat64
}
if p.Lambda < 10.0 {
// Use direct method.
var em float64
t := 0.0
for {
t += rnd()
if t >= p.Lambda {
break
}
em++
}
return em
}
// Generate using:
// W. Hörmann. "The transformed rejection method for generating Poisson
// random variables." Insurance: Mathematics and Economics
// 12.1 (1993): 39-45.
// Algorithm PTRS
rnd = rand.Float64
if rng != nil {
rnd = rng.Float64
}
b := 0.931 + 2.53*math.Sqrt(p.Lambda)
a := -0.059 + 0.02483*b
invalpha := 1.1239 + 1.1328/(b-3.4)
vr := 0.9277 - 3.6224/(b-2)
for {
U := rnd() - 0.5
V := rnd()
us := 0.5 - math.Abs(U)
k := math.Floor((2*a/us+b)*U + p.Lambda + 0.43)
if us >= 0.07 && V <= vr {
return k
}
if k <= 0 || (us < 0.013 && V > us) {
continue
}
lg, _ := math.Lgamma(k + 1)
if math.Log(V*invalpha/(a/(us*us)+b)) <= k*math.Log(p.Lambda)-p.Lambda-lg {
return k
}
}
}
// Skewness returns the skewness of the distribution.
func (p Poisson) Skewness() float64 {
return 1 / math.Sqrt(p.Lambda)
}
// StdDev returns the standard deviation of the probability distribution.
func (p Poisson) StdDev() float64 {
return math.Sqrt(p.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (p Poisson) Survival(x float64) float64 {
return 1 - p.CDF(x)
}
// Variance returns the variance of the probability distribution.
func (p Poisson) Variance() float64 {
return p.Lambda
}

142
vendor/gonum.org/v1/gonum/stat/distuv/statdist.go generated vendored Normal file
View File

@@ -0,0 +1,142 @@
// Copyright ©2018 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"gonum.org/v1/gonum/mathext"
)
// Bhattacharyya is a type for computing the Bhattacharyya distance between
// probability distributions.
//
// The Bhattacharyya distance is defined as
//
// D_B = -ln(BC(l,r))
// BC = \int_-∞^∞ (p(x)q(x))^(1/2) dx
//
// Where BC is known as the Bhattacharyya coefficient.
// The Bhattacharyya distance is related to the Hellinger distance by
//
// H(l,r) = sqrt(1-BC(l,r))
//
// For more information, see
//
// https://en.wikipedia.org/wiki/Bhattacharyya_distance
type Bhattacharyya struct{}
// DistBeta returns the Bhattacharyya distance between Beta distributions l and r.
// For Beta distributions, the Bhattacharyya distance is given by
//
// -ln(B((α_l + α_r)/2, (β_l + β_r)/2) / (B(α_l,β_l), B(α_r,β_r)))
//
// Where B is the Beta function.
func (Bhattacharyya) DistBeta(l, r Beta) float64 {
// Reference: https://en.wikipedia.org/wiki/Hellinger_distance#Examples
return -mathext.Lbeta((l.Alpha+r.Alpha)/2, (l.Beta+r.Beta)/2) +
0.5*mathext.Lbeta(l.Alpha, l.Beta) + 0.5*mathext.Lbeta(r.Alpha, r.Beta)
}
// DistNormal returns the Bhattacharyya distance Normal distributions l and r.
// For Normal distributions, the Bhattacharyya distance is given by
//
// s = (σ_l^2 + σ_r^2)/2
// BC = 1/8 (μ_l-μ_r)^2/s + 1/2 ln(s/(σ_l*σ_r))
func (Bhattacharyya) DistNormal(l, r Normal) float64 {
// Reference: https://en.wikipedia.org/wiki/Bhattacharyya_distance
m := l.Mu - r.Mu
s := (l.Sigma*l.Sigma + r.Sigma*r.Sigma) / 2
return 0.125*m*m/s + 0.5*math.Log(s) - 0.5*math.Log(l.Sigma) - 0.5*math.Log(r.Sigma)
}
// Hellinger is a type for computing the Hellinger distance between probability
// distributions.
//
// The Hellinger distance is defined as
//
// H^2(l,r) = 1/2 * int_x (\sqrt(l(x)) - \sqrt(r(x)))^2 dx
//
// and is bounded between 0 and 1. Note the above formula defines the squared
// Hellinger distance, while this returns the Hellinger distance itself.
// The Hellinger distance is related to the Bhattacharyya distance by
//
// H^2 = 1 - exp(-D_B)
//
// For more information, see
//
// https://en.wikipedia.org/wiki/Hellinger_distance
type Hellinger struct{}
// DistBeta computes the Hellinger distance between Beta distributions l and r.
// See the documentation of Bhattacharyya.DistBeta for the distance formula.
func (Hellinger) DistBeta(l, r Beta) float64 {
db := Bhattacharyya{}.DistBeta(l, r)
return math.Sqrt(-math.Expm1(-db))
}
// DistNormal computes the Hellinger distance between Normal distributions l and r.
// See the documentation of Bhattacharyya.DistNormal for the distance formula.
func (Hellinger) DistNormal(l, r Normal) float64 {
db := Bhattacharyya{}.DistNormal(l, r)
return math.Sqrt(-math.Expm1(-db))
}
// KullbackLeibler is a type for computing the Kullback-Leibler divergence from l to r.
//
// The Kullback-Leibler divergence is defined as
//
// D_KL(l || r ) = \int_x p(x) log(p(x)/q(x)) dx
//
// Note that the Kullback-Leibler divergence is not symmetric with respect to
// the order of the input arguments.
type KullbackLeibler struct{}
// DistBeta returns the Kullback-Leibler divergence between Beta distributions
// l and r.
//
// For two Beta distributions, the KL divergence is computed as
//
// D_KL(l || r) = log Γ(α_l+β_l) - log Γ(α_l) - log Γ(β_l)
// - log Γ(α_r+β_r) + log Γ(α_r) + log Γ(β_r)
// + (α_l-α_r)(ψ(α_l)-ψ(α_l+β_l)) + (β_l-β_r)(ψ(β_l)-ψ(α_l+β_l))
//
// Where Γ is the gamma function and ψ is the digamma function.
func (KullbackLeibler) DistBeta(l, r Beta) float64 {
// http://bariskurt.com/kullback-leibler-divergence-between-two-dirichlet-and-beta-distributions/
if l.Alpha <= 0 || l.Beta <= 0 {
panic("distuv: bad parameters for left distribution")
}
if r.Alpha <= 0 || r.Beta <= 0 {
panic("distuv: bad parameters for right distribution")
}
lab := l.Alpha + l.Beta
l1, _ := math.Lgamma(lab)
l2, _ := math.Lgamma(l.Alpha)
l3, _ := math.Lgamma(l.Beta)
lt := l1 - l2 - l3
r1, _ := math.Lgamma(r.Alpha + r.Beta)
r2, _ := math.Lgamma(r.Alpha)
r3, _ := math.Lgamma(r.Beta)
rt := r1 - r2 - r3
d0 := mathext.Digamma(l.Alpha + l.Beta)
ct := (l.Alpha-r.Alpha)*(mathext.Digamma(l.Alpha)-d0) + (l.Beta-r.Beta)*(mathext.Digamma(l.Beta)-d0)
return lt - rt + ct
}
// DistNormal returns the Kullback-Leibler divergence between Normal distributions
// l and r.
//
// For two Normal distributions, the KL divergence is computed as
//
// D_KL(l || r) = log(σ_r / σ_l) + (σ_l^2 + (μ_l-μ_r)^2)/(2 * σ_r^2) - 0.5
func (KullbackLeibler) DistNormal(l, r Normal) float64 {
d := l.Mu - r.Mu
v := (l.Sigma*l.Sigma + d*d) / (2 * r.Sigma * r.Sigma)
return math.Log(r.Sigma) - math.Log(l.Sigma) + v - 0.5
}

162
vendor/gonum.org/v1/gonum/stat/distuv/studentst.go generated vendored Normal file
View File

@@ -0,0 +1,162 @@
// Copyright ©2016 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
"gonum.org/v1/gonum/mathext"
)
const logPi = 1.1447298858494001741 // http://oeis.org/A053510
// StudentsT implements the three-parameter Student's T distribution, a distribution
// over the real numbers.
//
// The Student's T distribution has density function
//
// Γ((ν+1)/2) / (sqrt(νπ) Γ(ν/2) σ) (1 + 1/ν * ((x-μ)/σ)^2)^(-(ν+1)/2)
//
// The Student's T distribution approaches the normal distribution as ν → ∞.
//
// For more information, see https://en.wikipedia.org/wiki/Student%27s_t-distribution,
// specifically https://en.wikipedia.org/wiki/Student%27s_t-distribution#Non-standardized_Student.27s_t-distribution .
//
// The standard Student's T distribution is with Mu = 0, and Sigma = 1.
type StudentsT struct {
// Mu is the location parameter of the distribution, and the mean of the
// distribution
Mu float64
// Sigma is the scale parameter of the distribution. It is related to the
// standard deviation by std = Sigma * sqrt(Nu/(Nu-2))
Sigma float64
// Nu is the shape parameter of the distribution, representing the number of
// degrees of the distribution, and one less than the number of observations
// from a Normal distribution.
Nu float64
Src rand.Source
}
// CDF computes the value of the cumulative distribution function at x.
func (s StudentsT) CDF(x float64) float64 {
// transform to standard normal
y := (x - s.Mu) / s.Sigma
if y == 0 {
return 0.5
}
// For t > 0
// F(y) = 1 - 0.5 * I_t(y)(nu/2, 1/2)
// t(y) = nu/(y^2 + nu)
// and 1 - F(y) for t < 0
t := s.Nu / (y*y + s.Nu)
if y > 0 {
return 1 - 0.5*mathext.RegIncBeta(0.5*s.Nu, 0.5, t)
}
return 0.5 * mathext.RegIncBeta(s.Nu/2, 0.5, t)
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x.
func (s StudentsT) LogProb(x float64) float64 {
g1, _ := math.Lgamma((s.Nu + 1) / 2)
g2, _ := math.Lgamma(s.Nu / 2)
z := (x - s.Mu) / s.Sigma
return g1 - g2 - 0.5*math.Log(s.Nu) - 0.5*logPi - math.Log(s.Sigma) - ((s.Nu+1)/2)*math.Log(1+z*z/s.Nu)
}
// Mean returns the mean of the probability distribution.
func (s StudentsT) Mean() float64 {
return s.Mu
}
// Mode returns the mode of the distribution.
func (s StudentsT) Mode() float64 {
return s.Mu
}
// NumParameters returns the number of parameters in the distribution.
func (StudentsT) NumParameters() int {
return 3
}
// Prob computes the value of the probability density function at x.
func (s StudentsT) Prob(x float64) float64 {
return math.Exp(s.LogProb(x))
}
// Quantile returns the inverse of the cumulative distribution function.
func (s StudentsT) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
// F(x) = 1 - 0.5 * I_t(x)(nu/2, 1/2)
// t(x) = nu/(t^2 + nu)
if p == 0.5 {
return s.Mu
}
var y float64
if p > 0.5 {
// Know t > 0
t := mathext.InvRegIncBeta(s.Nu/2, 0.5, 2*(1-p))
y = math.Sqrt(s.Nu * (1 - t) / t)
} else {
t := mathext.InvRegIncBeta(s.Nu/2, 0.5, 2*p)
y = -math.Sqrt(s.Nu * (1 - t) / t)
}
// Convert out of standard normal
return y*s.Sigma + s.Mu
}
// Rand returns a random sample drawn from the distribution.
func (s StudentsT) Rand() float64 {
// http://www.math.uah.edu/stat/special/Student.html
n := Normal{0, 1, s.Src}.Rand()
c := Gamma{s.Nu / 2, 0.5, s.Src}.Rand()
z := n / math.Sqrt(c/s.Nu)
return z*s.Sigma + s.Mu
}
// StdDev returns the standard deviation of the probability distribution.
//
// The standard deviation is undefined for ν <= 1, and this returns math.NaN().
func (s StudentsT) StdDev() float64 {
return math.Sqrt(s.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (s StudentsT) Survival(x float64) float64 {
// transform to standard normal
y := (x - s.Mu) / s.Sigma
if y == 0 {
return 0.5
}
// For t > 0
// F(y) = 1 - 0.5 * I_t(y)(nu/2, 1/2)
// t(y) = nu/(y^2 + nu)
// and 1 - F(y) for t < 0
t := s.Nu / (y*y + s.Nu)
if y > 0 {
return 0.5 * mathext.RegIncBeta(s.Nu/2, 0.5, t)
}
return 1 - 0.5*mathext.RegIncBeta(s.Nu/2, 0.5, t)
}
// Variance returns the variance of the probability distribution.
//
// The variance is undefined for ν <= 1, and this returns math.NaN().
func (s StudentsT) Variance() float64 {
if s.Nu <= 1 {
return math.NaN()
}
if s.Nu <= 2 {
return math.Inf(1)
}
return s.Sigma * s.Sigma * s.Nu / (s.Nu - 2)
}

279
vendor/gonum.org/v1/gonum/stat/distuv/triangle.go generated vendored Normal file
View File

@@ -0,0 +1,279 @@
// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// Triangle represents a triangle distribution (https://en.wikipedia.org/wiki/Triangular_distribution).
type Triangle struct {
a, b, c float64
src rand.Source
}
// NewTriangle constructs a new triangle distribution with lower limit a, upper limit b, and mode c.
// Constraints are a < b and a ≤ c ≤ b.
// This distribution is uncommon in nature, but may be useful for simulation.
func NewTriangle(a, b, c float64, src rand.Source) Triangle {
checkTriangleParameters(a, b, c)
return Triangle{a: a, b: b, c: c, src: src}
}
func checkTriangleParameters(a, b, c float64) {
if a >= b {
panic("triangle: constraint of a < b violated")
}
if a > c {
panic("triangle: constraint of a <= c violated")
}
if c > b {
panic("triangle: constraint of c <= b violated")
}
}
// CDF computes the value of the cumulative density function at x.
func (t Triangle) CDF(x float64) float64 {
switch {
case x <= t.a:
return 0
case x <= t.c:
d := x - t.a
return (d * d) / ((t.b - t.a) * (t.c - t.a))
case x < t.b:
d := t.b - x
return 1 - (d*d)/((t.b-t.a)*(t.b-t.c))
default:
return 1
}
}
// Entropy returns the entropy of the distribution.
func (t Triangle) Entropy() float64 {
return 0.5 + math.Log(t.b-t.a) - math.Ln2
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (Triangle) ExKurtosis() float64 {
return -3.0 / 5.0
}
// Fit is not appropriate for Triangle, because the distribution is generally used when there is little data.
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (t Triangle) LogProb(x float64) float64 {
return math.Log(t.Prob(x))
}
// Mean returns the mean of the probability distribution.
func (t Triangle) Mean() float64 {
return (t.a + t.b + t.c) / 3
}
// Median returns the median of the probability distribution.
func (t Triangle) Median() float64 {
if t.c >= (t.a+t.b)/2 {
return t.a + math.Sqrt((t.b-t.a)*(t.c-t.a)/2)
}
return t.b - math.Sqrt((t.b-t.a)*(t.b-t.c)/2)
}
// Mode returns the mode of the probability distribution.
func (t Triangle) Mode() float64 {
return t.c
}
// NumParameters returns the number of parameters in the distribution.
func (Triangle) NumParameters() int {
return 3
}
// Prob computes the value of the probability density function at x.
func (t Triangle) Prob(x float64) float64 {
switch {
case x < t.a:
return 0
case x < t.c:
return 2 * (x - t.a) / ((t.b - t.a) * (t.c - t.a))
case x == t.c:
return 2 / (t.b - t.a)
case x <= t.b:
return 2 * (t.b - x) / ((t.b - t.a) * (t.b - t.c))
default:
return 0
}
}
// Quantile returns the inverse of the cumulative probability distribution.
func (t Triangle) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
f := (t.c - t.a) / (t.b - t.a)
if p < f {
return t.a + math.Sqrt(p*(t.b-t.a)*(t.c-t.a))
}
return t.b - math.Sqrt((1-p)*(t.b-t.a)*(t.b-t.c))
}
// Rand returns a random sample drawn from the distribution.
func (t Triangle) Rand() float64 {
var rnd float64
if t.src == nil {
rnd = rand.Float64()
} else {
rnd = rand.New(t.src).Float64()
}
return t.Quantile(rnd)
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Sigma].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
func (t Triangle) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, t.NumParameters())
}
if len(deriv) != t.NumParameters() {
panic(badLength)
}
if (x < t.a) || (x > t.b) {
deriv[0] = math.NaN()
deriv[1] = math.NaN()
deriv[2] = math.NaN()
} else {
invBA := 1 / (t.b - t.a)
invCA := 1 / (t.c - t.a)
invBC := 1 / (t.b - t.c)
switch {
case x < t.c:
deriv[0] = -1/(x-t.a) + invBA + invCA
deriv[1] = -invBA
deriv[2] = -invCA
case x > t.c:
deriv[0] = invBA
deriv[1] = 1/(t.b-x) - invBA - invBC
deriv[2] = invBC
default:
deriv[0] = invBA
deriv[1] = -invBA
deriv[2] = 0
}
switch {
case x == t.a:
deriv[0] = math.NaN()
case x == t.b:
deriv[1] = math.NaN()
case x == t.c:
deriv[2] = math.NaN()
}
switch {
case t.a == t.c:
deriv[0] = math.NaN()
deriv[2] = math.NaN()
case t.b == t.c:
deriv[1] = math.NaN()
deriv[2] = math.NaN()
}
}
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
//
// Special cases (c is the mode of the distribution):
//
// ScoreInput(c) = NaN
// ScoreInput(x) = NaN for x not in (a, b)
func (t Triangle) ScoreInput(x float64) float64 {
if (x <= t.a) || (x >= t.b) || (x == t.c) {
return math.NaN()
}
if x < t.c {
return 1 / (x - t.a)
}
return 1 / (x - t.b)
}
// Skewness returns the skewness of the distribution.
func (t Triangle) Skewness() float64 {
n := math.Sqrt2 * (t.a + t.b - 2*t.c) * (2*t.a - t.b - t.c) * (t.a - 2*t.b + t.c)
d := 5 * math.Pow(t.a*t.a+t.b*t.b+t.c*t.c-t.a*t.b-t.a*t.c-t.b*t.c, 3.0/2.0)
return n / d
}
// StdDev returns the standard deviation of the probability distribution.
func (t Triangle) StdDev() float64 {
return math.Sqrt(t.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (t Triangle) Survival(x float64) float64 {
return 1 - t.CDF(x)
}
// parameters returns the parameters of the distribution.
func (t Triangle) parameters(p []Parameter) []Parameter {
nParam := t.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic("triangle: improper parameter length")
}
p[0].Name = "A"
p[0].Value = t.a
p[1].Name = "B"
p[1].Value = t.b
p[2].Name = "C"
p[2].Value = t.c
return p
}
// setParameters modifies the parameters of the distribution.
func (t *Triangle) setParameters(p []Parameter) {
if len(p) != t.NumParameters() {
panic("triangle: incorrect number of parameters to set")
}
if p[0].Name != "A" {
panic("triangle: " + panicNameMismatch)
}
if p[1].Name != "B" {
panic("triangle: " + panicNameMismatch)
}
if p[2].Name != "C" {
panic("triangle: " + panicNameMismatch)
}
checkTriangleParameters(p[0].Value, p[1].Value, p[2].Value)
t.a = p[0].Value
t.b = p[1].Value
t.c = p[2].Value
}
// Variance returns the variance of the probability distribution.
func (t Triangle) Variance() float64 {
return (t.a*t.a + t.b*t.b + t.c*t.c - t.a*t.b - t.a*t.c - t.b*t.c) / 18
}

211
vendor/gonum.org/v1/gonum/stat/distuv/uniform.go generated vendored Normal file
View File

@@ -0,0 +1,211 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// UnitUniform is an instantiation of the uniform distribution with Min = 0
// and Max = 1.
var UnitUniform = Uniform{Min: 0, Max: 1}
// Uniform represents a continuous uniform distribution (https://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29).
type Uniform struct {
Min float64
Max float64
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (u Uniform) CDF(x float64) float64 {
if x < u.Min {
return 0
}
if x > u.Max {
return 1
}
return (x - u.Min) / (u.Max - u.Min)
}
// Uniform doesn't have any of the DLogProbD? because the derivative is 0 everywhere
// except where it's undefined
// Entropy returns the entropy of the distribution.
func (u Uniform) Entropy() float64 {
return math.Log(u.Max - u.Min)
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (Uniform) ExKurtosis() float64 {
return -6.0 / 5.0
}
// Uniform doesn't have Fit because it's a bad idea to fit a uniform from data.
// LogProb computes the natural logarithm of the value of the probability density function at x.
func (u Uniform) LogProb(x float64) float64 {
if x < u.Min {
return math.Inf(-1)
}
if x > u.Max {
return math.Inf(-1)
}
return -math.Log(u.Max - u.Min)
}
// parameters returns the parameters of the distribution.
func (u Uniform) parameters(p []Parameter) []Parameter {
nParam := u.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic("uniform: improper parameter length")
}
p[0].Name = "Min"
p[0].Value = u.Min
p[1].Name = "Max"
p[1].Value = u.Max
return p
}
// Mean returns the mean of the probability distribution.
func (u Uniform) Mean() float64 {
return (u.Max + u.Min) / 2
}
// Median returns the median of the probability distribution.
func (u Uniform) Median() float64 {
return (u.Max + u.Min) / 2
}
// Uniform doesn't have a mode because it's any value in the distribution
// NumParameters returns the number of parameters in the distribution.
func (Uniform) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (u Uniform) Prob(x float64) float64 {
if x < u.Min {
return 0
}
if x > u.Max {
return 0
}
return 1 / (u.Max - u.Min)
}
// Quantile returns the inverse of the cumulative probability distribution.
func (u Uniform) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return p*(u.Max-u.Min) + u.Min
}
// Rand returns a random sample drawn from the distribution.
func (u Uniform) Rand() float64 {
var rnd float64
if u.Src == nil {
rnd = rand.Float64()
} else {
rnd = rand.New(u.Src).Float64()
}
return rnd*(u.Max-u.Min) + u.Min
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂Mu, ∂LogProb / ∂Sigma].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
func (u Uniform) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, u.NumParameters())
}
if len(deriv) != u.NumParameters() {
panic(badLength)
}
if (x < u.Min) || (x > u.Max) {
deriv[0] = math.NaN()
deriv[1] = math.NaN()
} else {
deriv[0] = 1 / (u.Max - u.Min)
deriv[1] = -deriv[0]
if x == u.Min {
deriv[0] = math.NaN()
}
if x == u.Max {
deriv[1] = math.NaN()
}
}
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
func (u Uniform) ScoreInput(x float64) float64 {
if (x <= u.Min) || (x >= u.Max) {
return math.NaN()
}
return 0
}
// Skewness returns the skewness of the distribution.
func (Uniform) Skewness() float64 {
return 0
}
// StdDev returns the standard deviation of the probability distribution.
func (u Uniform) StdDev() float64 {
return math.Sqrt(u.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (u Uniform) Survival(x float64) float64 {
if x < u.Min {
return 1
}
if x > u.Max {
return 0
}
return (u.Max - x) / (u.Max - u.Min)
}
// setParameters modifies the parameters of the distribution.
func (u *Uniform) setParameters(p []Parameter) {
if len(p) != u.NumParameters() {
panic("uniform: incorrect number of parameters to set")
}
if p[0].Name != "Min" {
panic("uniform: " + panicNameMismatch)
}
if p[1].Name != "Max" {
panic("uniform: " + panicNameMismatch)
}
u.Min = p[0].Value
u.Max = p[1].Value
}
// Variance returns the variance of the probability distribution.
func (u Uniform) Variance() float64 {
return 1.0 / 12.0 * (u.Max - u.Min) * (u.Max - u.Min)
}

232
vendor/gonum.org/v1/gonum/stat/distuv/weibull.go generated vendored Normal file
View File

@@ -0,0 +1,232 @@
// Copyright ©2014 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package distuv
import (
"math"
"golang.org/x/exp/rand"
)
// Weibull distribution. Valid range for x is [0,+∞).
type Weibull struct {
// Shape parameter of the distribution. A value of 1 represents
// the exponential distribution. A value of 2 represents the
// Rayleigh distribution. Valid range is (0,+∞).
K float64
// Scale parameter of the distribution. Valid range is (0,+∞).
Lambda float64
// Source of random numbers
Src rand.Source
}
// CDF computes the value of the cumulative density function at x.
func (w Weibull) CDF(x float64) float64 {
if x < 0 {
return 0
}
return -math.Expm1(-math.Pow(x/w.Lambda, w.K))
}
// Entropy returns the entropy of the distribution.
func (w Weibull) Entropy() float64 {
return eulerGamma*(1-1/w.K) + math.Log(w.Lambda/w.K) + 1
}
// ExKurtosis returns the excess kurtosis of the distribution.
func (w Weibull) ExKurtosis() float64 {
return (-6*w.gammaIPow(1, 4) + 12*w.gammaIPow(1, 2)*math.Gamma(1+2/w.K) - 3*w.gammaIPow(2, 2) - 4*math.Gamma(1+1/w.K)*math.Gamma(1+3/w.K) + math.Gamma(1+4/w.K)) / math.Pow(math.Gamma(1+2/w.K)-w.gammaIPow(1, 2), 2)
}
// gammIPow is a shortcut for computing the gamma function to a power.
func (w Weibull) gammaIPow(i, pow float64) float64 {
return math.Pow(math.Gamma(1+i/w.K), pow)
}
// LogProb computes the natural logarithm of the value of the probability
// density function at x. -Inf is returned if x is less than zero.
//
// Special cases occur when x == 0, and the result depends on the shape
// parameter as follows:
//
// If 0 < K < 1, LogProb returns +Inf.
// If K == 1, LogProb returns 0.
// If K > 1, LogProb returns -Inf.
func (w Weibull) LogProb(x float64) float64 {
if x < 0 {
return math.Inf(-1)
}
if x == 0 && w.K == 1 {
return 0
}
return math.Log(w.K) - math.Log(w.Lambda) + (w.K-1)*(math.Log(x)-math.Log(w.Lambda)) - math.Pow(x/w.Lambda, w.K)
}
// LogSurvival returns the log of the survival function (complementary CDF) at x.
func (w Weibull) LogSurvival(x float64) float64 {
if x < 0 {
return 0
}
return -math.Pow(x/w.Lambda, w.K)
}
// Mean returns the mean of the probability distribution.
func (w Weibull) Mean() float64 {
return w.Lambda * math.Gamma(1+1/w.K)
}
// Median returns the median of the normal distribution.
func (w Weibull) Median() float64 {
return w.Lambda * math.Pow(ln2, 1/w.K)
}
// Mode returns the mode of the normal distribution.
//
// The mode is NaN in the special case where the K (shape) parameter
// is less than 1.
func (w Weibull) Mode() float64 {
if w.K > 1 {
return w.Lambda * math.Pow((w.K-1)/w.K, 1/w.K)
}
return 0
}
// NumParameters returns the number of parameters in the distribution.
func (Weibull) NumParameters() int {
return 2
}
// Prob computes the value of the probability density function at x.
func (w Weibull) Prob(x float64) float64 {
if x < 0 {
return 0
}
return math.Exp(w.LogProb(x))
}
// Quantile returns the inverse of the cumulative probability distribution.
func (w Weibull) Quantile(p float64) float64 {
if p < 0 || p > 1 {
panic(badPercentile)
}
return w.Lambda * math.Pow(-math.Log(1-p), 1/w.K)
}
// Rand returns a random sample drawn from the distribution.
func (w Weibull) Rand() float64 {
var rnd float64
if w.Src == nil {
rnd = rand.Float64()
} else {
rnd = rand.New(w.Src).Float64()
}
return w.Quantile(rnd)
}
// Score returns the score function with respect to the parameters of the
// distribution at the input location x. The score function is the derivative
// of the log-likelihood at x with respect to the parameters
//
// (∂/∂θ) log(p(x;θ))
//
// If deriv is non-nil, len(deriv) must equal the number of parameters otherwise
// Score will panic, and the derivative is stored in-place into deriv. If deriv
// is nil a new slice will be allocated and returned.
//
// The order is [∂LogProb / ∂K, ∂LogProb / ∂λ].
//
// For more information, see https://en.wikipedia.org/wiki/Score_%28statistics%29.
//
// Special cases:
//
// Score(x) = [NaN, NaN] for x <= 0
func (w Weibull) Score(deriv []float64, x float64) []float64 {
if deriv == nil {
deriv = make([]float64, w.NumParameters())
}
if len(deriv) != w.NumParameters() {
panic(badLength)
}
if x > 0 {
deriv[0] = 1/w.K + math.Log(x) - math.Log(w.Lambda) - (math.Log(x)-math.Log(w.Lambda))*math.Pow(x/w.Lambda, w.K)
deriv[1] = (w.K * (math.Pow(x/w.Lambda, w.K) - 1)) / w.Lambda
return deriv
}
deriv[0] = math.NaN()
deriv[1] = math.NaN()
return deriv
}
// ScoreInput returns the score function with respect to the input of the
// distribution at the input location specified by x. The score function is the
// derivative of the log-likelihood
//
// (d/dx) log(p(x)) .
//
// Special cases:
//
// ScoreInput(x) = NaN for x <= 0
func (w Weibull) ScoreInput(x float64) float64 {
if x > 0 {
return (-w.K*math.Pow(x/w.Lambda, w.K) + w.K - 1) / x
}
return math.NaN()
}
// Skewness returns the skewness of the distribution.
func (w Weibull) Skewness() float64 {
stdDev := w.StdDev()
firstGamma, firstGammaSign := math.Lgamma(1 + 3/w.K)
logFirst := firstGamma + 3*(math.Log(w.Lambda)-math.Log(stdDev))
logSecond := math.Log(3) + math.Log(w.Mean()) + 2*math.Log(stdDev) - 3*math.Log(stdDev)
logThird := 3 * (math.Log(w.Mean()) - math.Log(stdDev))
return float64(firstGammaSign)*math.Exp(logFirst) - math.Exp(logSecond) - math.Exp(logThird)
}
// StdDev returns the standard deviation of the probability distribution.
func (w Weibull) StdDev() float64 {
return math.Sqrt(w.Variance())
}
// Survival returns the survival function (complementary CDF) at x.
func (w Weibull) Survival(x float64) float64 {
return math.Exp(w.LogSurvival(x))
}
// setParameters modifies the parameters of the distribution.
func (w *Weibull) setParameters(p []Parameter) {
if len(p) != w.NumParameters() {
panic("weibull: incorrect number of parameters to set")
}
if p[0].Name != "K" {
panic("weibull: " + panicNameMismatch)
}
if p[1].Name != "λ" {
panic("weibull: " + panicNameMismatch)
}
w.K = p[0].Value
w.Lambda = p[1].Value
}
// Variance returns the variance of the probability distribution.
func (w Weibull) Variance() float64 {
return math.Pow(w.Lambda, 2) * (math.Gamma(1+2/w.K) - w.gammaIPow(1, 2))
}
// parameters returns the parameters of the distribution.
func (w Weibull) parameters(p []Parameter) []Parameter {
nParam := w.NumParameters()
if p == nil {
p = make([]Parameter, nParam)
} else if len(p) != nParam {
panic("weibull: improper parameter length")
}
p[0].Name = "K"
p[0].Value = w.K
p[1].Name = "λ"
p[1].Value = w.Lambda
return p
}