Repository: scipy/scipy

Issue:
scale argument of entropy doesn't broadcast
## >= 2-d scale
### Reproducing code example:
```
>>> import numpy as np; from scipy import stats
>>> stats.beta(a=1, b=1, loc=0, scale=np.array([[1, 2], [3, 4]])).entropy()
```

### Error message:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/tos/py/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py", line 499, in entropy
    return self.dist.entropy(*self.args, **self.kwds)
  File "/Users/tos/py/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py", line 1119, in entropy
    place(output, cond0, self.vecentropy(*goodargs) + log(scale))
ValueError: operands could not be broadcast together with shapes (4,) (2,2)
```

## bad scale
### Reproducing code example:
```
>>> import numpy as np; from scipy import stats
>>> stats.beta(a=1, b=1, loc=0, scale=np.array([1, 2, -3])).entropy()
```

### Error message:
```
/Users/tos/py/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1119: RuntimeWarning: invalid value encountered in log
  place(output, cond0, self.vecentropy(*goodargs) + log(scale))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/tos/py/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py", line 499, in entropy
    return self.dist.entropy(*self.args, **self.kwds)
  File "/Users/tos/py/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py", line 1119, in entropy
    place(output, cond0, self.vecentropy(*goodargs) + log(scale))
ValueError: operands could not be broadcast together with shapes (2,) (3,)
```

### Scipy/Numpy/Python version information:
```
>>> import sys, scipy, numpy; print(scipy.__version__, numpy.__version__, sys.version_info)
1.1.0 1.14.5 sys.version_info(major=3, minor=6, micro=5, releaselevel='final', serial=0)
```



Discussion:

Resolving patch:
diff --git a/scipy/stats/_distn_infrastructure.py b/scipy/stats/_distn_infrastructure.py
--- a/scipy/stats/_distn_infrastructure.py
+++ b/scipy/stats/_distn_infrastructure.py
@@ -1109,12 +1109,15 @@ def entropy(self, *args, **kwds):
         """
         args, loc, scale = self._parse_args(*args, **kwds)
         # NB: for discrete distributions scale=1 by construction in _parse_args
+        loc, scale = map(asarray, (loc, scale))
         args = tuple(map(asarray, args))
         cond0 = self._argcheck(*args) & (scale > 0) & (loc == loc)
         output = zeros(shape(cond0), 'd')
         place(output, (1-cond0), self.badvalue)
-        goodargs = argsreduce(cond0, *args)
-        place(output, cond0, self.vecentropy(*goodargs) + log(scale))
+        goodargs = argsreduce(cond0, scale, *args)
+        goodscale = goodargs[0]
+        goodargs = goodargs[1:]
+        place(output, cond0, self.vecentropy(*goodargs) + log(goodscale))
         return output
 
     def moment(self, n, *args, **kwds):


Test patch:
diff --git a/scipy/stats/tests/common_tests.py b/scipy/stats/tests/common_tests.py
--- a/scipy/stats/tests/common_tests.py
+++ b/scipy/stats/tests/common_tests.py
@@ -102,6 +102,22 @@ def check_private_entropy(distfn, args, superclass):
                         superclass._entropy(distfn, *args))
 
 
+def check_entropy_vect_scale(distfn, arg):
+    # check 2-d
+    sc = np.asarray([[1, 2], [3, 4]])
+    v_ent = distfn.entropy(*arg, scale=sc)
+    s_ent = [distfn.entropy(*arg, scale=s) for s in sc.ravel()]
+    s_ent = np.asarray(s_ent).reshape(v_ent.shape)
+    assert_allclose(v_ent, s_ent, atol=1e-14)
+
+    # check invalid value, check cast
+    sc = [1, 2, -3]
+    v_ent = distfn.entropy(*arg, scale=sc)
+    s_ent = [distfn.entropy(*arg, scale=s) for s in sc]
+    s_ent = np.asarray(s_ent).reshape(v_ent.shape)
+    assert_allclose(v_ent, s_ent, atol=1e-14)
+
+
 def check_edge_support(distfn, args):
     # Make sure that x=self.a and self.b are handled correctly.
     x = [distfn.a, distfn.b]
diff --git a/scipy/stats/tests/test_continuous_basic.py b/scipy/stats/tests/test_continuous_basic.py
--- a/scipy/stats/tests/test_continuous_basic.py
+++ b/scipy/stats/tests/test_continuous_basic.py
@@ -12,7 +12,7 @@
 from. common_tests import (check_normalization, check_moment, check_mean_expect,
                            check_var_expect, check_skew_expect,
                            check_kurt_expect, check_entropy,
-                           check_private_entropy,
+                           check_private_entropy, check_entropy_vect_scale,
                            check_edge_support, check_named_args,
                            check_random_state_property,
                            check_meth_dtype, check_ppf_dtype, check_cmplx_deriv,
@@ -145,6 +145,8 @@ def test_cont_basic(distname, arg):
                 and distname != 'vonmises'):
             check_private_entropy(distfn, arg, stats.rv_continuous)
 
+        check_entropy_vect_scale(distfn, arg)
+
         check_edge_support(distfn, arg)
 
         check_meth_dtype(distfn, arg, meths)