mirror of
https://github.com/sigmasternchen/gleam-community-maths
synced 2025-03-15 07:59:01 +00:00
Merge pull request #28 from gleam-community/refactor/nil-errors
♻️ Replace `String` errors with `Nil`
This commit is contained in:
commit
77e13b9254
9 changed files with 178 additions and 353 deletions
|
@ -442,7 +442,7 @@ pub fn int_sum(arr: List(Int)) -> Int {
|
||||||
pub fn float_product(
|
pub fn float_product(
|
||||||
arr: List(Float),
|
arr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case arr, weights {
|
case arr, weights {
|
||||||
[], _ ->
|
[], _ ->
|
||||||
1.0
|
1.0
|
||||||
|
@ -452,22 +452,16 @@ pub fn float_product(
|
||||||
|> list.fold(1.0, fn(acc, a) { a *. acc })
|
|> list.fold(1.0, fn(acc, a) { a *. acc })
|
||||||
|> Ok
|
|> Ok
|
||||||
_, option.Some(warr) -> {
|
_, option.Some(warr) -> {
|
||||||
let results =
|
list.zip(arr, warr)
|
||||||
list.zip(arr, warr)
|
|> list.map(fn(a: #(Float, Float)) -> Result(Float, Nil) {
|
||||||
|> list.map(fn(a) {
|
pair.first(a)
|
||||||
pair.first(a)
|
|> elementary.power(pair.second(a))
|
||||||
|> elementary.power(pair.second(a))
|
})
|
||||||
})
|
|> result.all
|
||||||
|> result.all
|
|> result.map(fn(prods) {
|
||||||
case results {
|
prods
|
||||||
Ok(prods) ->
|
|> list.fold(1.0, fn(acc: Float, a: Float) -> Float { a *. acc })
|
||||||
prods
|
})
|
||||||
|> list.fold(1.0, fn(acc, a) { a *. acc })
|
|
||||||
|> Ok
|
|
||||||
Error(msg) ->
|
|
||||||
msg
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,12 +130,10 @@ pub fn combination(
|
||||||
n: Int,
|
n: Int,
|
||||||
k: Int,
|
k: Int,
|
||||||
mode: option.Option(CombinatoricsMode),
|
mode: option.Option(CombinatoricsMode),
|
||||||
) -> Result(Int, String) {
|
) -> Result(Int, Nil) {
|
||||||
case n, k {
|
case n, k {
|
||||||
_, _ if n < 0 ->
|
_, _ if n < 0 -> Error(Nil)
|
||||||
"Invalid input argument: n < 0. Valid input is n >= 0." |> Error
|
_, _ if k < 0 -> Error(Nil)
|
||||||
_, _ if k < 0 ->
|
|
||||||
"Invalid input argument: k < 0. Valid input is k >= 0." |> Error
|
|
||||||
_, _ -> {
|
_, _ -> {
|
||||||
case mode {
|
case mode {
|
||||||
option.Some(WithRepetitions) -> combination_with_repetitions(n, k)
|
option.Some(WithRepetitions) -> combination_with_repetitions(n, k)
|
||||||
|
@ -145,12 +143,11 @@ pub fn combination(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn combination_with_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
fn combination_with_repetitions(n: Int, k: Int) -> Result(Int, Nil) {
|
||||||
{ n + k - 1 }
|
combination_without_repetitions(n + k - 1, k)
|
||||||
|> combination_without_repetitions(k)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, Nil) {
|
||||||
case n, k {
|
case n, k {
|
||||||
_, _ if k == 0 || k == n -> {
|
_, _ if k == 0 || k == n -> {
|
||||||
1 |> Ok
|
1 |> Ok
|
||||||
|
@ -202,17 +199,11 @@ fn combination_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn factorial(n) -> Result(Int, String) {
|
pub fn factorial(n) -> Result(Int, Nil) {
|
||||||
case n {
|
case n {
|
||||||
_ if n < 0 ->
|
_ if n < 0 -> Error(Nil)
|
||||||
"Invalid input argument: n < 0. Valid input is n >= 0."
|
0 -> Ok(1)
|
||||||
|> Error
|
1 -> Ok(1)
|
||||||
0 ->
|
|
||||||
1
|
|
||||||
|> Ok
|
|
||||||
1 ->
|
|
||||||
1
|
|
||||||
|> Ok
|
|
||||||
_ ->
|
_ ->
|
||||||
list.range(1, n)
|
list.range(1, n)
|
||||||
|> list.fold(1, fn(acc, x) { acc * x })
|
|> list.fold(1, fn(acc, x) { acc * x })
|
||||||
|
@ -300,22 +291,16 @@ pub fn permutation(
|
||||||
n: Int,
|
n: Int,
|
||||||
k: Int,
|
k: Int,
|
||||||
mode: option.Option(CombinatoricsMode),
|
mode: option.Option(CombinatoricsMode),
|
||||||
) -> Result(Int, String) {
|
) -> Result(Int, Nil) {
|
||||||
case n, k {
|
case n, k, mode {
|
||||||
_, _ if n < 0 ->
|
_, _, _ if n < 0 -> Error(Nil)
|
||||||
"Invalid input argument: n < 0. Valid input is n >= 0." |> Error
|
_, _, _ if k < 0 -> Error(Nil)
|
||||||
_, _ if k < 0 ->
|
_, _, option.Some(WithRepetitions) -> permutation_with_repetitions(n, k)
|
||||||
"Invalid input argument: k < 0. Valid input is k >= 0." |> Error
|
_, _, _ -> permutation_without_repetitions(n, k)
|
||||||
_, _ -> {
|
|
||||||
case mode {
|
|
||||||
option.Some(WithRepetitions) -> permutation_with_repetitions(n, k)
|
|
||||||
_ -> permutation_without_repetitions(n, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, Nil) {
|
||||||
case n, k {
|
case n, k {
|
||||||
_, _ if k < 0 || k > n -> {
|
_, _ if k < 0 || k > n -> {
|
||||||
0 |> Ok
|
0 |> Ok
|
||||||
|
@ -330,7 +315,7 @@ fn permutation_without_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn permutation_with_repetitions(n: Int, k: Int) -> Result(Int, String) {
|
fn permutation_with_repetitions(n: Int, k: Int) -> Result(Int, Nil) {
|
||||||
let n_float = conversion.int_to_float(n)
|
let n_float = conversion.int_to_float(n)
|
||||||
let k_float = conversion.int_to_float(k)
|
let k_float = conversion.int_to_float(k)
|
||||||
// 'n' ank 'k' are positive integers, so no errors here...
|
// 'n' ank 'k' are positive integers, so no errors here...
|
||||||
|
@ -388,29 +373,20 @@ pub fn list_combination(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
mode: option.Option(CombinatoricsMode),
|
mode: option.Option(CombinatoricsMode),
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> Result(iterator.Iterator(List(a)), Nil) {
|
||||||
case k {
|
case k, mode {
|
||||||
_ if k < 0 ->
|
_, _ if k < 0 -> Error(Nil)
|
||||||
"Invalid input argument: k < 0. Valid input is k >= 0."
|
_, option.Some(WithRepetitions) -> list_combination_with_repetitions(arr, k)
|
||||||
|> Error
|
_, _ -> list_combination_without_repetitions(arr, k)
|
||||||
_ ->
|
|
||||||
case mode {
|
|
||||||
option.Some(WithRepetitions) ->
|
|
||||||
list_combination_with_repetitions(arr, k)
|
|
||||||
_ -> list_combination_without_repetitions(arr, k)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list_combination_without_repetitions(
|
fn list_combination_without_repetitions(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> Result(iterator.Iterator(List(a)), Nil) {
|
||||||
case k, list.length(arr) {
|
case k, list.length(arr) {
|
||||||
_, arr_length if k > arr_length -> {
|
_, arr_length if k > arr_length -> Error(Nil)
|
||||||
"Invalid input argument: k > length(arr). Valid input is 0 <= k <= length(arr)."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
// Special case: When k = n, then the entire list is the only valid combination
|
// Special case: When k = n, then the entire list is the only valid combination
|
||||||
_, arr_length if k == arr_length -> {
|
_, arr_length if k == arr_length -> {
|
||||||
iterator.single(arr) |> Ok
|
iterator.single(arr) |> Ok
|
||||||
|
@ -446,7 +422,7 @@ fn do_list_combination_without_repetitions(
|
||||||
fn list_combination_with_repetitions(
|
fn list_combination_with_repetitions(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> Result(iterator.Iterator(List(a)), Nil) {
|
||||||
Ok(do_list_combination_with_repetitions(iterator.from_list(arr), k, []))
|
Ok(do_list_combination_with_repetitions(iterator.from_list(arr), k, []))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,17 +504,12 @@ pub fn list_permutation(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
mode: option.Option(CombinatoricsMode),
|
mode: option.Option(CombinatoricsMode),
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> Result(iterator.Iterator(List(a)), Nil) {
|
||||||
case k {
|
case k, mode {
|
||||||
_ if k < 0 ->
|
_, _ if k < 0 -> Error(Nil)
|
||||||
"Invalid input argument: k < 0. Valid input is k >= 0."
|
_, option.Some(WithRepetitions) ->
|
||||||
|> Error
|
Ok(list_permutation_with_repetitions(arr, k))
|
||||||
_ ->
|
_, _ -> list_permutation_without_repetitions(arr, k)
|
||||||
case mode {
|
|
||||||
option.Some(WithRepetitions) ->
|
|
||||||
list_permutation_with_repetitions(arr, k)
|
|
||||||
_ -> list_permutation_without_repetitions(arr, k)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,12 +529,9 @@ fn remove_first_by_index(
|
||||||
fn list_permutation_without_repetitions(
|
fn list_permutation_without_repetitions(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> Result(iterator.Iterator(List(a)), Nil) {
|
||||||
case k, list.length(arr) {
|
case k, list.length(arr) {
|
||||||
_, arr_length if k > arr_length -> {
|
_, arr_length if k > arr_length -> Error(Nil)
|
||||||
"Invalid input argument: k > length(arr). Valid input is 0 <= k <= length(arr)."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
_, _ -> {
|
_, _ -> {
|
||||||
let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) })
|
let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) })
|
||||||
Ok(do_list_permutation_without_repetitions(
|
Ok(do_list_permutation_without_repetitions(
|
||||||
|
@ -594,9 +562,9 @@ fn do_list_permutation_without_repetitions(
|
||||||
fn list_permutation_with_repetitions(
|
fn list_permutation_with_repetitions(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
k: Int,
|
k: Int,
|
||||||
) -> Result(iterator.Iterator(List(a)), String) {
|
) -> iterator.Iterator(List(a)) {
|
||||||
let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) })
|
let indexed_arr = list.index_map(arr, fn(x, i) { #(i, x) })
|
||||||
Ok(do_list_permutation_with_repetitions(indexed_arr, k))
|
do_list_permutation_with_repetitions(indexed_arr, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_list_permutation_with_repetitions(
|
fn do_list_permutation_with_repetitions(
|
||||||
|
|
|
@ -98,14 +98,10 @@ import gleam/option
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn acos(x: Float) -> Result(Float, String) {
|
pub fn acos(x: Float) -> Result(Float, Nil) {
|
||||||
case x >=. -1.0 && x <=. 1.0 {
|
case x >=. -1.0 && x <=. 1.0 {
|
||||||
True ->
|
True -> Ok(do_acos(x))
|
||||||
do_acos(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,14 +146,10 @@ fn do_acos(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn acosh(x: Float) -> Result(Float, String) {
|
pub fn acosh(x: Float) -> Result(Float, Nil) {
|
||||||
case x >=. 1.0 {
|
case x >=. 1.0 {
|
||||||
True ->
|
True -> Ok(do_acosh(x))
|
||||||
do_acosh(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x < 1. Valid input is x >= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,14 +197,10 @@ fn do_acosh(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn asin(x: Float) -> Result(Float, String) {
|
pub fn asin(x: Float) -> Result(Float, Nil) {
|
||||||
case x >=. -1.0 && x <=. 1.0 {
|
case x >=. -1.0 && x <=. 1.0 {
|
||||||
True ->
|
True -> Ok(do_asin(x))
|
||||||
do_asin(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x >= -1 or x <= 1. Valid input is -1. <= x <= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,14 +382,10 @@ fn do_atan2(a: Float, b: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn atanh(x: Float) -> Result(Float, String) {
|
pub fn atanh(x: Float) -> Result(Float, Nil) {
|
||||||
case x >. -1.0 && x <. 1.0 {
|
case x >. -1.0 && x <. 1.0 {
|
||||||
True ->
|
True -> Ok(do_atanh(x))
|
||||||
do_atanh(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x > -1 or x < 1. Valid input is -1. < x < 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,14 +737,10 @@ fn do_exponential(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn natural_logarithm(x: Float) -> Result(Float, String) {
|
pub fn natural_logarithm(x: Float) -> Result(Float, Nil) {
|
||||||
case x >. 0.0 {
|
case x >. 0.0 {
|
||||||
True ->
|
True -> Ok(do_natural_logarithm(x))
|
||||||
do_natural_logarithm(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x <= 0. Valid input is x > 0."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,30 +790,19 @@ fn do_natural_logarithm(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String) {
|
pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, Nil) {
|
||||||
case x >. 0.0 {
|
case x >. 0.0, base {
|
||||||
True ->
|
True, option.Some(a) ->
|
||||||
case base {
|
case a >. 0.0 && a != 1.0 {
|
||||||
option.Some(a) ->
|
False -> Error(Nil)
|
||||||
case a >. 0.0 && a != 1.0 {
|
True -> {
|
||||||
True -> {
|
// Apply the "change of base formula"
|
||||||
// Apply the "change of base formula"
|
let assert Ok(numerator) = logarithm_10(x)
|
||||||
let assert Ok(numerator) = logarithm_10(x)
|
let assert Ok(denominator) = logarithm_10(a)
|
||||||
let assert Ok(denominator) = logarithm_10(a)
|
Ok(numerator /. denominator)
|
||||||
numerator /. denominator
|
}
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
_ ->
|
|
||||||
"Invalid input argument: base <= 0 or base == 1. Valid input is base > 0 and base != 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
_ ->
|
_, _ -> Error(Nil)
|
||||||
"Invalid input argument: x <= 0. Valid input is x > 0."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,14 +846,10 @@ pub fn logarithm(x: Float, base: option.Option(Float)) -> Result(Float, String)
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn logarithm_2(x: Float) -> Result(Float, String) {
|
pub fn logarithm_2(x: Float) -> Result(Float, Nil) {
|
||||||
case x >. 0.0 {
|
case x >. 0.0 {
|
||||||
True ->
|
True -> Ok(do_logarithm_2(x))
|
||||||
do_logarithm_2(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x <= 0. Valid input is x > 0."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,14 +897,10 @@ fn do_logarithm_2(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn logarithm_10(x: Float) -> Result(Float, String) {
|
pub fn logarithm_10(x: Float) -> Result(Float, Nil) {
|
||||||
case x >. 0.0 {
|
case x >. 0.0 {
|
||||||
True ->
|
True -> Ok(do_logarithm_10(x))
|
||||||
do_logarithm_10(x)
|
False -> Error(Nil)
|
||||||
|> Ok
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: x <= 0. Valid input is x > 0."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +954,7 @@ fn do_logarithm_10(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn power(x: Float, y: Float) -> Result(Float, String) {
|
pub fn power(x: Float, y: Float) -> Result(Float, Nil) {
|
||||||
let fractional = do_ceiling(y) -. y >. 0.0
|
let fractional = do_ceiling(y) -. y >. 0.0
|
||||||
// In the following check:
|
// In the following check:
|
||||||
// 1. If the base (x) is negative and the exponent (y) is fractional
|
// 1. If the base (x) is negative and the exponent (y) is fractional
|
||||||
|
@ -1002,9 +963,7 @@ pub fn power(x: Float, y: Float) -> Result(Float, String) {
|
||||||
// expression is equivalent to the exponent (y) divided by 0 and an
|
// expression is equivalent to the exponent (y) divided by 0 and an
|
||||||
// error should be returned
|
// error should be returned
|
||||||
case { x <. 0.0 && fractional } || { x == 0.0 && y <. 0.0 } {
|
case { x <. 0.0 && fractional } || { x == 0.0 && y <. 0.0 } {
|
||||||
True ->
|
True -> Error(Nil)
|
||||||
"Invalid input argument: x < 0 and y is fractional or x = 0 and y < 0."
|
|
||||||
|> Error
|
|
||||||
False ->
|
False ->
|
||||||
do_power(x, y)
|
do_power(x, y)
|
||||||
|> Ok
|
|> Ok
|
||||||
|
@ -1055,19 +1014,13 @@ fn do_ceiling(a: Float) -> Float
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn square_root(x: Float) -> Result(Float, String) {
|
pub fn square_root(x: Float) -> Result(Float, Nil) {
|
||||||
// In the following check:
|
// In the following check:
|
||||||
// 1. If x is negative then return an error as it will otherwise be an
|
// 1. If x is negative then return an error as it will otherwise be an
|
||||||
// imaginary number
|
// imaginary number
|
||||||
case x <. 0.0 {
|
case x <. 0.0 {
|
||||||
True ->
|
True -> Error(Nil)
|
||||||
"Invalid input argument: x < 0."
|
False -> power(x, 1.0 /. 2.0)
|
||||||
|> Error
|
|
||||||
False -> {
|
|
||||||
let assert Ok(result) = power(x, 1.0 /. 2.0)
|
|
||||||
result
|
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1107,19 +1060,13 @@ pub fn square_root(x: Float) -> Result(Float, String) {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn cube_root(x: Float) -> Result(Float, String) {
|
pub fn cube_root(x: Float) -> Result(Float, Nil) {
|
||||||
// In the following check:
|
// In the following check:
|
||||||
// 1. If x is negative then return an error as it will otherwise be an
|
// 1. If x is negative then return an error as it will otherwise be an
|
||||||
// imaginary number
|
// imaginary number
|
||||||
case x <. 0.0 {
|
case x <. 0.0 {
|
||||||
True ->
|
True -> Error(Nil)
|
||||||
"Invalid input argument: x < 0."
|
False -> power(x, 1.0 /. 3.0)
|
||||||
|> Error
|
|
||||||
False -> {
|
|
||||||
let assert Ok(result) = power(x, 1.0 /. 3.0)
|
|
||||||
result
|
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,25 +1109,13 @@ pub fn cube_root(x: Float) -> Result(Float, String) {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn nth_root(x: Float, n: Int) -> Result(Float, String) {
|
pub fn nth_root(x: Float, n: Int) -> Result(Float, Nil) {
|
||||||
// In the following check:
|
// In the following check:
|
||||||
// 1. If x is negative then return an error as it will otherwise be an
|
// 1. If x is negative then return an error as it will otherwise be an
|
||||||
// imaginary number
|
// imaginary number
|
||||||
case x <. 0.0 {
|
case x >=. 0.0 && n >= 1 {
|
||||||
True ->
|
True -> power(x, 1.0 /. int.to_float(n))
|
||||||
"Invalid input argument: x < 0. Valid input is x > 0"
|
False -> Error(Nil)
|
||||||
|> Error
|
|
||||||
False ->
|
|
||||||
case n >= 1 {
|
|
||||||
True -> {
|
|
||||||
let assert Ok(result) = power(x, 1.0 /. int.to_float(n))
|
|
||||||
result
|
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
False ->
|
|
||||||
"Invalid input argument: n < 1. Valid input is n >= 2."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@ import gleam/int
|
||||||
import gleam/list
|
import gleam/list
|
||||||
import gleam/option
|
import gleam/option
|
||||||
import gleam/pair
|
import gleam/pair
|
||||||
|
import gleam/result
|
||||||
import gleam/set
|
import gleam/set
|
||||||
import gleam_community/maths/arithmetics
|
import gleam_community/maths/arithmetics
|
||||||
import gleam_community/maths/conversion
|
import gleam_community/maths/conversion
|
||||||
|
@ -72,21 +73,15 @@ fn validate_lists(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Bool, String) {
|
) -> Result(Bool, Nil) {
|
||||||
case xarr, yarr {
|
case xarr, yarr {
|
||||||
[], _ ->
|
[], _ -> Error(Nil)
|
||||||
"Invalid input argument: The list xarr is empty."
|
_, [] -> Error(Nil)
|
||||||
|> Error
|
|
||||||
_, [] ->
|
|
||||||
"Invalid input argument: The list yarr is empty."
|
|
||||||
|> Error
|
|
||||||
_, _ -> {
|
_, _ -> {
|
||||||
let xarr_length = list.length(xarr)
|
let xarr_length = list.length(xarr)
|
||||||
let yarr_length = list.length(yarr)
|
let yarr_length = list.length(yarr)
|
||||||
case xarr_length == yarr_length, weights {
|
case xarr_length == yarr_length, weights {
|
||||||
False, _ ->
|
False, _ -> Error(Nil)
|
||||||
"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."
|
|
||||||
|> Error
|
|
||||||
True, option.None -> {
|
True, option.None -> {
|
||||||
True
|
True
|
||||||
|> Ok
|
|> Ok
|
||||||
|
@ -97,9 +92,7 @@ fn validate_lists(
|
||||||
True -> {
|
True -> {
|
||||||
validate_weights(warr)
|
validate_weights(warr)
|
||||||
}
|
}
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input argument: length(weights) != length(xarr) and length(weights) != length(yarr). Valid input is when length(weights) == length(xarr) == length(yarr)."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,16 +100,12 @@ fn validate_lists(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_weights(warr: List(Float)) -> Result(Bool, String) {
|
fn validate_weights(warr: List(Float)) -> Result(Bool, Nil) {
|
||||||
// Check that all the given weights are positive
|
// Check that all the given weights are positive
|
||||||
let assert Ok(minimum) = piecewise.list_minimum(warr, float.compare)
|
let assert Ok(minimum) = piecewise.list_minimum(warr, float.compare)
|
||||||
case minimum >=. 0.0 {
|
case minimum >=. 0.0 {
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input argument: One or more weights are negative. Valid input is when all weights are >= 0."
|
True -> Ok(True)
|
||||||
|> Error
|
|
||||||
True ->
|
|
||||||
True
|
|
||||||
|> Ok
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +163,7 @@ pub fn norm(
|
||||||
arr: List(Float),
|
arr: List(Float),
|
||||||
p: Float,
|
p: Float,
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case arr, weights {
|
case arr, weights {
|
||||||
[], _ ->
|
[], _ ->
|
||||||
0.0
|
0.0
|
||||||
|
@ -221,10 +210,7 @@ pub fn norm(
|
||||||
|> Error
|
|> Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
False -> {
|
False -> Error(Nil)
|
||||||
"Invalid input argument: length(weights) != length(arr). Valid input is when length(weights) == length(arr)."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +272,7 @@ pub fn manhattan_distance(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
minkowski_distance(xarr, yarr, 1.0, weights)
|
minkowski_distance(xarr, yarr, 1.0, weights)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,26 +340,17 @@ pub fn minkowski_distance(
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
p: Float,
|
p: Float,
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case validate_lists(xarr, yarr, weights) {
|
use _ <- result.try(validate_lists(xarr, yarr, weights))
|
||||||
Error(msg) ->
|
case p <. 1.0 {
|
||||||
msg
|
True -> Error(Nil)
|
||||||
|> Error
|
False -> {
|
||||||
Ok(_) -> {
|
let differences: List(Float) =
|
||||||
case p <. 1.0 {
|
list.zip(xarr, yarr)
|
||||||
True ->
|
|> list.map(fn(tuple: #(Float, Float)) -> Float {
|
||||||
"Invalid input argument: p < 1. Valid input is p >= 1."
|
pair.first(tuple) -. pair.second(tuple)
|
||||||
|> Error
|
})
|
||||||
False -> {
|
norm(differences, p, weights)
|
||||||
let differences =
|
|
||||||
list.zip(xarr, yarr)
|
|
||||||
|> list.map(fn(tuple) { pair.first(tuple) -. pair.second(tuple) })
|
|
||||||
|
|
||||||
let assert Ok(result) = norm(differences, p, weights)
|
|
||||||
result
|
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,7 +411,7 @@ pub fn euclidean_distance(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
minkowski_distance(xarr, yarr, 2.0, weights)
|
minkowski_distance(xarr, yarr, 2.0, weights)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +461,7 @@ pub fn euclidean_distance(
|
||||||
pub fn chebyshev_distance(
|
pub fn chebyshev_distance(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case validate_lists(xarr, yarr, option.None) {
|
case validate_lists(xarr, yarr, option.None) {
|
||||||
Error(msg) ->
|
Error(msg) ->
|
||||||
msg
|
msg
|
||||||
|
@ -540,11 +517,9 @@ pub fn chebyshev_distance(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn mean(arr: List(Float)) -> Result(Float, String) {
|
pub fn mean(arr: List(Float)) -> Result(Float, Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
_ ->
|
_ ->
|
||||||
arr
|
arr
|
||||||
|> arithmetics.float_sum(option.None)
|
|> arithmetics.float_sum(option.None)
|
||||||
|
@ -664,34 +639,27 @@ fn do_median(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
|
pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, Nil) {
|
||||||
case arr {
|
case arr, ddof {
|
||||||
[] ->
|
[], _ -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
_, _ if ddof < 0 -> Error(Nil)
|
||||||
|> Error
|
_, _ -> {
|
||||||
_ ->
|
let assert Ok(mean) = mean(arr)
|
||||||
case ddof < 0 {
|
arr
|
||||||
True ->
|
|> list.map(fn(a: Float) -> Float {
|
||||||
"Invalid input argument: ddof < 0. Valid input is ddof >= 0."
|
let assert Ok(result) = elementary.power(a -. mean, 2.0)
|
||||||
|> Error
|
result
|
||||||
False -> {
|
})
|
||||||
let assert Ok(mean) = mean(arr)
|
|> arithmetics.float_sum(option.None)
|
||||||
arr
|
|> fn(a: Float) -> Float {
|
||||||
|> list.map(fn(a) {
|
a
|
||||||
let assert Ok(result) = elementary.power(a -. mean, 2.0)
|
/. {
|
||||||
result
|
conversion.int_to_float(list.length(arr))
|
||||||
})
|
-. conversion.int_to_float(ddof)
|
||||||
|> arithmetics.float_sum(option.None)
|
|
||||||
|> fn(a) {
|
|
||||||
a
|
|
||||||
/. {
|
|
||||||
conversion.int_to_float(list.length(arr))
|
|
||||||
-. conversion.int_to_float(ddof)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|> Ok
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|> Ok
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,25 +709,18 @@ pub fn variance(arr: List(Float), ddof: Int) -> Result(Float, String) {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, String) {
|
pub fn standard_deviation(arr: List(Float), ddof: Int) -> Result(Float, Nil) {
|
||||||
case arr {
|
case arr, ddof {
|
||||||
[] ->
|
[], _ -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
_, _ if ddof < 0 -> Error(Nil)
|
||||||
|> Error
|
_, _ -> {
|
||||||
_ ->
|
let assert Ok(variance) = variance(arr, ddof)
|
||||||
case ddof < 0 {
|
// The computed variance will always be positive
|
||||||
True ->
|
// So an error should never be returned
|
||||||
"Invalid input argument: ddof < 0. Valid input is ddof >= 0."
|
let assert Ok(stdev) = elementary.square_root(variance)
|
||||||
|> Error
|
stdev
|
||||||
False -> {
|
|> Ok
|
||||||
let assert Ok(variance) = variance(arr, ddof)
|
}
|
||||||
// The computed variance will always be positive
|
|
||||||
// So an error should never be returned
|
|
||||||
let assert Ok(stdev) = elementary.square_root(variance)
|
|
||||||
stdev
|
|
||||||
|> Ok
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,7 +885,7 @@ pub fn tversky_index(
|
||||||
yset: set.Set(a),
|
yset: set.Set(a),
|
||||||
alpha: Float,
|
alpha: Float,
|
||||||
beta: Float,
|
beta: Float,
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case alpha >=. 0.0, beta >=. 0.0 {
|
case alpha >=. 0.0, beta >=. 0.0 {
|
||||||
True, True -> {
|
True, True -> {
|
||||||
let intersection =
|
let intersection =
|
||||||
|
@ -943,18 +904,7 @@ pub fn tversky_index(
|
||||||
/. { intersection +. alpha *. difference1 +. beta *. difference2 }
|
/. { intersection +. alpha *. difference1 +. beta *. difference2 }
|
||||||
|> Ok
|
|> Ok
|
||||||
}
|
}
|
||||||
False, True -> {
|
_, _ -> Error(Nil)
|
||||||
"Invalid input argument: alpha < 0. Valid input is alpha >= 0."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
True, False -> {
|
|
||||||
"Invalid input argument: beta < 0. Valid input is beta >= 0."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
_, _ -> {
|
|
||||||
"Invalid input argument: alpha < 0 and beta < 0. Valid input is alpha >= 0 and beta >= 0."
|
|
||||||
|> Error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1027,7 @@ pub fn cosine_similarity(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case validate_lists(xarr, yarr, weights) {
|
case validate_lists(xarr, yarr, weights) {
|
||||||
Error(msg) ->
|
Error(msg) ->
|
||||||
msg
|
msg
|
||||||
|
@ -1173,7 +1123,7 @@ pub fn canberra_distance(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case validate_lists(xarr, yarr, weights) {
|
case validate_lists(xarr, yarr, weights) {
|
||||||
Error(msg) ->
|
Error(msg) ->
|
||||||
msg
|
msg
|
||||||
|
@ -1266,7 +1216,7 @@ pub fn braycurtis_distance(
|
||||||
xarr: List(Float),
|
xarr: List(Float),
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
weights: option.Option(List(Float)),
|
weights: option.Option(List(Float)),
|
||||||
) -> Result(Float, String) {
|
) -> Result(Float, Nil) {
|
||||||
case validate_lists(xarr, yarr, weights) {
|
case validate_lists(xarr, yarr, weights) {
|
||||||
Error(msg) ->
|
Error(msg) ->
|
||||||
msg
|
msg
|
||||||
|
|
|
@ -949,11 +949,9 @@ pub fn minmax(x: a, y: a, compare: fn(a, a) -> order.Order) {
|
||||||
pub fn list_minimum(
|
pub fn list_minimum(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
compare: fn(a, a) -> order.Order,
|
compare: fn(a, a) -> order.Order,
|
||||||
) -> Result(a, String) {
|
) -> Result(a, Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
[x, ..rest] ->
|
[x, ..rest] ->
|
||||||
Ok(
|
Ok(
|
||||||
list.fold(rest, x, fn(acc, element) {
|
list.fold(rest, x, fn(acc, element) {
|
||||||
|
@ -1003,11 +1001,9 @@ pub fn list_minimum(
|
||||||
pub fn list_maximum(
|
pub fn list_maximum(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
compare: fn(a, a) -> order.Order,
|
compare: fn(a, a) -> order.Order,
|
||||||
) -> Result(a, String) {
|
) -> Result(a, Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
[x, ..rest] ->
|
[x, ..rest] ->
|
||||||
Ok(
|
Ok(
|
||||||
list.fold(rest, x, fn(acc, element) {
|
list.fold(rest, x, fn(acc, element) {
|
||||||
|
@ -1063,11 +1059,9 @@ pub fn list_maximum(
|
||||||
pub fn arg_minimum(
|
pub fn arg_minimum(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
compare: fn(a, a) -> order.Order,
|
compare: fn(a, a) -> order.Order,
|
||||||
) -> Result(List(Int), String) {
|
) -> Result(List(Int), Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
_ -> {
|
_ -> {
|
||||||
let assert Ok(min) =
|
let assert Ok(min) =
|
||||||
arr
|
arr
|
||||||
|
@ -1133,11 +1127,9 @@ pub fn arg_minimum(
|
||||||
pub fn arg_maximum(
|
pub fn arg_maximum(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
compare: fn(a, a) -> order.Order,
|
compare: fn(a, a) -> order.Order,
|
||||||
) -> Result(List(Int), String) {
|
) -> Result(List(Int), Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
_ -> {
|
_ -> {
|
||||||
let assert Ok(max) =
|
let assert Ok(max) =
|
||||||
arr
|
arr
|
||||||
|
@ -1203,11 +1195,9 @@ pub fn arg_maximum(
|
||||||
pub fn extrema(
|
pub fn extrema(
|
||||||
arr: List(a),
|
arr: List(a),
|
||||||
compare: fn(a, a) -> order.Order,
|
compare: fn(a, a) -> order.Order,
|
||||||
) -> Result(#(a, a), String) {
|
) -> Result(#(a, a), Nil) {
|
||||||
case arr {
|
case arr {
|
||||||
[] ->
|
[] -> Error(Nil)
|
||||||
"Invalid input argument: The list is empty."
|
|
||||||
|> Error
|
|
||||||
[x, ..rest] ->
|
[x, ..rest] ->
|
||||||
Ok(
|
Ok(
|
||||||
list.fold(rest, #(x, x), fn(acc, element) {
|
list.fold(rest, #(x, x), fn(acc, element) {
|
||||||
|
|
|
@ -135,7 +135,7 @@ fn float_absolute_difference(a: Float, b: Float) -> Float {
|
||||||
/// let rtol = 0.01
|
/// let rtol = 0.01
|
||||||
/// let atol = 0.10
|
/// let atol = 0.10
|
||||||
/// predicates.all_close(xarr, yarr, rtol, atol)
|
/// predicates.all_close(xarr, yarr, rtol, atol)
|
||||||
/// |> fn(zarr), String)) {
|
/// |> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) {
|
||||||
/// case zarr {
|
/// case zarr {
|
||||||
/// Ok(arr) ->
|
/// Ok(arr) ->
|
||||||
/// arr
|
/// arr
|
||||||
|
@ -159,13 +159,11 @@ pub fn all_close(
|
||||||
yarr: List(Float),
|
yarr: List(Float),
|
||||||
rtol: Float,
|
rtol: Float,
|
||||||
atol: Float,
|
atol: Float,
|
||||||
) -> Result(List(Bool), String) {
|
) -> Result(List(Bool), Nil) {
|
||||||
let xlen = list.length(xarr)
|
let xlen = list.length(xarr)
|
||||||
let ylen = list.length(yarr)
|
let ylen = list.length(yarr)
|
||||||
case xlen == ylen {
|
case xlen == ylen {
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input argument: length(xarr) != length(yarr). Valid input is when length(xarr) == length(yarr)."
|
|
||||||
|> Error
|
|
||||||
True ->
|
True ->
|
||||||
list.zip(xarr, yarr)
|
list.zip(xarr, yarr)
|
||||||
|> list.map(fn(z) { is_close(pair.first(z), pair.second(z), rtol, atol) })
|
|> list.map(fn(z) { is_close(pair.first(z), pair.second(z), rtol, atol) })
|
||||||
|
|
|
@ -160,7 +160,7 @@ pub fn linear_space(
|
||||||
stop: Float,
|
stop: Float,
|
||||||
num: Int,
|
num: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
) -> Result(iterator.Iterator(Float), String) {
|
) -> Result(iterator.Iterator(Float), Nil) {
|
||||||
let direction = case start <=. stop {
|
let direction = case start <=. stop {
|
||||||
True -> 1.0
|
True -> 1.0
|
||||||
False -> -1.0
|
False -> -1.0
|
||||||
|
@ -184,9 +184,7 @@ pub fn linear_space(
|
||||||
})
|
})
|
||||||
|> Ok
|
|> Ok
|
||||||
}
|
}
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input: num < 1. Valid input is num >= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,7 +239,7 @@ pub fn logarithmic_space(
|
||||||
num: Int,
|
num: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
base: Float,
|
base: Float,
|
||||||
) -> Result(iterator.Iterator(Float), String) {
|
) -> Result(iterator.Iterator(Float), Nil) {
|
||||||
case num > 0 {
|
case num > 0 {
|
||||||
True -> {
|
True -> {
|
||||||
let assert Ok(linspace) = linear_space(start, stop, num, endpoint)
|
let assert Ok(linspace) = linear_space(start, stop, num, endpoint)
|
||||||
|
@ -252,9 +250,7 @@ pub fn logarithmic_space(
|
||||||
})
|
})
|
||||||
|> Ok
|
|> Ok
|
||||||
}
|
}
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input: num < 1. Valid input is num >= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,11 +312,9 @@ pub fn geometric_space(
|
||||||
stop: Float,
|
stop: Float,
|
||||||
num: Int,
|
num: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
) -> Result(iterator.Iterator(Float), String) {
|
) -> Result(iterator.Iterator(Float), Nil) {
|
||||||
case start == 0.0 || stop == 0.0 {
|
case start == 0.0 || stop == 0.0 {
|
||||||
True ->
|
True -> Error(Nil)
|
||||||
"Invalid input: Neither 'start' nor 'stop' can be zero, as they must be non-zero for logarithmic calculations."
|
|
||||||
|> Error
|
|
||||||
False ->
|
False ->
|
||||||
case num > 0 {
|
case num > 0 {
|
||||||
True -> {
|
True -> {
|
||||||
|
@ -328,9 +322,7 @@ pub fn geometric_space(
|
||||||
let assert Ok(log_stop) = elementary.logarithm_10(stop)
|
let assert Ok(log_stop) = elementary.logarithm_10(stop)
|
||||||
logarithmic_space(log_start, log_stop, num, endpoint, 10.0)
|
logarithmic_space(log_start, log_stop, num, endpoint, 10.0)
|
||||||
}
|
}
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input: num < 1. Valid input is num >= 1."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ fn gamma_lanczos(x: Float) -> Float {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, String) {
|
pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, Nil) {
|
||||||
case a >. 0.0 && x >=. 0.0 {
|
case a >. 0.0 && x >=. 0.0 {
|
||||||
True -> {
|
True -> {
|
||||||
let assert Ok(v) = elementary.power(x, a)
|
let assert Ok(v) = elementary.power(x, a)
|
||||||
|
@ -173,9 +173,7 @@ pub fn incomplete_gamma(a: Float, x: Float) -> Result(Float, String) {
|
||||||
|> Ok
|
|> Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
False ->
|
False -> Error(Nil)
|
||||||
"Invalid input argument: a <= 0 or x < 0. Valid input is a > 0 and x >= 0."
|
|
||||||
|> Error
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub fn float_list_all_close_test() {
|
||||||
let rtol = 0.01
|
let rtol = 0.01
|
||||||
let atol = 0.1
|
let atol = 0.1
|
||||||
predicates.all_close(xarr, yarr, rtol, atol)
|
predicates.all_close(xarr, yarr, rtol, atol)
|
||||||
|> fn(zarr) {
|
|> fn(zarr: Result(List(Bool), Nil)) -> Result(Bool, Nil) {
|
||||||
case zarr {
|
case zarr {
|
||||||
Ok(arr) ->
|
Ok(arr) ->
|
||||||
arr
|
arr
|
||||||
|
|
Loading…
Reference in a new issue