@approx(x:numeric, y:numeric) ; listable
(x ~ y)
This predicate returns true if
abs(x - y) < $APPROX_ABS
or
abs((x - y)/max(x, y)) < $APPROX_RATIO
The predefined variable $APPROX_ABS
is initalized to 1e-5
so (x ~ y)
means x
and y
differ by less than 0.00001
.
The predefined variable $APPROX_RATIO
is initalized to 0.1
so (x ~ y)
means x
and y
differ by less than 10% .
By changing the value of these variables, one changes the level of
approximation for the following calls to @approx
. The value of
$APPROX_ABS
controls the absolute difference of the two arguments,
while $APPROX_RATIO
controls the relative difference. The function
returns false if the constraints on the absolute difference and the
relative difference, are not meet.
Notice: Using this function to check if a number is near zero is
adequate and amounts to looking at the absolute difference: (x ~ 0)
results in the comparaison of fabs(x)
which is compared to
$APPROX_ABS
while the relative difference evaluates to 1
(as
a result of abs(x/x)
).
Extension: The predicate is extended in three ways to handle arbitrary data structures:
-
If one argument is a tab and the other is a numeric u, the numeric argument is extended into a tab (all elements of the extension are equal to u) and the predicate returns true if it hold pointwise for all elements of the tabs. For example
returns(tab[1, 2] ~ 1.000001)
false
because we have(1 ~ 1.000001)
but we don’t have(2 ~ 1.000001)
. -
The function accepts nested tabs as arguments and in this case distributes itself over the elements of the arrays as needed.
-
If the the arguments are neither a numeric nor a tab, they must be equal.