# [Python-ideas] Approximately equal operator

Andre Roberge andre.roberge at gmail.com
Fri Jun 15 18:56:43 EDT 2018

```On Fri, Jun 15, 2018 at 3:12 PM Richard Damon <Richard at damon-family.org>
wrote:

> On 6/15/18 1:38 PM, Andre Roberge wrote:
> > I have a suggestion to make inspired by the current discussion about
> > trigonometric functions in degrees, and the desire to have them show
> > "exact" values in some special cases.
> >
> > I suggest that it would be useful to have operators for performing
> > **approximate** comparisons. I believe that such operators would be
> > useful both for students learning using Python as well as experts
> > doing numerical computations.
> >
> > For discussion purpose, I will use ~= as representing an operator
> > testing for approximate equality. (I will show some sample usage
> below).
> >
> > When teaching students, the availability of both == and ~= would give
> > the opportunity to discuss the fact that numerical computations using
> > floats are approximate, while having the possibility to write code
> > that is readable using the approximate equality operator instead of
> > the strict equality operator when needed.
> >
> > Before I started writing this email, I had noticed that numpy includes
> > at least two functions (isclose and allclose) whose purpose is to
> > perform such approximate comparisons. [1]  I had completely missed the
> > fact that Python added the function isclose() in the math module in
> > version 3.5, as described in PEP 485 [0].  I would suggest that the
> > possibility of using operators instead of explicit function calls
> > could make programs easier to write and read, both for beginners and
> > experts alike.  I note that PEP 485 makes no mention of introducing
> > operators as a possibility.
> >
> > In addition to an approximate equality operator, it would be natural
> > to include two additional operators, greater than or approximately
> > equal, and lesser than or approximately equal.  These could be written
> > respectively as >~= and <~=.  I did consider using some relevant utf-8
> > symbol instead of combination of ascii characters, but I think that it
> > would be easier to write programs if one does not require characters
> > nor found on any normal keyboard.
> >
> > Some time ago, I created a toy module [2] to enable easy experiments
> > with some syntactic additions to Python.  Using this module, I created
> > a very poor and limited implementation that shows what using these
> > proposed o[erators might look like [3] ...  My current implementation
> > is slightly different from either Numpy or Python's math.isclose()
> > function [This may no longer be the case soon as I plan to change it
> > to use Python's version instead.] .  As is the case for isclose(),
> > there are two paramaters to be set to determine if the values are
> > close enough to be considered approximately equal: an absolute
> > tolerance and a relative one.  Given that one cannot pass parameters
> > to an operator, my implementation includes a function which can change
> > the values of these parameters for a given session. If these new
> > operators were to be added to Python, such a function would either
> > have to be added as a builtin or as a special function in the math
> module.
> >
> > Here's a sample session for demonstration purpose...
> >
> > \$ python -m experimental
> > experimental console version 0.9.5. [Python version: 3.6.1]
> >
> > ~~> 0.1 + 0.2
> > 0.30000000000000004
> > ~~> 0.1 + 0.2 == 0.3
> > False
> > ~~> from __experimental__ import approx
> > ~~> 0.1 + 0.2 ~= 0.3    # use approximately equal operator
> > True
> > ~~> 0.1 + 0.2 <~= 0.3
> > True
> > ~~> 0.1 + 0.2 >~= 0.3
> > True
> > ~~> 2 ** 0.5
> > 1.4142135623730951
> > ~~> 2**0.5 ~= 1.414
> > False
> > ~~> set_tols(0.001, 0.001)
> > ~~> 2**0.5 ~= 1.414
> > True
> >
> >
> > André Roberge
> >
> > [0] https://www.python.org/dev/peps/pep-0485/
> >
> > [1] See for
> > example
> https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.isclose.html
> >
> > [2] https://github.com/aroberge/experimental
> >
> > [3]
> >
> The big issue with 'approximately equals' is that the definition of it
> is hard to come up with. This is especially true for small values. In
> particular how small does a number need to be to be ~= 0. You also get
> inconsistencies,  you can have a ~= b, and b ~= c but not a ~= c. You
> can have a + b ~= c but not a ~= c - b
>
> should 0.0000001 ~= 0.00000011
>
> To properly handle this sort of thing you need that tolerance parameter,
> but the values you give should be carefully though about for THAT
> comparison, having a 'global' value is apt to lead to laziness and wrong
>
>
​Both you and Antoine Pitrou made an excellent point about relying on
non-explicitly defined values for the tolerance parameters.

I've made some changes to my proof-of-concept model [1] so that it requires
the user to define the two tolerance parameters (relative and absolute) in
a way that they are accessible within the scope where the operators are
used. I also use the existing isclose() function in the math module instead
of my previous version - and use the same name for the two parameters.
Here's a sample session:

> python -m experimental
experimental console version 0.9.6. [Python version: 3.6.1]

~~> from __experimental__ import approx
~~> 0.1 + 0.2
0.30000000000000004
~~> 0.1 + 0.2 == 0.3
False
~~> # Attempt to use approximate comparison with defining tolerances
~~> 0.1 + 0.2 ~= 0.3
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'rel_tol' is not defined
~~> rel_tol = abs_tol = 1e-8
~~> 0.1 + 0.2 ~= 0.3
True
~~> 2**0.5 ~= 1.414
False
~~> abs_tol = 0.001
~~> 2**0.5 ~= 1.414
True

I would predict that most of the usage would be in some if or while
statements, rather than simple comparisons like those illustrated above.

With this change, would using these operators (as "syntactic sugar") be a

* people doing heavy numerical work and wanting code as readable as possible
* teaching mostly beginners about finite precision for floating point
arithmetics
* people wishing to have trigonometric functions with arguments in degrees,
as in a current discussion on this forum.

[1] available on github as mentioned previously or using "pip install
experimental

​André Roberge

> --
> Richard Damon
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180615/b7056322/attachment-0001.html>
```