github.com/qioalice/ekago/v3@v3.3.2-0.20221202205325-5c262d586ee4/ekamath/stat.go (about) 1 // Copyright © 2020-2022. All rights reserved. 2 // Author: Ilya Stroy. 3 // Contacts: iyuryevich@pm.me, https://github.com/qioalice 4 // License: https://opensource.org/licenses/MIT 5 6 package ekamath 7 8 import ( 9 "fmt" 10 11 "github.com/qioalice/ekago/v3/ekaext" 12 ) 13 14 type Stat[T ekaext.Numeric] interface { 15 fmt.Stringer 16 17 Min() T 18 Max() T 19 Avg() T 20 N() int 21 Count(v T) 22 Clear() 23 } 24 25 //////////////////////////////////////////////////////////////////////////////// 26 27 type _StatImpl[T ekaext.Numeric] struct { 28 min, max, avg T 29 n int 30 isCumulative bool 31 } 32 33 func (s *_StatImpl[T]) Min() T { return s.min } 34 func (s *_StatImpl[T]) Max() T { return s.max } 35 func (s *_StatImpl[T]) N() int { return s.n } 36 37 func (s *_StatImpl[T]) Avg() T { 38 39 if s.isCumulative { 40 return s.avg / T(s.n) 41 } else { 42 return s.avg 43 } 44 } 45 46 func (s *_StatImpl[T]) Count(v T) { 47 48 if s.n == 0 { 49 s.min, s.max, s.avg, s.n = v, v, v, 1 50 return 51 } 52 53 s.min = Min(s.min, v) 54 s.max = Max(s.max, v) 55 56 if !s.isCumulative { 57 s.avg = v - s.avg/T(s.n+1) + s.avg 58 } else { 59 s.avg += v 60 } 61 } 62 63 func (s *_StatImpl[T]) Clear() { 64 s.min, s.max, s.avg, s.n = 0, 0, 0, 0 65 } 66 67 func (s *_StatImpl[T]) String() string { 68 return fmt.Sprintf("<[%d] Min: %v, Max: %v, Avg: %v>", 69 s.N(), s.Min(), s.Max(), s.Avg()) 70 } 71 72 //////////////////////////////////////////////////////////////////////////////// 73 74 func NewStatCumulative[T ekaext.Numeric]() Stat[T] { 75 return &_StatImpl[T]{isCumulative: true} 76 } 77 78 func NewStatIterative[T ekaext.Numeric]() Stat[T] { 79 return &_StatImpl[T]{isCumulative: false} 80 }