1
0
mirror of https://github.com/golang/go synced 2024-11-21 23:34:42 -07:00

Added Percentile function to calculate the p-th percentile of a slice of float64 numbers.

This commit is contained in:
HEMANTH M 2024-10-05 20:53:32 +05:30
parent f9359622fe
commit 6efd1117bf

View File

@ -12,8 +12,7 @@ import (
// Mean returns the mean (average) of a slice of float64 numbers. // Mean returns the mean (average) of a slice of float64 numbers.
// //
// Special cases are: // Special cases are:
// // Mean([]float64{}) = 0
// Mean([]float64{}) = 0
func Mean(numbers []float64) float64 { func Mean(numbers []float64) float64 {
if len(numbers) == 0 { if len(numbers) == 0 {
return 0 return 0
@ -30,29 +29,30 @@ func Mean(numbers []float64) float64 {
// Median returns the median of a slice of float64 numbers. // Median returns the median of a slice of float64 numbers.
// //
// Special cases are: // Special cases are:
// // Median([]float64{}) = 0
// Median([]float64{}) = 0
func Median(numbers []float64) float64 { func Median(numbers []float64) float64 {
if len(numbers) == 0 { if len(numbers) == 0 {
return 0 return 0
} }
// Create a sorted copy of the input slice
sorted := make([]float64, len(numbers)) sorted := make([]float64, len(numbers))
copy(sorted, numbers) copy(sorted, numbers)
sort.Float64s(sorted) sort.Float64s(sorted)
n := len(sorted) n := len(sorted)
if n%2 == 0 { if n%2 == 0 {
// If even, return the average of the two middle numbers
return (sorted[n/2-1] + sorted[n/2]) / 2 return (sorted[n/2-1] + sorted[n/2]) / 2
} }
// If odd, return the middle number
return sorted[n/2] return sorted[n/2]
} }
// Mode returns the mode(s) of a slice of float64 numbers. // Mode returns the mode(s) of a slice of float64 numbers.
// //
// Special cases are: // Special cases are:
// // Mode([]float64{}) = nil
// Mode([]float64{}) = nil
func Mode(numbers []float64) []float64 { func Mode(numbers []float64) []float64 {
if len(numbers) == 0 { if len(numbers) == 0 {
return nil return nil
@ -83,8 +83,7 @@ func Mode(numbers []float64) []float64 {
// Variance returns the variance of a slice of float64 numbers. // Variance returns the variance of a slice of float64 numbers.
// //
// Special cases are: // Special cases are:
// // Variance([]float64{}) = 0
// Variance([]float64{}) = 0
func Variance(numbers []float64) float64 { func Variance(numbers []float64) float64 {
if len(numbers) == 0 { if len(numbers) == 0 {
return 0 return 0
@ -103,8 +102,34 @@ func Variance(numbers []float64) float64 {
// StdDev returns the standard deviation of a slice of float64 numbers. // StdDev returns the standard deviation of a slice of float64 numbers.
// //
// Special cases are: // Special cases are:
// // StdDev([]float64{}) = 0
// StdDev([]float64{}) = 0
func StdDev(numbers []float64) float64 { func StdDev(numbers []float64) float64 {
return math.Sqrt(Variance(numbers)) return math.Sqrt(Variance(numbers))
} }
// Percentile returns the p-th percentile of a slice of float64 numbers.
// The percentile is the value below which a given percentage of observations fall.
//
// Special cases are:
// Percentile([]float64{}, p) = 0 for any p
func Percentile(numbers []float64, p float64) float64 {
if len(numbers) == 0 || p < 0 || p > 100 {
return 0
}
// Sort the slice
sorted := make([]float64, len(numbers))
copy(sorted, numbers)
sort.Float64s(sorted)
index := (p / 100) * float64(len(sorted)-1)
i := int(index)
// Handle the case for interpolation between two values if not an integer
if index == float64(i) {
return sorted[i]
}
// Linear interpolation
return sorted[i]*(float64(i+1)-index) + sorted[i+1]*(index-float64(i))
}