Repository: scipy/scipy

Issue:
BUG: scipy.integrate.simps returns NaN when span of x is 0
### Describe your issue.

Obviously, this is an edge case, but I think it should be handled. Having an array for x with no span (all values are the same), integrate.simpson returns NaN and throws a couple divide by 0 errors from _quadrature. Instead, since integrating over a span of 0 is in fact 0, I think the function should return 0.

### Reproducing Code Example

```python
scipy.integrate.simpson(range(5), [0,0,0,0,0])
```


### Error message

```shell
C:\AeroApps\AnacondaP3x64-5.1.0\envs\cf310\lib\site-packages\scipy\integrate\_quadrature.py:415: RuntimeWarning: invalid value encountered in true_divide
  h0divh1 = h0 / h1
C:\AeroApps\AnacondaP3x64-5.1.0\envs\cf310\lib\site-packages\scipy\integrate\_quadrature.py:417: RuntimeWarning: invalid value encountered in true_divide
  y[slice1] * (hsum * hsum / hprod) +
Out[58]: nan
```


### SciPy/NumPy/Python version information

1.8.0 1.22.3 sys.version_info(major=3, minor=10, micro=2, releaselevel='final', serial=0)


Discussion:
I have created pull request #15800 for this issue.
@tupui could you please review it?

Resolving patch:
diff --git a/scipy/integrate/_quadrature.py b/scipy/integrate/_quadrature.py
--- a/scipy/integrate/_quadrature.py
+++ b/scipy/integrate/_quadrature.py
@@ -407,14 +407,20 @@ def _basic_simpson(y, start, stop, x, dx, axis):
         h = np.diff(x, axis=axis)
         sl0 = tupleset(slice_all, axis, slice(start, stop, step))
         sl1 = tupleset(slice_all, axis, slice(start+1, stop+1, step))
-        h0 = h[sl0]
-        h1 = h[sl1]
+        h0 = np.float64(h[sl0])
+        h1 = np.float64(h[sl1])
         hsum = h0 + h1
         hprod = h0 * h1
-        h0divh1 = h0 / h1
-        tmp = hsum/6.0 * (y[slice0] * (2 - 1.0/h0divh1) +
-                          y[slice1] * (hsum * hsum / hprod) +
-                          y[slice2] * (2 - h0divh1))
+        h0divh1 = np.true_divide(h0, h1, out=np.zeros_like(h0), where=h1 != 0)
+        tmp = hsum/6.0 * (y[slice0] *
+                          (2.0 - np.true_divide(1.0, h0divh1,
+                                                out=np.zeros_like(h0divh1),
+                                                where=h0divh1 != 0)) +
+                          y[slice1] * (hsum *
+                                       np.true_divide(hsum, hprod,
+                                                      out=np.zeros_like(hsum),
+                                                      where=hprod != 0)) +
+                          y[slice2] * (2.0 - h0divh1))
         result = np.sum(tmp, axis=axis)
     return result
 


Test patch:
diff --git a/scipy/integrate/tests/test_quadrature.py b/scipy/integrate/tests/test_quadrature.py
--- a/scipy/integrate/tests/test_quadrature.py
+++ b/scipy/integrate/tests/test_quadrature.py
@@ -153,6 +153,31 @@ def test_simpson(self):
         assert_equal(simpson(y, x=x, even='first'), 13.75)
         assert_equal(simpson(y, x=x, even='last'), 14)
 
+        # Tests for checking base case
+        x = np.array([3])
+        y = np.power(x, 2)
+        assert_equal(simpson(y, x=x, axis=0), 0.0)
+        assert_equal(simpson(y, x=x, axis=-1), 0.0)
+
+        x = np.array([3, 3, 3, 3])
+        y = np.power(x, 2)
+        assert_equal(simpson(y, x=x, axis=0), 0.0)
+        assert_equal(simpson(y, x=x, axis=-1), 0.0)
+
+        x = np.array([[1, 2, 4, 8], [1, 2, 4, 8], [1, 2, 4, 8]])
+        y = np.power(x, 2)
+        zero_axis = [0.0, 0.0, 0.0, 0.0]
+        default_axis = [175.75, 175.75, 175.75]
+        assert_equal(simpson(y, x=x, axis=0), zero_axis)
+        assert_equal(simpson(y, x=x, axis=-1), default_axis)
+
+        x = np.array([[1, 2, 4, 8], [1, 2, 4, 8], [1, 8, 16, 32]])
+        y = np.power(x, 2)
+        zero_axis = [0.0, 136.0, 1088.0, 8704.0]
+        default_axis = [175.75, 175.75, 11292.25]
+        assert_equal(simpson(y, x=x, axis=0), zero_axis)
+        assert_equal(simpson(y, x=x, axis=-1), default_axis)
+
     def test_simps(self):
         # Basic coverage test for the alias
         y = np.arange(4)