mirror of
https://github.com/sigmasternchen/gleam-community-maths
synced 2025-03-15 07:59:01 +00:00
Implement both list & yielder-based functions for sequence-related functions.
This commit is contained in:
parent
46d2309268
commit
dd4832fc72
2 changed files with 794 additions and 74 deletions
|
@ -21,8 +21,6 @@
|
||||||
//// .katex { font-size: 1.10em; }
|
//// .katex { font-size: 1.10em; }
|
||||||
////</style>
|
////</style>
|
||||||
////
|
////
|
||||||
//// ---
|
|
||||||
////
|
|
||||||
|
|
||||||
import gleam/bool
|
import gleam/bool
|
||||||
import gleam/float
|
import gleam/float
|
||||||
|
@ -5278,7 +5276,7 @@ fn incomplete_gamma_sum(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
/// The function returns an iterator generating evenly spaced values within a specified interval
|
/// The function returns a list of evenly spaced values within a specified interval
|
||||||
/// `[start, stop)` based on a given increment size.
|
/// `[start, stop)` based on a given increment size.
|
||||||
///
|
///
|
||||||
/// Note that if `increment > 0`, the sequence progresses from `start` towards `stop`, while if
|
/// Note that if `increment > 0`, the sequence progresses from `start` towards `stop`, while if
|
||||||
|
@ -5287,25 +5285,21 @@ fn incomplete_gamma_sum(
|
||||||
/// <details>
|
/// <details>
|
||||||
/// <summary>Example:</summary>
|
/// <summary>Example:</summary>
|
||||||
///
|
///
|
||||||
/// import gleam/yielder
|
|
||||||
/// import gleeunit/should
|
/// import gleeunit/should
|
||||||
/// import gleam_community/maths
|
/// import gleam_community/maths
|
||||||
///
|
///
|
||||||
/// pub fn example () {
|
/// pub fn example () {
|
||||||
/// maths.arange(1.0, 5.0, 1.0)
|
/// maths.step_range(1.0, 5.0, 1.0)
|
||||||
/// |> yielder.to_list()
|
|
||||||
/// |> should.equal([1.0, 2.0, 3.0, 4.0])
|
/// |> should.equal([1.0, 2.0, 3.0, 4.0])
|
||||||
///
|
///
|
||||||
/// // No points returned since
|
/// // No points returned since
|
||||||
/// // start is smaller than stop and the step is positive
|
/// // start is smaller than stop and the step is positive
|
||||||
/// maths.arange(5.0, 1.0, 1.0)
|
/// maths.step_range(5.0, 1.0, 1.0)
|
||||||
/// |> yielder.to_list()
|
|
||||||
/// |> should.equal([])
|
/// |> should.equal([])
|
||||||
///
|
///
|
||||||
/// // Points returned since
|
/// // Points returned since
|
||||||
/// // start smaller than stop but negative step
|
/// // start smaller than stop but negative step
|
||||||
/// maths.arange(5.0, 1.0, -1.0)
|
/// maths.step_range(5.0, 1.0, -1.0)
|
||||||
/// |> yielder.to_list()
|
|
||||||
/// |> should.equal([5.0, 4.0, 3.0, 2.0])
|
/// |> should.equal([5.0, 4.0, 3.0, 2.0])
|
||||||
/// }
|
/// }
|
||||||
/// </details>
|
/// </details>
|
||||||
|
@ -5316,7 +5310,91 @@ fn incomplete_gamma_sum(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
pub fn arange(start: Float, stop: Float, increment: Float) -> Yielder(Float) {
|
pub fn step_range(start: Float, stop: Float, increment: Float) -> List(Float) {
|
||||||
|
case
|
||||||
|
{ start >=. stop && increment >. 0.0 }
|
||||||
|
|| { start <=. stop && increment <. 0.0 }
|
||||||
|
{
|
||||||
|
True -> []
|
||||||
|
False -> {
|
||||||
|
let direction = case start <=. stop {
|
||||||
|
True -> 1.0
|
||||||
|
False -> -1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let increment_abs = float.absolute_value(increment)
|
||||||
|
let distance = float.absolute_value(start -. stop)
|
||||||
|
let steps = float.round(distance /. increment_abs)
|
||||||
|
let adjusted_stop = stop -. increment_abs *. direction
|
||||||
|
|
||||||
|
// Generate the sequence from 'adjusted_stop' towards 'start'
|
||||||
|
do_step_range(adjusted_stop, increment_abs *. direction, steps, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_step_range(
|
||||||
|
current: Float,
|
||||||
|
increment: Float,
|
||||||
|
remaining_steps: Int,
|
||||||
|
acc: List(Float),
|
||||||
|
) -> List(Float) {
|
||||||
|
case remaining_steps {
|
||||||
|
0 -> acc
|
||||||
|
_ ->
|
||||||
|
do_step_range(current -. increment, increment, remaining_steps - 1, [
|
||||||
|
current,
|
||||||
|
..acc
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
/// The function is similar to [`step_range`](#step_range) but instead returns a yielder
|
||||||
|
/// (lazily evaluated sequence of elements). This function can be used whenever there is a need
|
||||||
|
/// to generate a larger-than-usual sequence of elements.
|
||||||
|
///
|
||||||
|
/// <details>
|
||||||
|
/// <summary>Example:</summary>
|
||||||
|
///
|
||||||
|
/// import gleam/yielder.{Next, Done}
|
||||||
|
/// import gleeunit/should
|
||||||
|
/// import gleam_community/maths
|
||||||
|
///
|
||||||
|
/// pub fn example () {
|
||||||
|
/// let range = maths.yield_step_range(1.0, 2.5, 0.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(range)
|
||||||
|
/// should.equal(element, 1.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 1.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 2.0)
|
||||||
|
///
|
||||||
|
/// // We have generated 3 values over the interval [1.0, 2.5)
|
||||||
|
/// // in increments of 0.5, so the 4th will be 'Done'
|
||||||
|
/// should.equal(yielder.step(rest), Done)
|
||||||
|
/// }
|
||||||
|
/// </details>
|
||||||
|
///
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="#">
|
||||||
|
/// <small>Back to top ↑</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
pub fn yield_step_range(
|
||||||
|
start: Float,
|
||||||
|
stop: Float,
|
||||||
|
increment: Float,
|
||||||
|
) -> Yielder(Float) {
|
||||||
// Check if the range would be empty due to direction and increment
|
// Check if the range would be empty due to direction and increment
|
||||||
case
|
case
|
||||||
{ start >=. stop && increment >. 0.0 }
|
{ start >=. stop && increment >. 0.0 }
|
||||||
|
@ -5345,22 +5423,20 @@ pub fn arange(start: Float, stop: Float, increment: Float) -> Yielder(Float) {
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
/// The function returns an iterator for generating linearly spaced points over a specified
|
/// The function returns a list of linearly spaced points over a specified
|
||||||
/// interval. The endpoint of the interval can optionally be included/excluded. The number of
|
/// interval. The endpoint of the interval can optionally be included/excluded. The number of
|
||||||
/// points and whether the endpoint is included determine the spacing between values.
|
/// points and whether the endpoint is included determine the spacing between values.
|
||||||
///
|
///
|
||||||
/// <details>
|
/// <details>
|
||||||
/// <summary>Example:</summary>
|
/// <summary>Example:</summary>
|
||||||
///
|
///
|
||||||
/// import gleam/yielder
|
|
||||||
/// import gleeunit/should
|
/// import gleeunit/should
|
||||||
/// import gleam_community/maths
|
/// import gleam_community/maths
|
||||||
///
|
///
|
||||||
/// pub fn example () {
|
/// pub fn example () {
|
||||||
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
||||||
/// let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, True)
|
/// let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, True)
|
||||||
/// let pairs =
|
/// let pairs = linspace |> list.zip([10.0, 12.5, 15.0, 17.5, 20.0])
|
||||||
/// linspace |> yielder.to_list() |> list.zip([10.0, 12.5, 15.0, 17.5, 20.0])
|
|
||||||
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
||||||
/// result
|
/// result
|
||||||
/// |> list.all(fn(x) { x == True })
|
/// |> list.all(fn(x) { x == True })
|
||||||
|
@ -5383,6 +5459,98 @@ pub fn linear_space(
|
||||||
stop: Float,
|
stop: Float,
|
||||||
steps: Int,
|
steps: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
|
) -> Result(List(Float), Nil) {
|
||||||
|
let direction = case start <=. stop {
|
||||||
|
True -> 1.0
|
||||||
|
False -> -1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
let increment_abs = case endpoint {
|
||||||
|
True -> float.absolute_value(start -. stop) /. int.to_float(steps - 1)
|
||||||
|
False -> float.absolute_value(start -. stop) /. int.to_float(steps)
|
||||||
|
}
|
||||||
|
|
||||||
|
let adjusted_stop = case endpoint {
|
||||||
|
True -> stop
|
||||||
|
False -> stop -. increment_abs *. direction
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the sequence from 'adjusted_stop' towards 'start'
|
||||||
|
case steps > 0 {
|
||||||
|
True -> {
|
||||||
|
Ok(do_linear_space(adjusted_stop, increment_abs *. direction, steps, []))
|
||||||
|
}
|
||||||
|
False -> Error(Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn do_linear_space(
|
||||||
|
current: Float,
|
||||||
|
increment: Float,
|
||||||
|
remaining_steps: Int,
|
||||||
|
acc: List(Float),
|
||||||
|
) -> List(Float) {
|
||||||
|
case remaining_steps {
|
||||||
|
0 -> acc
|
||||||
|
_ ->
|
||||||
|
do_linear_space(current -. increment, increment, remaining_steps - 1, [
|
||||||
|
current,
|
||||||
|
..acc
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
/// The function is similar to [`linear_space`](#linear_space) but instead returns a yielder
|
||||||
|
/// (lazily evaluated sequence of elements). This function can be used whenever there is a need
|
||||||
|
/// to generate a larger-than-usual sequence of elements.
|
||||||
|
///
|
||||||
|
/// <details>
|
||||||
|
/// <summary>Example:</summary>
|
||||||
|
///
|
||||||
|
/// import gleam/yielder.{Next, Done}
|
||||||
|
/// import gleeunit/should
|
||||||
|
/// import gleam_community/maths
|
||||||
|
///
|
||||||
|
/// pub fn example () {
|
||||||
|
/// let assert Ok(linspace) = maths.yield_linear_space(10.0, 20.0, 5, True)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(linspace)
|
||||||
|
/// should.equal(element, 10.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 12.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 15.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 17.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 20.0)
|
||||||
|
///
|
||||||
|
/// // We have generated 5 values, so the 6th will be 'Done'
|
||||||
|
/// should.equal(yielder.step(rest), Done)
|
||||||
|
/// }
|
||||||
|
/// </details>
|
||||||
|
///
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="#">
|
||||||
|
/// <small>Back to top ↑</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
pub fn yield_linear_space(
|
||||||
|
start: Float,
|
||||||
|
stop: Float,
|
||||||
|
steps: Int,
|
||||||
|
endpoint: Bool,
|
||||||
) -> Result(Yielder(Float), Nil) {
|
) -> Result(Yielder(Float), Nil) {
|
||||||
let direction = case start <=. stop {
|
let direction = case start <=. stop {
|
||||||
True -> 1.0
|
True -> 1.0
|
||||||
|
@ -5415,7 +5583,7 @@ pub fn linear_space(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
/// The function returns an iterator for generating logarithmically spaced points over a specified
|
/// The function returns a list of logarithmically spaced points over a specified
|
||||||
/// interval. The endpoint of the interval can optionally be included/excluded. The number of
|
/// interval. The endpoint of the interval can optionally be included/excluded. The number of
|
||||||
/// points, base, and whether the endpoint is included determine the spacing between values.
|
/// points, base, and whether the endpoint is included determine the spacing between values.
|
||||||
///
|
///
|
||||||
|
@ -5427,14 +5595,13 @@ pub fn linear_space(
|
||||||
/// <details>
|
/// <details>
|
||||||
/// <summary>Example:</summary>
|
/// <summary>Example:</summary>
|
||||||
///
|
///
|
||||||
/// import gleam/yielder
|
|
||||||
/// import gleeunit/should
|
/// import gleeunit/should
|
||||||
/// import gleam_community/maths
|
/// import gleam_community/maths
|
||||||
///
|
///
|
||||||
/// pub fn example () {
|
/// pub fn example () {
|
||||||
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
||||||
/// let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
/// let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
||||||
/// let pairs = logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0])
|
/// let pairs = logspace |> list.zip([10.0, 100.0, 1000.0])
|
||||||
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
||||||
/// result
|
/// result
|
||||||
/// |> list.all(fn(x) { x == True })
|
/// |> list.all(fn(x) { x == True })
|
||||||
|
@ -5458,11 +5625,74 @@ pub fn logarithmic_space(
|
||||||
steps: Int,
|
steps: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
base: Float,
|
base: Float,
|
||||||
) -> Result(Yielder(Float), Nil) {
|
) -> Result(List(Float), Nil) {
|
||||||
case steps > 0 && base >=. 0.0 {
|
case steps > 0 && base >=. 0.0 {
|
||||||
True -> {
|
True -> {
|
||||||
let assert Ok(linspace) = linear_space(start, stop, steps, endpoint)
|
let assert Ok(linspace) = linear_space(start, stop, steps, endpoint)
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
list.map(linspace, fn(value) {
|
||||||
|
let assert Ok(result) = float.power(base, value)
|
||||||
|
result
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
False -> Error(Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
/// The function is similar to [`logarithmic_space`](#logarithmic_space) but instead returns a yielder
|
||||||
|
/// (lazily evaluated sequence of elements). This function can be used whenever there is a need
|
||||||
|
/// to generate a larger-than-usual sequence of elements.
|
||||||
|
///
|
||||||
|
/// <details>
|
||||||
|
/// <summary>Example:</summary>
|
||||||
|
///
|
||||||
|
/// import gleam/yielder.{Next, Done}
|
||||||
|
/// import gleeunit/should
|
||||||
|
/// import gleam_community/maths
|
||||||
|
///
|
||||||
|
/// pub fn example () {
|
||||||
|
/// let assert Ok(logspace) =
|
||||||
|
/// maths.yield_logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(logspace)
|
||||||
|
/// should.equal(element, 10.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 100.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 1000.0)
|
||||||
|
///
|
||||||
|
/// // We have generated 3 values, so the 4th will be 'Done'
|
||||||
|
/// should.equal(yielder.step(rest), Done)
|
||||||
|
/// }
|
||||||
|
/// </details>
|
||||||
|
///
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="#">
|
||||||
|
/// <small>Back to top ↑</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
pub fn yield_logarithmic_space(
|
||||||
|
start: Float,
|
||||||
|
stop: Float,
|
||||||
|
steps: Int,
|
||||||
|
endpoint: Bool,
|
||||||
|
base: Float,
|
||||||
|
) -> Result(Yielder(Float), Nil) {
|
||||||
|
case steps > 0 && base >=. 0.0 {
|
||||||
|
True -> {
|
||||||
|
let assert Ok(linspace) = yield_linear_space(start, stop, steps, endpoint)
|
||||||
|
|
||||||
Ok(
|
Ok(
|
||||||
yielder.map(linspace, fn(value) {
|
yielder.map(linspace, fn(value) {
|
||||||
let assert Ok(result) = float.power(base, value)
|
let assert Ok(result) = float.power(base, value)
|
||||||
|
@ -5480,7 +5710,7 @@ pub fn logarithmic_space(
|
||||||
/// </a>
|
/// </a>
|
||||||
/// </div>
|
/// </div>
|
||||||
///
|
///
|
||||||
/// The function returns an iterator for generating a geometric progression between two specified
|
/// The function returns a list of a geometric progression between two specified
|
||||||
/// values, where each value is a constant multiple of the previous one. Unlike
|
/// values, where each value is a constant multiple of the previous one. Unlike
|
||||||
/// [`logarithmic_space`](#logarithmic_space), this function allows specifying the starting
|
/// [`logarithmic_space`](#logarithmic_space), this function allows specifying the starting
|
||||||
/// and ending values (`start` and `stop`) directly, without requiring them to be transformed
|
/// and ending values (`start` and `stop`) directly, without requiring them to be transformed
|
||||||
|
@ -5504,7 +5734,7 @@ pub fn logarithmic_space(
|
||||||
/// pub fn example () {
|
/// pub fn example () {
|
||||||
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
/// let assert Ok(tolerance) = float.power(10.0, -6.0)
|
||||||
/// let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, True)
|
/// let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, True)
|
||||||
/// let pairs = logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0])
|
/// let pairs = logspace |> list.zip([10.0, 100.0, 1000.0])
|
||||||
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
/// let assert Ok(result) = maths.all_close(pairs, 0.0, tolerance)
|
||||||
/// result
|
/// result
|
||||||
/// |> list.all(fn(x) { x == True })
|
/// |> list.all(fn(x) { x == True })
|
||||||
|
@ -5534,7 +5764,7 @@ pub fn geometric_space(
|
||||||
stop: Float,
|
stop: Float,
|
||||||
steps: Int,
|
steps: Int,
|
||||||
endpoint: Bool,
|
endpoint: Bool,
|
||||||
) -> Result(Yielder(Float), Nil) {
|
) -> Result(List(Float), Nil) {
|
||||||
case start <=. 0.0 || stop <=. 0.0 || steps < 0 {
|
case start <=. 0.0 || stop <=. 0.0 || steps < 0 {
|
||||||
True -> Error(Nil)
|
True -> Error(Nil)
|
||||||
False -> {
|
False -> {
|
||||||
|
@ -5545,6 +5775,62 @@ pub fn geometric_space(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
/// The function is similar to [`geometric_space`](#geometric_space) but instead returns a yielder
|
||||||
|
/// (lazily evaluated sequence of elements). This function can be used whenever there is a need
|
||||||
|
/// to generate a larger-than-usual sequence of elements.
|
||||||
|
///
|
||||||
|
/// <details>
|
||||||
|
/// <summary>Example:</summary>
|
||||||
|
///
|
||||||
|
/// import gleam/yielder.{Next, Done}
|
||||||
|
/// import gleeunit/should
|
||||||
|
/// import gleam_community/maths
|
||||||
|
///
|
||||||
|
/// pub fn example () {
|
||||||
|
/// let assert Ok(logspace) = maths.yield_geometric_space(10.0, 1000.0, 3, True)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(logspace)
|
||||||
|
/// should.equal(element, 10.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 100.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 1000.0)
|
||||||
|
///
|
||||||
|
/// // We have generated 3 values, so the 4th will be 'Done'
|
||||||
|
/// should.equal(yielder.step(rest), Done)
|
||||||
|
/// }
|
||||||
|
/// </details>
|
||||||
|
///
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="#">
|
||||||
|
/// <small>Back to top ↑</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
pub fn yield_geometric_space(
|
||||||
|
start: Float,
|
||||||
|
stop: Float,
|
||||||
|
steps: Int,
|
||||||
|
endpoint: Bool,
|
||||||
|
) -> Result(Yielder(Float), Nil) {
|
||||||
|
case start <=. 0.0 || stop <=. 0.0 || steps < 0 {
|
||||||
|
True -> Error(Nil)
|
||||||
|
False -> {
|
||||||
|
let assert Ok(log_start) = logarithm_10(start)
|
||||||
|
let assert Ok(log_stop) = logarithm_10(stop)
|
||||||
|
yield_logarithmic_space(log_start, log_stop, steps, endpoint, 10.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <div style="text-align: right;">
|
/// <div style="text-align: right;">
|
||||||
/// <a href="https://github.com/gleam-community/maths/issues">
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
/// <small>Spot a typo? Open an issue!</small>
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
@ -5557,20 +5843,17 @@ pub fn geometric_space(
|
||||||
/// <details>
|
/// <details>
|
||||||
/// <summary>Example:</summary>
|
/// <summary>Example:</summary>
|
||||||
///
|
///
|
||||||
/// import gleam/yielder
|
|
||||||
/// import gleeunit/should
|
/// import gleeunit/should
|
||||||
/// import gleam_community/maths
|
/// import gleam_community/maths
|
||||||
///
|
///
|
||||||
/// pub fn example() {
|
/// pub fn example() {
|
||||||
/// let assert Ok(sym_space) = maths.symmetric_space(0.0, 5.0, 5)
|
/// let assert Ok(symspace) = maths.symmetric_space(0.0, 5.0, 5)
|
||||||
/// sym_space
|
/// symspace
|
||||||
/// |> yielder.to_list()
|
|
||||||
/// |> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
/// |> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
||||||
///
|
///
|
||||||
/// // A negative radius reverses the order of the values
|
/// // A negative radius reverses the order of the values
|
||||||
/// let assert Ok(sym_space) = maths.symmetric_space(0.0, -5.0, 5)
|
/// let assert Ok(symspace) = maths.symmetric_space(0.0, -5.0, 5)
|
||||||
/// sym_space
|
/// symspace
|
||||||
/// |> yielder.to_list()
|
|
||||||
/// |> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
|
/// |> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
|
||||||
/// }
|
/// }
|
||||||
/// </details>
|
/// </details>
|
||||||
|
@ -5585,7 +5868,7 @@ pub fn symmetric_space(
|
||||||
center: Float,
|
center: Float,
|
||||||
radius: Float,
|
radius: Float,
|
||||||
steps: Int,
|
steps: Int,
|
||||||
) -> Result(Yielder(Float), Nil) {
|
) -> Result(List(Float), Nil) {
|
||||||
case steps > 0 {
|
case steps > 0 {
|
||||||
False -> Error(Nil)
|
False -> Error(Nil)
|
||||||
True -> {
|
True -> {
|
||||||
|
@ -5595,3 +5878,64 @@ pub fn symmetric_space(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="https://github.com/gleam-community/maths/issues">
|
||||||
|
/// <small>Spot a typo? Open an issue!</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
/// The function is similar to [`symmetric_space`](#symmetric_space) but instead returns a yielder
|
||||||
|
/// (lazily evaluated sequence of elements). This function can be used whenever there is a need
|
||||||
|
/// to generate a larger-than-usual sequence of elements.
|
||||||
|
///
|
||||||
|
/// <details>
|
||||||
|
/// <summary>Example:</summary>
|
||||||
|
///
|
||||||
|
/// import gleam/yielder.{Next, Done}
|
||||||
|
/// import gleeunit/should
|
||||||
|
/// import gleam_community/maths
|
||||||
|
///
|
||||||
|
/// pub fn example() {
|
||||||
|
/// let assert Ok(symspace) = maths.yield_symmetric_space(0.0, 5.0, 5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(symspace)
|
||||||
|
/// should.equal(element, -5.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, -2.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 0.0)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 2.5)
|
||||||
|
///
|
||||||
|
/// let assert Next(element, rest) = yielder.step(rest)
|
||||||
|
/// should.equal(element, 5.0)
|
||||||
|
///
|
||||||
|
/// // We have generated 5 values, so the 6th will be 'Done'
|
||||||
|
/// should.equal(yielder.step(rest), Done)
|
||||||
|
/// }
|
||||||
|
/// </details>
|
||||||
|
///
|
||||||
|
/// <div style="text-align: right;">
|
||||||
|
/// <a href="#">
|
||||||
|
/// <small>Back to top ↑</small>
|
||||||
|
/// </a>
|
||||||
|
/// </div>
|
||||||
|
///
|
||||||
|
pub fn yield_symmetric_space(
|
||||||
|
center: Float,
|
||||||
|
radius: Float,
|
||||||
|
steps: Int,
|
||||||
|
) -> Result(Yielder(Float), Nil) {
|
||||||
|
case steps > 0 {
|
||||||
|
False -> Error(Nil)
|
||||||
|
True -> {
|
||||||
|
let start = center -. radius
|
||||||
|
let stop = center +. radius
|
||||||
|
yield_linear_space(start, stop, steps, True)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@ import gleam/yielder
|
||||||
import gleam_community/maths
|
import gleam_community/maths
|
||||||
import gleeunit/should
|
import gleeunit/should
|
||||||
|
|
||||||
pub fn list_linear_space_test() {
|
pub fn yield_linear_space_test() {
|
||||||
let assert Ok(tol) = float.power(10.0, -6.0)
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
|
|
||||||
// Check that the function agrees, at some arbitrary input
|
// Check that the function agrees, at some arbitrary input
|
||||||
// points, with known function values
|
// points, with known function values
|
||||||
// ---> With endpoint included
|
// ---> With endpoint included
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 50.0, 5, True)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 50.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 20.0, 30.0, 40.0, 50.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 20.0, 30.0, 40.0, 50.0]),
|
||||||
|
@ -21,7 +21,7 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, True)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 20.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 12.5, 15.0, 17.5, 20.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 12.5, 15.0, 17.5, 20.0]),
|
||||||
|
@ -34,7 +34,7 @@ pub fn list_linear_space_test() {
|
||||||
|
|
||||||
// Try with negative stop
|
// Try with negative stop
|
||||||
// ----> Without endpoint included
|
// ----> Without endpoint included
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 50.0, 5, False)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 50.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 18.0, 26.0, 34.0, 42.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 18.0, 26.0, 34.0, 42.0]),
|
||||||
|
@ -45,7 +45,7 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, False)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 20.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 12.0, 14.0, 16.0, 18.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 12.0, 14.0, 16.0, 18.0]),
|
||||||
|
@ -57,7 +57,7 @@ pub fn list_linear_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// Try with negative stop
|
// Try with negative stop
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, -50.0, 5, False)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, -50.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace
|
linspace
|
||||||
|
@ -70,7 +70,7 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, -20.0, 5, True)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, -20.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace
|
linspace
|
||||||
|
@ -84,7 +84,7 @@ pub fn list_linear_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// Try with negative start
|
// Try with negative start
|
||||||
let assert Ok(linspace) = maths.linear_space(-10.0, 50.0, 5, False)
|
let assert Ok(linspace) = maths.yield_linear_space(-10.0, 50.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([-10.0, 2.0, 14.0, 26.0, 38.0]),
|
linspace |> yielder.to_list() |> list.zip([-10.0, 2.0, 14.0, 26.0, 38.0]),
|
||||||
|
@ -95,7 +95,7 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(linspace) = maths.linear_space(-10.0, 20.0, 5, True)
|
let assert Ok(linspace) = maths.yield_linear_space(-10.0, 20.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([-10.0, -2.5, 5.0, 12.5, 20.0]),
|
linspace |> yielder.to_list() |> list.zip([-10.0, -2.5, 5.0, 12.5, 20.0]),
|
||||||
|
@ -109,7 +109,7 @@ pub fn list_linear_space_test() {
|
||||||
// Check that when start == stop and steps > 0, then
|
// Check that when start == stop and steps > 0, then
|
||||||
// the value (start/stop) is just repeated, since the
|
// the value (start/stop) is just repeated, since the
|
||||||
// step increment will be 0
|
// step increment will be 0
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 10.0, 5, True)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 10.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
||||||
|
@ -120,7 +120,7 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(linspace) = maths.linear_space(10.0, 10.0, 5, False)
|
let assert Ok(linspace) = maths.yield_linear_space(10.0, 10.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
linspace |> yielder.to_list() |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
linspace |> yielder.to_list() |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
||||||
|
@ -131,18 +131,149 @@ pub fn list_linear_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
|
// A negative number of points does not work (-5)
|
||||||
|
maths.yield_linear_space(10.0, 50.0, -5, True)
|
||||||
|
|> should.be_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_linear_space_test() {
|
||||||
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
|
|
||||||
|
// Check that the function agrees, at some arbitrary input
|
||||||
|
// points, with known function values
|
||||||
|
// ---> With endpoint included
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 50.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 20.0, 30.0, 40.0, 50.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 12.5, 15.0, 17.5, 20.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Try with negative stop
|
||||||
|
// ----> Without endpoint included
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 50.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 18.0, 26.0, 34.0, 42.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 20.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 12.0, 14.0, 16.0, 18.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Try with negative stop
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, -50.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace
|
||||||
|
|> list.zip([10.0, -2.0, -14.0, -26.0, -38.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, -20.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace
|
||||||
|
|> list.zip([10.0, 2.5, -5.0, -12.5, -20.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Try with negative start
|
||||||
|
let assert Ok(linspace) = maths.linear_space(-10.0, 50.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([-10.0, 2.0, 14.0, 26.0, 38.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(linspace) = maths.linear_space(-10.0, 20.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([-10.0, -2.5, 5.0, 12.5, 20.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Check that when start == stop and steps > 0, then
|
||||||
|
// the value (start/stop) is just repeated, since the
|
||||||
|
// step increment will be 0
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 10.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(linspace) = maths.linear_space(10.0, 10.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
linspace |> list.zip([10.0, 10.0, 10.0, 10.0, 10.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
// A negative number of points does not work (-5)
|
// A negative number of points does not work (-5)
|
||||||
maths.linear_space(10.0, 50.0, -5, True)
|
maths.linear_space(10.0, 50.0, -5, True)
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_logarithmic_space_test() {
|
pub fn yield_logarithmic_space_test() {
|
||||||
let assert Ok(tol) = float.power(10.0, -6.0)
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
// Check that the function agrees, at some arbitrary input
|
// Check that the function agrees, at some arbitrary input
|
||||||
// points, with known function values
|
// points, with known function values
|
||||||
// ---> With endpoint included
|
// ---> With endpoint included
|
||||||
// - Positive start, stop
|
// - Positive start, stop
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0]),
|
logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0]),
|
||||||
|
@ -154,7 +285,8 @@ pub fn list_logarithmic_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// - Positive start, negative stop
|
// - Positive start, negative stop
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(1.0, -3.0, 3, True, 10.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(1.0, -3.0, 3, True, 10.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([10.0, 0.1, 0.001]),
|
logspace |> yielder.to_list() |> list.zip([10.0, 0.1, 0.001]),
|
||||||
|
@ -166,7 +298,8 @@ pub fn list_logarithmic_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// - Positive stop, negative start
|
// - Positive stop, negative start
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(-1.0, 3.0, 3, True, 10.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(-1.0, 3.0, 3, True, 10.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([0.1, 10.0, 1000.0]),
|
logspace |> yielder.to_list() |> list.zip([0.1, 10.0, 1000.0]),
|
||||||
|
@ -179,7 +312,8 @@ pub fn list_logarithmic_space_test() {
|
||||||
|
|
||||||
// ----> Without endpoint included
|
// ----> Without endpoint included
|
||||||
// - Positive start, stop
|
// - Positive start, stop
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, False, 10.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(1.0, 3.0, 3, False, 10.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -195,7 +329,8 @@ pub fn list_logarithmic_space_test() {
|
||||||
// Check that when start == stop and steps > 0, then
|
// Check that when start == stop and steps > 0, then
|
||||||
// the value (start/stop) is just repeated, since the
|
// the value (start/stop) is just repeated, since the
|
||||||
// step increment will be 0
|
// step increment will be 0
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(5.0, 5.0, 5, True, 5.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(5.0, 5.0, 5, True, 5.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -207,7 +342,8 @@ pub fn list_logarithmic_space_test() {
|
||||||
result
|
result
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
let assert Ok(logspace) = maths.logarithmic_space(5.0, 5.0, 5, False, 5.0)
|
let assert Ok(logspace) =
|
||||||
|
maths.yield_logarithmic_space(5.0, 5.0, 5, False, 5.0)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -220,6 +356,84 @@ pub fn list_logarithmic_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
|
// A negative number of points does not work (-3)
|
||||||
|
maths.yield_logarithmic_space(1.0, 3.0, -3, True, 10.0)
|
||||||
|
|> should.be_error()
|
||||||
|
|
||||||
|
// A negative base does not work (-10)
|
||||||
|
maths.yield_logarithmic_space(1.0, 3.0, 3, True, -10.0)
|
||||||
|
|> should.be_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_logarithmic_space_test() {
|
||||||
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
|
// Check that the function agrees, at some arbitrary input
|
||||||
|
// points, with known function values
|
||||||
|
// ---> With endpoint included
|
||||||
|
// - Positive start, stop
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, True, 10.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([10.0, 100.0, 1000.0]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// - Positive start, negative stop
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(1.0, -3.0, 3, True, 10.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([10.0, 0.1, 0.001]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// - Positive stop, negative start
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(-1.0, 3.0, 3, True, 10.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([0.1, 10.0, 1000.0]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// ----> Without endpoint included
|
||||||
|
// - Positive start, stop
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(1.0, 3.0, 3, False, 10.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([10.0, 46.41588834, 215.443469]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Check that when start == stop and steps > 0, then
|
||||||
|
// the value (start/stop) is just repeated, since the
|
||||||
|
// step increment will be 0
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(5.0, 5.0, 5, True, 5.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([3125.0, 3125.0, 3125.0, 3125.0, 3125.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
let assert Ok(logspace) = maths.logarithmic_space(5.0, 5.0, 5, False, 5.0)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([3125.0, 3125.0, 3125.0, 3125.0, 3125.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
// A negative number of points does not work (-3)
|
// A negative number of points does not work (-3)
|
||||||
maths.logarithmic_space(1.0, 3.0, -3, True, 10.0)
|
maths.logarithmic_space(1.0, 3.0, -3, True, 10.0)
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
|
@ -229,13 +443,13 @@ pub fn list_logarithmic_space_test() {
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_geometric_space_test() {
|
pub fn yield_geometric_space_test() {
|
||||||
let assert Ok(tol) = float.power(10.0, -6.0)
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
// Check that the function agrees, at some arbitrary input
|
// Check that the function agrees, at some arbitrary input
|
||||||
// points, with known function values
|
// points, with known function values
|
||||||
// ---> With endpoint included
|
// ---> With endpoint included
|
||||||
// - Positive start, stop
|
// - Positive start, stop
|
||||||
let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, True)
|
let assert Ok(logspace) = maths.yield_geometric_space(10.0, 1000.0, 3, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0]),
|
logspace |> yielder.to_list() |> list.zip([10.0, 100.0, 1000.0]),
|
||||||
|
@ -247,7 +461,7 @@ pub fn list_geometric_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// - Positive start, negative stop
|
// - Positive start, negative stop
|
||||||
let assert Ok(logspace) = maths.geometric_space(10.0, 0.001, 3, True)
|
let assert Ok(logspace) = maths.yield_geometric_space(10.0, 0.001, 3, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([10.0, 0.1, 0.001]),
|
logspace |> yielder.to_list() |> list.zip([10.0, 0.1, 0.001]),
|
||||||
|
@ -259,7 +473,7 @@ pub fn list_geometric_space_test() {
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
// - Positive stop, negative start
|
// - Positive stop, negative start
|
||||||
let assert Ok(logspace) = maths.geometric_space(0.1, 1000.0, 3, True)
|
let assert Ok(logspace) = maths.yield_geometric_space(0.1, 1000.0, 3, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace |> yielder.to_list() |> list.zip([0.1, 10.0, 1000.0]),
|
logspace |> yielder.to_list() |> list.zip([0.1, 10.0, 1000.0]),
|
||||||
|
@ -272,7 +486,7 @@ pub fn list_geometric_space_test() {
|
||||||
|
|
||||||
// ----> Without endpoint included
|
// ----> Without endpoint included
|
||||||
// - Positive start, stop
|
// - Positive start, stop
|
||||||
let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, False)
|
let assert Ok(logspace) = maths.yield_geometric_space(10.0, 1000.0, 3, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -288,7 +502,7 @@ pub fn list_geometric_space_test() {
|
||||||
// Check that when start == stop and steps > 0, then
|
// Check that when start == stop and steps > 0, then
|
||||||
// the value (start/stop) is just repeated, since the
|
// the value (start/stop) is just repeated, since the
|
||||||
// step increment will be 0
|
// step increment will be 0
|
||||||
let assert Ok(logspace) = maths.geometric_space(5.0, 5.0, 5, True)
|
let assert Ok(logspace) = maths.yield_geometric_space(5.0, 5.0, 5, True)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -301,7 +515,7 @@ pub fn list_geometric_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
let assert Ok(logspace) = maths.geometric_space(5.0, 5.0, 5, False)
|
let assert Ok(logspace) = maths.yield_geometric_space(5.0, 5.0, 5, False)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
logspace
|
logspace
|
||||||
|
@ -314,6 +528,88 @@ pub fn list_geometric_space_test() {
|
||||||
|> list.all(fn(x) { x == True })
|
|> list.all(fn(x) { x == True })
|
||||||
|> should.be_true()
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Test invalid input (start and stop can't be less than or equal to 0.0)
|
||||||
|
maths.yield_geometric_space(0.0, 1000.0, 3, False)
|
||||||
|
|> should.be_error()
|
||||||
|
|
||||||
|
maths.yield_geometric_space(-1000.0, 0.0, 3, False)
|
||||||
|
|> should.be_error()
|
||||||
|
|
||||||
|
// A negative number of points does not work
|
||||||
|
maths.yield_geometric_space(-1000.0, 0.0, -3, False)
|
||||||
|
|> should.be_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_geometric_space_test() {
|
||||||
|
let assert Ok(tol) = float.power(10.0, -6.0)
|
||||||
|
// Check that the function agrees, at some arbitrary input
|
||||||
|
// points, with known function values
|
||||||
|
// ---> With endpoint included
|
||||||
|
// - Positive start, stop
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([10.0, 100.0, 1000.0]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// - Positive start, negative stop
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(10.0, 0.001, 3, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([10.0, 0.1, 0.001]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// - Positive stop, negative start
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(0.1, 1000.0, 3, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(logspace |> list.zip([0.1, 10.0, 1000.0]), 0.0, tol)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// ----> Without endpoint included
|
||||||
|
// - Positive start, stop
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(10.0, 1000.0, 3, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([10.0, 46.41588834, 215.443469]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Check that when start == stop and steps > 0, then
|
||||||
|
// the value (start/stop) is just repeated, since the
|
||||||
|
// step increment will be 0
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(5.0, 5.0, 5, True)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([5.0, 5.0, 5.0, 5.0, 5.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
let assert Ok(logspace) = maths.geometric_space(5.0, 5.0, 5, False)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
logspace
|
||||||
|
|> list.zip([5.0, 5.0, 5.0, 5.0, 5.0]),
|
||||||
|
0.0,
|
||||||
|
tol,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
// Test invalid input (start and stop can't be less than or equal to 0.0)
|
// Test invalid input (start and stop can't be less than or equal to 0.0)
|
||||||
maths.geometric_space(0.0, 1000.0, 3, False)
|
maths.geometric_space(0.0, 1000.0, 3, False)
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
|
@ -326,75 +622,107 @@ pub fn list_geometric_space_test() {
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_arange_test() {
|
pub fn list_step_range_test() {
|
||||||
// Positive start, stop, step
|
// Positive start, stop, step
|
||||||
maths.arange(1.0, 5.0, 1.0)
|
maths.step_range(1.0, 5.0, 1.0)
|
||||||
|
|> should.equal([1.0, 2.0, 3.0, 4.0])
|
||||||
|
|
||||||
|
maths.step_range(1.0, 5.0, 0.5)
|
||||||
|
|> should.equal([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5])
|
||||||
|
|
||||||
|
maths.step_range(1.0, 2.0, 0.25)
|
||||||
|
|> should.equal([1.0, 1.25, 1.5, 1.75])
|
||||||
|
|
||||||
|
// Reverse (switch start/stop largest/smallest value)
|
||||||
|
maths.step_range(5.0, 1.0, 1.0)
|
||||||
|
|> should.equal([])
|
||||||
|
|
||||||
|
// Reverse negative step
|
||||||
|
maths.step_range(5.0, 1.0, -1.0)
|
||||||
|
|> should.equal([5.0, 4.0, 3.0, 2.0])
|
||||||
|
|
||||||
|
// Positive start, negative stop, step
|
||||||
|
maths.step_range(5.0, -1.0, -1.0)
|
||||||
|
|> should.equal([5.0, 4.0, 3.0, 2.0, 1.0, 0.0])
|
||||||
|
|
||||||
|
// Negative start, stop, step
|
||||||
|
maths.step_range(-5.0, -1.0, -1.0)
|
||||||
|
|> should.equal([])
|
||||||
|
|
||||||
|
// Negative start, stop, positive step
|
||||||
|
maths.step_range(-5.0, -1.0, 1.0)
|
||||||
|
|> should.equal([-5.0, -4.0, -3.0, -2.0])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn yield_step_range_test() {
|
||||||
|
// Positive start, stop, step
|
||||||
|
maths.yield_step_range(1.0, 5.0, 1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([1.0, 2.0, 3.0, 4.0])
|
|> should.equal([1.0, 2.0, 3.0, 4.0])
|
||||||
|
|
||||||
maths.arange(1.0, 5.0, 0.5)
|
maths.yield_step_range(1.0, 5.0, 0.5)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5])
|
|> should.equal([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5])
|
||||||
|
|
||||||
maths.arange(1.0, 2.0, 0.25)
|
maths.yield_step_range(1.0, 2.0, 0.25)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([1.0, 1.25, 1.5, 1.75])
|
|> should.equal([1.0, 1.25, 1.5, 1.75])
|
||||||
|
|
||||||
// Reverse (switch start/stop largest/smallest value)
|
// Reverse (switch start/stop largest/smallest value)
|
||||||
maths.arange(5.0, 1.0, 1.0)
|
maths.yield_step_range(5.0, 1.0, 1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([])
|
|> should.equal([])
|
||||||
|
|
||||||
// Reverse negative step
|
// Reverse negative step
|
||||||
maths.arange(5.0, 1.0, -1.0)
|
maths.yield_step_range(5.0, 1.0, -1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([5.0, 4.0, 3.0, 2.0])
|
|> should.equal([5.0, 4.0, 3.0, 2.0])
|
||||||
|
|
||||||
// Positive start, negative stop, step
|
// Positive start, negative stop, step
|
||||||
maths.arange(5.0, -1.0, -1.0)
|
maths.yield_step_range(5.0, -1.0, -1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([5.0, 4.0, 3.0, 2.0, 1.0, 0.0])
|
|> should.equal([5.0, 4.0, 3.0, 2.0, 1.0, 0.0])
|
||||||
|
|
||||||
// Negative start, stop, step
|
// Negative start, stop, step
|
||||||
maths.arange(-5.0, -1.0, -1.0)
|
maths.yield_step_range(-5.0, -1.0, -1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([])
|
|> should.equal([])
|
||||||
|
|
||||||
// Negative start, stop, positive step
|
// Negative start, stop, positive step
|
||||||
maths.arange(-5.0, -1.0, 1.0)
|
maths.yield_step_range(-5.0, -1.0, 1.0)
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([-5.0, -4.0, -3.0, -2.0])
|
|> should.equal([-5.0, -4.0, -3.0, -2.0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_symmetric_space_test() {
|
pub fn yield_symmetric_space_test() {
|
||||||
let assert Ok(tolerance) = float.power(10.0, -6.0)
|
let assert Ok(tolerance) = float.power(10.0, -6.0)
|
||||||
|
|
||||||
// Check that the function agrees, at some arbitrary input
|
// Check that the function agrees, at some arbitrary input
|
||||||
// points, with known function values
|
// points, with known function values
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(0.0, 5.0, 5)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, 5.0, 5)
|
||||||
sym_space
|
sym_space
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
||||||
|
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(0.0, 5.0, 5)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, 5.0, 5)
|
||||||
sym_space
|
sym_space
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
||||||
|
|
||||||
// Negative center
|
// Negative center
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(-10.0, 5.0, 5)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(-10.0, 5.0, 5)
|
||||||
sym_space
|
sym_space
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([-15.0, -12.5, -10.0, -7.5, -5.0])
|
|> should.equal([-15.0, -12.5, -10.0, -7.5, -5.0])
|
||||||
|
|
||||||
// Negative Radius (simply reverses the order of the values)
|
// Negative Radius (simply reverses the order of the values)
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(0.0, -5.0, 5)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, -5.0, 5)
|
||||||
sym_space
|
sym_space
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
|
|> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
|
||||||
|
|
||||||
// Uneven number of points
|
// Uneven number of points
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(0.0, 2.0, 4)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, 2.0, 4)
|
||||||
let assert Ok(result) =
|
let assert Ok(result) =
|
||||||
maths.all_close(
|
maths.all_close(
|
||||||
sym_space
|
sym_space
|
||||||
|
@ -410,11 +738,59 @@ pub fn list_symmetric_space_test() {
|
||||||
// Check that when radius == 0 and steps > 0, then
|
// Check that when radius == 0 and steps > 0, then
|
||||||
// the value center value is just repeated, since the
|
// the value center value is just repeated, since the
|
||||||
// step increment will be 0
|
// step increment will be 0
|
||||||
let assert Ok(sym_space) = maths.symmetric_space(10.0, 0.0, 4)
|
let assert Ok(sym_space) = maths.yield_symmetric_space(10.0, 0.0, 4)
|
||||||
sym_space
|
sym_space
|
||||||
|> yielder.to_list()
|
|> yielder.to_list()
|
||||||
|> should.equal([10.0, 10.0, 10.0, 10.0])
|
|> should.equal([10.0, 10.0, 10.0, 10.0])
|
||||||
|
|
||||||
|
// A negative number of points does not work (-5)
|
||||||
|
maths.yield_symmetric_space(0.0, 5.0, -5)
|
||||||
|
|> should.be_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list_symmetric_space_test() {
|
||||||
|
let assert Ok(tolerance) = float.power(10.0, -6.0)
|
||||||
|
|
||||||
|
// Check that the function agrees, at some arbitrary input
|
||||||
|
// points, with known function values
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(0.0, 5.0, 5)
|
||||||
|
sym_space
|
||||||
|
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
||||||
|
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(0.0, 5.0, 5)
|
||||||
|
sym_space
|
||||||
|
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
|
||||||
|
|
||||||
|
// Negative center
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(-10.0, 5.0, 5)
|
||||||
|
sym_space
|
||||||
|
|> should.equal([-15.0, -12.5, -10.0, -7.5, -5.0])
|
||||||
|
|
||||||
|
// Negative Radius (simply reverses the order of the values)
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(0.0, -5.0, 5)
|
||||||
|
sym_space
|
||||||
|
|> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
|
||||||
|
|
||||||
|
// Uneven number of points
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(0.0, 2.0, 4)
|
||||||
|
let assert Ok(result) =
|
||||||
|
maths.all_close(
|
||||||
|
sym_space
|
||||||
|
|> list.zip([-2.0, -0.6666666666666667, 0.6666666666666665, 2.0]),
|
||||||
|
0.0,
|
||||||
|
tolerance,
|
||||||
|
)
|
||||||
|
result
|
||||||
|
|> list.all(fn(x) { x == True })
|
||||||
|
|> should.be_true()
|
||||||
|
|
||||||
|
// Check that when radius == 0 and steps > 0, then
|
||||||
|
// the value center value is just repeated, since the
|
||||||
|
// step increment will be 0
|
||||||
|
let assert Ok(sym_space) = maths.symmetric_space(10.0, 0.0, 4)
|
||||||
|
sym_space
|
||||||
|
|> should.equal([10.0, 10.0, 10.0, 10.0])
|
||||||
|
|
||||||
// A negative number of points does not work (-5)
|
// A negative number of points does not work (-5)
|
||||||
maths.symmetric_space(0.0, 5.0, -5)
|
maths.symmetric_space(0.0, 5.0, -5)
|
||||||
|> should.be_error()
|
|> should.be_error()
|
||||||
|
|
Loading…
Reference in a new issue