diff --git a/math.scad b/math.scad index 934d332..10b7463 100644 --- a/math.scad +++ b/math.scad @@ -712,6 +712,7 @@ function matrix_inverse(A) = assert(is_matrix(A,square=true),"Input to matrix_inverse() must be a square matrix") linear_solve(A,ident(len(A))); + // Function: null_space() // Usage: // null_space(A) @@ -723,7 +724,7 @@ function null_space(A,eps=1e-12) = let( Q_R=qr_factor(transpose(A),pivot=true), R=Q_R[1], - zrow = [for(i=idx(R)) if (is_zero(R[i],eps)) i] + zrow = [for(i=idx(R)) if (all_zero(R[i],eps)) i] ) len(zrow)==0 ? [] @@ -900,9 +901,9 @@ function norm_fro(A) = // Section: Comparisons and Logic -// Function: is_zero() +// Function: all_zero() // Usage: -// is_zero(x); +// all_zero(x); // Description: // Returns true if the 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. @@ -911,19 +912,19 @@ function norm_fro(A) = // x = The value to check. // eps = The maximum allowed variance. Default: `EPSILON` (1e-9) // Example: -// is_zero(0); // Returns: true. -// is_zero(1e-3); // Returns: false. -// is_zero([0,0,0]); // Returns: true. -// is_zero([0,0,1e-3]); // Returns: false. -function is_zero(x, eps=EPSILON) = - is_list(x)? (x != [] && [for (xx=x) if(!is_zero(xx,eps=eps)) 1] == []) : +// all_zero(0); // Returns: true. +// all_zero(1e-3); // Returns: false. +// all_zero([0,0,0]); // Returns: true. +// all_zero([0,0,1e-3]); // Returns: false. +function all_zero(x, eps=EPSILON) = + is_list(x)? (x != [] && [for (xx=x) if(!all_zero(xx,eps=eps)) 1] == []) : is_num(x)? approx(x,eps) : false; -// Function: is_positive() +// Function: all_positive() // Usage: -// is_positive(x); +// all_positive(x); // Description: // Returns true if the number passed to it is greater than zero. // If passed a list, recursively checks if all items in the list are positive. @@ -931,22 +932,22 @@ function is_zero(x, eps=EPSILON) = // Arguments: // x = The value to check. // Example: -// is_positive(-2); // Returns: false. -// is_positive(0); // Returns: false. -// is_positive(2); // Returns: true. -// is_positive([0,0,0]); // Returns: false. -// is_positive([0,1,2]); // Returns: false. -// is_positive([3,1,2]); // Returns: true. -// is_positive([3,-1,2]); // Returns: false. -function is_positive(x) = - is_list(x)? (x != [] && [for (xx=x) if(!is_positive(xx)) 1] == []) : +// all_positive(-2); // Returns: false. +// all_positive(0); // Returns: false. +// all_positive(2); // Returns: true. +// all_positive([0,0,0]); // Returns: false. +// all_positive([0,1,2]); // Returns: false. +// all_positive([3,1,2]); // Returns: true. +// all_positive([3,-1,2]); // Returns: false. +function all_positive(x) = + is_list(x)? (x != [] && [for (xx=x) if(!all_positive(xx)) 1] == []) : is_num(x)? x>0 : false; -// Function: is_negative() +// Function: all_negative() // Usage: -// is_negative(x); +// all_negative(x); // Description: // Returns true if the number passed to it is less than zero. // If passed a list, recursively checks if all items in the list are negative. @@ -954,23 +955,23 @@ function is_positive(x) = // Arguments: // x = The value to check. // Example: -// is_negative(-2); // Returns: true. -// is_negative(0); // Returns: false. -// is_negative(2); // Returns: false. -// is_negative([0,0,0]); // Returns: false. -// is_negative([0,1,2]); // Returns: false. -// is_negative([3,1,2]); // Returns: false. -// is_negative([3,-1,2]); // Returns: false. -// is_negative([-3,-1,-2]); // Returns: true. -function is_negative(x) = - is_list(x)? (x != [] && [for (xx=x) if(!is_negative(xx)) 1] == []) : +// all_negative(-2); // Returns: true. +// all_negative(0); // Returns: false. +// all_negative(2); // Returns: false. +// all_negative([0,0,0]); // Returns: false. +// all_negative([0,1,2]); // Returns: false. +// all_negative([3,1,2]); // Returns: false. +// all_negative([3,-1,2]); // Returns: false. +// all_negative([-3,-1,-2]); // Returns: true. +function all_negative(x) = + is_list(x)? (x != [] && [for (xx=x) if(!all_negative(xx)) 1] == []) : is_num(x)? x<0 : false; -// Function: is_nonpositive() +// Function: all_nonpositive() // Usage: -// is_nonpositive(x); +// all_nonpositive(x); // Description: // Returns true if the 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. @@ -978,23 +979,23 @@ function is_negative(x) = // Arguments: // x = The value to check. // Example: -// is_nonpositive(-2); // Returns: true. -// is_nonpositive(0); // Returns: true. -// is_nonpositive(2); // Returns: false. -// is_nonpositive([0,0,0]); // Returns: true. -// is_nonpositive([0,1,2]); // Returns: false. -// is_nonpositive([3,1,2]); // Returns: false. -// is_nonpositive([3,-1,2]); // Returns: false. -// is_nonpositive([-3,-1,-2]); // Returns: true. -function is_nonpositive(x) = - is_list(x)? (x != [] && [for (xx=x) if(!is_nonpositive(xx)) 1] == []) : +// all_nonpositive(-2); // Returns: true. +// all_nonpositive(0); // Returns: true. +// all_nonpositive(2); // Returns: false. +// all_nonpositive([0,0,0]); // Returns: true. +// all_nonpositive([0,1,2]); // Returns: false. +// all_nonpositive([3,1,2]); // Returns: false. +// all_nonpositive([3,-1,2]); // Returns: false. +// all_nonpositive([-3,-1,-2]); // Returns: true. +function all_nonpositive(x) = + is_list(x)? (x != [] && [for (xx=x) if(!all_nonpositive(xx)) 1] == []) : is_num(x)? x<=0 : false; -// Function: is_nonnegative() +// Function: all_nonnegative() // Usage: -// is_nonnegative(x); +// all_nonnegative(x); // Description: // Returns true if the 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. @@ -1002,17 +1003,17 @@ function is_nonpositive(x) = // Arguments: // x = The value to check. // Example: -// is_nonnegative(-2); // Returns: false. -// is_nonnegative(0); // Returns: true. -// is_nonnegative(2); // Returns: true. -// is_nonnegative([0,0,0]); // Returns: true. -// is_nonnegative([0,1,2]); // Returns: true. -// is_nonnegative([0,-1,-2]); // Returns: false. -// is_nonnegative([3,1,2]); // Returns: true. -// is_nonnegative([3,-1,2]); // Returns: false. -// is_nonnegative([-3,-1,-2]); // Returns: false. -function is_nonnegative(x) = - is_list(x)? (x != [] && [for (xx=x) if(!is_nonnegative(xx)) 1] == []) : +// all_nonnegative(-2); // Returns: false. +// all_nonnegative(0); // Returns: true. +// all_nonnegative(2); // Returns: true. +// all_nonnegative([0,0,0]); // Returns: true. +// all_nonnegative([0,1,2]); // Returns: true. +// all_nonnegative([0,-1,-2]); // Returns: false. +// all_nonnegative([3,1,2]); // Returns: true. +// all_nonnegative([3,-1,2]); // Returns: false. +// all_nonnegative([-3,-1,-2]); // Returns: false. +function all_nonnegative(x) = + is_list(x)? (x != [] && [for (xx=x) if(!all_nonnegative(xx)) 1] == []) : is_num(x)? x>=0 : false; diff --git a/tests/test_math.scad b/tests/test_math.scad index 9a25cec..720235c 100644 --- a/tests/test_math.scad +++ b/tests/test_math.scad @@ -100,104 +100,104 @@ module test_is_matrix() { test_is_matrix(); -module test_is_zero() { - assert(is_zero(0)); - assert(is_zero([0,0,0])); - assert(is_zero([[0,0,0],[0,0]])); - assert(is_zero([EPSILON/2,EPSILON/2,EPSILON/2])); - assert(!is_zero(1e-3)); - assert(!is_zero([0,0,1e-3])); - assert(!is_zero([EPSILON*10,0,0])); - assert(!is_zero([0,EPSILON*10,0])); - assert(!is_zero([0,0,EPSILON*10])); - assert(!is_zero(true)); - assert(!is_zero(false)); - assert(!is_zero(INF)); - assert(!is_zero(-INF)); - assert(!is_zero(NAN)); - assert(!is_zero("foo")); - assert(!is_zero([])); - assert(!is_zero([0:1:2])); +module test_all_zero() { + assert(all_zero(0)); + assert(all_zero([0,0,0])); + assert(all_zero([[0,0,0],[0,0]])); + assert(all_zero([EPSILON/2,EPSILON/2,EPSILON/2])); + assert(!all_zero(1e-3)); + assert(!all_zero([0,0,1e-3])); + assert(!all_zero([EPSILON*10,0,0])); + assert(!all_zero([0,EPSILON*10,0])); + assert(!all_zero([0,0,EPSILON*10])); + assert(!all_zero(true)); + assert(!all_zero(false)); + assert(!all_zero(INF)); + assert(!all_zero(-INF)); + assert(!all_zero(NAN)); + assert(!all_zero("foo")); + assert(!all_zero([])); + assert(!all_zero([0:1:2])); } -test_is_zero(); +test_all_zero(); -module test_is_positive() { - assert(!is_positive(-2)); - assert(!is_positive(0)); - assert(is_positive(2)); - assert(!is_positive([0,0,0])); - assert(!is_positive([0,1,2])); - assert(is_positive([3,1,2])); - assert(!is_positive([3,-1,2])); - assert(!is_positive([])); - assert(!is_positive(true)); - assert(!is_positive(false)); - assert(!is_positive("foo")); - assert(!is_positive([0:1:2])); +module test_all_positive() { + assert(!all_positive(-2)); + assert(!all_positive(0)); + assert(all_positive(2)); + assert(!all_positive([0,0,0])); + assert(!all_positive([0,1,2])); + assert(all_positive([3,1,2])); + assert(!all_positive([3,-1,2])); + assert(!all_positive([])); + assert(!all_positive(true)); + assert(!all_positive(false)); + assert(!all_positive("foo")); + assert(!all_positive([0:1:2])); } -test_is_positive(); +test_all_positive(); -module test_is_negative() { - assert(is_negative(-2)); - assert(!is_negative(0)); - assert(!is_negative(2)); - assert(!is_negative([0,0,0])); - assert(!is_negative([0,1,2])); - assert(!is_negative([3,1,2])); - assert(!is_negative([3,-1,2])); - assert(is_negative([-3,-1,-2])); - assert(!is_negative([-3,1,-2])); - assert(is_negative([[-5,-7],[-3,-1,-2]])); - assert(!is_negative([[-5,-7],[-3,1,-2]])); - assert(!is_negative([])); - assert(!is_negative(true)); - assert(!is_negative(false)); - assert(!is_negative("foo")); - assert(!is_negative([0:1:2])); +module test_all_negative() { + assert(all_negative(-2)); + assert(!all_negative(0)); + assert(!all_negative(2)); + assert(!all_negative([0,0,0])); + assert(!all_negative([0,1,2])); + assert(!all_negative([3,1,2])); + assert(!all_negative([3,-1,2])); + assert(all_negative([-3,-1,-2])); + assert(!all_negative([-3,1,-2])); + assert(all_negative([[-5,-7],[-3,-1,-2]])); + assert(!all_negative([[-5,-7],[-3,1,-2]])); + assert(!all_negative([])); + assert(!all_negative(true)); + assert(!all_negative(false)); + assert(!all_negative("foo")); + assert(!all_negative([0:1:2])); } -test_is_negative(); +test_all_negative(); -module test_is_nonpositive() { - assert(is_nonpositive(-2)); - assert(is_nonpositive(0)); - assert(!is_nonpositive(2)); - assert(is_nonpositive([0,0,0])); - assert(!is_nonpositive([0,1,2])); - assert(is_nonpositive([0,-1,-2])); - assert(!is_nonpositive([3,1,2])); - assert(!is_nonpositive([3,-1,2])); - assert(!is_nonpositive([])); - assert(!is_nonpositive(true)); - assert(!is_nonpositive(false)); - assert(!is_nonpositive("foo")); - assert(!is_nonpositive([0:1:2])); +module test_all_nonpositive() { + assert(all_nonpositive(-2)); + assert(all_nonpositive(0)); + assert(!all_nonpositive(2)); + assert(all_nonpositive([0,0,0])); + assert(!all_nonpositive([0,1,2])); + assert(all_nonpositive([0,-1,-2])); + assert(!all_nonpositive([3,1,2])); + assert(!all_nonpositive([3,-1,2])); + assert(!all_nonpositive([])); + assert(!all_nonpositive(true)); + assert(!all_nonpositive(false)); + assert(!all_nonpositive("foo")); + assert(!all_nonpositive([0:1:2])); } -test_is_nonpositive(); +test_all_nonpositive(); -module test_is_nonnegative() { - assert(!is_nonnegative(-2)); - assert(is_nonnegative(0)); - assert(is_nonnegative(2)); - assert(is_nonnegative([0,0,0])); - assert(is_nonnegative([0,1,2])); - assert(is_nonnegative([3,1,2])); - assert(!is_nonnegative([3,-1,2])); - assert(!is_nonnegative([-3,-1,-2])); - assert(!is_nonnegative([[-5,-7],[-3,-1,-2]])); - assert(!is_nonnegative([[-5,-7],[-3,1,-2]])); - assert(!is_nonnegative([[5,7],[3,-1,2]])); - assert(is_nonnegative([[5,7],[3,1,2]])); - assert(!is_nonnegative([])); - assert(!is_nonnegative(true)); - assert(!is_nonnegative(false)); - assert(!is_nonnegative("foo")); - assert(!is_nonnegative([0:1:2])); +module test_all_nonnegative() { + assert(!all_nonnegative(-2)); + assert(all_nonnegative(0)); + assert(all_nonnegative(2)); + assert(all_nonnegative([0,0,0])); + assert(all_nonnegative([0,1,2])); + assert(all_nonnegative([3,1,2])); + assert(!all_nonnegative([3,-1,2])); + assert(!all_nonnegative([-3,-1,-2])); + assert(!all_nonnegative([[-5,-7],[-3,-1,-2]])); + assert(!all_nonnegative([[-5,-7],[-3,1,-2]])); + assert(!all_nonnegative([[5,7],[3,-1,2]])); + assert(all_nonnegative([[5,7],[3,1,2]])); + assert(!all_nonnegative([])); + assert(!all_nonnegative(true)); + assert(!all_nonnegative(false)); + assert(!all_nonnegative("foo")); + assert(!all_nonnegative([0:1:2])); } -test_is_nonnegative(); +test_all_nonnegative(); module test_approx() { @@ -975,7 +975,7 @@ module test_null_space(){ function nullcheck(A,dim) = let(v=null_space(A)) - len(v)==dim && is_zero(A*transpose(v),eps=1e-12); + len(v)==dim && all_zero(A*transpose(v),eps=1e-12); A = [[-1, 2, -5, 2],[-3,-1,3,-3],[5,0,5,0],[3,-4,11,-4]]; assert(nullcheck(A,1)); diff --git a/version.scad b/version.scad index 262b891..86a9e2e 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,419]; +BOSL_VERSION = [2,0,420]; // Section: BOSL Library Version Functions