medianWindow type
Vladimir Bauer
7 years ago
| 14 | 14 | Set(float64) |
| 15 | 15 | } |
| 16 | 16 | |
| 17 | type median struct { | |
| 18 | window [3]float64 | |
| 19 | dst []float64 | |
| 17 | type medianWindow [3]float64 | |
| 18 | ||
| 19 | func (s *medianWindow) Len() int { return len(s) } | |
| 20 | func (s *medianWindow) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | |
| 21 | func (s *medianWindow) Less(i, j int) bool { return s[i] < s[j] } | |
| 22 | ||
| 23 | func (s *medianWindow) Add(value float64) { | |
| 24 | s[0], s[1] = s[1], s[2] | |
| 25 | s[2] = value | |
| 20 | 26 | } |
| 21 | 27 | |
| 22 | type sortable []float64 | |
| 23 | ||
| 24 | func (s sortable) Len() int { return len(s) } | |
| 25 | func (s sortable) Swap(i, j int) { s[i], s[j] = s[j], s[i] } | |
| 26 | func (s sortable) Less(i, j int) bool { return s[i] < s[j] } | |
| 27 | ||
| 28 | func (s *median) Add(v float64) { | |
| 29 | s.window[0], s.window[1] = s.window[1], s.window[2] | |
| 30 | s.window[2] = v | |
| 28 | func (s *medianWindow) Value() float64 { | |
| 29 | tmp := *s | |
| 30 | sort.Sort(&tmp) | |
| 31 | return tmp[1] | |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | func (s *median) Value() float64 { | |
| 34 | copy(s.dst, s.window[:]) | |
| 35 | sort.Sort(sortable(s.dst)) | |
| 36 | return s.dst[1] | |
| 37 | } | |
| 38 | ||
| 39 | func (s *median) Set(value float64) { | |
| 40 | for i, _ := range s.window { | |
| 41 | s.window[i] = value | |
| 34 | func (s *medianWindow) Set(value float64) { | |
| 35 | for i := 0; i < len(s); i++ { | |
| 36 | s[i] = value | |
| 42 | 37 | } |
| 43 | 38 | } |
| 44 | 39 | |
| 45 | 40 | // NewMedian is fixed last 3 samples median MovingAverage. |
| 46 | 41 | func NewMedian() MovingAverage { |
| 47 | return &median{ | |
| 48 | dst: make([]float64, 3), | |
| 49 | } | |
| 42 | return new(medianWindow) | |
| 50 | 43 | } |
| 51 | 44 | |
| 52 | 45 | type medianEwma struct { |
| 57 | 50 | |
| 58 | 51 | func (s *medianEwma) Add(v float64) { |
| 59 | 52 | s.median.Add(v) |
| 60 | s.count++ | |
| 61 | if s.count >= 3 { | |
| 53 | if s.count >= 2 { | |
| 62 | 54 | s.MovingAverage.Add(s.median.Value()) |
| 63 | 55 | } |
| 56 | s.count++ | |
| 64 | 57 | } |
| 65 | 58 | |
| 66 | 59 | // NewMedianEwma is ewma based MovingAverage, which gets its values from median MovingAverage. |