[Scipy-svn] r7121 - trunk/scipy/optimize/tests

scipy-svn at scipy.org scipy-svn at scipy.org
Wed Feb 2 16:44:08 EST 2011


Author: ptvirtan
Date: 2011-02-02 15:44:07 -0600 (Wed, 02 Feb 2011)
New Revision: 7121

Modified:
   trunk/scipy/optimize/tests/test_linesearch.py
   trunk/scipy/optimize/tests/test_optimize.py
Log:
TST: optimize: add some leeway for additional FP rounding error

For instance, if arrays happen to be not aligned on 16-byte boundaries
when using MKL, this produces additional (insignificant) rounding error.
The tests should allow for this.

Modified: trunk/scipy/optimize/tests/test_linesearch.py
===================================================================
--- trunk/scipy/optimize/tests/test_linesearch.py	2011-02-02 17:47:10 UTC (rev 7120)
+++ trunk/scipy/optimize/tests/test_linesearch.py	2011-02-02 21:44:07 UTC (rev 7121)
@@ -2,7 +2,8 @@
 Tests for line search routines
 """
 
-from numpy.testing import assert_, assert_equal, assert_array_almost_equal
+from numpy.testing import assert_, assert_equal, \
+     assert_array_almost_equal, assert_array_almost_equal_nulp
 import scipy.optimize.linesearch as ls
 import numpy as np
 
@@ -36,6 +37,12 @@
 def assert_line_armijo(x, p, s, f, **kw):
     assert_armijo(s, phi=lambda sp: f(x + p*sp), **kw)
 
+def assert_fp_equal(x, y, err_msg="", nulp=50):
+    """Assert two arrays are equal, up to some floating-point rounding error"""
+    try:
+        assert_array_almost_equal_nulp(x, y, nulp)
+    except AssertionError, e:
+        raise AssertionError("%s\n%s" % (e, err_msg))
 
 class TestLineSearch(object):
     # -- scalar functions; must have dphi(0.) < 0
@@ -123,8 +130,8 @@
             c += 1
             s, phi1, phi0 = ls.scalar_search_wolfe1(phi, derphi, phi(0),
                                                     old_phi0, derphi(0))
-            assert_equal(phi0, phi(0), name)
-            assert_equal(phi1, phi(s), name)
+            assert_fp_equal(phi0, phi(0), name)
+            assert_fp_equal(phi1, phi(s), name)
             assert_wolfe(s, phi, derphi, err_msg=name)
 
         assert_(c > 3) # check that the iterator really works...
@@ -133,16 +140,16 @@
         for name, phi, derphi, old_phi0 in self.scalar_iter():
             s, phi1, phi0, derphi1 = ls.scalar_search_wolfe2(
                 phi, derphi, phi(0), old_phi0, derphi(0))
-            assert_equal(phi0, phi(0), name)
-            assert_equal(phi1, phi(s), name)
+            assert_fp_equal(phi0, phi(0), name)
+            assert_fp_equal(phi1, phi(s), name)
             if derphi1 is not None:
-                assert_equal(derphi1, derphi(s), name)
+                assert_fp_equal(derphi1, derphi(s), name)
             assert_wolfe(s, phi, derphi, err_msg="%s %g" % (name, old_phi0))
 
     def test_scalar_search_armijo(self):
         for name, phi, derphi, old_phi0 in self.scalar_iter():
             s, phi1 = ls.scalar_search_armijo(phi, phi(0), derphi(0))
-            assert_equal(phi1, phi(s), name)
+            assert_fp_equal(phi1, phi(s), name)
             assert_armijo(s, phi, err_msg="%s %g" % (name, old_phi0))
 
     # -- Generic line searches
@@ -158,10 +165,10 @@
                                                            g0, f0, old_f,
                                                            amax=smax)
             assert_equal(self.fcount, fc+gc)
-            assert_equal(ofv, f(x))
+            assert_fp_equal(ofv, f(x))
             if s is None:
                 continue
-            assert_equal(fv, f(x + s*p))
+            assert_fp_equal(fv, f(x + s*p))
             assert_array_almost_equal(gv, fprime(x + s*p), decimal=14)
             if s < smax:
                 c += 1
@@ -180,8 +187,8 @@
                                                            g0, f0, old_f,
                                                            amax=smax)
             assert_equal(self.fcount, fc+gc)
-            assert_equal(ofv, f(x))
-            assert_equal(fv, f(x + s*p))
+            assert_fp_equal(ofv, f(x))
+            assert_fp_equal(fv, f(x + s*p))
             if gv is not None:
                 assert_array_almost_equal(gv, fprime(x + s*p), decimal=14)
             if s < smax:
@@ -198,7 +205,7 @@
             s, fc, fv = ls.line_search_armijo(f, x, p, g0, f0)
             c += 1
             assert_equal(self.fcount, fc)
-            assert_equal(fv, f(x + s*p))
+            assert_fp_equal(fv, f(x + s*p))
             assert_line_armijo(x, p, s, f, err_msg=name)
         assert_(c >= 9)
 

Modified: trunk/scipy/optimize/tests/test_optimize.py
===================================================================
--- trunk/scipy/optimize/tests/test_optimize.py	2011-02-02 17:47:10 UTC (rev 7120)
+++ trunk/scipy/optimize/tests/test_optimize.py	2011-02-02 21:44:07 UTC (rev 7121)
@@ -120,7 +120,14 @@
 
         # Ensure that function call counts are 'known good'; these are from
         # Scipy 0.7.0. Don't allow them to increase.
-        assert_(self.funccalls == 116, self.funccalls)
+        #
+        # However, some leeway must be added: the exact evaluation
+        # count is sensitive to numerical error, and floating-point
+        # computations are not bit-for-bit reproducible across
+        # machines, and when using e.g. MKL, data alignment
+        # etc. affect the rounding error.
+        #
+        assert_(self.funccalls <= 116 + 20, self.funccalls)
         assert_(self.gradcalls == 0, self.gradcalls)
 
         # Ensure that the function behaves the same; this is from Scipy 0.7.0




More information about the Scipy-svn mailing list