Repository: sympy/sympy

Issue:
Transposing an expression of a matrix multiplied by a scalar raises AttributeError
Transposing an expression consisting of matrices scaled by scalar quantities raises AttributeError.

Using SymPy 1.4 leads to this error.
```python
>>> import sympy as sm
>>> sm.__version__
1.4
>>> x = sm.symbols('x')
>>> c = sm.cos(x)
>>> M = sm.MatrixSymbol('M', 3, 3)
>>> N = sm.MatrixSymbol('N', 3, 3)
>>> expr = (N  +  (c * M) )
>>> expr.T
AttributeError: 'cos' object has no attribute 'shape'
>>> sm.transpose(expr)
AttributeError: 'cos' object has no attribute 'shape'
>>> sm.Transpose(expr)
(cos(x)*M + N).T
```

While SymPy 1.3 deals with it correctly.
```python
>>> import sympy as sm
>>> sm.__version__
1.3
>>> x = sm.symbols('x')
>>> c = sm.cos(x)
>>> M = sm.MatrixSymbol('M', 3, 3)
>>> N = sm.MatrixSymbol('N', 3, 3)
>>> expr = (N  +  (c * M) )
>>> expr.T
(cos(x)*M).T + N.T
>>> sm.transpose(expr)
(cos(x)*M).T + N.T
>>> sm.Transpose(expr)
(cos(x)*M + N).T
```
For SymPy 1.4, I have to set an assumption to the x = sm.symbols('x', real=True) in order to solve correctly, which leads to undesirable effects later on in my project when trying to pickle and unpickle objects that contains sympy expressions.

Discussion:

Patch:
diff --git a/sympy/matrices/expressions/matmul.py b/sympy/matrices/expressions/matmul.py
index 45d0c7b943..6e97c2d36a 100644
--- a/sympy/matrices/expressions/matmul.py
+++ b/sympy/matrices/expressions/matmul.py
@@ -109,7 +109,27 @@ def as_coeff_mmul(self):
         return coeff, MatMul(*matrices)
 
     def _eval_transpose(self):
-        return MatMul(*[transpose(arg) for arg in self.args[::-1]]).doit()
+        """Transposition of matrix multiplication.
+
+        Notes
+        =====
+
+        The following rules are applied.
+
+        Transposition for matrix multiplied with another matrix:
+        `\\left(A B\\right)^{T} = B^{T} A^{T}`
+
+        Transposition for matrix multiplied with scalar:
+        `\\left(c A\\right)^{T} = c A^{T}`
+
+        References
+        ==========
+
+        .. [1] https://en.wikipedia.org/wiki/Transpose
+        """
+        coeff, matrices = self.as_coeff_matrices()
+        return MatMul(
+            coeff, *[transpose(arg) for arg in matrices[::-1]]).doit()
 
     def _eval_adjoint(self):
         return MatMul(*[adjoint(arg) for arg in self.args[::-1]]).doit()


Test patch:
diff --git a/sympy/matrices/expressions/tests/test_matmul.py b/sympy/matrices/expressions/tests/test_matmul.py
index 20fcafc776..65b50d63b5 100644
--- a/sympy/matrices/expressions/tests/test_matmul.py
+++ b/sympy/matrices/expressions/tests/test_matmul.py
@@ -40,6 +40,7 @@ def test_transpose():
     MT = Matrix(2, 2, [1, 3, 2 + I, 4])
     assert transpose(M) == MT
     assert transpose(2*M) == 2*MT
+    assert transpose(x*M) == x*MT
     assert transpose(MatMul(2, M)) == MatMul(2, MT).doit()
 
 
diff --git a/sympy/matrices/expressions/tests/test_transpose.py b/sympy/matrices/expressions/tests/test_transpose.py
index 27f6d37d87..27636d1bba 100644
--- a/sympy/matrices/expressions/tests/test_transpose.py
+++ b/sympy/matrices/expressions/tests/test_transpose.py
@@ -36,6 +36,17 @@ def test_transpose():
     assert Transpose(A*B).doit() == Transpose(B) * Transpose(A)
 
 
+def test_transpose_MatAdd_MatMul():
+    # Issue 16807
+    from sympy.functions.elementary.trigonometric import cos
+
+    x = symbols('x')
+    M = MatrixSymbol('M', 3, 3)
+    N = MatrixSymbol('N', 3, 3)
+
+    assert (N + (cos(x) * M)).T == cos(x)*M.T + N.T
+
+
 def test_refine():
     assert refine(C.T, Q.symmetric(C)) == C