Files
sjy01-image-proc/vendor/gonum.org/v1/gonum/stat/distuv/alphastable.go
2024-10-24 15:46:01 +08:00

114 lines
3.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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)
}