
Hi, I was always using something like abs(x-y) < eps or (abs(x-y) < eps).all() but today I needed to also make sure this works for larger numbers, where I need to compare relative errors, so I found this: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm and wrote this: def feq(a, b, max_relative_error=1e-12, max_absolute_error=1e-12): a = float(a) b = float(b) # if the numbers are close enough (absolutely), then they are equal if abs(a-b) < max_absolute_error: return True # if not, they can still be equal if their relative error is small if abs(b) > abs(a): relative_error = abs((a-b)/b) else: relative_error = abs((a-b)/a) return relative_error <= max_relative_error Is there any function in numpy, that implements this? Or maybe even the better, integer based version, as referenced in the link above? I need this in tests, where I calculate something on some mesh, then compare to the correct solution projected on some other mesh, so I have to deal with accuracy issues. Ondrej

On Mon, Jul 19, 2010 at 6:31 PM, Ondrej Certik <ondrej@certik.cz> wrote:
Hi,
I was always using something like
abs(x-y) < eps
or
(abs(x-y) < eps).all()
but today I needed to also make sure this works for larger numbers, where I need to compare relative errors, so I found this:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
and wrote this:
def feq(a, b, max_relative_error=1e-12, max_absolute_error=1e-12): a = float(a) b = float(b) # if the numbers are close enough (absolutely), then they are equal if abs(a-b) < max_absolute_error: return True # if not, they can still be equal if their relative error is small if abs(b) > abs(a): relative_error = abs((a-b)/b) else: relative_error = abs((a-b)/a) return relative_error <= max_relative_error
Is there any function in numpy, that implements this? Or maybe even the better, integer based version, as referenced in the link above?
I need this in tests, where I calculate something on some mesh, then compare to the correct solution projected on some other mesh, so I have to deal with accuracy issues.
Is allclose close enough? np.allclose(a, b, rtol=1.0000000000000001e-05, atol=1e-08) Returns True if two arrays are element-wise equal within a tolerance. The tolerance values are positive, typically very small numbers. The relative difference (`rtol` * abs(`b`)) and the absolute difference `atol` are added together to compare against the absolute difference between `a` and `b`.

Hi Keith! On Mon, Jul 19, 2010 at 6:40 PM, Keith Goodman <kwgoodman@gmail.com> wrote:
On Mon, Jul 19, 2010 at 6:31 PM, Ondrej Certik <ondrej@certik.cz> wrote:
Hi,
I was always using something like
abs(x-y) < eps
or
(abs(x-y) < eps).all()
but today I needed to also make sure this works for larger numbers, where I need to compare relative errors, so I found this:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
and wrote this:
def feq(a, b, max_relative_error=1e-12, max_absolute_error=1e-12): a = float(a) b = float(b) # if the numbers are close enough (absolutely), then they are equal if abs(a-b) < max_absolute_error: return True # if not, they can still be equal if their relative error is small if abs(b) > abs(a): relative_error = abs((a-b)/b) else: relative_error = abs((a-b)/a) return relative_error <= max_relative_error
Is there any function in numpy, that implements this? Or maybe even the better, integer based version, as referenced in the link above?
I need this in tests, where I calculate something on some mesh, then compare to the correct solution projected on some other mesh, so I have to deal with accuracy issues.
Is allclose close enough?
np.allclose(a, b, rtol=1.0000000000000001e-05, atol=1e-08)
Returns True if two arrays are element-wise equal within a tolerance.
The tolerance values are positive, typically very small numbers. The relative difference (`rtol` * abs(`b`)) and the absolute difference `atol` are added together to compare against the absolute difference between `a` and `b`.
thanks for this. This should do the job. I'll give it a shot and report back. Ondrej

On Tue, Jul 20, 2010 at 3:31 AM, Ondrej Certik <ondrej@certik.cz> wrote:
Hi,
I was always using something like
abs(x-y) < eps
or
(abs(x-y) < eps).all()
but today I needed to also make sure this works for larger numbers, where I need to compare relative errors, so I found this:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
Actually, there is better, as mentioned in that same page. I implemented the functions for reliable, amplitude independent floating point comparison: assert_array_max_ulp: Given two arrays a and b, check that every item differs in at most N Unit in the Last Place. assert_array_almost_equal_nulp Compare two arrays relatively to their spacing. It is a relatively robust method to compare two arrays whose amplitude is variable. Note ---- An assertion is raised if the following condition is not met: abs(x - y) <= nulps * spacing(max(abs(x), abs(y))) Parameters ---------- x: array_like first input array y: array_like second input array nulp: int max number of unit in the last place for tolerance (see Note) I think we should go toward using those almost everywhere we need floating point comparison in testing, cheers, David

ke, 2010-07-21 kello 10:46 +0200, David Cournapeau kirjoitti: [clip: assert nulps]
I think we should go toward using those almost everywhere we need floating point comparison in testing,
I think we also need an assertion function that behaves like np.allclose -- the ULPs are somewhat unintuitive to work with, and an atol/rtol combination also gets the job done, so some people might prefer that. There's `assert_tol_equal` in scipy.special tests that could just be copied to numpy.testing. Pauli
participants (4)
-
David Cournapeau
-
Keith Goodman
-
Ondrej Certik
-
Pauli Virtanen