From 59ac7070a07d9d4aa0c46eb9c35a4695f2aed1cf Mon Sep 17 00:00:00 2001 From: Arthur Guiot Date: Fri, 9 Sep 2022 09:30:54 -0400 Subject: [PATCH] Improved quantile --- Euler.xcodeproj/project.pbxproj | 4 ++++ Sources/Euler/Statistics/Quantile.swift | 8 ++++---- Tests/EulerTests/StatisticsTests.swift | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 Tests/EulerTests/StatisticsTests.swift diff --git a/Euler.xcodeproj/project.pbxproj b/Euler.xcodeproj/project.pbxproj index f27c728a..25cc543b 100644 --- a/Euler.xcodeproj/project.pbxproj +++ b/Euler.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 68C12AD12483284800BB4B3A /* Engineering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68C12AD02483284800BB4B3A /* Engineering.swift */; }; 68C12AD32483392C00BB4B3A /* Substring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68C12AD22483392C00BB4B3A /* Substring.swift */; }; 68C12AD524833E6500BB4B3A /* TablesTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68C12AD424833E6500BB4B3A /* TablesTest.swift */; }; + 68F6882C28CA9BB9009806F2 /* StatisticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F6882B28CA9BB9009806F2 /* StatisticsTests.swift */; }; OBJ_176 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Expression.swift */; }; OBJ_177 /* Grouper.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* Grouper.swift */; }; OBJ_178 /* LaTeX.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* LaTeX.swift */; }; @@ -153,6 +154,7 @@ 68C12AD02483284800BB4B3A /* Engineering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Engineering.swift; sourceTree = ""; }; 68C12AD22483392C00BB4B3A /* Substring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Substring.swift; sourceTree = ""; }; 68C12AD424833E6500BB4B3A /* TablesTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TablesTest.swift; sourceTree = ""; }; + 68F6882B28CA9BB9009806F2 /* StatisticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatisticsTests.swift; sourceTree = ""; }; "Euler::Euler::Product" /* Euler.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Euler.framework; sourceTree = BUILT_PRODUCTS_DIR; }; "Euler::EulerTests::Product" /* EulerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = EulerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_10 /* Expression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = ""; }; @@ -593,6 +595,7 @@ OBJ_106 /* NodeTests.swift */, OBJ_107 /* Tools */, 68C12AD424833E6500BB4B3A /* TablesTest.swift */, + 68F6882B28CA9BB9009806F2 /* StatisticsTests.swift */, ); name = EulerTests; path = Tests/EulerTests; @@ -787,6 +790,7 @@ OBJ_270 /* ExtensionsTests.swift in Sources */, OBJ_271 /* GeneratorsTests.swift in Sources */, OBJ_272 /* GeometryTests.swift in Sources */, + 68F6882C28CA9BB9009806F2 /* StatisticsTests.swift in Sources */, OBJ_273 /* MatrixTest.swift in Sources */, OBJ_274 /* NodeTests.swift in Sources */, OBJ_275 /* Convenience.swift in Sources */, diff --git a/Sources/Euler/Statistics/Quantile.swift b/Sources/Euler/Statistics/Quantile.swift index 84d4668d..41843fc4 100644 --- a/Sources/Euler/Statistics/Quantile.swift +++ b/Sources/Euler/Statistics/Quantile.swift @@ -33,9 +33,9 @@ public extension Statistics { let half = Int(floor(Double(sorted.count) / 2.0)) if self.list.count % 2 == 0 { - return sorted[half] - } else { return (sorted[half - 1] + sorted[half]) / 2 + } else { + return sorted[half] } } @@ -49,8 +49,8 @@ public extension Statistics { var array = self.list let n = array.removeFirst() let sorted = array.sorted() - let index = (sorted.count - 1) * n - guard let floored = floor(index).asInt() else { throw QuantileError.ArrayLength } + let index = Double(sorted.count - 1) * percentage + let floored = Int(index) let diff = index - BigDouble(floored) if index + 1 >= BigDouble(sorted.count) { diff --git a/Tests/EulerTests/StatisticsTests.swift b/Tests/EulerTests/StatisticsTests.swift new file mode 100644 index 00000000..6b77a5d4 --- /dev/null +++ b/Tests/EulerTests/StatisticsTests.swift @@ -0,0 +1,25 @@ +// +// StatisticsTests.swift +// EulerTests +// +// Created by Arthur Guiot on 08/09/2022. +// + +import XCTest +import Euler +class StatisticsTests: XCTestCase { + func testQuantile() { + let array: [BN] = [32.2, 32.0, 30.4, 31.0, 31.2, 31.2, 30.3, 29.6, 30.5, 30.7] + + let stats = Statistics(list: array) + + XCTAssertEqual(stats.median, BN(617, over: 20)) + XCTAssertEqual(try stats.quantile(percentage: 0.5), 30.7) + XCTAssertEqual(try stats.quantile(percentage: 0.25), 30.4) + XCTAssertEqual(try stats.quantile(percentage: 0.75), 31.2) + } + + static var allTests = [ + ("Quantile", testQuantile), + ] +}