Repository: scipy/scipy

Issue:
sparse.linalg.expm of an empty matrix
Computing the matrix exponential of an empty matrix raises a ValueError exception.

#### Reproducing code example:

```
 scipy.linalg.expm(np.zeros((0, 0)))
```

#### Error message:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/linalg/matfuncs.py", line 256, in expm
    return scipy.sparse.linalg.expm(A)
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 606, in expm
    return _expm(A, use_exact_onenorm='auto')
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 647, in _expm
    eta_1 = max(h.d4_loose, h.d6_loose)
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 458, in d4_loose
    return self.d4_tight
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 434, in d4_tight
    self._d4_exact = _onenorm(self.A4)**(1/4.)
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 407, in A4
    self.A2, self.A2, structure=self.structure)
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 400, in A2
    self.A, self.A, structure=self.structure)
  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.7/site-packages/scipy/sparse/linalg/matfuncs.py", line 178, in _smart_matrix_product
    out = f(alpha, A, B)
ValueError: On entry to DTRMM parameter number 9 had an illegal value
```

#### Scipy/Numpy/Python version information:

1.3.1 1.17.2 sys.version_info(major=3, minor=7, micro=4, releaselevel='final', serial=0)



Discussion:

Resolving patch:
diff --git a/scipy/sparse/linalg/matfuncs.py b/scipy/sparse/linalg/matfuncs.py
--- a/scipy/sparse/linalg/matfuncs.py
+++ b/scipy/sparse/linalg/matfuncs.py
@@ -605,6 +605,14 @@ def _expm(A, use_exact_onenorm):
     if len(A.shape) != 2 or A.shape[0] != A.shape[1]:
         raise ValueError('expected a square matrix')
 
+    # gracefully handle size-0 input,
+    # carefully handling sparse scenario
+    if A.shape == (0, 0):
+        out = np.zeros([0, 0], dtype=A.dtype)
+        if isspmatrix(A) or is_pydata_spmatrix(A):
+            return A.__class__(out)
+        return out
+
     # Trivial case
     if A.shape == (1, 1):
         out = [[np.exp(A[0, 0])]]


Test patch:
diff --git a/scipy/linalg/tests/test_matfuncs.py b/scipy/linalg/tests/test_matfuncs.py
--- a/scipy/linalg/tests/test_matfuncs.py
+++ b/scipy/linalg/tests/test_matfuncs.py
@@ -629,6 +629,12 @@ def test_single_elt(self):
         assert_allclose(outTwo[0, 0], complex(-0.52896401032626006,
                                               -0.84864425749518878))
 
+    def test_empty_matrix_input(self):
+        # handle gh-11082
+        A = np.zeros((0, 0))
+        result = expm(A)
+        assert result.size == 0
+
 
 class TestExpmFrechet(object):