-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cnf ran: reorganize powermanagement helpers (#160)
This moves the powermanagement stats file to be a package under ran and adds unit tests for it. Additionally, the metric collections helpers have been moved to their own package under powermanagement.
- Loading branch information
Showing
6 changed files
with
432 additions
and
361 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package stats | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
"slices" | ||
) | ||
|
||
// Mean computes the arithmetic mean of the input array. | ||
func Mean(input []float64) (float64, error) { | ||
if len(input) < 1 { | ||
return math.NaN(), fmt.Errorf("input array must have at least 1 element") | ||
} | ||
|
||
sum := 0.0 | ||
for _, x := range input { | ||
sum += x | ||
} | ||
|
||
return sum / float64(len(input)), nil | ||
} | ||
|
||
// StdDev computes the population standard deviation of the input array. | ||
func StdDev(input []float64) (float64, error) { | ||
if len(input) < 1 { | ||
return math.NaN(), fmt.Errorf("input array must have at least 1 element") | ||
} | ||
|
||
mean, _ := Mean(input) | ||
|
||
sum := 0.0 | ||
for _, x := range input { | ||
sum += (x - mean) * (x - mean) | ||
} | ||
|
||
return math.Sqrt(sum / float64(len(input))), nil | ||
} | ||
|
||
// Median computes the median value of the input array. | ||
func Median(input []float64) (float64, error) { | ||
if len(input) < 1 { | ||
return math.NaN(), fmt.Errorf("input array must have at least 1 element") | ||
} | ||
|
||
numElements := len(input) | ||
|
||
// sort a copy of the input array | ||
inputCopy := make([]float64, numElements) | ||
copy(inputCopy, input) | ||
|
||
slices.Sort(inputCopy) | ||
|
||
if numElements%2 == 1 { | ||
return inputCopy[numElements/2], nil | ||
} | ||
|
||
return (inputCopy[numElements/2] + inputCopy[numElements/2-1]) / 2, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package stats | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const epsilon float64 = 1e-9 | ||
|
||
func TestMean(t *testing.T) { | ||
testCases := []struct { | ||
input []float64 | ||
expectedOutput float64 | ||
expectedError error | ||
}{ | ||
{ | ||
input: []float64{1, 2, 3, 4, 5}, | ||
expectedOutput: 3, | ||
expectedError: nil, | ||
}, | ||
{ | ||
input: []float64{}, | ||
expectedOutput: math.NaN(), | ||
expectedError: fmt.Errorf("input array must have at least 1 element"), | ||
}, | ||
} | ||
|
||
for _, testCase := range testCases { | ||
output, err := Mean(testCase.input) | ||
assert.Equal(t, testCase.expectedError, err) | ||
|
||
if testCase.expectedError == nil { | ||
assert.InDelta(t, testCase.expectedOutput, output, epsilon) | ||
} | ||
} | ||
} | ||
|
||
func TestStdDev(t *testing.T) { | ||
testCases := []struct { | ||
input []float64 | ||
expectedOutput float64 | ||
expectedError error | ||
}{ | ||
{ | ||
input: []float64{1, 2, 3, 4, 5}, | ||
expectedOutput: math.Sqrt2, | ||
expectedError: nil, | ||
}, | ||
{ | ||
input: []float64{}, | ||
expectedOutput: math.NaN(), | ||
expectedError: fmt.Errorf("input array must have at least 1 element"), | ||
}, | ||
} | ||
|
||
for _, testCase := range testCases { | ||
output, err := StdDev(testCase.input) | ||
assert.Equal(t, testCase.expectedError, err) | ||
|
||
if testCase.expectedError == nil { | ||
assert.InDelta(t, testCase.expectedOutput, output, epsilon) | ||
} | ||
} | ||
} | ||
|
||
func TestMedian(t *testing.T) { | ||
testCases := []struct { | ||
input []float64 | ||
expectedOutput float64 | ||
expectedError error | ||
}{ | ||
{ | ||
input: []float64{1, 2, 3, 4, 5}, | ||
expectedOutput: 3, | ||
expectedError: nil, | ||
}, | ||
{ | ||
input: []float64{}, | ||
expectedOutput: math.NaN(), | ||
expectedError: fmt.Errorf("input array must have at least 1 element"), | ||
}, | ||
} | ||
|
||
for _, testCase := range testCases { | ||
output, err := Median(testCase.input) | ||
assert.Equal(t, testCase.expectedError, err) | ||
|
||
if testCase.expectedError == nil { | ||
assert.InDelta(t, testCase.expectedOutput, output, epsilon) | ||
} | ||
} | ||
} |
Oops, something went wrong.