Skip to content
Open
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
26 changes: 26 additions & 0 deletions SigmaSwiftStatistics/GeometricMean.swift
Original file line number Diff line number Diff line change
@@ -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
}
}
28 changes: 28 additions & 0 deletions SigmaSwiftStatistics/HarmonicMean.swift
Original file line number Diff line number Diff line change
@@ -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
}
}
48 changes: 48 additions & 0 deletions SigmaSwiftStatistics/Mode.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// Mode.swift
// SigmaSwiftStatistics
//
// Created by Alan James Salmoni on 19/01/2017.
// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved.
//

import Foundation

public extension Sigma {
/**

Returns the mode(s) from the array after it is sorted and the indices where it occurs

https://en.wikipedia.org/wiki/Mode_(statistics)

- parameter values: Array of decimal numbers.
- returns: The mode value itself and an array of the indices where the mode occurs

Example:

Sigma.mode([1, 12, 9.5, 3, -5, 12]) // (12, [1,5])

*/
public static func mode(_ values: [Double]) -> (Double, [Int])? {
let count = values.count
if count == 0 { return nil }
else if count == 1 {
return (values[0], [0])
}
var mode_value = values[0]
var mode_indices: [Int] = [0]

for index in 1...(count - 1) {
if values[index] > mode_value {
mode_value = values[index]
mode_indices = [index]
}
else if values[index] == mode_value {
mode_indices.append(index)
}
}
return (mode_value, mode_indices)
}
}


21 changes: 21 additions & 0 deletions SigmaSwiftStatistics/Probabilities.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Foundation

public extension Sigma {

public static func gammln(xx: Double) -> Double? {
let coeffs = [76.18009173, -86.50532033, 24.01409822, -1.231739516, 0.120858003e-2, -0.536382e-5]
var x = xx - 1.0
var tmp = x + 5.5
tmp = tmp - (x + 0.5) * log(tmp)
var ser = 1.0
for coeff in coeffs {
x = x + 1.0
ser = ser + (coeff / x)
}
return -tmp + log(2.50662827465*ser)
}



}

152 changes: 152 additions & 0 deletions SigmaSwiftStatistics/Ttest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
//
// Ttest.swift
// SigmaSwiftStatistics
//
// Created by Alan James Salmoni on 19/01/2017.
// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved.
//

import Foundation

public extension Sigma {
/**

Performs one of 3 t-tests: Single sample, unpaired samples, paired samples.

Paired is also known as related, within or dependent
Unpaired is also known as unrelated, between or independent

https://en.wikipedia.org/wiki/Student's_t-test

*/

/*

One sample t-test

This performs a one-sample t-test and returns the t-statistic, the degrees of freedom, the probability (p-value)
and the Cohen's d statistic

- parameter values: Array of double numbers.
- returns: t (the t statistic), df (degrees of freedom) and p (probability), d (Cohen's d)

Example:

Sigma.tTest_one(

*/
public static func tTest_one(_ values: [Double], userMean: Double) -> Dictionary<String, Double>? {
let count = Double(values.count)
if count == 0 { return nil }
else if count == 1 {
return (nil)
}

let df = count - 1.0

let numerator = average(values)! - userMean
let denominator = standardDeviationSample(values)! / sqrt(Double(count))

if denominator != 0.0 {
let t = numerator / denominator

let probability = tProbability(DF: df, T: t)!

// compile results into dictionary
var results = [String: Double]()

// store sums of squares
results["t"] = t
results["df"] = df
results["probability"] = probability
results["D"] = 0.0

return results
}
else {
return nil
}
}

public static func tTest(_ values1: [Double], _ values2: [Double], testTails: Int = 2, testType: Int = 1) -> Dictionary<String, Double>? {
let count1 = Double(values1.count)
let count2 = Double(values2.count)
if count1 < 2 { return nil }
if count2 < 2 { return nil }
var df: Double
var t: Double // ignore warning about 't' not being used
var numerator: Double
var denominator: Double

if (testType < 1 || testType > 3) {
return nil
}
else if testType == 1 { // Paired t-test
if count1 != count2 { return nil }
df = Double(count1 - 1)

var deltaSum: Double = 0.0
var deltaSquared: Double = 0.0
var delta: Double = 0.0

for idx in 0...Int(count1 - 1.0) {
delta = values1[idx] - values2[idx]
deltaSum += delta
deltaSquared += (delta * delta)
}

numerator = deltaSum / count1
denominator = sqrt((deltaSquared - ((deltaSum * deltaSum) / count1)) / ((count1 - 1.0) * count1))

}
else { // Unpaired t-test
let m1 = average(values1)!
let m2 = average(values2)!
let s1 = varianceSample(values1)!
let s2 = varianceSample(values2)!
df = Double(count1 + count2 - 2.0)

let sd = ((s1 * (count1 - 1)) + (s2 * (count2 - 1))) / (count1 + count2 - 2.0)

// Alternative DF formula for unequal variances (heteroscedastic)
if testType == 3 {
let s12 = s1 / count1
let s22 = s2 / count2
let dfNumerator = (s12 + s22) * (s12 + s22)
let dfDenominator1 = (s12 * s12) / (count1 - 1.0)
let dfDenominator2 = (s22 * s22) / (count2 - 1.0)

print (dfNumerator, dfDenominator1, dfDenominator2)
let dfDenominator = dfDenominator1 + dfDenominator2
df = dfNumerator / dfDenominator
}

numerator = m1 - m2
denominator = sqrt((sd / count1) + (sd / count2))
}

if denominator == 0.0 {
print ("Divide by zero")
return nil
}
else {
let t = numerator / denominator

// Calculate the probability
let probability = tProbability(DF: df, T: t)!

// compile results into dictionary
var results = [String: Double]()

// store sums of squares
results["t"] = t
results["df"] = df
results["probability"] = probability

return results
}
}

}


9 changes: 9 additions & 0 deletions SigmaSwiftStatistics/multipleRegression.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// multipleRegression.swift
// SigmaSwiftStatistics
//
// Created by Alan James Salmoni on 22/02/2017.
// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved.
//

import Foundation
9 changes: 9 additions & 0 deletions SigmaSwiftStatistics/univariateANOVA.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// univariateANOVA.swift
// SigmaSwiftStatistics
//
// Created by Alan James Salmoni on 16/02/2017.
// Copyright © 2017 Evgenii Neumerzhitckii. All rights reserved.
//

import Foundation
45 changes: 45 additions & 0 deletions SigmaSwiftStatisticsTests/GeometricMeanTests.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}

}
45 changes: 45 additions & 0 deletions SigmaSwiftStatisticsTests/HarmonicMeanTests.swift
Original file line number Diff line number Diff line change
@@ -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)
}
}

}
Loading