From a51ad0ac23d6c903fd74c672043d560330765457 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Tue, 24 Jan 2017 18:35:50 +0000 Subject: [PATCH 1/9] First commit of ranks function. --- SigmaSwiftStatistics/Ranks.swift | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 SigmaSwiftStatistics/Ranks.swift diff --git a/SigmaSwiftStatistics/Ranks.swift b/SigmaSwiftStatistics/Ranks.swift new file mode 100644 index 0000000..a769dcc --- /dev/null +++ b/SigmaSwiftStatistics/Ranks.swift @@ -0,0 +1,88 @@ +// +// Ranks.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 21/01/2017. +// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved. +// + +import Foundation + +public extension Sigma { + + /* + this ranks a vector (single dimensional array) of floats. + + Parameter values: + - Array of doubles to be ranked + - Start value for ranking (defaults to 1) + - How to deal with ties. Defaults to "mean" + - "mean" uses the arithmetic mean, + - "max" uses the maximum possible rank for all ties + - "min" uses the minimum rank for all ties + - "first" awards a descending rank starting so first occurence gets the highest rank down to the last + - "last" awards an ascending rank starting so the last occurance gets the highest rank down to the first + + Returns: + - Array of floats with the rank of each item + + Examples: + Sigma.rank([2,3,6,5,3]) // [1.0, 2.5, 5.0, 4.0, 2.5] + Sigma.rank([100,100,100,100], start: 10) // [11.5, 11.5, 11.5, 11.5] + Sigma.rank([100,100,100,100], ties: "max") // [1.0, 1.0, 1.0, 1.0] + Sigma.rank([100,100,100,100], ties: "min") // [4.0, 4.0, 4.0, 4.0] + Sigma.rank([100,100,100,100], ties: "first") // [1.0, 2.0, 3.0, 4.0] + Sigma.rank([100,100,100,100], ties: "last") // [4.0, 3.0, 2.0, 1.0] + + */ + + public static func rank(_ values: [Double], start: Double = 1.0, ties: String = "mean") -> [Double]? { + let count_all = values.count + if count_all == 0 { + return nil + } + var rank: Double + if ties == "mean" { + rank = start - 0.5 + } + else if ties == "max" || ties == "min" || ties == "first" || ties == "last" { + rank = start - 1.0 + } + else { + return nil + } + var increment: Double + var tiny_increment: Double + var unique_vals: [Double] + var unique_freqs: [Int] + (unique_vals, unique_freqs) = Sigma.frequencies(values: values)! + var ranks = [Double](repeating: 0, count: count_all) + for (idx, value) in unique_vals.enumerated() { + increment = Double(unique_freqs[idx]) + tiny_increment = 1.0 + for idx in 0...(count_all - 1) { + if value == values[idx] { + if ties == "mean" { + ranks[idx] = rank + (increment / 2.0) + } + else if ties == "min" { + ranks[idx] = rank + 1 + } + else if ties == "max" { + ranks[idx] = rank + increment + } + else if ties == "first" { + ranks[idx] = rank + tiny_increment + tiny_increment += 1 + } + else if ties == "last" { + ranks[idx] = rank + increment - tiny_increment + 1.0 + tiny_increment += 1 + } + } + } + rank += increment + } + return ranks + } +} From 711f1c178d857f0e2655dfad17de5c929a7da14e Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Tue, 24 Jan 2017 18:52:17 +0000 Subject: [PATCH 2/9] First commit of unit test for the ranks function. --- SigmaSwiftStatisticsTests/RanksTest.swift | 97 +++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 SigmaSwiftStatisticsTests/RanksTest.swift diff --git a/SigmaSwiftStatisticsTests/RanksTest.swift b/SigmaSwiftStatisticsTests/RanksTest.swift new file mode 100644 index 0000000..3da8061 --- /dev/null +++ b/SigmaSwiftStatisticsTests/RanksTest.swift @@ -0,0 +1,97 @@ +// +// RanksTest.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 21/01/2017. +// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved. +// + +import XCTest +import SigmaSwiftStatistics + +class RanksTests: XCTestCase { + + // MARK: - ranking data + + func testRanksEmpty() { + let result = Sigma.rank([]) + XCTAssertNil(result) + } + + func testRanksSingle() { + let data = [50.0] + let result = Sigma.rank(data)! + XCTAssertEqual([1.0], result) + } + + func testRanksTiesMean() { + let data = [100.0, 100.0, 100.0, 100.0] + let result = Sigma.rank(data, ties: "mean")! + XCTAssertEqual([2.5, 2.5, 2.5, 2.5], result) + } + + func testRanksTiesMin() { + let data = [100.0, 100.0, 100.0, 100.0] + let result = Sigma.rank(data, ties: "min")! + XCTAssertEqual([1.0, 1.0, 1.0, 1.0], result) + } + + func testRanksTiesMax() { + let data = [100.0, 100.0, 100.0, 100.0] + let result = Sigma.rank(data, ties: "max")! + XCTAssertEqual([4.0, 4.0, 4.0, 4.0], result) + } + + func testRanksTiesFirst() { + let data = [100.0, 100.0, 100.0, 100.0] + let result = Sigma.rank(data, ties: "first")! + XCTAssertEqual([1.0, 2.0, 3.0, 4.0], result) + } + + func testRanksTiesLast() { + let data = [100.0, 100.0, 100.0, 100.0] + let result = Sigma.rank(data, ties: "last")! + XCTAssertEqual([4.0, 3.0, 2.0, 1.0], result) + } + + func testRanksBlank() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0])! + XCTAssertEqual([1.5, 10.5, 4.0, 6.5, 4.0, 1.5, 4.0, 6.5, 8.5, 10.5, 8.5], result) + } + + func testRanksStart() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: 100)! + XCTAssertEqual([100.5, 109.5, 103.0, 105.5, 103.0, 100.5, 103.0, 105.5, 107.5, 109.5, 107.5], result) + } + + func testRanksMean() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], ties: "mean")! + XCTAssertEqual([1.5, 10.5, 4.0, 6.5, 4.0, 1.5, 4.0, 6.5, 8.5, 10.5, 8.5], result) + } + + func testRanksStartMean() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: 50, ties: "mean")! + XCTAssertEqual([50.5, 59.5, 53.0, 55.5, 53.0, 50.5, 53.0, 55.5, 57.5, 59.5, 57.5], result) + } + + func testRanksStartTiesMin() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: 25, ties: "min")! + XCTAssertEqual([25.0, 34.0, 27.0, 30.0, 27.0, 25.0, 27.0, 30.0, 32.0, 34.0, 32.0], result) + } + + func testRanksStartTiesMax() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: -99, ties: "max")! + XCTAssertEqual([-98.0, -89.0, -95.0, -93.0, -95.0, -98.0, -95.0, -93.0, -91.0, -89.0, -91.0], result) + } + + func testRanksStartTiesFirst() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: 0, ties: "first")! + XCTAssertEqual([0.0, 9.0, 2.0, 5.0, 3.0, 1.0, 4.0, 6.0, 7.0, 10.0, 8.0], result) + } + + func testRanksStartTiesLast() { + let result = Sigma.rank([1.0 ,6.0, 2.0 ,3.0 ,2.0 ,1.0 ,2.0 ,3.0 ,5.0 ,6.0 ,5.0], start: 2500, ties: "last")! + XCTAssertEqual([2501.0, 2510.0, 2504.0, 2506.0, 2503.0, 2500.0, 2502.0, 2505.0, 2508.0, 2509.0, 2507.0], result) + } + +} From 970eb28642e00939e5b9cc1486638eb6c57ae7d6 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:28:54 +0000 Subject: [PATCH 3/9] First commit for unique values function --- SigmaSwiftStatistics/UniqueValues.swift | 33 +++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 SigmaSwiftStatistics/UniqueValues.swift diff --git a/SigmaSwiftStatistics/UniqueValues.swift b/SigmaSwiftStatistics/UniqueValues.swift new file mode 100644 index 0000000..f47c047 --- /dev/null +++ b/SigmaSwiftStatistics/UniqueValues.swift @@ -0,0 +1,33 @@ +// +// UniqueValues.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 21/01/2017. +// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved. +// + +import Foundation + +public extension Sigma { + + /* + This returns a list of the values within a vector without regard to frequency + + Parameter values: + - Array of doubles to be analysed + + Return values: + - An unsorted array containing all values that occur within the parameter array. All duplicates are returned as a single value + + Example: + Sigma.uniqueValues([1,2,3,4,5,4,3,5]) // [1,2,3,4,5] + + */ + + public static func uniqueValues(values: [Double]) -> [Double]? { + let count = Double(values.count) + if count == 0 { return nil } + let unique = Array(Set(values)) + return unique + } +} From ebc6722dca734119801302be52c9e628c8425363 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:29:26 +0000 Subject: [PATCH 4/9] First commit for unit tests for unique values function --- .../UniqueValuesTests.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 SigmaSwiftStatisticsTests/UniqueValuesTests.swift diff --git a/SigmaSwiftStatisticsTests/UniqueValuesTests.swift b/SigmaSwiftStatisticsTests/UniqueValuesTests.swift new file mode 100644 index 0000000..16c2108 --- /dev/null +++ b/SigmaSwiftStatisticsTests/UniqueValuesTests.swift @@ -0,0 +1,36 @@ +import XCTest +import SigmaSwiftStatistics + +class UniqueValuesTests: XCTestCase { + // MARK: - Unique values + + func testEmptyArray() { + let result = Sigma.uniqueValues(values: []) + XCTAssertNil(result) + } + + func testArraySingle() { + let result = Sigma.uniqueValues(values: [-99]) + XCTAssertEqual([-99], result!) + } + + func testArrayHomogenous() { + let result = Sigma.uniqueValues(values: [55,55,55,55,55]) + XCTAssertEqual([55], result!) + } + + func testArrayPositive() { + let result = Sigma.uniqueValues(values: [2,5,6,5,6,2,5]) + XCTAssertEqual([2,5,6], result!) + } + + func testArrayNegative() { + let result = Sigma.uniqueValues(values: [-4,-5,-4,-5,-99,-5])?.sorted(by: <) + XCTAssertEqual([-99, -5,-4], result!) + } + + func testArrayMixed() { + let result = Sigma.uniqueValues(values: [55,-55,10,-10,-999, 10, -10, -55, 55, -999, 55])?.sorted(by: <) + XCTAssertEqual([-999, -55, -10, 10, 55], result!) + } +} From b0f074ef4aa00eab2f8347443f327e805fe2b398 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:32:51 +0000 Subject: [PATCH 5/9] First commit of frequencies function plus unit tests --- SigmaSwiftStatistics/Frequencies.swift | 45 ++++++++++++ .../FrequenciesTests.swift | 72 +++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 SigmaSwiftStatistics/Frequencies.swift create mode 100644 SigmaSwiftStatisticsTests/FrequenciesTests.swift diff --git a/SigmaSwiftStatistics/Frequencies.swift b/SigmaSwiftStatistics/Frequencies.swift new file mode 100644 index 0000000..0031eff --- /dev/null +++ b/SigmaSwiftStatistics/Frequencies.swift @@ -0,0 +1,45 @@ +// +// Frequencies.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 21/01/2017. +// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved. +// + +import Foundation + +public extension Sigma { + + public static func frequencies(values: [Double]) -> ([Double], [Int])? { + /* + This returns two lists from an array, the first containing the unique values and the second containing how often each value occurs. + + Parameter values: + - Array of doubles to be analysed + + Return values: + - Two arrays as a tuple: + - An array containing all the values that occur within the parameter's array (see uniqueValues) + - An array containing how often each value occurs in the parameter's array + + Example: + Sigma.frequencies([1,2,3,4,5,4,3,5]) // ([1,2,3,4,5], [1, 1, 2, 2, 2]) + + Would this be better returned as a dictionary with each unique value a key and the frequency the value? + + */ + let count = values.count + if count == 0 { return nil } + let unique_vals = Sigma.uniqueValues(values: values)!.sorted(by: <) + let count_uniques = unique_vals.count + var frequencies = [Int](repeating: 0, count: count_uniques) + for (idx_uniques, unique_val) in unique_vals.enumerated() { + for datum in values { + if unique_val == datum { + frequencies[idx_uniques] += 1 + } + } + } + return (unique_vals, frequencies) + } +} diff --git a/SigmaSwiftStatisticsTests/FrequenciesTests.swift b/SigmaSwiftStatisticsTests/FrequenciesTests.swift new file mode 100644 index 0000000..8fad3e6 --- /dev/null +++ b/SigmaSwiftStatisticsTests/FrequenciesTests.swift @@ -0,0 +1,72 @@ +import XCTest +import SigmaSwiftStatistics + +class FrequenciesTests: XCTestCase { +// MARK: - Frequencies + + func testEmptyArray() { + if let _ = Sigma.frequencies(values: []) { + XCTFail() + } + else { + XCTAssertNil(nil) + } + } + + func testSingleArray() { + if let result = Sigma.frequencies(values: [-99.999]) { + let (unique_values, value_frequencies) = result + // (-99.999, [1]) + XCTAssertEqual([-99.999], unique_values) + XCTAssertEqual([1], value_frequencies) + } + else { + XCTAssertNil(nil) + } + } + + func testHomogenousArray() { + if let result = Sigma.frequencies(values: [-99.999, -99.999, -99.999, -99.999, -99.999, -99.999]) { + let (unique_values, value_frequencies) = result + // (-99.999, [6]) + XCTAssertEqual([-99.999], unique_values) + XCTAssertEqual([6], value_frequencies) + } + else { + XCTAssertNil(nil) + } + } + + func testPositiveArray() { + if let result = Sigma.frequencies(values: [6,2,9999,9999,2,79,6,6]) { + let (unique_values, value_frequencies) = result + // (2,6,79,9999, [2,3,1,2]) + XCTAssertEqual([2,6,79,9999], unique_values) + XCTAssertEqual([2,3,1,2], value_frequencies) + } + else { + XCTAssertNil(nil) + } + } + + func testNegativeArray() { + if let result = Sigma.frequencies(values: [-99.999, -0.0001, -99.999, -99.999, -99.999, -99.999]) { + let (unique_values, value_frequencies) = result + // (-99.999, [1]) + XCTAssertEqual([-99.999, -0.0001], unique_values) + XCTAssertEqual([5,1], value_frequencies) + } + else { + XCTAssertNil(nil) + } + } + + func testMixedArray() { + if let result = Sigma.frequencies(values: [-99.999, -99.999, -99.999, 99.999, -99.999, 99.999]) { + let (unique_values, value_frequencies) = result + // (-99.999, [1]) + XCTAssertEqual([-99.999, 99.999], unique_values) + XCTAssertEqual([4,2], value_frequencies) + } + } +} From 615d8941f19271b18599305f93f1c08363a13192 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:36:18 +0000 Subject: [PATCH 6/9] First commit of function for geometric mean --- SigmaSwiftStatistics/GeometricMean.swift | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 SigmaSwiftStatistics/GeometricMean.swift diff --git a/SigmaSwiftStatistics/GeometricMean.swift b/SigmaSwiftStatistics/GeometricMean.swift new file mode 100644 index 0000000..26ffbd8 --- /dev/null +++ b/SigmaSwiftStatistics/GeometricMean.swift @@ -0,0 +1,26 @@ +// +// GeometricMean.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 30/12/2016. +// Copyright © 2016 Evgenii Neumerzhitckii. All rights reserved. +// +import Foundation + +public extension Sigma { + + public static func geometricMean(data: [Double]) -> Double? { + let count = data.count + if count == 0 { + return nil + } + var data_log: [Double] = [] + var log_val: Double + for item in data { + log_val = log(item) + data_log.append(log_val) + } + let return_val = exp(average(data_log)!) + return return_val + } +} From fc7ef6a5564c32969e933f58606c1481e0b0f0b4 Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:37:05 +0000 Subject: [PATCH 7/9] First commit of unit tests for the geometric mean function --- .../GeometricMeanTests.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 SigmaSwiftStatisticsTests/GeometricMeanTests.swift diff --git a/SigmaSwiftStatisticsTests/GeometricMeanTests.swift b/SigmaSwiftStatisticsTests/GeometricMeanTests.swift new file mode 100644 index 0000000..5aa8de5 --- /dev/null +++ b/SigmaSwiftStatisticsTests/GeometricMeanTests.swift @@ -0,0 +1,45 @@ +import XCTest +import SigmaSwiftStatistics + +class GeometricMeanTests: XCTestCase { + + func testGeometricMean_Normal() { + let data_array = [0.52662978, 0.77362142, 0.57550701, 0.04158415, 0.03447811, + 0.08848505, 0.5236469 , 0.25523548, 0.89229563, 0.71272614, + 0.17107995, 0.26764894, 0.27308645, 0.38404429, 0.12755542, + 0.9856573 , 0.91394384, 0.50584635, 0.31623642, 0.13751698, + 0.68101821, 0.71853529, 0.66112074, 0.71656707, 0.35927775, + 0.76151524, 0.94317209, 0.01808385, 0.36550638, 0.9901121 , + 0.60259119, 0.62285146, 0.61310069, 0.55510847, 0.15929895, + 0.80369179, 0.26319102, 0.49952759, 0.34527164, 0.08919652, + 0.61979169, 0.43286263, 0.42874006, 0.1784381 , 0.51625026, + 0.74231264, 0.34506245, 0.70310094, 0.09531878, 0.02909812] + if let result = Sigma.geometricMean(data: data_array) { + XCTAssertEqualWithAccuracy(0.34079044910152717, result, accuracy: 0.000000000000001) + } + else { + XCTAssertNil(nil) + } + } + + func testGeometricMean_EmptyArray() { + let data_array: [Double] = [] + if let _ = Sigma.geometricMean(data: data_array) { + XCTFail() + } + else { + XCTAssertNil(nil) + } + } + + func testGeometricMean_SingleElement() { + let data_array = [0.52662978] + if let result = Sigma.geometricMean(data: data_array) { + XCTAssertEqualWithAccuracy(0.52662978000000005, result, accuracy: 0.000000000000001) + } + else { + XCTAssertNil(nil) + } + } + +} From 13260b6525bb197bce3e34903a3beed97528534f Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:38:37 +0000 Subject: [PATCH 8/9] First commit of harmonic mean function --- SigmaSwiftStatistics/HarmonicMean.swift | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 SigmaSwiftStatistics/HarmonicMean.swift diff --git a/SigmaSwiftStatistics/HarmonicMean.swift b/SigmaSwiftStatistics/HarmonicMean.swift new file mode 100644 index 0000000..147b8ce --- /dev/null +++ b/SigmaSwiftStatistics/HarmonicMean.swift @@ -0,0 +1,28 @@ + +// +// HarmonicMean.swift +// SigmaSwiftStatistics +// +// Created by Alan James Salmoni on 30/12/2016. +// Copyright © 2016 Evgenii Neumerzhitckii. All rights reserved. +// +import Foundation + +public extension Sigma { + + public static func harmonicMean(data: [Double]) -> Double? { + let count = data.count + if count == 0 { + return nil + } + var data_inv: [Double] = [] + var inv_val: Double + for item in data { + inv_val = 1.0 / item + data_inv.append(inv_val) + } + let m1 = average(data_inv) + let hm = 1.0 / m1! + return hm + } +} From be0c0a8576c10a921b0844a09189673205917f7b Mon Sep 17 00:00:00 2001 From: "Alan J. Salmoni" Date: Thu, 26 Jan 2017 19:38:55 +0000 Subject: [PATCH 9/9] First commit of unit tests for the harmonic mean function --- .../HarmonicMeanTests.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 SigmaSwiftStatisticsTests/HarmonicMeanTests.swift diff --git a/SigmaSwiftStatisticsTests/HarmonicMeanTests.swift b/SigmaSwiftStatisticsTests/HarmonicMeanTests.swift new file mode 100644 index 0000000..d95df50 --- /dev/null +++ b/SigmaSwiftStatisticsTests/HarmonicMeanTests.swift @@ -0,0 +1,45 @@ +import XCTest +import SigmaSwiftStatistics + +class HarmonicMeanTests: XCTestCase { + + func testHarmonicMean_Normal() { + let data_array = [0.52662978, 0.77362142, 0.57550701, 0.04158415, 0.03447811, + 0.08848505, 0.5236469 , 0.25523548, 0.89229563, 0.71272614, + 0.17107995, 0.26764894, 0.27308645, 0.38404429, 0.12755542, + 0.9856573 , 0.91394384, 0.50584635, 0.31623642, 0.13751698, + 0.68101821, 0.71853529, 0.66112074, 0.71656707, 0.35927775, + 0.76151524, 0.94317209, 0.01808385, 0.36550638, 0.9901121 , + 0.60259119, 0.62285146, 0.61310069, 0.55510847, 0.15929895, + 0.80369179, 0.26319102, 0.49952759, 0.34527164, 0.08919652, + 0.61979169, 0.43286263, 0.42874006, 0.1784381 , 0.51625026, + 0.74231264, 0.34506245, 0.70310094, 0.09531878, 0.02909812] + if let result = Sigma.harmonicMean(data: data_array) { + XCTAssertEqualWithAccuracy(0.17589575818127001, result, accuracy: 0.000000000000001) + } + else { + XCTAssertNil(nil) + } + } + + func testGeometricMean_EmptyArray() { + let data_array: [Double] = [] + if let _ = Sigma.harmonicMean(data: data_array) { + XCTFail() + } + else { + XCTAssertNil(nil) + } + } + + func testGeometricMean_SingleElement() { + let data_array = [0.52662978] + if let result = Sigma.harmonicMean(data: data_array) { + XCTAssertEqualWithAccuracy(0.52662978000000005, result, accuracy: 0.000000000000001) + } + else { + XCTAssertNil(nil) + } + } + +}