Repository: sympy/sympy (Python)

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:
It started not working after #16164, after it does not catch attributeerror.
But besides, I don't think there was a proper handler before.

It happens because transpose applied to scalar makes `is_Matrix==True`.

I'm not sure that transposition for scalar can return itself, because I didn't find the definition for transpose applied for a single scalar (and a scalar is not a 1*1 matrix)
https://en.wikipedia.org/wiki/Transpose
but transposition for scalar-matrix multiplication is defined.

I have worked on changes to fix the example 
```python
        coeff, matrices = self.as_coeff_matrices()
        return MatMul(
            coeff, *[transpose(arg) for arg in matrices[::-1]]).doit()
```



Patch:
diff --git a/sympy/matrices/expressions/matmul.py b/sympy/matrices/expressions/matmul.py
index 45d0c7b943b7..6e97c2d36ab8 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 20fcafc7761e..65b50d63b562 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 27f6d37d8760..27636d1bba00 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