mirror of
https://github.com/sigmasternchen/gleam-community-maths
synced 2025-03-15 07:59:01 +00:00
Merge pull request #27 from gleam-community/refactor/remove-let-annotations
♻️ Remove type annotations from let bindings and lambdas.
This commit is contained in:
commit
2ac9811a07
10 changed files with 443 additions and 467 deletions
|
@ -86,8 +86,8 @@ import gleam_community/maths/piecewise
|
|||
/// </div>
|
||||
///
|
||||
pub fn gcd(x: Int, y: Int) -> Int {
|
||||
let absx: Int = piecewise.int_absolute_value(x)
|
||||
let absy: Int = piecewise.int_absolute_value(y)
|
||||
let absx = piecewise.int_absolute_value(x)
|
||||
let absy = piecewise.int_absolute_value(y)
|
||||
do_gcd(absx, absy)
|
||||
}
|
||||
|
||||
|
@ -197,8 +197,8 @@ pub fn int_euclidean_modulo(x: Int, y: Int) -> Int {
|
|||
/// </div>
|
||||
///
|
||||
pub fn lcm(x: Int, y: Int) -> Int {
|
||||
let absx: Int = piecewise.int_absolute_value(x)
|
||||
let absy: Int = piecewise.int_absolute_value(y)
|
||||
let absx = piecewise.int_absolute_value(x)
|
||||
let absy = piecewise.int_absolute_value(y)
|
||||
absx * absy / do_gcd(absx, absy)
|
||||
}
|
||||
|
||||
|
@ -240,11 +240,11 @@ pub fn divisors(n: Int) -> List(Int) {
|
|||
}
|
||||
|
||||
fn find_divisors(n: Int) -> List(Int) {
|
||||
let nabs: Float = piecewise.float_absolute_value(conversion.int_to_float(n))
|
||||
let nabs = piecewise.float_absolute_value(conversion.int_to_float(n))
|
||||
let assert Ok(sqrt_result) = elementary.square_root(nabs)
|
||||
let max: Int = conversion.float_to_int(sqrt_result) + 1
|
||||
let max = conversion.float_to_int(sqrt_result) + 1
|
||||
list.range(2, max)
|
||||
|> list.fold([1, n], fn(acc: List(Int), i: Int) -> List(Int) {
|
||||
|> list.fold([1, n], fn(acc, i) {
|
||||
case n % i == 0 {
|
||||
True -> [i, n / i, ..acc]
|
||||
False -> acc
|
||||
|
@ -288,7 +288,7 @@ fn find_divisors(n: Int) -> List(Int) {
|
|||
/// </div>
|
||||
///
|
||||
pub fn proper_divisors(n: Int) -> List(Int) {
|
||||
let divisors: List(Int) = find_divisors(n)
|
||||
let divisors = find_divisors(n)
|
||||
divisors
|
||||
|> list.take(list.length(divisors) - 1)
|
||||
}
|
||||
|
@ -340,12 +340,10 @@ pub fn float_sum(arr: List(Float), weights: option.Option(List(Float))) -> Float
|
|||
[], _ -> 0.0
|
||||
_, option.None ->
|
||||
arr
|
||||
|> list.fold(0.0, fn(acc: Float, a: Float) -> Float { a +. acc })
|
||||
|> list.fold(0.0, fn(acc, a) { a +. acc })
|
||||
_, option.Some(warr) -> {
|
||||
list.zip(arr, warr)
|
||||
|> list.fold(0.0, fn(acc: Float, a: #(Float, Float)) -> Float {
|
||||
pair.first(a) *. pair.second(a) +. acc
|
||||
})
|
||||
|> list.fold(0.0, fn(acc, a) { pair.first(a) *. pair.second(a) +. acc })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -395,7 +393,7 @@ pub fn int_sum(arr: List(Int)) -> Int {
|
|||
[] -> 0
|
||||
_ ->
|
||||
arr
|
||||
|> list.fold(0, fn(acc: Int, a: Int) -> Int { a + acc })
|
||||
|> list.fold(0, fn(acc, a) { a + acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,12 +449,12 @@ pub fn float_product(
|
|||
|> Ok
|
||||
_, option.None ->
|
||||
arr
|
||||
|> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|
||||
|> list.fold(1.0, fn(acc, a) { a *. acc })
|
||||
|> Ok
|
||||
_, option.Some(warr) -> {
|
||||
let results =
|
||||
list.zip(arr, warr)
|
||||
|> list.map(fn(a: #(Float, Float)) -> Result(Float, String) {
|
||||
|> list.map(fn(a) {
|
||||
pair.first(a)
|
||||
|> elementary.power(pair.second(a))
|
||||
})
|
||||
|
@ -464,7 +462,7 @@ pub fn float_product(
|
|||
case results {
|
||||
Ok(prods) ->
|
||||
prods
|
||||
|> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|
||||
|> list.fold(1.0, fn(acc, a) { a *. acc })
|
||||
|> Ok
|
||||
Error(msg) ->
|
||||
msg
|
||||
|
@ -519,7 +517,7 @@ pub fn int_product(arr: List(Int)) -> Int {
|
|||
[] -> 1
|
||||
_ ->
|
||||
arr
|
||||
|> list.fold(1, fn(acc: Int, a: Int) -> Int { a * acc })
|
||||
|> list.fold(1, fn(acc, a) { a * acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -569,7 +567,7 @@ pub fn float_cumulative_sum(arr: List(Float)) -> List(Float) {
|
|||
[] -> []
|
||||
_ ->
|
||||
arr
|
||||
|> list.scan(0.0, fn(acc: Float, a: Float) -> Float { a +. acc })
|
||||
|> list.scan(0.0, fn(acc, a) { a +. acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -619,7 +617,7 @@ pub fn int_cumulative_sum(arr: List(Int)) -> List(Int) {
|
|||
[] -> []
|
||||
_ ->
|
||||
arr
|
||||
|> list.scan(0, fn(acc: Int, a: Int) -> Int { a + acc })
|
||||
|> list.scan(0, fn(acc, a) { a + acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -671,7 +669,7 @@ pub fn float_cumulative_product(arr: List(Float)) -> List(Float) {
|
|||
[] -> []
|
||||
_ ->
|
||||
arr
|
||||
|> list.scan(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|
||||
|> list.scan(1.0, fn(acc, a) { a *. acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -723,6 +721,6 @@ pub fn int_cumulative_product(arr: List(Int)) -> List(Int) {
|
|||
[] -> []
|
||||
_ ->
|
||||
arr
|
||||
|> list.scan(1, fn(acc: Int, a: Int) -> Int { a * acc })
|
||||
|> list.scan(1, fn(acc, a) { a * acc })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
|||
False -> n - k
|
||||
}
|
||||
list.range(1, min)
|
||||
|> list.fold(1, fn(acc: Int, x: Int) -> Int { acc * { n + 1 - x } / x })
|
||||
|> list.fold(1, fn(acc, x) { acc * { n + 1 - x } / x })
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ pub fn factorial(n) -> Result(Int, String) {
|
|||
|> Ok
|
||||
_ ->
|
||||
list.range(1, n)
|
||||
|> list.fold(1, fn(acc: Int, x: Int) -> Int { acc * x })
|
||||
|> list.fold(1, fn(acc, x) { acc * x })
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
|||
}
|
||||
_, _ ->
|
||||
list.range(0, k - 1)
|
||||
|> list.fold(1, fn(acc: Int, x: Int) -> Int { acc * { n - x } })
|
||||
|> list.fold(1, fn(acc, x) { acc * { n - x } })
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -654,16 +654,9 @@ fn do_list_permutation_with_repetitions(
|
|||
///
|
||||
pub fn cartesian_product(xset: set.Set(a), yset: set.Set(a)) -> set.Set(#(a, a)) {
|
||||
xset
|
||||
|> set.fold(
|
||||
set.new(),
|
||||
fn(accumulator0: set.Set(#(a, a)), member0: a) -> set.Set(#(a, a)) {
|
||||
set.fold(
|
||||
yset,
|
||||
accumulator0,
|
||||
fn(accumulator1: set.Set(#(a, a)), member1: a) -> set.Set(#(a, a)) {
|
||||
set.insert(accumulator1, #(member0, member1))
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
|> set.fold(set.new(), fn(accumulator0: set.Set(#(a, a)), member0: a) {
|
||||
set.fold(yset, accumulator0, fn(accumulator1: set.Set(#(a, a)), member1: a) {
|
||||
set.insert(accumulator1, #(member0, member1))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -994,7 +994,7 @@ fn do_logarithm_10(a: Float) -> Float
|
|||
/// </div>
|
||||
///
|
||||
pub fn power(x: Float, y: Float) -> Result(Float, String) {
|
||||
let fractional: Bool = do_ceiling(y) -. y >. 0.0
|
||||
let fractional = do_ceiling(y) -. y >. 0.0
|
||||
// In the following check:
|
||||
// 1. If the base (x) is negative and the exponent (y) is fractional
|
||||
// then return an error as it will otherwise be an imaginary number
|
||||
|
|
|
@ -81,8 +81,8 @@ fn validate_lists(
|
|||
"Invalid input argument: The list yarr is empty."
|
||||
|> Error
|
||||
_, _ -> {
|
||||
let xarr_length: Int = list.length(xarr)
|
||||
let yarr_length: Int = list.length(yarr)
|
||||
let xarr_length = list.length(xarr)
|
||||
let yarr_length = list.length(yarr)
|
||||
case xarr_length == yarr_length, weights {
|
||||
False, _ ->
|
||||
"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."
|
||||
|
@ -92,7 +92,7 @@ fn validate_lists(
|
|||
|> Ok
|
||||
}
|
||||
True, option.Some(warr) -> {
|
||||
let warr_length: Int = list.length(warr)
|
||||
let warr_length = list.length(warr)
|
||||
case xarr_length == warr_length {
|
||||
True -> {
|
||||
validate_weights(warr)
|
||||
|
@ -180,9 +180,9 @@ pub fn norm(
|
|||
0.0
|
||||
|> Ok
|
||||
_, option.None -> {
|
||||
let aggregate: Float =
|
||||
let aggregate =
|
||||
arr
|
||||
|> list.fold(0.0, fn(accumulator: Float, element: Float) -> Float {
|
||||
|> list.fold(0.0, fn(accumulator, element) {
|
||||
let assert Ok(result) =
|
||||
piecewise.float_absolute_value(element)
|
||||
|> elementary.power(p)
|
||||
|
@ -193,28 +193,25 @@ pub fn norm(
|
|||
|> Ok
|
||||
}
|
||||
_, option.Some(warr) -> {
|
||||
let arr_length: Int = list.length(arr)
|
||||
let warr_length: Int = list.length(warr)
|
||||
let arr_length = list.length(arr)
|
||||
let warr_length = list.length(warr)
|
||||
case arr_length == warr_length {
|
||||
True -> {
|
||||
case validate_weights(warr) {
|
||||
Ok(_) -> {
|
||||
let tuples: List(#(Float, Float)) = list.zip(arr, warr)
|
||||
let aggregate: Float =
|
||||
let tuples = list.zip(arr, warr)
|
||||
let aggregate =
|
||||
tuples
|
||||
|> list.fold(
|
||||
0.0,
|
||||
fn(accumulator: Float, tuple: #(Float, Float)) -> Float {
|
||||
let first_element: Float = pair.first(tuple)
|
||||
let second_element: Float = pair.second(tuple)
|
||||
let assert Ok(result) =
|
||||
elementary.power(
|
||||
piecewise.float_absolute_value(first_element),
|
||||
p,
|
||||
)
|
||||
second_element *. result +. accumulator
|
||||
},
|
||||
)
|
||||
|> list.fold(0.0, fn(accumulator, tuple) {
|
||||
let first_element = pair.first(tuple)
|
||||
let second_element = pair.second(tuple)
|
||||
let assert Ok(result) =
|
||||
elementary.power(
|
||||
piecewise.float_absolute_value(first_element),
|
||||
p,
|
||||
)
|
||||
second_element *. result +. accumulator
|
||||
})
|
||||
let assert Ok(result) = elementary.power(aggregate, 1.0 /. p)
|
||||
result
|
||||
|> Ok
|
||||
|
@ -368,11 +365,9 @@ pub fn minkowski_distance(
|
|||
"Invalid input argument: p < 1. Valid input is p >= 1."
|
||||
|> Error
|
||||
False -> {
|
||||
let differences: List(Float) =
|
||||
let differences =
|
||||
list.zip(xarr, yarr)
|
||||
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||
pair.first(tuple) -. pair.second(tuple)
|
||||
})
|
||||
|> list.map(fn(tuple) { pair.first(tuple) -. pair.second(tuple) })
|
||||
|
||||
let assert Ok(result) = norm(differences, p, weights)
|
||||
result
|
||||
|
@ -496,7 +491,7 @@ pub fn chebyshev_distance(
|
|||
|> Error
|
||||
Ok(_) -> {
|
||||
list.zip(xarr, yarr)
|
||||
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||
|> list.map(fn(tuple) {
|
||||
{ pair.first(tuple) -. pair.second(tuple) }
|
||||
|> piecewise.float_absolute_value()
|
||||
})
|
||||
|
@ -553,9 +548,7 @@ pub fn mean(arr: List(Float)) -> Result(Float, String) {
|
|||
_ ->
|
||||
arr
|
||||
|> arithmetics.float_sum(option.None)
|
||||
|> fn(a: Float) -> Float {
|
||||
a /. conversion.int_to_float(list.length(arr))
|
||||
}
|
||||
|> fn(a) { a /. conversion.int_to_float(list.length(arr)) }
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -651,7 +644,7 @@ fn do_median(
|
|||
///
|
||||
/// pub fn example () {
|
||||
/// // Degrees of freedom
|
||||
/// let ddof: Int = 1
|
||||
/// let ddof = 1
|
||||
///
|
||||
/// // An empty list returns an error
|
||||
/// []
|
||||
|
@ -684,12 +677,12 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
|
|||
False -> {
|
||||
let assert Ok(mean) = mean(arr)
|
||||
arr
|
||||
|> list.map(fn(a: Float) -> Float {
|
||||
|> list.map(fn(a) {
|
||||
let assert Ok(result) = elementary.power(a -. mean, 2.0)
|
||||
result
|
||||
})
|
||||
|> arithmetics.float_sum(option.None)
|
||||
|> fn(a: Float) -> Float {
|
||||
|> fn(a) {
|
||||
a
|
||||
/. {
|
||||
conversion.int_to_float(list.length(arr))
|
||||
|
@ -728,7 +721,7 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
|
|||
///
|
||||
/// pub fn example () {
|
||||
/// // Degrees of freedom
|
||||
/// let ddof: Int = 1
|
||||
/// let ddof = 1
|
||||
///
|
||||
/// // An empty list returns an error
|
||||
/// []
|
||||
|
@ -802,8 +795,8 @@ pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, String)
|
|||
/// import gleam/set
|
||||
///
|
||||
/// pub fn example () {
|
||||
/// let xset: set.Set(String) = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let yset: set.Set(String) =
|
||||
/// let xset = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let yset =
|
||||
/// set.from_list(["monkey", "rhino", "ostrich", "salmon"])
|
||||
/// metrics.jaccard_index(xset, yset)
|
||||
/// |> should.equal(1.0 /. 7.0)
|
||||
|
@ -854,8 +847,8 @@ pub fn jaccard_index(xset: set.Set(a), yset: set.Set(a)) -> Float {
|
|||
/// import gleam/set
|
||||
///
|
||||
/// pub fn example () {
|
||||
/// let xset: set.Set(String) = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let yset: set.Set(String) =
|
||||
/// let xset = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let yset =
|
||||
/// set.from_list(["monkey", "rhino", "ostrich", "salmon", "spider"])
|
||||
/// metrics.sorensen_dice_coefficient(xset, yset)
|
||||
/// |> should.equal(2.0 *. 1.0 /. { 4.0 +. 5.0 })
|
||||
|
@ -911,8 +904,8 @@ pub fn sorensen_dice_coefficient(xset: set.Set(a), yset: set.Set(a)) -> Float {
|
|||
/// import gleam/set
|
||||
///
|
||||
/// pub fn example () {
|
||||
/// let yset: set.Set(String) = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let xset: set.Set(String) =
|
||||
/// let yset = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
/// let xset =
|
||||
/// set.from_list(["monkey", "rhino", "ostrich", "salmon"])
|
||||
/// // Test Jaccard index (alpha = beta = 1)
|
||||
/// metrics.tversky_index(xset, yset, 1.0, 1.0)
|
||||
|
@ -934,15 +927,15 @@ pub fn tversky_index(
|
|||
) -> Result(Float, String) {
|
||||
case alpha >=. 0.0, beta >=. 0.0 {
|
||||
True, True -> {
|
||||
let intersection: Float =
|
||||
let intersection =
|
||||
set.intersection(xset, yset)
|
||||
|> set.size()
|
||||
|> conversion.int_to_float()
|
||||
let difference1: Float =
|
||||
let difference1 =
|
||||
set.difference(xset, yset)
|
||||
|> set.size()
|
||||
|> conversion.int_to_float()
|
||||
let difference2: Float =
|
||||
let difference2 =
|
||||
set.difference(yset, xset)
|
||||
|> set.size()
|
||||
|> conversion.int_to_float()
|
||||
|
@ -1000,9 +993,9 @@ pub fn tversky_index(
|
|||
/// import gleam/set
|
||||
///
|
||||
/// pub fn example () {
|
||||
/// let set_a: set.Set(String) =
|
||||
/// let set_a =
|
||||
/// set.from_list(["horse", "dog", "hippo", "monkey", "bird"])
|
||||
/// let set_b: set.Set(String) =
|
||||
/// let set_b =
|
||||
/// set.from_list(["monkey", "bird", "ostrich", "salmon"])
|
||||
/// metrics.overlap_coefficient(set_a, set_b)
|
||||
/// |> should.equal(2.0 /. 4.0)
|
||||
|
@ -1016,11 +1009,11 @@ pub fn tversky_index(
|
|||
/// </div>
|
||||
///
|
||||
pub fn overlap_coefficient(xset: set.Set(a), yset: set.Set(a)) -> Float {
|
||||
let intersection: Float =
|
||||
let intersection =
|
||||
set.intersection(xset, yset)
|
||||
|> set.size()
|
||||
|> conversion.int_to_float()
|
||||
let minsize: Float =
|
||||
let minsize =
|
||||
piecewise.minimum(set.size(xset), set.size(yset), int.compare)
|
||||
|> conversion.int_to_float()
|
||||
intersection /. minsize
|
||||
|
@ -1090,36 +1083,34 @@ pub fn cosine_similarity(
|
|||
msg
|
||||
|> Error
|
||||
Ok(_) -> {
|
||||
let zipped_arr: List(#(Float, Float)) = list.zip(xarr, yarr)
|
||||
let zipped_arr = list.zip(xarr, yarr)
|
||||
|
||||
let numerator_elements: List(Float) =
|
||||
let numerator_elements =
|
||||
zipped_arr
|
||||
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||
pair.first(tuple) *. pair.second(tuple)
|
||||
})
|
||||
|> list.map(fn(tuple) { pair.first(tuple) *. pair.second(tuple) })
|
||||
|
||||
case weights {
|
||||
option.None -> {
|
||||
let numerator: Float =
|
||||
let numerator =
|
||||
numerator_elements
|
||||
|> arithmetics.float_sum(option.None)
|
||||
|
||||
let assert Ok(xarr_norm) = norm(xarr, 2.0, option.None)
|
||||
let assert Ok(yarr_norm) = norm(yarr, 2.0, option.None)
|
||||
let denominator: Float = {
|
||||
let denominator = {
|
||||
xarr_norm *. yarr_norm
|
||||
}
|
||||
numerator /. denominator
|
||||
|> Ok
|
||||
}
|
||||
_ -> {
|
||||
let numerator: Float =
|
||||
let numerator =
|
||||
numerator_elements
|
||||
|> arithmetics.float_sum(weights)
|
||||
|
||||
let assert Ok(xarr_norm) = norm(xarr, 2.0, weights)
|
||||
let assert Ok(yarr_norm) = norm(yarr, 2.0, weights)
|
||||
let denominator: Float = {
|
||||
let denominator = {
|
||||
xarr_norm *. yarr_norm
|
||||
}
|
||||
numerator /. denominator
|
||||
|
@ -1188,7 +1179,7 @@ pub fn canberra_distance(
|
|||
msg
|
||||
|> Error
|
||||
Ok(_) -> {
|
||||
let arr: List(Float) =
|
||||
let arr =
|
||||
list.zip(xarr, yarr)
|
||||
|> list.map(canberra_distance_helper)
|
||||
|
||||
|
@ -1209,9 +1200,9 @@ pub fn canberra_distance(
|
|||
}
|
||||
|
||||
fn canberra_distance_helper(tuple: #(Float, Float)) -> Float {
|
||||
let numerator: Float =
|
||||
let numerator =
|
||||
piecewise.float_absolute_value({ pair.first(tuple) -. pair.second(tuple) })
|
||||
let denominator: Float = {
|
||||
let denominator = {
|
||||
piecewise.float_absolute_value(pair.first(tuple))
|
||||
+. piecewise.float_absolute_value(pair.second(tuple))
|
||||
}
|
||||
|
@ -1281,17 +1272,17 @@ pub fn braycurtis_distance(
|
|||
msg
|
||||
|> Error
|
||||
Ok(_) -> {
|
||||
let zipped_arr: List(#(Float, Float)) = list.zip(xarr, yarr)
|
||||
let numerator_elements: List(Float) =
|
||||
let zipped_arr = list.zip(xarr, yarr)
|
||||
let numerator_elements =
|
||||
zipped_arr
|
||||
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||
|> list.map(fn(tuple) {
|
||||
piecewise.float_absolute_value({
|
||||
pair.first(tuple) -. pair.second(tuple)
|
||||
})
|
||||
})
|
||||
let denominator_elements: List(Float) =
|
||||
let denominator_elements =
|
||||
zipped_arr
|
||||
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||
|> list.map(fn(tuple) {
|
||||
piecewise.float_absolute_value({
|
||||
pair.first(tuple) +. pair.second(tuple)
|
||||
})
|
||||
|
|
|
@ -424,9 +424,9 @@ fn do_round(p: Float, x: Float, mode: option.Option(RoundingMode)) -> Float {
|
|||
}
|
||||
|
||||
fn round_to_nearest(p: Float, x: Float) -> Float {
|
||||
let xabs: Float = float_absolute_value(x) *. p
|
||||
let xabs_truncated: Float = truncate_float(xabs)
|
||||
let remainder: Float = xabs -. xabs_truncated
|
||||
let xabs = float_absolute_value(x) *. p
|
||||
let xabs_truncated = truncate_float(xabs)
|
||||
let remainder = xabs -. xabs_truncated
|
||||
case remainder {
|
||||
_ if remainder >. 0.5 -> float_sign(x) *. truncate_float(xabs +. 1.0) /. p
|
||||
_ if remainder == 0.5 -> {
|
||||
|
@ -441,8 +441,8 @@ fn round_to_nearest(p: Float, x: Float) -> Float {
|
|||
}
|
||||
|
||||
fn round_ties_away(p: Float, x: Float) -> Float {
|
||||
let xabs: Float = float_absolute_value(x) *. p
|
||||
let remainder: Float = xabs -. truncate_float(xabs)
|
||||
let xabs = float_absolute_value(x) *. p
|
||||
let remainder = xabs -. truncate_float(xabs)
|
||||
case remainder {
|
||||
_ if remainder >=. 0.5 -> float_sign(x) *. truncate_float(xabs +. 1.0) /. p
|
||||
_ -> float_sign(x) *. truncate_float(xabs) /. p
|
||||
|
@ -450,9 +450,9 @@ fn round_ties_away(p: Float, x: Float) -> Float {
|
|||
}
|
||||
|
||||
fn round_ties_up(p: Float, x: Float) -> Float {
|
||||
let xabs: Float = float_absolute_value(x) *. p
|
||||
let xabs_truncated: Float = truncate_float(xabs)
|
||||
let remainder: Float = xabs -. xabs_truncated
|
||||
let xabs = float_absolute_value(x) *. p
|
||||
let xabs_truncated = truncate_float(xabs)
|
||||
let remainder = xabs -. xabs_truncated
|
||||
case remainder {
|
||||
_ if remainder >=. 0.5 && x >=. 0.0 ->
|
||||
float_sign(x) *. truncate_float(xabs +. 1.0) /. p
|
||||
|
@ -823,7 +823,7 @@ pub fn int_flip_sign(x: Int) -> Int {
|
|||
/// </a>
|
||||
/// </div>
|
||||
///
|
||||
pub fn minimum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a {
|
||||
pub fn minimum(x: a, y: a, compare: fn(a, a) -> order.Order) {
|
||||
case compare(x, y) {
|
||||
order.Lt -> x
|
||||
order.Eq -> x
|
||||
|
@ -869,7 +869,7 @@ pub fn minimum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a {
|
|||
/// </a>
|
||||
/// </div>
|
||||
///
|
||||
pub fn maximum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a {
|
||||
pub fn maximum(x: a, y: a, compare: fn(a, a) -> order.Order) {
|
||||
case compare(x, y) {
|
||||
order.Lt -> y
|
||||
order.Eq -> y
|
||||
|
@ -909,7 +909,7 @@ pub fn maximum(x: a, y: a, compare: fn(a, a) -> order.Order) -> a {
|
|||
/// </a>
|
||||
/// </div>
|
||||
///
|
||||
pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) -> #(a, a) {
|
||||
pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) {
|
||||
#(minimum(x, y, compare), maximum(x, y, compare))
|
||||
}
|
||||
|
||||
|
@ -956,7 +956,7 @@ pub fn list_minimum(
|
|||
|> Error
|
||||
[x, ..rest] ->
|
||||
Ok(
|
||||
list.fold(rest, x, fn(acc: a, element: a) {
|
||||
list.fold(rest, x, fn(acc, element) {
|
||||
case compare(element, acc) {
|
||||
order.Lt -> element
|
||||
_ -> acc
|
||||
|
@ -1010,7 +1010,7 @@ pub fn list_maximum(
|
|||
|> Error
|
||||
[x, ..rest] ->
|
||||
Ok(
|
||||
list.fold(rest, x, fn(acc: a, element: a) {
|
||||
list.fold(rest, x, fn(acc, element) {
|
||||
case compare(acc, element) {
|
||||
order.Lt -> element
|
||||
_ -> acc
|
||||
|
@ -1073,13 +1073,13 @@ pub fn arg_minimum(
|
|||
arr
|
||||
|> list_minimum(compare)
|
||||
arr
|
||||
|> list.index_map(fn(element: a, index: Int) -> Int {
|
||||
|> list.index_map(fn(element, index) {
|
||||
case compare(element, min) {
|
||||
order.Eq -> index
|
||||
_ -> -1
|
||||
}
|
||||
})
|
||||
|> list.filter(fn(index: Int) -> Bool {
|
||||
|> list.filter(fn(index) {
|
||||
case index {
|
||||
-1 -> False
|
||||
_ -> True
|
||||
|
@ -1143,13 +1143,13 @@ pub fn arg_maximum(
|
|||
arr
|
||||
|> list_maximum(compare)
|
||||
arr
|
||||
|> list.index_map(fn(element: a, index: Int) -> Int {
|
||||
|> list.index_map(fn(element, index) {
|
||||
case compare(element, max) {
|
||||
order.Eq -> index
|
||||
_ -> -1
|
||||
}
|
||||
})
|
||||
|> list.filter(fn(index: Int) -> Bool {
|
||||
|> list.filter(fn(index) {
|
||||
case index {
|
||||
-1 -> False
|
||||
_ -> True
|
||||
|
@ -1210,9 +1210,9 @@ pub fn extrema(
|
|||
|> Error
|
||||
[x, ..rest] ->
|
||||
Ok(
|
||||
list.fold(rest, #(x, x), fn(acc: #(a, a), element: a) {
|
||||
let first: a = pair.first(acc)
|
||||
let second: a = pair.second(acc)
|
||||
list.fold(rest, #(x, x), fn(acc, element) {
|
||||
let first = pair.first(acc)
|
||||
let second = pair.second(acc)
|
||||
case compare(element, first), compare(second, element) {
|
||||
order.Lt, order.Lt -> #(element, element)
|
||||
order.Lt, _ -> #(element, second)
|
||||
|
|
|
@ -71,12 +71,12 @@ import gleam_community/maths/piecewise
|
|||
/// import gleam_community/maths/predicates
|
||||
///
|
||||
/// pub fn example () {
|
||||
/// let val: Float = 99.
|
||||
/// let ref_val: Float = 100.
|
||||
/// let val = 99.
|
||||
/// let ref_val = 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
|
||||
/// let rtol = 0.01
|
||||
/// let atol = 0.10
|
||||
/// floatx.is_close(val, ref_val, rtol, atol)
|
||||
/// |> should.be_true()
|
||||
/// }
|
||||
|
@ -89,8 +89,8 @@ import gleam_community/maths/piecewise
|
|||
/// </div>
|
||||
///
|
||||
pub fn is_close(a: Float, b: Float, rtol: Float, atol: Float) -> Bool {
|
||||
let x: Float = float_absolute_difference(a, b)
|
||||
let y: Float = atol +. rtol *. float_absolute_value(b)
|
||||
let x = float_absolute_difference(a, b)
|
||||
let y = atol +. rtol *. float_absolute_value(b)
|
||||
case x <=. y {
|
||||
True -> True
|
||||
False -> False
|
||||
|
@ -126,20 +126,20 @@ fn float_absolute_difference(a: Float, b: Float) -> Float {
|
|||
/// import gleam_community/maths/predicates
|
||||
///
|
||||
/// 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)
|
||||
/// let val = 99.
|
||||
/// let ref_val = 100.
|
||||
/// let xarr = list.repeat(val, 42)
|
||||
/// let yarr = 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
|
||||
/// let rtol = 0.01
|
||||
/// let atol = 0.10
|
||||
/// predicates.all_close(xarr, yarr, rtol, atol)
|
||||
/// |> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) {
|
||||
/// |> fn(zarr), String)) {
|
||||
/// case zarr {
|
||||
/// Ok(arr) ->
|
||||
/// arr
|
||||
/// |> list.all(fn(a: Bool) -> Bool { a })
|
||||
/// |> list.all(fn(a) { a })
|
||||
/// |> Ok
|
||||
/// _ -> Nil |> Error
|
||||
/// }
|
||||
|
@ -160,17 +160,15 @@ pub fn all_close(
|
|||
rtol: Float,
|
||||
atol: Float,
|
||||
) -> Result(List(Bool), String) {
|
||||
let xlen: Int = list.length(xarr)
|
||||
let ylen: Int = list.length(yarr)
|
||||
let xlen = list.length(xarr)
|
||||
let ylen = list.length(yarr)
|
||||
case xlen == ylen {
|
||||
False ->
|
||||
"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."
|
||||
|> Error
|
||||
True ->
|
||||
list.zip(xarr, yarr)
|
||||
|> list.map(fn(z: #(Float, Float)) -> Bool {
|
||||
is_close(pair.first(z), pair.second(z), rtol, atol)
|
||||
})
|
||||
|> list.map(fn(z) { is_close(pair.first(z), pair.second(z), rtol, atol) })
|
||||
|> Ok
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +302,7 @@ fn do_sum(arr: List(Int)) -> Int {
|
|||
[] -> 0
|
||||
_ ->
|
||||
arr
|
||||
|> list.fold(0, fn(acc: Int, a: Int) -> Int { a + acc })
|
||||
|> list.fold(0, fn(acc, a) { a + acc })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +444,7 @@ fn miller_rabin_test(n: Int, k: Int) -> Bool {
|
|||
_, 0 -> True
|
||||
_, _ -> {
|
||||
// Generate a random int in the range [2, n]
|
||||
let random_candidate: Int = 2 + int.random(n - 2)
|
||||
let random_candidate = 2 + int.random(n - 2)
|
||||
case powmod_with_check(random_candidate, n - 1, n) == 1 {
|
||||
True -> miller_rabin_test(n, k - 1)
|
||||
False -> False
|
||||
|
@ -459,7 +457,7 @@ fn powmod_with_check(base: Int, exponent: Int, modulus: Int) -> Int {
|
|||
case exponent, { exponent % 2 } == 0 {
|
||||
0, _ -> 1
|
||||
_, True -> {
|
||||
let x: Int = powmod_with_check(base, exponent / 2, modulus)
|
||||
let x = powmod_with_check(base, exponent / 2, modulus)
|
||||
case { x * x } % modulus, x != 1 && x != { modulus - 1 } {
|
||||
1, True -> 0
|
||||
_, _ -> { x * x } % modulus
|
||||
|
|
|
@ -102,7 +102,7 @@ pub fn arange(
|
|||
|> conversion.float_to_int()
|
||||
|
||||
iterator.range(0, num - 1)
|
||||
|> iterator.map(fn(i: Int) {
|
||||
|> iterator.map(fn(i) {
|
||||
start +. conversion.int_to_float(i) *. step_abs *. direction
|
||||
})
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ pub fn linear_space(
|
|||
num: Int,
|
||||
endpoint: Bool,
|
||||
) -> Result(iterator.Iterator(Float), String) {
|
||||
let direction: Float = case start <=. stop {
|
||||
let direction = case start <=. stop {
|
||||
True -> 1.0
|
||||
False -> -1.0
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ pub fn linear_space(
|
|||
case num > 0 {
|
||||
True -> {
|
||||
iterator.range(0, num - 1)
|
||||
|> iterator.map(fn(i: Int) -> Float {
|
||||
|> iterator.map(fn(i) {
|
||||
start +. conversion.int_to_float(i) *. increment *. direction
|
||||
})
|
||||
|> Ok
|
||||
|
@ -246,7 +246,7 @@ pub fn logarithmic_space(
|
|||
True -> {
|
||||
let assert Ok(linspace) = linear_space(start, stop, num, endpoint)
|
||||
linspace
|
||||
|> iterator.map(fn(i: Float) -> Float {
|
||||
|> iterator.map(fn(i) {
|
||||
let assert Ok(result) = elementary.power(base, i)
|
||||
result
|
||||
})
|
||||
|
|
|
@ -76,17 +76,17 @@ pub fn beta(x: Float, y: Float) -> Float {
|
|||
/// </div>
|
||||
///
|
||||
pub fn erf(x: Float) -> Float {
|
||||
let assert [a1, a2, a3, a4, a5]: List(Float) = [
|
||||
let assert [a1, a2, a3, a4, a5] = [
|
||||
0.254829592, -0.284496736, 1.421413741, -1.453152027, 1.061405429,
|
||||
]
|
||||
let p: Float = 0.3275911
|
||||
let p = 0.3275911
|
||||
|
||||
let sign: Float = piecewise.float_sign(x)
|
||||
let x: Float = piecewise.float_absolute_value(x)
|
||||
let sign = piecewise.float_sign(x)
|
||||
let x = piecewise.float_absolute_value(x)
|
||||
|
||||
// Formula 7.1.26 given in Abramowitz and Stegun.
|
||||
let t: Float = 1.0 /. { 1.0 +. p *. x }
|
||||
let y: Float =
|
||||
let t = 1.0 /. { 1.0 +. p *. x }
|
||||
let y =
|
||||
1.0
|
||||
-. { { { { a5 *. t +. a4 } *. t +. a3 } *. t +. a2 } *. t +. a1 }
|
||||
*. t
|
||||
|
@ -131,14 +131,14 @@ fn gamma_lanczos(x: Float) -> Float {
|
|||
/. { elementary.sin(elementary.pi() *. x) *. gamma_lanczos(1.0 -. x) }
|
||||
False -> {
|
||||
let z = x -. 1.0
|
||||
let x: Float =
|
||||
list.index_fold(lanczos_p, 0.0, fn(acc: Float, v: Float, index: Int) {
|
||||
let x =
|
||||
list.index_fold(lanczos_p, 0.0, fn(acc, v, index) {
|
||||
case index > 0 {
|
||||
True -> acc +. v /. { z +. conversion.int_to_float(index) }
|
||||
False -> v
|
||||
}
|
||||
})
|
||||
let t: Float = z +. lanczos_g +. 0.5
|
||||
let t = z +. lanczos_g +. 0.5
|
||||
let assert Ok(v1) = elementary.power(2.0 *. elementary.pi(), 0.5)
|
||||
let assert Ok(v2) = elementary.power(t, z +. 0.5)
|
||||
v1 *. v2 *. elementary.exponential(-1.0 *. t) *. x
|
||||
|
@ -189,8 +189,8 @@ fn incomplete_gamma_sum(
|
|||
case t {
|
||||
0.0 -> s
|
||||
_ -> {
|
||||
let ns: Float = s +. t
|
||||
let nt: Float = t *. { x /. { a +. n } }
|
||||
let ns = s +. t
|
||||
let nt = t *. { x /. { a +. n } }
|
||||
incomplete_gamma_sum(a, x, nt, ns, n +. 1.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -317,7 +317,7 @@ pub fn median_test() {
|
|||
|
||||
pub fn variance_test() {
|
||||
// Degrees of freedom
|
||||
let ddof: Int = 1
|
||||
let ddof = 1
|
||||
|
||||
// An empty list returns an error
|
||||
[]
|
||||
|
@ -332,7 +332,7 @@ pub fn variance_test() {
|
|||
|
||||
pub fn standard_deviation_test() {
|
||||
// Degrees of freedom
|
||||
let ddof: Int = 1
|
||||
let ddof = 1
|
||||
|
||||
// An empty list returns an error
|
||||
[]
|
||||
|
@ -349,19 +349,18 @@ pub fn jaccard_index_test() {
|
|||
metrics.jaccard_index(set.from_list([]), set.from_list([]))
|
||||
|> should.equal(0.0)
|
||||
|
||||
let set_a: set.Set(Int) = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b: set.Set(Int) = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
let set_a = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
metrics.jaccard_index(set_a, set_b)
|
||||
|> should.equal(4.0 /. 10.0)
|
||||
|
||||
let set_c: set.Set(Int) = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d: set.Set(Int) = set.from_list([6, 7, 8, 9, 10])
|
||||
let set_c = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d = set.from_list([6, 7, 8, 9, 10])
|
||||
metrics.jaccard_index(set_c, set_d)
|
||||
|> should.equal(0.0 /. 11.0)
|
||||
|
||||
let set_e: set.Set(String) = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
let set_f: set.Set(String) =
|
||||
set.from_list(["monkey", "rhino", "ostrich", "salmon"])
|
||||
let set_e = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
let set_f = set.from_list(["monkey", "rhino", "ostrich", "salmon"])
|
||||
metrics.jaccard_index(set_e, set_f)
|
||||
|> should.equal(1.0 /. 7.0)
|
||||
}
|
||||
|
@ -370,19 +369,18 @@ pub fn sorensen_dice_coefficient_test() {
|
|||
metrics.sorensen_dice_coefficient(set.from_list([]), set.from_list([]))
|
||||
|> should.equal(0.0)
|
||||
|
||||
let set_a: set.Set(Int) = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b: set.Set(Int) = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
let set_a = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
metrics.sorensen_dice_coefficient(set_a, set_b)
|
||||
|> should.equal(2.0 *. 4.0 /. { 7.0 +. 7.0 })
|
||||
|
||||
let set_c: set.Set(Int) = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d: set.Set(Int) = set.from_list([6, 7, 8, 9, 10])
|
||||
let set_c = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d = set.from_list([6, 7, 8, 9, 10])
|
||||
metrics.sorensen_dice_coefficient(set_c, set_d)
|
||||
|> should.equal(2.0 *. 0.0 /. { 6.0 +. 5.0 })
|
||||
|
||||
let set_e: set.Set(String) = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
let set_f: set.Set(String) =
|
||||
set.from_list(["monkey", "rhino", "ostrich", "salmon", "spider"])
|
||||
let set_e = set.from_list(["cat", "dog", "hippo", "monkey"])
|
||||
let set_f = set.from_list(["monkey", "rhino", "ostrich", "salmon", "spider"])
|
||||
metrics.sorensen_dice_coefficient(set_e, set_f)
|
||||
|> should.equal(2.0 *. 1.0 /. { 4.0 +. 5.0 })
|
||||
}
|
||||
|
@ -391,20 +389,18 @@ pub fn overlap_coefficient_test() {
|
|||
metrics.overlap_coefficient(set.from_list([]), set.from_list([]))
|
||||
|> should.equal(0.0)
|
||||
|
||||
let set_a: set.Set(Int) = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b: set.Set(Int) = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
let set_a = set.from_list([0, 1, 2, 5, 6, 8, 9])
|
||||
let set_b = set.from_list([0, 2, 3, 4, 5, 7, 9])
|
||||
metrics.overlap_coefficient(set_a, set_b)
|
||||
|> should.equal(4.0 /. 7.0)
|
||||
|
||||
let set_c: set.Set(Int) = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d: set.Set(Int) = set.from_list([6, 7, 8, 9, 10])
|
||||
let set_c = set.from_list([0, 1, 2, 3, 4, 5])
|
||||
let set_d = set.from_list([6, 7, 8, 9, 10])
|
||||
metrics.overlap_coefficient(set_c, set_d)
|
||||
|> should.equal(0.0 /. 5.0)
|
||||
|
||||
let set_e: set.Set(String) =
|
||||
set.from_list(["horse", "dog", "hippo", "monkey", "bird"])
|
||||
let set_f: set.Set(String) =
|
||||
set.from_list(["monkey", "bird", "ostrich", "salmon"])
|
||||
let set_e = set.from_list(["horse", "dog", "hippo", "monkey", "bird"])
|
||||
let set_f = set.from_list(["monkey", "bird", "ostrich", "salmon"])
|
||||
metrics.overlap_coefficient(set_e, set_f)
|
||||
|> should.equal(2.0 /. 4.0)
|
||||
}
|
||||
|
|
|
@ -3,31 +3,31 @@ import gleam_community/maths/predicates
|
|||
import gleeunit/should
|
||||
|
||||
pub fn float_is_close_test() {
|
||||
let val: Float = 99.0
|
||||
let ref_val: Float = 100.0
|
||||
let val = 99.0
|
||||
let ref_val = 100.0
|
||||
// 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.1
|
||||
let rtol = 0.01
|
||||
let atol = 0.1
|
||||
predicates.is_close(val, ref_val, rtol, atol)
|
||||
|> should.be_true()
|
||||
}
|
||||
|
||||
pub fn float_list_all_close_test() {
|
||||
let val: Float = 99.0
|
||||
let ref_val: Float = 100.0
|
||||
let xarr: List(Float) = list.repeat(val, 42)
|
||||
let yarr: List(Float) = list.repeat(ref_val, 42)
|
||||
let val = 99.0
|
||||
let ref_val = 100.0
|
||||
let xarr = list.repeat(val, 42)
|
||||
let yarr = 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.1
|
||||
let rtol = 0.01
|
||||
let atol = 0.1
|
||||
predicates.all_close(xarr, yarr, rtol, atol)
|
||||
|> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) {
|
||||
|> fn(zarr) {
|
||||
case zarr {
|
||||
Ok(arr) ->
|
||||
arr
|
||||
|> list.all(fn(a: Bool) -> Bool { a })
|
||||
|> list.all(fn(a) { a })
|
||||
|> Ok
|
||||
_ ->
|
||||
Nil
|
||||
|
|
Loading…
Reference in a new issue