-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathpareto.go
executable file
·108 lines (95 loc) · 2.42 KB
/
pareto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package prob
import (
"math"
"math/rand"
)
//The Pareto Distribution is a continuous probability distribution
// with parameters α > 0, k > 0.
//
// See: https://en.wikipedia.org/wiki/Pareto_distribution
type Pareto struct {
Scale float64 `json:"scale"`
Shape float64 `json:"shape"`
}
func NewPareto(scale float64, shape float64) (Pareto, error) {
dist := Pareto{scale, shape}
if err := dist.Validate(); err != nil {
return dist, err
}
return dist, nil
}
func (dist Pareto) Validate() error {
if dist.Scale <= 0 {
return InvalidParamsError{ "Scale must be greater than zero." }
}
if dist.Shape <= 0 {
return InvalidParamsError{ "Shape must be greater than zero." }
}
return nil
}
func (dist Pareto) Mean() float64 {
if (dist.Shape <= 1.0) {
return math.Inf(1)
}
result := (dist.Shape * dist.Scale) / (dist.Shape - 1)
return result
}
func (dist Pareto) Variance() float64 {
if (dist.Shape <= 2.0) {
return math.Inf(1)
}
result := (dist.Shape * dist.Scale * dist.Scale) / ((dist.Shape - 1) * (dist.Shape - 1) * (dist.Shape - 2))
return result
}
func (dist Pareto) Skewness() float64 {
if (dist.Shape < 3.0) {
return math.NaN()
}
result := 2 * (1 + dist.Shape) / (dist.Shape - 3) * math.Sqrt((dist.Shape - 2) / dist.Shape)
return result
}
func (dist Pareto) Kurtosis() float64 {
if (dist.Shape < 3.0) {
return math.NaN()
}
result := 3 * (dist.Shape - 2) * ((3 * dist.Shape * dist.Shape) + dist.Shape + 2) / ((dist.Shape - 4) * (dist.Shape - 3) * dist.Shape)
return result
}
func (dist Pareto) StdDev() float64 {
variance := dist.Variance()
if math.IsInf(variance, 0) {
return math.Inf(1)
}
result := math.Sqrt(variance)
return result
}
func (dist Pareto) RelStdDev() float64 {
variance := dist.Variance()
if math.IsInf(variance, 0) {
return math.Inf(1)
}
mean := dist.Mean()
if math.IsInf(mean, 0) {
return math.Inf(1)
}
result := math.Sqrt(variance) / mean
return result
}
func (dist Pareto) Pdf(x float64) float64 {
if x < dist.Scale {
return 0.0
}
result := dist.Shape * math.Pow(dist.Scale, dist.Shape) / math.Pow(x, dist.Shape + 1)
return result
}
func (dist Pareto) Cdf(x float64) float64 {
if (x < dist.Scale) {
return 0.0
}
result := 1 - math.Pow(dist.Scale / x, dist.Shape)
return result
}
func (dist Pareto) Random() float64 {
value := dist.Scale / math.Pow(rand.Float64(), 1 / dist.Shape)
return value
}