From 78d574a74665c8bc062c26755c80a8b524bce347 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 10 Jul 2023 13:45:50 -0400 Subject: [Feature] Major update: Track measurements that may be delayed Among other major feature additions, this version of the client tracks any measurements that may be long delayed and considers their presence or absence as part of a stability measurement. This version of the client also more closely tracks the spec. In particular, it performs a sinle-sided trimmed mean rather than a double-sided trimmed mean. Signed-off-by: Will Hawkins --- series/statistics.go | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 series/statistics.go (limited to 'series/statistics.go') diff --git a/series/statistics.go b/series/statistics.go new file mode 100644 index 0000000..2742aa7 --- /dev/null +++ b/series/statistics.go @@ -0,0 +1,74 @@ +package series + +import ( + "github.com/network-quality/goresponsiveness/utilities" + "golang.org/x/exp/constraints" +) + +func SeriesStandardDeviation[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket]) (bool, float64) { + complete := s.Complete() + + inputValues := s.GetValues() + + actualValues := utilities.Filter(inputValues, func(d utilities.Optional[Data]) bool { + return utilities.IsSome[Data](d) + }) + values := utilities.Fmap(actualValues, func(d utilities.Optional[Data]) Data { return utilities.GetSome[Data](d) }) + + return complete, utilities.CalculateStandardDeviation[Data](values) +} + +func Percentile[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket], p int) (bool, Data) { + complete := s.Complete() + + inputValues := s.GetValues() + + actualValues := utilities.Filter(inputValues, func(d utilities.Optional[Data]) bool { + return utilities.IsSome[Data](d) + }) + values := utilities.Fmap(actualValues, func(d utilities.Optional[Data]) Data { return utilities.GetSome[Data](d) }) + + return complete, utilities.CalculatePercentile(values, p) +} + +func AllSequentialIncreasesLessThan[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket], limit float64, +) (bool, bool, float64) { + complete := s.Complete() + + inputValues := s.GetValues() + + actualValues := utilities.Filter(utilities.Reverse(inputValues), func(d utilities.Optional[Data]) bool { + return utilities.IsSome[Data](d) + }) + values := utilities.Fmap(actualValues, func(d utilities.Optional[Data]) Data { return utilities.GetSome[Data](d) }) + + result, actualLimit := utilities.AllSequentialIncreasesLessThan(values, limit) + return complete, result, actualLimit +} + +func CalculateAverage[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket]) (bool, float64) { + complete := s.Complete() + + inputValues := s.GetValues() + + actualValues := utilities.Filter(inputValues, func(d utilities.Optional[Data]) bool { + return utilities.IsSome[Data](d) + }) + values := utilities.Fmap(actualValues, func(d utilities.Optional[Data]) Data { return utilities.GetSome[Data](d) }) + + return complete, utilities.CalculateAverage(values) +} + +func TrimmedMean[Data utilities.Number, Bucket constraints.Ordered](s WindowSeries[Data, Bucket], trim int) (bool, float64, []Data) { + complete := s.Complete() + + inputValues := s.GetValues() + + actualValues := utilities.Filter(inputValues, func(d utilities.Optional[Data]) bool { + return utilities.IsSome[Data](d) + }) + values := utilities.Fmap(actualValues, func(d utilities.Optional[Data]) Data { return utilities.GetSome[Data](d) }) + + trimmedMean, trimmedElements := utilities.TrimmedMean(values, trim) + return complete, trimmedMean, trimmedElements +} -- cgit v1.2.3