From 2a365e62590fef335da6b5d365090a3b0269bb07 Mon Sep 17 00:00:00 2001 From: NicklasXYZ Date: Tue, 3 Jan 2023 22:12:47 +0100 Subject: [PATCH] Update ToC of modules --- src/gleam_community/maths/float.gleam | 25 +- src/gleam_community/maths/float_list.gleam | 563 ++++++++++++++++----- src/gleam_community/maths/int.gleam | 29 +- src/gleam_community/maths/int_list.gleam | 20 - 4 files changed, 472 insertions(+), 165 deletions(-) diff --git a/src/gleam_community/maths/float.gleam b/src/gleam_community/maths/float.gleam index bb4b526..399d0d2 100644 --- a/src/gleam_community/maths/float.gleam +++ b/src/gleam_community/maths/float.gleam @@ -27,32 +27,25 @@ //// --- //// //// * **Rounding functions** -//// * [`ceiling`](#ceiling) +//// * [`ceil`](#ceil) //// * [`floor`](#floor) -//// * [`truncate`](#truncate) +//// * [`trunc`](#trunc) //// * [`round`](#round) -//// * **Division functions** -//// * [`gcd`](#gcd) -//// * [`lcm`](#lcm) //// * **Sign and absolute value functions** //// * [`abs2`](#abs2) -//// * [`absdiff`](#abs_diff) +//// * [`absdiff`](#absdiff) //// * [`sign`](#sign) -//// * [`flipsign`](#flipsign) //// * [`copysign`](#copysign) +//// * [`flipsign`](#flipsign) //// * **Powers, logs and roots** //// * [`exp`](#exp) +//// * [`ln`](#ln) //// * [`log`](#log) //// * [`log10`](#log10) //// * [`log2`](#log2) //// * [`pow`](#pow) -//// -//// * [`isqrt`](#isqrt) -//// * [`icbrt`](#icbrt) -//// //// * [`sqrt`](#sqrt) //// * [`cbrt`](#cbrt) -//// * [`nthrt`](#nthrt) //// * [`hypot`](#hypot) //// * **Trigonometric and hyperbolic functions** //// * [`acos`](#acos) @@ -70,7 +63,7 @@ //// * [`tanh`](#tanh) //// * [`deg2rad`](#deg2rad) //// * [`rad2deg`](#rad2deg) -//// * **Mathematical functions** +//// * **Misc. mathematical functions** //// * [`min`](#min) //// * [`max`](#max) //// * [`minmax`](#minmax) @@ -83,10 +76,10 @@ //// * [`pi`](#pi) //// * [`tau`](#tau) //// * **Tests** -//// * [`ispow2`](#ispow2) //// * [`isclose`](#isclose) -//// * [`iseven`](#iseven) -//// * [`isodd`](#isodd) +//// * **Misc. functions** +//// * [`to_int`](#to_int) + import gleam/list import gleam/int diff --git a/src/gleam_community/maths/float_list.gleam b/src/gleam_community/maths/float_list.gleam index 77b0089..008b1d3 100644 --- a/src/gleam_community/maths/float_list.gleam +++ b/src/gleam_community/maths/float_list.gleam @@ -26,13 +26,25 @@ //// //// --- //// -//// * **Miscellaneous functions** -//// * [`allclose`](#allclose) +//// * **Distances, sums and products** +//// * [`sum`](#sum) +//// * [`prod`](#prod) +//// * [`norm`](#norm) +//// * [`cumsum`](#cumsum) +//// * [`cumprod`](#cumprod) +//// * **Ranges and intervals** +//// * [`linspace`](#linspace) +//// * [`logspace`](#linspace) +//// * [`geomspace`](#linspace) +//// * **Misc. mathematical functions** //// * [`amax`](#amax) //// * [`amin`](#amin) //// * [`argmax`](#argmax) //// * [`argmin`](#argmin) +//// * [`extrema`](#extrema) +//// * **Tests** //// * [`allclose`](#allclose) +//// * **Misc. functions** //// * [`trim`](#trim) import gleam/list @@ -47,8 +59,9 @@ import gleam_community/maths/float as floatx /// /// /// -/// Determine if a list of values are close to or equivalent to a -/// another list of reference values. +/// Return evenly spaced numbers over a specified interval. +/// Returns num evenly spaced samples, calculated over the interval [start, stop]. +/// The endpoint of the interval can optionally be excluded. /// ///
/// Example: @@ -57,25 +70,7 @@ import gleam_community/maths/float as floatx /// import gleam_stats/stats /// /// 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 -/// stats.allclose(xarr, yarr, rtol, atol) -/// |> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) { -/// case zarr { -/// Ok(arr) -> -/// arr -/// |> list.all(fn(a: Bool) -> Bool { a }) -/// |> Ok -/// _ -> Nil |> Error -/// } -/// } -/// |> should.equal(Ok(True)) +/// /// } ///
/// @@ -85,24 +80,135 @@ import gleam_community/maths/float as floatx /// /// /// -pub fn allclose( - xarr: List(Float), - yarr: List(Float), - rtol: Float, - atol: Float, -) -> Result(List(Bool), String) { - let xlen: Int = list.length(xarr) - let ylen: Int = 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 { - floatx.isclose(pair.first(z), pair.second(z), rtol, atol) - }) - |> Ok +pub fn linspace( + start: Float, + stop: Float, + num: Int, + endpoint: option.Option, + retstep: option.Option, +) -> List(Float) { + todo +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Return numbers spaced evenly on a log scale. +/// In linear space, the sequence starts at base ** start (base to the power of start) and ends with base ** stop. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn logspace( + start: Float, + stop: Float, + num: Int, + endpoint: option.Option, + retstep: option.Option, + base: Int, +) -> List(Float) { + todo +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Return numbers spaced evenly on a log scale (a geometric progression). +/// This is similar to logspace, but with endpoints specified directly. Each output sample is a constant multiple of the previous. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn geomspace( + start: Float, + stop: Float, + num: Int, + endpoint: option.Option, + retstep: option.Option, +) -> List(Float) { + todo +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Calculcate the sum of the elements in a list: +/// +/// \\[ +/// \sum_{i=1}^n x_i +/// \\] +/// +/// In the formula, $$n$$ is the length of the list and +/// $$x_i$$ is the value in the input list indexed by $$i$$. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// // An empty list returns an error +/// [] +/// |> stats.sum() +/// |> should.equal(0.) +/// +/// // Valid input returns a result +/// [1., 2., 3.] +/// |> stats.sum() +/// |> should.equal(6.) +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn sum(arr: List(Float)) -> Float { + case arr { + [] -> 0.0 + _ -> + arr + |> list.fold(0.0, fn(acc: Float, a: Float) -> Float { a +. acc }) } } @@ -112,7 +218,14 @@ pub fn allclose( /// /// /// -/// Returns the indices of the minimum values in a list. +/// Calculcate the product of the elements in a list: +/// +/// \\[ +/// \prod_{i=1}^n x_i +/// \\] +/// +/// In the formula, $$n$$ is the length of the list and +/// $$x_i$$ is the value in the input list indexed by $$i$$. /// ///
/// Example: @@ -121,15 +234,15 @@ pub fn allclose( /// import gleam_stats/stats /// /// pub fn example () { -/// // An empty lists returns an error +/// // An empty list returns an error /// [] -/// |> stats.argmin() -/// |> should.be_error() -/// +/// |> stats.sum() +/// |> should.equal(0.) +/// /// // Valid input returns a result -/// [4., 4., 3., 2., 1.] -/// |> stats.argmin() -/// |> should.equal(Ok([4])) +/// [1., 2., 3.] +/// |> stats.prod() +/// |> should.equal(6.) /// } ///
/// @@ -139,30 +252,12 @@ pub fn allclose( /// /// /// -pub fn argmin(arr: List(Float)) -> Result(List(Int), String) { +pub fn prod(arr: List(Float)) -> Float { case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - assert Ok(min) = - arr - |> amin() + [] -> 0.0 + _ -> arr - |> list.index_map(fn(index: Int, a: Float) -> Int { - case a -. min { - 0. -> index - _ -> -1 - } - }) - |> list.filter(fn(index: Int) -> Bool { - case index { - -1 -> False - _ -> True - } - }) - |> Ok - } + |> list.fold(0.0, fn(acc: Float, a: Float) -> Float { a *. acc }) } } @@ -172,7 +267,14 @@ pub fn argmin(arr: List(Float)) -> Result(List(Int), String) { /// /// /// -/// Returns the indices of the maximum values in a list. +/// Calculcate the cumulative sum of the elements in a list: +/// +/// \\[ +/// \sum_{i=1}^n x_i +/// \\] +/// +/// In the formula, $$n$$ is the length of the list and +/// $$x_i$$ is the value in the input list indexed by $$i$$. /// ///
/// Example: @@ -181,15 +283,15 @@ pub fn argmin(arr: List(Float)) -> Result(List(Int), String) { /// import gleam_stats/stats /// /// pub fn example () { -/// // An empty lists returns an error +/// // An empty list returns an error /// [] -/// |> stats.argmax() -/// |> should.be_error() -/// +/// |> stats.sum() +/// |> should.equal(0.) +/// /// // Valid input returns a result -/// [4., 4., 3., 2., 1.] -/// |> stats.argmax() -/// |> should.equal(Ok([0, 1])) +/// [1., 2., 3.] +/// |> stats.sum() +/// |> should.equal(6.) /// } ///
/// @@ -199,31 +301,80 @@ pub fn argmin(arr: List(Float)) -> Result(List(Int), String) { /// /// /// -pub fn argmax(arr: List(Float)) -> Result(List(Int), String) { - case arr { - [] -> - "Invalid input argument: The list is empty." - |> Error - _ -> { - assert Ok(max) = - arr - |> amax() - arr - |> list.index_map(fn(index: Int, a: Float) -> Int { - case a -. max { - 0. -> index - _ -> -1 - } - }) - |> list.filter(fn(index: Int) -> Bool { - case index { - -1 -> False - _ -> True - } - }) - |> Ok - } - } +pub fn cumsum(arr: List(Float)) -> List(Float) { + todo +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Calculcate the cumulative product of the elements in a list: +/// +/// \\[ +/// \prod_{i=1}^n x_i +/// \\] +/// +/// In the formula, $$n$$ is the length of the list and +/// $$x_i$$ is the value in the input list indexed by $$i$$. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// // An empty list returns an error +/// [] +/// |> stats.sum() +/// |> should.equal(0.) +/// +/// // Valid input returns a result +/// [1., 2., 3.] +/// |> stats.prod() +/// |> should.equal(6.) +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn cumprod(arr: List(Float)) -> List(Float) { + todo +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn norm(xarr: List(Float), yarr: List(Float), p: Int) -> List(Float) { + todo } ///
@@ -336,6 +487,126 @@ pub fn amin(arr: List(Float)) -> Result(Float, String) { } } +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Returns the indices of the maximum values in a list. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// // An empty lists returns an error +/// [] +/// |> stats.argmax() +/// |> should.be_error() +/// +/// // Valid input returns a result +/// [4., 4., 3., 2., 1.] +/// |> stats.argmax() +/// |> should.equal(Ok([0, 1])) +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn argmax(arr: List(Float)) -> Result(List(Int), String) { + case arr { + [] -> + "Invalid input argument: The list is empty." + |> Error + _ -> { + assert Ok(max) = + arr + |> amax() + arr + |> list.index_map(fn(index: Int, a: Float) -> Int { + case a -. max { + 0. -> index + _ -> -1 + } + }) + |> list.filter(fn(index: Int) -> Bool { + case index { + -1 -> False + _ -> True + } + }) + |> Ok + } + } +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// Returns the indices of the minimum values in a list. +/// +///
+/// Example: +/// +/// import gleeunit/should +/// import gleam_stats/stats +/// +/// pub fn example () { +/// // An empty lists returns an error +/// [] +/// |> stats.argmin() +/// |> should.be_error() +/// +/// // Valid input returns a result +/// [4., 4., 3., 2., 1.] +/// |> stats.argmin() +/// |> should.equal(Ok([4])) +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn argmin(arr: List(Float)) -> Result(List(Int), String) { + case arr { + [] -> + "Invalid input argument: The list is empty." + |> Error + _ -> { + assert Ok(min) = + arr + |> amin() + arr + |> list.index_map(fn(index: Int, a: Float) -> Int { + case a -. min { + 0. -> index + _ -> -1 + } + }) + |> list.filter(fn(index: Int) -> Bool { + case index { + -1 -> False + _ -> True + } + }) + |> Ok + } + } +} + ///
/// /// Spot a typo? Open an issue! @@ -371,23 +642,69 @@ pub fn amin(arr: List(Float)) -> Result(Float, String) { /// pub fn extrema(arr: List(Float)) -> Result(#(Float, Float), String) { todo - // case arr { - // [] -> - // "Invalid input argument: The list is empty." - // |> Error - // _ -> { - // assert Ok(val0) = list.at(arr, 0) - // arr - // |> list.fold( - // val0, - // fn(acc: Float, a: Float) { - // case a <. acc { - // True -> a - // False -> acc - // } - // }, - // ) - // |> Ok - // } - // } +} + +///
+/// +/// Spot a typo? Open an issue! +/// +///
+/// +/// 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/stats +/// +/// 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 +/// stats.allclose(xarr, yarr, rtol, atol) +/// |> fn(zarr: Result(List(Bool), String)) -> Result(Bool, Nil) { +/// case zarr { +/// Ok(arr) -> +/// arr +/// |> list.all(fn(a: Bool) -> Bool { a }) +/// |> Ok +/// _ -> Nil |> Error +/// } +/// } +/// |> should.equal(Ok(True)) +/// } +///
+/// +///
+/// +/// Back to top ↑ +/// +///
+/// +pub fn allclose( + xarr: List(Float), + yarr: List(Float), + rtol: Float, + atol: Float, +) -> Result(List(Bool), String) { + let xlen: Int = list.length(xarr) + let ylen: Int = 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 { + floatx.isclose(pair.first(z), pair.second(z), rtol, atol) + }) + |> Ok + } } diff --git a/src/gleam_community/maths/int.gleam b/src/gleam_community/maths/int.gleam index 3e89f1b..d86cd6f 100644 --- a/src/gleam_community/maths/int.gleam +++ b/src/gleam_community/maths/int.gleam @@ -26,14 +26,29 @@ //// //// --- //// -//// * **Mathematical functions** +//// * **Sign and absolute value functions** +//// * [`abs2`](#abs2) //// * [`absdiff`](#abs_diff) -//// * [`flipsign`](#flipsign) -//// * [`max`](#max) -//// * [`min`](#min) -//// * [`minmax`](#minmax) -//// * [`round`](#round) //// * [`sign`](#sign) +//// * [`copysign`](#copysign) +//// * [`flipsign`](#flipsign) +//// * **Powers, logs and roots** +//// * [`exp`](#exp) +//// * [`ln`](#ln) +//// * [`log`](#log) +//// * [`log10`](#log10) +//// * [`log2`](#log2) +//// * [`pow`](#pow) +//// * [`sqrt`](#sqrt) +//// * [`cbrt`](#cbrt) +//// * [`hypot`](#hypot) +//// * **Misc. mathematical functions** +//// * [`min`](#min) +//// * [`max`](#max) +//// * [`minmax`](#minmax) +//// * **Division functions** +//// * [`gcd`](#gcd) +//// * [`lcm`](#lcm) //// * **Combinatorial functions** //// * [`combination`](#combination) //// * [`factorial`](#factorial) @@ -42,6 +57,8 @@ //// * [`ispow2`](#ispow2) //// * [`iseven`](#iseven) //// * [`isodd`](#isodd) +//// * **Misc. functions** +//// * [`to_float`](#to_float) import gleam/list import gleam/int diff --git a/src/gleam_community/maths/int_list.gleam b/src/gleam_community/maths/int_list.gleam index f8eb5bc..d448316 100644 --- a/src/gleam_community/maths/int_list.gleam +++ b/src/gleam_community/maths/int_list.gleam @@ -277,7 +277,6 @@ pub fn amin(arr: List(Float)) -> Result(Float, String) { /// ///
/// -/// Returns the minimum value of a list. /// ///
/// Example: @@ -306,23 +305,4 @@ pub fn amin(arr: List(Float)) -> Result(Float, String) { /// pub fn extrema(arr: List(Float)) -> Result(#(Float, Float), String) { todo - // case arr { - // [] -> - // "Invalid input argument: The list is empty." - // |> Error - // _ -> { - // assert Ok(val0) = list.at(arr, 0) - // arr - // |> list.fold( - // val0, - // fn(acc: Float, a: Float) { - // case a <. acc { - // True -> a - // False -> acc - // } - // }, - // ) - // |> Ok - // } - // } }