package utils
|
|
import (
|
"github.com/shopspring/decimal"
|
"sort"
|
)
|
|
// Average 取平均值
|
func Average(numbers []decimal.Decimal) decimal.Decimal {
|
if len(numbers) == 0 {
|
return decimal.Decimal{}
|
}
|
if len(numbers) == 1 {
|
return numbers[0]
|
}
|
var sum decimal.Decimal
|
for _, d := range numbers {
|
sum = sum.Add(d)
|
}
|
return sum.Div(decimal.NewFromInt(int64(len(numbers))))
|
}
|
|
// Deviation 偏差
|
func Deviation(numbers []decimal.Decimal) decimal.Decimal {
|
if len(numbers) == 0 || len(numbers) == 1 {
|
return decimal.Decimal{}
|
}
|
avgNum := Average(numbers)
|
var diffSquaredSum decimal.Decimal
|
for _, n := range numbers {
|
diff := n.Sub(avgNum)
|
diffSquaredSum = diffSquaredSum.Add(diff.Mul(diff))
|
}
|
return diffSquaredSum.Div(decimal.NewFromInt(int64(len(numbers))))
|
}
|
|
// TotalDeviation 总差
|
func TotalDeviation(numbers []decimal.Decimal, average decimal.Decimal) decimal.Decimal {
|
if len(numbers) < 2 {
|
return decimal.Zero
|
}
|
|
n := len(numbers)
|
ratio := decimal.NewFromFloat(0.02)
|
length := decimal.NewFromInt(int64(n)).Mul(ratio).Ceil().IntPart()
|
if length >= int64(n) {
|
return decimal.Zero
|
}
|
|
sort.Slice(numbers, func(i, j int) bool {
|
return numbers[i].LessThan(numbers[j])
|
})
|
|
minPart := numbers[:length-1]
|
maxPart := numbers[length:]
|
|
minAverage := Average(minPart)
|
maxAverage := Average(maxPart)
|
|
minDiff := minAverage.Sub(average).Abs()
|
maxDiff := maxAverage.Sub(average).Abs()
|
|
return decimal.Max(minDiff, maxDiff)
|
}
|