github.com/blend/go-sdk@v1.20220411.3/mathutil/percentile.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package mathutil 9 10 import ( 11 "math" 12 "time" 13 ) 14 15 // Percentile finds the relative standing in a slice of floats. 16 // `percent` should be given on the interval [0,100.0). 17 func Percentile(input []float64, percent float64) float64 { 18 if len(input) == 0 { 19 return 0 20 } 21 22 return PercentileSorted(CopySort(input), percent) 23 } 24 25 // PercentileSorted finds the relative standing in a sorted slice of floats. 26 // `percent` should be given on the interval [0,100.0). 27 func PercentileSorted(sortedInput []float64, percent float64) float64 { 28 index := (percent / 100.0) * float64(len(sortedInput)) 29 percentile := float64(0) 30 i := int(math.RoundToEven(index)) 31 if index == float64(int64(index)) { 32 percentile = (sortedInput[i-1] + sortedInput[i]) / 2.0 33 } else { 34 percentile = sortedInput[i-1] 35 } 36 37 return percentile 38 } 39 40 // PercentileOfDuration finds the relative standing in a slice of durations 41 func PercentileOfDuration(input []time.Duration, percentile float64) time.Duration { 42 if len(input) == 0 { 43 return 0 44 } 45 return PercentileSortedDurations(CopySortDurations(input), percentile) 46 } 47 48 // PercentileSortedDurations finds the relative standing in a sorted slice of durations 49 func PercentileSortedDurations(sortedInput []time.Duration, percentile float64) time.Duration { 50 index := (percentile / 100.0) * float64(len(sortedInput)) 51 if index == float64(int64(index)) { 52 i := int(RoundPlaces(index, 0)) 53 54 if i < 1 { 55 return time.Duration(0) 56 } 57 58 return MeanDurations([]time.Duration{sortedInput[i-1], sortedInput[i]}) 59 } 60 61 i := int(RoundPlaces(index, 0)) 62 if i < 1 { 63 return time.Duration(0) 64 } 65 66 return sortedInput[i-1] 67 }