move comparison functions out of math.scad and arrays.scad into comparisons.scad

rename arrays.scad to lists.scad
This commit is contained in:
Adrian Mariano
2021-10-26 23:12:51 -04:00
parent 8cfb77cf64
commit 71dab62432
8 changed files with 1492 additions and 1216 deletions

223
math.scad
View File

@@ -866,158 +866,6 @@ function convolve(p,q) =
// Section: Comparisons and Logic
// Function: all_zero()
// Usage:
// x = all_zero(x, [eps]);
// Description:
// Returns true if the finite number passed to it is approximately zero, to within `eps`.
// If passed a list, recursively checks if all items in the list are approximately zero.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// eps = The maximum allowed variance. Default: `EPSILON` (1e-9)
// Example:
// a = all_zero(0); // Returns: true.
// b = all_zero(1e-3); // Returns: false.
// c = all_zero([0,0,0]); // Returns: true.
// d = all_zero([0,0,1e-3]); // Returns: false.
function all_zero(x, eps=EPSILON) =
is_finite(x)? approx(x,eps) :
is_list(x)? (x != [] && [for (xx=x) if(!all_zero(xx,eps=eps)) 1] == []) :
false;
// Function: all_nonzero()
// Usage:
// test = all_nonzero(x, [eps]);
// Description:
// Returns true if the finite number passed to it is not almost zero, to within `eps`.
// If passed a list, recursively checks if all items in the list are not almost zero.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// eps = The maximum allowed variance. Default: `EPSILON` (1e-9)
// Example:
// a = all_nonzero(0); // Returns: false.
// b = all_nonzero(1e-3); // Returns: true.
// c = all_nonzero([0,0,0]); // Returns: false.
// d = all_nonzero([0,0,1e-3]); // Returns: false.
// e = all_nonzero([1e-3,1e-3,1e-3]); // Returns: true.
function all_nonzero(x, eps=EPSILON) =
is_finite(x)? !approx(x,eps) :
is_list(x)? (x != [] && [for (xx=x) if(!all_nonzero(xx,eps=eps)) 1] == []) :
false;
// Function: all_positive()
// Usage:
// test = all_positive(x);
// Description:
// Returns true if the finite number passed to it is greater than zero.
// If passed a list, recursively checks if all items in the list are positive.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// Example:
// a = all_positive(-2); // Returns: false.
// b = all_positive(0); // Returns: false.
// c = all_positive(2); // Returns: true.
// d = all_positive([0,0,0]); // Returns: false.
// e = all_positive([0,1,2]); // Returns: false.
// f = all_positive([3,1,2]); // Returns: true.
// g = all_positive([3,-1,2]); // Returns: false.
function all_positive(x) =
is_num(x)? x>0 :
is_list(x)? (x != [] && [for (xx=x) if(!all_positive(xx)) 1] == []) :
false;
// Function: all_negative()
// Usage:
// test = all_negative(x);
// Description:
// Returns true if the finite number passed to it is less than zero.
// If passed a list, recursively checks if all items in the list are negative.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// Example:
// a = all_negative(-2); // Returns: true.
// b = all_negative(0); // Returns: false.
// c = all_negative(2); // Returns: false.
// d = all_negative([0,0,0]); // Returns: false.
// e = all_negative([0,1,2]); // Returns: false.
// f = all_negative([3,1,2]); // Returns: false.
// g = all_negative([3,-1,2]); // Returns: false.
// h = all_negative([-3,-1,-2]); // Returns: true.
function all_negative(x) =
is_num(x)? x<0 :
is_list(x)? (x != [] && [for (xx=x) if(!all_negative(xx)) 1] == []) :
false;
// Function: all_nonpositive()
// Usage:
// all_nonpositive(x);
// Description:
// Returns true if the finite number passed to it is less than or equal to zero.
// If passed a list, recursively checks if all items in the list are nonpositive.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// Example:
// a = all_nonpositive(-2); // Returns: true.
// b = all_nonpositive(0); // Returns: true.
// c = all_nonpositive(2); // Returns: false.
// d = all_nonpositive([0,0,0]); // Returns: true.
// e = all_nonpositive([0,1,2]); // Returns: false.
// f = all_nonpositive([3,1,2]); // Returns: false.
// g = all_nonpositive([3,-1,2]); // Returns: false.
// h = all_nonpositive([-3,-1,-2]); // Returns: true.
function all_nonpositive(x) =
is_num(x)? x<=0 :
is_list(x)? (x != [] && [for (xx=x) if(!all_nonpositive(xx)) 1] == []) :
false;
// Function: all_nonnegative()
// Usage:
// all_nonnegative(x);
// Description:
// Returns true if the finite number passed to it is greater than or equal to zero.
// If passed a list, recursively checks if all items in the list are nonnegative.
// Otherwise, returns false.
// Arguments:
// x = The value to check.
// Example:
// a = all_nonnegative(-2); // Returns: false.
// b = all_nonnegative(0); // Returns: true.
// c = all_nonnegative(2); // Returns: true.
// d = all_nonnegative([0,0,0]); // Returns: true.
// e = all_nonnegative([0,1,2]); // Returns: true.
// f = all_nonnegative([0,-1,-2]); // Returns: false.
// g = all_nonnegative([3,1,2]); // Returns: true.
// h = all_nonnegative([3,-1,2]); // Returns: false.
// i = all_nonnegative([-3,-1,-2]); // Returns: false.
function all_nonnegative(x) =
is_num(x)? x>=0 :
is_list(x)? (x != [] && [for (xx=x) if(!all_nonnegative(xx)) 1] == []) :
false;
// Function all_equal()
// Usage:
// b = all_equal(vec, [eps]);
// Description:
// Returns true if all of the entries in vec are equal to each other, or approximately equal to each other if eps is set.
// Arguments:
// vec = vector to check
// eps = Set to tolerance for approximate equality. Default: 0
function all_equal(vec,eps=0) =
eps==0 ? [for(v=vec) if (v!=vec[0]) v] == []
: [for(v=vec) if (!approx(v,vec[0])) v] == [];
// Function: all_integer()
@@ -1044,76 +892,6 @@ function all_integer(x) =
false;
// Function: approx()
// Usage:
// test = approx(a, b, [eps])
// Description:
// Compares two numbers or vectors, and returns true if they are closer than `eps` to each other.
// Arguments:
// a = First value.
// b = Second value.
// eps = The maximum allowed difference between `a` and `b` that will return true.
// Example:
// test1 = approx(-0.3333333333,-1/3); // Returns: true
// test2 = approx(0.3333333333,1/3); // Returns: true
// test3 = approx(0.3333,1/3); // Returns: false
// test4 = approx(0.3333,1/3,eps=1e-3); // Returns: true
// test5 = approx(PI,3.1415926536); // Returns: true
function approx(a,b,eps=EPSILON) =
(a==b && is_bool(a) == is_bool(b)) ||
(is_num(a) && is_num(b) && abs(a-b) <= eps) ||
(is_list(a) && is_list(b) && len(a) == len(b) && [] == [for (i=idx(a)) if (!approx(a[i],b[i],eps=eps)) 1]);
function _type_num(x) =
is_undef(x)? 0 :
is_bool(x)? 1 :
is_num(x)? 2 :
is_nan(x)? 3 :
is_string(x)? 4 :
is_list(x)? 5 : 6;
// Function: compare_vals()
// Usage:
// test = compare_vals(a, b);
// Description:
// Compares two values. Lists are compared recursively.
// Returns <0 if a<b. Returns >0 if a>b. Returns 0 if a==b.
// If types are not the same, then undef < bool < nan < num < str < list < range.
// Arguments:
// a = First value to compare.
// b = Second value to compare.
function compare_vals(a, b) =
(a==b)? 0 :
let(t1=_type_num(a), t2=_type_num(b)) (t1!=t2)? (t1-t2) :
is_list(a)? compare_lists(a,b) :
is_nan(a)? 0 :
(a<b)? -1 : (a>b)? 1 : 0;
// Function: compare_lists()
// Usage:
// test = compare_lists(a, b)
// Description:
// Compare contents of two lists using `compare_vals()`.
// Returns <0 if `a`<`b`.
// Returns 0 if `a`==`b`.
// Returns >0 if `a`>`b`.
// Arguments:
// a = First list to compare.
// b = Second list to compare.
function compare_lists(a, b) =
a==b? 0 :
let(
cmps = [
for (i = [0:1:min(len(a),len(b))-1])
let( cmp = compare_vals(a[i],b[i]) )
if (cmp!=0) cmp
]
)
cmps==[]? (len(a)-len(b)) : cmps[0];
// Function: any()
// Usage:
@@ -1230,7 +1008,6 @@ function _count_true_bool(l, nmax, i=0, out=0) =
);
// Section: Calculus
// Function: deriv()