Repository: scipy/scipy

Issue:
macOS test failues for test_solve_continuous_are
Failures on the newly completing daily builds:

```
======================================================================
FAIL: test_solvers.test_solve_continuous_are((array([[  0.00000000e+00,   1.00000000e+00,   0.00000000e+00,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/scipy/linalg/tests/test_solvers.py", line 293, in _test_factory
    assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/numpy/testing/utils.py", line 811, in assert_array_almost_equal
    header=('Arrays are not almost equal to %d decimals' % decimal))
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/numpy/testing/utils.py", line 644, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not almost equal to 14 decimals

(mismatch 6.25%)
 x: array([[ -6.66133815e-15,  -9.32587341e-15,  -1.33226763e-15,
         -4.88498131e-15],
       [ -9.32587341e-15,  -1.19904087e-14,  -3.55271368e-15,...
 y: array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

======================================================================
FAIL: test_solvers.test_solve_continuous_are((array([[  0.00000000e+00,   4.00000000e-01,   0.00000000e+00,
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/scipy/linalg/tests/test_solvers.py", line 293, in _test_factory
    assert_array_almost_equal(res, np.zeros_like(res), decimal=dec)
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/numpy/testing/utils.py", line 811, in assert_array_almost_equal
    header=('Arrays are not almost equal to %d decimals' % decimal))
  File "/Users/travis/build/MacPython/scipy-wheels/venv/lib/python2.7/site-packages/numpy/testing/utils.py", line 644, in assert_array_compare
    raise AssertionError(msg)
AssertionError: 
Arrays are not almost equal to 10 decimals

(mismatch 6.25%)
 x: array([[  2.01543449e-10,   7.12108150e-11,   5.43845524e-12,
          2.44526344e-11],
       [  7.12108150e-11,   1.14477317e-11,  -1.07208686e-12,...
 y: array([[ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])
```

https://api.travis-ci.org/jobs/205184824/log.txt?deansi=true

It looks like these could be fixed by relaxing the test thresholds to 13 decimals and 9 decimals respectively, but are these acceptable?



Discussion:
@ilayn comments?
Yes, they are perfectly acceptable. Thank you for discovering these. We simply used a rough guesstimate (extra two orders of magnitude play) about the precision confirmed by Travis setup back then. 

But things are getting modified constantly, hence we relax the precision along the way. I'll make a PR asap. 

Resolving patch:
diff --git a/scipy/spatial/distance.py b/scipy/spatial/distance.py
--- a/scipy/spatial/distance.py
+++ b/scipy/spatial/distance.py
@@ -2115,6 +2115,9 @@ def cdist(XA, XB, metric='euclidean', p=None, V=None, VI=None, w=None):
     # between all pairs of vectors in XA and XB using the distance metric 'abc'
     # but with a more succinct, verifiable, but less efficient implementation.
 
+    # Store input arguments to check whether we can modify later.
+    input_XA, input_XB = XA, XB
+
     XA = np.asarray(XA, order='c')
     XB = np.asarray(XB, order='c')
 
@@ -2242,6 +2245,8 @@ def cdist(XA, XB, metric='euclidean', p=None, V=None, VI=None, w=None):
         elif mstr in ['correlation', 'co']:
             XA = _convert_to_double(XA)
             XB = _convert_to_double(XB)
+            XA = XA.copy() if XA is input_XA else XA
+            XB = XB.copy() if XB is input_XB else XB
             XA -= XA.mean(axis=1)[:, np.newaxis]
             XB -= XB.mean(axis=1)[:, np.newaxis]
             _cosine_cdist(XA, XB, dm)


Test patch:
diff --git a/scipy/linalg/tests/test_decomp.py b/scipy/linalg/tests/test_decomp.py
--- a/scipy/linalg/tests/test_decomp.py
+++ b/scipy/linalg/tests/test_decomp.py
@@ -225,7 +225,8 @@ def _check_gen_eig(self, A, B):
 
         perm = np.lexsort(w)
         permt = np.lexsort(wt)
-        assert_allclose(w[:,perm], wt[:,permt], err_msg=msg)
+        assert_allclose(w[:,perm], wt[:,permt], atol=1e-7, rtol=1e-7,
+                        err_msg=msg)
 
         length = np.empty(len(vr))
         for i in xrange(len(vr)):
@@ -247,7 +248,8 @@ def _check_gen_eig(self, A, B):
             if all(isfinite(res[:,i])):
                 assert_allclose(res[:,i], 0, rtol=1e-13, atol=1e-13, err_msg=msg)
 
-        assert_allclose(sort(w[isfinite(w)]), sort(wt[isfinite(wt)]), err_msg=msg)
+        assert_allclose(sort(w[isfinite(w)]), sort(wt[isfinite(wt)]),
+                        atol=1e-7, rtol=1e-7, err_msg=msg)
 
         length = np.empty(len(vr))
         for i in xrange(len(vr)):
@@ -2119,7 +2121,7 @@ def qz_decomp(self, sort):
             ret = [ordqz(Ai, Bi, sort=sort) for Ai, Bi in zip(self.A, self.B)]
         finally:
             np.seterr(**olderr)
-            
+
         return tuple(ret)
 
     def check(self, A, B, sort, AA, BB, alpha, beta, Q, Z):
diff --git a/scipy/linalg/tests/test_solvers.py b/scipy/linalg/tests/test_solvers.py
--- a/scipy/linalg/tests/test_solvers.py
+++ b/scipy/linalg/tests/test_solvers.py
@@ -277,8 +277,8 @@ def test_solve_continuous_are():
     #
     # If the test is failing use "None" for that entry.
     #
-    min_decimal = (14, 12, 14, 14, 11, 6, None, 5, 7, 14, 14,
-                   None, 10, 14, 13, 14, None, 12, None, None)
+    min_decimal = (14, 12, 13, 14, 11, 6, None, 5, 7, 14, 14,
+                   None, 9, 14, 13, 14, None, 12, None, None)
 
     def _test_factory(case, dec):
         """Checks if 0 = XA + A'X - XB(R)^{-1} B'X + Q is true"""
diff --git a/scipy/spatial/tests/test_distance.py b/scipy/spatial/tests/test_distance.py
--- a/scipy/spatial/tests/test_distance.py
+++ b/scipy/spatial/tests/test_distance.py
@@ -1523,6 +1523,20 @@ def test_sokalmichener():
     assert_equal(dist1, dist2)
 
 
+def test_modifies_input():
+    # test whether cdist or pdist modifies input arrays
+    X1 = np.asarray([[1., 2., 3.],
+                     [1.2, 2.3, 3.4],
+                     [2.2, 2.3, 4.4],
+                     [22.2, 23.3, 44.4]])
+    X1_copy = X1.copy()
+    for metric in _METRICS_NAMES:
+        kwargs = {"w": 1.0 / X1.std(axis=0)} if metric == "wminkowski" else {}
+        cdist(X1, X1, metric, **kwargs)
+        pdist(X1, metric, **kwargs)
+        assert_array_equal(X1, X1_copy)
+
+
 def test_Xdist_deprecated_args():
     # testing both cdist and pdist deprecated warnings
     X1 = np.asarray([[1., 2., 3.],