Repository: scipy/scipy

Issue:
TST: linalg: test_decomp_cossin.py::test_cossin_separate[float64] failing on Python-debug & ATLAS CI job
See https://github.com/scipy/scipy/actions/runs/7789889662/job/21242511850?pr=20032 for example
```
FAILED ../linalg/tests/test_decomp_cossin.py::test_cossin_separate[float64] - AssertionError: 
Not equal to tolerance rtol=0, atol=2.22045e-15

Mismatched elements: 3897 / 6400 (60.9%)
Max absolute difference: 0.72137716
Max relative difference: 2.
 x: array([[ 0.107602,  0.008004,  0.163714, ..., -0.094327,  0.021723,
        -0.074046],
       [ 0.044608, -0.063854,  0.031058, ...,  0.085616, -0.000242,...
 y: array([[ 0.107602,  0.008004,  0.163714, ..., -0.094327, -0.021723,
        -0.074046],
       [ 0.044608, -0.063854,  0.031058, ...,  0.085616,  0.000242,...
= 1 failed, 45846 passed, 2493 skipped, 149 xfailed, 12 xpassed in 859.62s (0:14:19) =
```


Discussion:
Looks like a column sign flip happening again or another LAPACK change happened somewhere else.

Resolving patch:
diff --git a/scipy/linalg/_decomp_cossin.py b/scipy/linalg/_decomp_cossin.py
--- a/scipy/linalg/_decomp_cossin.py
+++ b/scipy/linalg/_decomp_cossin.py
@@ -170,7 +170,8 @@ def cossin(X, p=None, q=None, separate=False,
 
     method_name = csd.typecode + driver
     if info < 0:
-        raise ValueError(f'illegal value in argument {-info} of internal {method_name}')
+        raise ValueError(f'illegal value in argument {-info} '
+                         f'of internal {method_name}')
     if info > 0:
         raise LinAlgError(f"{method_name} did not converge: {info}")
 


Test patch:
diff --git a/scipy/linalg/tests/test_decomp_cossin.py b/scipy/linalg/tests/test_decomp_cossin.py
--- a/scipy/linalg/tests/test_decomp_cossin.py
+++ b/scipy/linalg/tests/test_decomp_cossin.py
@@ -1,6 +1,6 @@
 import pytest
 import numpy as np
-from numpy.random import seed
+from numpy.random import default_rng
 from numpy.testing import assert_allclose
 
 from scipy.linalg.lapack import _compute_lwork
@@ -28,11 +28,11 @@
                          ])
 @pytest.mark.parametrize('swap_sign', [True, False])
 def test_cossin(dtype_, m, p, q, swap_sign):
-    seed(1234)
+    rng = default_rng(1708093570726217)
     if dtype_ in COMPLEX_DTYPES:
-        x = np.array(unitary_group.rvs(m), dtype=dtype_)
+        x = np.array(unitary_group.rvs(m, random_state=rng), dtype=dtype_)
     else:
-        x = np.array(ortho_group.rvs(m), dtype=dtype_)
+        x = np.array(ortho_group.rvs(m, random_state=rng), dtype=dtype_)
 
     u, cs, vh = cossin(x, p, q,
                        swap_sign=swap_sign)
@@ -69,8 +69,8 @@ def test_cossin(dtype_, m, p, q, swap_sign):
 
 
 def test_cossin_mixed_types():
-    seed(1234)
-    x = np.array(ortho_group.rvs(4), dtype=np.float64)
+    rng = default_rng(1708093736390459)
+    x = np.array(ortho_group.rvs(4, random_state=rng), dtype=np.float64)
     u, cs, vh = cossin([x[:2, :2],
                         np.array(x[:2, 2:], dtype=np.complex128),
                         x[2:, :2],
@@ -116,6 +116,7 @@ def test_cossin_error_non_square():
     with pytest.raises(ValueError, match="only supports square"):
         cossin(np.array([[1, 2]]), 1, 1)
 
+
 def test_cossin_error_partitioning():
     x = np.array(ortho_group.rvs(4), dtype=np.float64)
     with pytest.raises(ValueError, match="invalid p=0.*0<p<4.*"):
@@ -130,14 +131,15 @@ def test_cossin_error_partitioning():
 
 @pytest.mark.parametrize("dtype_", DTYPES)
 def test_cossin_separate(dtype_):
-    seed(1234)
-    m, p, q = 250, 80, 170
+    rng = default_rng(1708093590167096)
+    m, p, q = 98, 37, 61
 
     pfx = 'or' if dtype_ in REAL_DTYPES else 'un'
-    X = ortho_group.rvs(m) if pfx == 'or' else unitary_group.rvs(m)
+    X = (ortho_group.rvs(m, random_state=rng) if pfx == 'or'
+         else unitary_group.rvs(m, random_state=rng))
     X = np.array(X, dtype=dtype_)
 
-    drv, dlw = get_lapack_funcs((pfx + 'csd', pfx + 'csd_lwork'),[X])
+    drv, dlw = get_lapack_funcs((pfx + 'csd', pfx + 'csd_lwork'), [X])
     lwval = _compute_lwork(dlw, m, p, q)
     lwvals = {'lwork': lwval} if pfx == 'or' else dict(zip(['lwork',
                                                             'lrwork'],