Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ public extension Collection {
) -> Double {

guard !self.isEmpty else { return .signalingNaN }
guard self.count > 1 else { return 0 }
guard self.count > 1 else {
switch composition {
case .sample: return .signalingNaN
case .population: return 0
}
}

let mean = self.mean(variable: variable)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,43 @@ struct StandardDeviationTests {
((-5 ... 5).map(\.realValue), 3.3166247904, DataSetComposition.sample),
((1 ... 5).map(\.realValue), 1.4142135624, DataSetComposition.population),
((-5 ... 5).map(\.realValue), 3.1622776602, DataSetComposition.population),
])
func validData(data: [Double], expectedVariance: Double, composition: DataSetComposition) {
#expect(data.standardDeviation(variable: \.self, from: composition).isApproximatelyEqual(to: expectedVariance, absoluteTolerance: 1e-6))
([42.0, 42.0], 0.0, DataSetComposition.sample),
([42.0, 42.0], 0.0, DataSetComposition.population),
] as [([Double], Double, DataSetComposition)])
func validData(data: [Double], expectedStdDev: Double, composition: DataSetComposition) {
#expect(data.standardDeviation(variable: \.self, from: composition).isApproximatelyEqual(to: expectedStdDev, absoluteTolerance: 1e-6))
}

@Test("Standard deviation of empty collection is undefined", arguments: [[Double]()], DataSetComposition.allCases)
func emptyCollection(data: [Double], composition: DataSetComposition) {
#expect(data.standardDeviation(variable: \.self, from: composition).isNaN)
}

@Test("Standard deviation of single element collection is 0", arguments: [[1], [-1]] , DataSetComposition.allCases)
func singleElementCollection(data: [Double], composition: DataSetComposition) {
#expect(data.standardDeviation(variable: \.self, from: composition) == 0)
@Test(
"Population standard deviation of single-element collection is 0",
arguments: [[1.0], [-1.0], [42.0]] as [[Double]]
)
func singleElementPopulationStdDev(data: [Double]) {
#expect(data.standardDeviation(variable: \.self, from: .population) == 0)
}

@Test(
"Sample standard deviation of single-element collection is undefined",
arguments: [[1.0], [-1.0], [42.0]] as [[Double]]
)
func singleElementSampleStdDev(data: [Double]) {
#expect(data.standardDeviation(variable: \.self, from: .sample).isNaN)
}

@Test("Standard deviation of collection containing NaN is NaN", arguments: DataSetComposition.allCases)
func collectionContainingNaN(composition: DataSetComposition) {
let data = [1.0, Double.nan, 3.0]
#expect(data.standardDeviation(variable: \.self, from: composition).isNaN)
}

@Test("Standard deviation of collection containing infinity is NaN", arguments: DataSetComposition.allCases)
func collectionContainingInfinity(composition: DataSetComposition) {
let data = [1.0, Double.infinity, 3.0]
#expect(data.standardDeviation(variable: \.self, from: composition).isNaN)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct VarianceTests {
((-5 ... 5).map(\.realValue), 11.0, DataSetComposition.sample),
((1 ... 5).map(\.realValue), 2, DataSetComposition.population),
((-5 ... 5).map(\.realValue), 10, DataSetComposition.population),
([42.0, 42.0], 0.0, DataSetComposition.sample),
([42.0, 42.0], 0.0, DataSetComposition.population),
] as [([Double], Double, DataSetComposition)]
)
func validData(data: [Double], expectedVariance: Double, composition: DataSetComposition) {
Expand All @@ -21,8 +23,31 @@ struct VarianceTests {
#expect(data.variance(variable: \.self, from: composition).isNaN)
}

@Test("Variance of single element collection is 0", arguments: [[1], [-1]] , DataSetComposition.allCases)
func singleElementCollection(data: [Double], composition: DataSetComposition) {
#expect(data.variance(variable: \.self, from: composition) == 0)
@Test(
"Population variance of single-element collection is 0",
arguments: [[1.0], [-1.0], [42.0]] as [[Double]]
)
func singleElementPopulationVariance(data: [Double]) {
#expect(data.variance(variable: \.self, from: .population) == 0)
}

@Test(
"Sample variance of single-element collection is undefined",
arguments: [[1.0], [-1.0], [42.0]] as [[Double]]
)
func singleElementSampleVariance(data: [Double]) {
#expect(data.variance(variable: \.self, from: .sample).isNaN)
}

@Test("Variance of collection containing NaN is NaN", arguments: DataSetComposition.allCases)
func collectionContainingNaN(composition: DataSetComposition) {
let data = [1.0, Double.nan, 3.0]
#expect(data.variance(variable: \.self, from: composition).isNaN)
}

@Test("Variance of collection containing infinity is NaN", arguments: DataSetComposition.allCases)
func collectionContainingInfinity(composition: DataSetComposition) {
let data = [1.0, Double.infinity, 3.0]
#expect(data.variance(variable: \.self, from: composition).isNaN)
}
}
Loading