-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathopts.go
122 lines (105 loc) · 2.78 KB
/
opts.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package stl
import (
"github.com/chewxy/stl/loess"
)
// Config is a configuration structure
type Config struct {
// Width represents the width of the LOESS smoother in data points
Width int
// Jump is the number of points to skip between smoothing,
Jump int
// Which weight updating function should be used?
Fn loess.WeightUpdate
}
// Opt is a function that helps build the conf
type Opt func(*state)
// WithSeasonalConfig configures the seasonal component of the decomposition process.
func WithSeasonalConfig(conf Config) Opt {
return func(s *state) {
s.sConf = conf
}
}
// WithTrendConfig configures the trend component of the decomposition process.
func WithTrendConfig(conf Config) Opt {
return func(s *state) {
s.tConf = conf
}
}
// WithLowpassConfig configures the operation that performs the lowpass filter in the decomposition process
func WithLowpassConfig(conf Config) Opt {
return func(s *state) {
s.lConf = conf
}
}
// WithRobustIter indicates how many iterations of "robust" (i.e. outlier removal) to do.
// The default is 0.
func WithRobustIter(n int) Opt {
return func(s *state) {
s.robustIter = n
}
}
// WithIter indicates how many iterations to run.
// The default is 2.
func WithIter(n int) Opt {
return func(s *state) {
s.innerIter = n
}
}
// DefaultSeasonal returns the default configuration for the operation that works on the seasonal component.
func DefaultSeasonal(width int) Config {
if width <= 0 {
panic("Cannot use negative window width for seasonal smoothing.")
}
jmp := int(0.1 * float64(width))
if jmp <= 0 {
jmp = 1
}
return Config{
Width: width,
Jump: jmp,
Fn: loess.Linear,
}
}
// DefaultTrend returns the default configuration for the operation that works on the trend component.
func DefaultTrend(periodicity, width int) Config {
if periodicity <= 0 {
panic("Cannot use negative periodicity for trend smoothing.")
}
if width <= 0 {
panic("Cannot use negative window width for trend smoothing.")
}
jmp := int(0.1 * float64(width))
if jmp <= 0 {
jmp = 1
}
return Config{
Width: trendWidth(periodicity, width),
Jump: jmp,
Fn: loess.Linear,
}
}
// DefaultLowPass returns the default configuration for the operation that works on the lowpass component.
func DefaultLowPass(periodicity int) Config {
if periodicity <= 0 {
panic("Cannot use negative periodicity for low pass smoothing.")
}
jmp := int(0.1 * float64(periodicity))
if jmp <= 0 {
jmp = 1
}
return Config{
Width: periodicity,
Jump: jmp,
Fn: loess.Linear,
}
}
// from the original paper's numerical analysis section
func trendWidth(periodicity int, seasonalWidth int) int {
p := float64(periodicity)
w := float64(seasonalWidth)
de := int(1.5*p/(1-1.5/w) + 0.5)
if de <= 0 {
panic("Default trend width calculation overflowed")
}
return de
}