14

What is the best way to implement a unittest that compares two numpy float arrays.

I've tried unittest.assertEqual() but didn't work for float arrays because float are never 100% equal. I can't use assertAlmostEqual because it tests the round(floats) equality ...

does anyone emplemented something like this

self.assertFloatArrayEqual(array1, array2, msg = "array are not equal")

thanks

Chris Morgan
  • 86,207
  • 24
  • 208
  • 215
Cobry
  • 4,348
  • 8
  • 33
  • 49
  • Not sure if this will help you, but for comparing floats have you tried something like the `is` keyword? – eazar001 Feb 17 '13 at 12:02
  • The answer to my question [Compare (assert equality of) two complex data structures containing numpy arrays in unittest](http://stackoverflow.com/questions/14246983/compare-assert-equality-of-two-complex-data-structures-containing-numpy-arrays) could work for you (may not really be a duplicate though). – Lev Levitsky Feb 17 '13 at 12:03
  • Using "is" is not comparing for approximate equality like requested but comparing for identity. Equality and identity are two very different beasts! – Ulrich Eckhardt Feb 17 '13 at 12:05
  • Please put some attention into writing your question title. What you had had vanishingly small quantity of meaning. If you're specific, people are much more likely to look. – Chris Morgan Feb 17 '13 at 12:28

3 Answers3

30

If you are using numpy anyway, why not use the numpy testing functions?

numpy.testing.assert_array_almost_equal

and

numpy.testing.assert_array_almost_equal_nulp

These also handles NaN's fine, check shape, etc.

seberg
  • 8,785
  • 2
  • 31
  • 30
8

Try

self.assertTrue(numpy.allclose(array1, array2, rtol=1e-05, atol=1e-08))

The allclose function from the numpy module, checks whether two arrays are the same within machine precision a given relative and absolute tolerance . rtol and atol are optional parameters with default values as given above.

Thanks to @DSM for correcting me.

Jan
  • 4,932
  • 1
  • 26
  • 30
  • 3
    "within machine precision": I hope you're not writing code assuming that! The default tolerances are `rtol=1.e-5, atol=1.e-8` in my version, and that's nowhere close to machine precision. – DSM Feb 17 '13 at 12:31
  • 1
    While I think that the unittest variant for array comparisons provides nicer output when differences are found, this is still far better than rolling one's own. – Ulrich Eckhardt Feb 17 '13 at 20:35
1

There is a version that can compare two arrays, which of course requires that numpy arrays behave properly, i.e. that they have a len() and that they allow square brackets to access elements. Now, concerning rounding errors, there is the possibility to define a delta or a range, which you could use, but I don't think this allows the use on arrays.

I'm afraid you'll have to roll your own.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55