gleam_stats/stats
A module containing several helpful functions for computing and working with statistics.
- Types
- Statistical functions
- Miscellaneous functions
Types
A type used to represent the bins in a histogram. The type is an alias of a tuple containing a min/max range and a count of the values in that range.
Example:
import gleeunit/should
import gleam/pair
import gleam_stats/math
pub fn example () {
// Create a bin
let bin: math.Bin = tuple(math.Range(0., 1.), 999)
// Retrieve min and max values
let math.Range(min, max) = pair.first(bin)
min
|> should.equal(0.)
max
|> should.equal(1.)
// Retrieve count
let count = pair.second(bin)
count
|> should.equal(999)
}
pub type Bin =
#(Range, Int)
A type used to represent a min/max interval. The Range
type is among
others used to represent the bin boundaries in a histogram.
Example:
import gleam_stats/math
import gleeunit/should
pub fn example () {
// Create a range
let range = math.Range(0., 1.)
// Retrieve min and max values
let math.Range(min, max) = range
min
|> should.equal(0.)
max
|> should.equal(1.)
}
pub type Range {
Range(min: Float, max: Float)
}
Constructors
-
Range(min: Float, max: Float)
Functions
pub fn allclose(xarr: List(Float), yarr: List(Float), rtol: Float, atol: Float) -> Result(
List(Bool),
Nil,
)
Determine if a list of values are close to or equivalent to a another list of reference values.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
let val: Float = 99.
let ref_val: Float = 100.
let xarr: List(Float) = list.repeat(val, 42)
let yarr: List(Float) = list.repeat(ref_val, 42)
// We set 'atol' and 'rtol' such that the values are equivalent
// if 'val' is within 1 percent of 'ref_val' +/- 0.1
let rtol: Float = 0.01
let atol: Float = 0.10
math.allclose(xarr, yarr, rtol, atol)
|> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) {
case zarr {
Ok(arr) ->
arr
|> list.all(fn(a: Bool) -> Bool { a })
|> Ok()
_ -> Error(Nil)
}
}
|> should.equal(Ok(True))
}
pub fn amax(arr: List(Float)) -> Result(Float, Nil)
Returns the maximum value of a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.amax()
|> should.equal(Error(Nil))
[4., 4., 3., 2., 1.]
|> math.amax()
|> should.equal(Ok(4.))
}
pub fn amin(arr: List(Float)) -> Result(Float, Nil)
Returns the minimum value of a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.amin()
|> should.equal(Error(Nil))
[4., 4., 3., 2., 1.]
|> math.amin()
|> should.equal(Ok(1.))
}
pub fn argmax(arr: List(Float)) -> Result(List(Int), Nil)
Returns the indices of the maximum values in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.argmax()
|> should.equal(Error(Nil))
[4., 4., 3., 2., 1.]
|> math.argmax()
|> should.equal(Ok([0, 1]))
}
pub fn argmin(arr: List(Float)) -> Result(List(Int), Nil)
Returns the indices of the minimum values in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.argmin()
|> should.equal(Error(Nil))
[4., 4., 3., 2., 1.]
|> math.argmin()
|> should.equal(Ok([4]))
}
pub fn correlation(xarr: List(Float), yarr: List(Float)) -> Result(
Float,
Nil,
)
Calculate the Pearson correlation coefficient to determine the linear relationship between the elements in two lists of equal length.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
math.correlation([], [])
|> should.equal(Error(Nil))
// Perfect positive correlation
let xarr0: List(Float) =
list.range(0, 100)
|> list.map(fn(x: Int) -> Float { int.to_float(x) })
let yarr0: List(Float) =
list.range(0, 100)
|> list.map(fn(x: Int) -> Float { int.to_float(x) })
math.correlation(xarr0, yarr0)
|> should.equal(Ok(1.))
// Perfect negative correlation
let xarr0: List(Float) =
list.range(0, 100)
|> list.map(fn(x: Int) -> Float { -1. *. int.to_float(x) })
let yarr0: List(Float) =
list.range(0, 100)
|> list.map(fn(x: Int) -> Float { int.to_float(x) })
math.correlation(xarr0, yarr0)
|> should.equal(Ok(-1.))
}
pub fn freedman_diaconis_rule(arr: List(Float)) -> Result(
Float,
Nil,
)
Use Freedman-Diaconis’s Rule to determine the bin widths of a histogram.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.freedman_diaconis_rule()
|> should.equal(Error(Nil))
// Calculate histogram bin widths
list.range(0, 1000)
|> list.map(fn(x: Int) -> Float { int.to_float(x) })
|> math.freedman_diaconis_rule()
|> should.equal(Ok(10.))
}
pub fn gmean(arr: List(Float)) -> Result(Float, Nil)
Calculcate the geometric mean of the elements in a list. Note that the geometric mean is only defined for positive numbers.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.gmean()
|> should.equal(Error(Nil))
[1., 3., 9.]
|> math.gmean()
|> should.equal(Ok(3.))
}
pub fn histogram(arr: List(Float), width: Float) -> Result(
List(#(Range, Int)),
Nil,
)
Create a histogram of the elements in a list.
Example:
import gleam_stats/math
import gleeunit/should
pub fn example () {
list.range(0, 100)
|> list.map(fn(x: Int) -> Float { int.to_float(x) })
// Below 25. is the bin width
// The Freedman-Diaconis’s Rule can be used to determine a decent value
|> math.histogram(25.)
|> should.equal(Ok([
tuple(math.Range(0., 25.), 25),
tuple(math.Range(25., 50.), 25),
tuple(math.Range(50., 75.), 25),
tuple(math.Range(75., 100.), 25),
]))
[]
|> math.histogram(1.)
|> should.equal(Error(Nil))
}
pub fn hmean(arr: List(Float)) -> Result(Float, Nil)
Calculcate the harmonic mean of the elements in a list. Note that the harmonic mean is only defined for positive numbers.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.hmean()
|> should.equal(Error(Nil))
[1., 3., 6.]
|> math.hmean()
|> should.equal(Ok(2.))
}
pub fn iqr(arr: List(Float)) -> Result(Float, Nil)
Calculate the interquartile range (IQR) of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.iqr()
|> should.equal(Error(Nil))
[1., 2., 3., 4., 5.]
|> math.iqr()
|> should.equal(Ok(3.))
}
pub fn isclose(a: Float, b: Float, rtol: Float, atol: Float) -> Bool
Determine if a given value is close to or equivalent to a reference value based on supplied relative and absolute tolerance values. The equivalance of the two given values are then determined based on the equation:
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
let val: Float = 99.
let ref_val: Float = 100.
// We set 'atol' and 'rtol' such that the values are equivalent
// if 'val' is within 1 percent of 'ref_val' +/- 0.1
let rtol: Float = 0.01
let atol: Float = 0.10
math.isclose(val, ref_val, rtol, atol)
|> should.be_true()
}
pub fn kurtosis(arr: List(Float)) -> Result(Float, Nil)
Calculcate the sample kurtosis of a list of elements using the definition of Fisher.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.skewness()
|> should.equal(Error(Nil))
// No tail
// -> Fisher's definition gives kurtosis -3
[1., 1., 1., 1.]
|> math.kurtosis()
|> should.equal(Ok(-3.))
// Distribution with a tail
// -> Higher kurtosis
[1., 1., 1., 2.]
|> math.kurtosis()
|> fn(x: Result(Float, Nil)) -> Bool {
case x {
Ok(x) -> x >. -3.
}
}
|> should.be_true()
}
pub fn mean(arr: List(Float)) -> Result(Float, Nil)
Calculcate the arithmetic mean of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.mean()
|> should.equal(Error(Nil))
[1., 2., 3.]
|> math.mean()
|> should.equal(Ok(2.))
}
pub fn median(arr: List(Float)) -> Result(Float, Nil)
Calculcate the median of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.median()
|> should.equal(Error(Nil))
[1., 2., 3.]
|> math.median()
|> should.equal(Ok(2.))
[1., 2., 3., 4.]
|> math.median()
|> should.equal(Ok(2.5))
}
pub fn moment(arr: List(Float), n: Int) -> Result(Float, Nil)
Calculcate the n’th moment about the mean of a list of elements.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.moment(0)
|> should.equal(Error(Nil))
// 0th moment about the mean is 1. per definition
[0., 1., 2., 3., 4.]
|> math.moment(0)
|> should.equal(Ok(1.))
// 1st moment about the mean is 0. per definition
[0., 1., 2., 3., 4.]
|> math.moment(1)
|> should.equal(Ok(0.))
[0., 1., 2., 3., 4.]
|> math.moment(2)
|> should.equal(Ok(2.))
}
pub fn percentile(arr: List(Float), n: Int) -> Result(Float, Nil)
Calculate the n’th percentile of the elements in a list using linear interpolation between closest ranks.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.percentile(40)
|> should.equal(Error(Nil))
// Calculate 40th percentile
[15., 20., 35., 40., 50.]
|> math.percentile(40)
|> should.equal(Ok(29.))
}
pub fn skewness(arr: List(Float)) -> Result(Float, Nil)
Calculcate the sample skewness of a list of elements using the Fisher-Pearson coefficient of skewness.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.skewness()
|> should.equal(Error(Nil))
// No skewness
// -> Zero skewness
[1., 2., 3., 4.]
|> math.skewness()
|> should.equal(Ok(0.))
// Right-skewed distribution
// -> Positive skewness
[1., 1., 1., 2.]
|> math.skewness()
|> fn(x: Result(Float, Nil)) -> Bool {
case x {
Ok(x) -> x >. 0.
}
}
|> should.be_true()
}
pub fn std(arr: List(Float), ddof: Int) -> Result(Float, Nil)
Calculcate the sample standard deviation of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
// Degrees of freedom
let ddof: Int = 1
[]
|> math.std(ddof)
|> should.equal(Error(Nil))
[1., 2., 3.]
|> math.std(ddof)
|> should.equal(Ok(1.))
}
pub fn sum(arr: List(Float)) -> Float
Calculcate the sum of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.sum()
|> should.equal(0.)
[1., 2., 3.]
|> math.sum()
|> should.equal(6.)
}
pub fn trim(arr: List(Float), min: Int, max: Int) -> Result(
List(Float),
Nil,
)
Trim a list to a certain size given min/max indices. The min/max indices are inclusive.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
|> math.trim(0, 0)
|> should.equal(Error(Nil))
// Trim list to only middle part of list
[1., 2., 3., 4., 5., 6.]
|> math.trim(1, 4)
|> should.equal(Ok([2., 3., 4., 5.]))
}
pub fn var(arr: List(Float), ddof: Int) -> Result(Float, Nil)
Calculcate the sample variance of the elements in a list.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
// Degrees of freedom
let ddof: Int = 1
[]
|> math.var(ddof)
|> should.equal(Error(Nil))
[1., 2., 3.]
|> math.var(ddof)
|> should.equal(Ok(1.))
}
pub fn zscore(arr: List(Float), ddof: Int) -> Result(
List(Float),
Nil,
)
Calculate the z-score of each value in the list relative to the sample mean and standard deviation.
Example:
import gleeunit/should
import gleam_stats/math
pub fn example () {
[]
// Use degrees of freedom = 1
|> math.zscore(1)
|> should.equal(Error(Nil))
[1., 2., 3.]
// Use degrees of freedom = 1
|> math.zscore(1)
|> should.equal(Ok([-1., 0., 1.]))
}