Merge pull request #718 from revarbat/revarbat_dev

Speed optimizations for approx()
This commit is contained in:
Revar Desmera 2021-11-04 21:39:17 -07:00 committed by GitHub
commit 0b10c7309d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -12,7 +12,8 @@
// Usage:
// test = approx(a, b, [eps])
// Description:
// Compares two numbers or vectors, and returns true if they are closer than `eps` to each other.
// Compares two numbers, vectors, or matrices. Returns true if they are closer than `eps` to each other.
// Results are undefined if `a` and `b` are of different types, or if vectors or matrices contain non-numbers.
// Arguments:
// a = First value.
// b = Second value.
@ -23,10 +24,20 @@
// 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
// test6 = approx([0,0,sin(45)],[0,0,sqrt(2)/2]); // 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]);
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))
let(aa=a[i], bb=b[i])
if(
is_num(aa) && is_num(bb)? abs(aa-bb) > eps :
!approx(aa,bb,eps=eps)
) 1
]
) : false;
// Function: all_zero()
@ -778,3 +789,4 @@ function list_smallest(list, k) =
let( bigger = [for(li=list) if(li>v) li ] )
concat(smaller, equal, list_smallest(bigger, k-len(smaller) -len(equal)));
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap