gleam-community-maths/test/gleam_community/sequences_test.gleam

797 lines
22 KiB
Gleam

import gleam/float
import gleam/list
import gleam/yielder
import gleam_community/maths
import gleeunit/should
pub fn yield_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.yield_linear_space(10.0, 50.0, 5, True)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, 20.0, 5, True)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, 50.0, 5, False)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, 20.0, 5, False)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, -50.0, 5, False)
let assert Ok(result) =
maths.all_close(
linspace
|> yielder.to_list()
|> 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.yield_linear_space(10.0, -20.0, 5, True)
let assert Ok(result) =
maths.all_close(
linspace
|> yielder.to_list()
|> 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.yield_linear_space(-10.0, 50.0, 5, False)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(-10.0, 20.0, 5, True)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, 10.0, 5, True)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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.yield_linear_space(10.0, 10.0, 5, False)
let assert Ok(result) =
maths.all_close(
linspace |> yielder.to_list() |> 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)
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)
maths.linear_space(10.0, 50.0, -5, True)
|> should.be_error()
}
pub fn yield_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.yield_logarithmic_space(1.0, 3.0, 3, True, 10.0)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_logarithmic_space(1.0, -3.0, 3, True, 10.0)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_logarithmic_space(-1.0, 3.0, 3, True, 10.0)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_logarithmic_space(1.0, 3.0, 3, False, 10.0)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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.yield_logarithmic_space(5.0, 5.0, 5, True, 5.0)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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.yield_logarithmic_space(5.0, 5.0, 5, False, 5.0)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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)
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)
maths.logarithmic_space(1.0, 3.0, -3, True, 10.0)
|> should.be_error()
// A negative base does not work (-10)
maths.logarithmic_space(1.0, 3.0, 3, True, -10.0)
|> should.be_error()
}
pub fn yield_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.yield_geometric_space(10.0, 1000.0, 3, True)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_geometric_space(10.0, 0.001, 3, True)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_geometric_space(0.1, 1000.0, 3, True)
let assert Ok(result) =
maths.all_close(
logspace |> yielder.to_list() |> 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.yield_geometric_space(10.0, 1000.0, 3, False)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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.yield_geometric_space(5.0, 5.0, 5, True)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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.yield_geometric_space(5.0, 5.0, 5, False)
let assert Ok(result) =
maths.all_close(
logspace
|> yielder.to_list()
|> 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)
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)
maths.geometric_space(0.0, 1000.0, 3, False)
|> should.be_error()
maths.geometric_space(-1000.0, 0.0, 3, False)
|> should.be_error()
// A negative number of points does not work
maths.geometric_space(-1000.0, 0.0, -3, False)
|> should.be_error()
}
pub fn list_step_range_test() {
// Positive start, stop, step
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()
|> should.equal([1.0, 2.0, 3.0, 4.0])
maths.yield_step_range(1.0, 5.0, 0.5)
|> yielder.to_list()
|> should.equal([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5])
maths.yield_step_range(1.0, 2.0, 0.25)
|> yielder.to_list()
|> should.equal([1.0, 1.25, 1.5, 1.75])
// Reverse (switch start/stop largest/smallest value)
maths.yield_step_range(5.0, 1.0, 1.0)
|> yielder.to_list()
|> should.equal([])
// Reverse negative step
maths.yield_step_range(5.0, 1.0, -1.0)
|> yielder.to_list()
|> should.equal([5.0, 4.0, 3.0, 2.0])
// Positive start, negative stop, step
maths.yield_step_range(5.0, -1.0, -1.0)
|> yielder.to_list()
|> should.equal([5.0, 4.0, 3.0, 2.0, 1.0, 0.0])
// Negative start, stop, step
maths.yield_step_range(-5.0, -1.0, -1.0)
|> yielder.to_list()
|> should.equal([])
// Negative start, stop, positive step
maths.yield_step_range(-5.0, -1.0, 1.0)
|> yielder.to_list()
|> should.equal([-5.0, -4.0, -3.0, -2.0])
}
pub fn yield_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.yield_symmetric_space(0.0, 5.0, 5)
sym_space
|> yielder.to_list()
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, 5.0, 5)
sym_space
|> yielder.to_list()
|> should.equal([-5.0, -2.5, 0.0, 2.5, 5.0])
// Negative center
let assert Ok(sym_space) = maths.yield_symmetric_space(-10.0, 5.0, 5)
sym_space
|> yielder.to_list()
|> 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.yield_symmetric_space(0.0, -5.0, 5)
sym_space
|> yielder.to_list()
|> should.equal([5.0, 2.5, 0.0, -2.5, -5.0])
// Uneven number of points
let assert Ok(sym_space) = maths.yield_symmetric_space(0.0, 2.0, 4)
let assert Ok(result) =
maths.all_close(
sym_space
|> yielder.to_list()
|> 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.yield_symmetric_space(10.0, 0.0, 4)
sym_space
|> yielder.to_list()
|> 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)
maths.symmetric_space(0.0, 5.0, -5)
|> should.be_error()
}