I am using SymPy for symbolic matrix calculations, however, certain statements are very big. It seems there is a way to simplify them further. I have used simplify() but I have not been successful in getting what I want.
For example the image below is a matrix, which has been obtained as result of execution of long list of previous matrix calculations. The output of series of matrix calculations, which requires further simplification
The final statement has two additions and one matrix multiplication. I wonder if there is any way to also execute the matrix multiplication on the right so we can simply end up with 3 matrix summations?
I understand this can be done by doing certain algebraic manipulations by hand but I am more interested in a command to execute, such that the command takes the whole statement as the input and does all the simplifications including any multiplications and additions and outputs what I need. This should all be done using sympy. In other words, if an addition or a multiplication can be done then I want it done and not being left undone.
This is MCVE, which mimics my problem
from sympy import *
init_printing()
J_22 = MatrixSymbol('J_22', 3, 3)
COV_b=Matrix([[2,1,1],[1,2,1],[1,1,2]])
(COV_b+J_22)*COV_b
The output of this code is

However, I would like to have this as the output

I understand that in this simple example I could simply fix the problem by the following code
from sympy import *
init_printing()
J_22 = MatrixSymbol('J_22', 3, 3)
COV_b=Matrix([[2,1,1],[1,2,1],[1,1,2]])
(COV_b*COV_b+J_22*COV_b)
However, this is just a simple example, in the actual problem this cannot be seen before the output is generated. Hence, I would like to be able to use a command, which takes the output of the first provided code as input and outputs the desired output.
UPDATE:@WelcometoStackOverflow provided a function, which simplifies things a lot but still leaves the matrix addition undone.
from sympy import *
init_printing()
J_22 = MatrixSymbol('J_22', 3, 3)
COV_b=Matrix([[2,1,1],[1,2,1],[1,1,2]])
T=(COV_b+J_22)*COV_b+COV_b
def expand_matmul(expr):
import itertools
for a in preorder_traversal(expr):
if isinstance(a, MatMul):
terms = [f.args if isinstance(f, MatAdd) else [f] for f in a.args]
expanded = Add(*[MatMul(*t) for t in itertools.product(*terms)])
if a != expanded:
expr = expr.xreplace({a: expanded})
return expand_matmul(expr)
return expr
expand_matmul(T)
The output is
![enter image description here[4]](https://i.stack.imgur.com/fdXct.png)
with the summation between the first two matrices still not executed.