# NonCommutativeMultiply in Matrix Multiplication

Is there a way to preserve the order of elements in the multiplication of matrices when the elements themselves are matrices?

For example, if I have:

Matrix1 = {{Amat[x],Bmat[x]},{Cmat[x],Dmat[x]}};
Matrix2 = {{Amat[y],Bmat[y]},{Cmat[y],Dmat[y]}};


Where each of the Amat,Bmat,Cmat, and Dmat are all matrices dependent upon some input x or y. I can form the matrices:

Matrix3 = KroneckerProduct[Matrix1,IdentityMatrix[2]];
Matrix4 = KroneckerProduct[IdentityMatrix[2],Matrix2];


And I can take their product:

Matrix3.Matrix4


which outputs:

{{Amat[x] Amat[y], Amat[x] Bmat[y], Amat[y] Bmat[x], Bmat[x] Bmat[y]},
{Amat[x] Cmat[y], Amat[x] Dmat[y], Bmat[x] Cmat[y], Bmat[x] Dmat[y]},
{Amat[y] Cmat[x], Bmat[y] Cmat[x], Amat[y] Dmat[x], Bmat[y] Dmat[x]},
{Cmat[x] Cmat[y], Cmat[x] Dmat[y], Cmat[y] Dmat[x], Dmat[x] Dmat[y]}}


But we see that the entry in the first row of the third column is Amat[y]Bmat[x] when it should be Bmat[x]Amat[y] due to the non-commutative matrix multiplication.

The answers in Matrix multiplication of non-commuting objects and Matrix multiplication in Block Form symbolic calculation by Mathematica I believe give me what I want, but I also expected a FullSimplify to simplify 0's:

For example, using the first solution from Matrix multiplication of non-commuting objects, defining

ncdot[ten1_, ten2_] := Inner[NonCommutativeMultiply, ten1, ten2, Plus]


and applying this (and FullSimplify) to Matrix3 and Marix4 we have:

FullSimplify[ncdot[Matrix3,Matrix4]] = {{0 ** 0 + 0 ** Cmat[y] + Amat[x] ** Amat[y] + Bmat[x] ** 0,
0 ** 0 + 0 ** Dmat[y] + Amat[x] ** Bmat[y] + Bmat[x] ** 0,
0 ** 0 + 0 ** Cmat[y] + Amat[x] ** 0 + Bmat[x] ** Amat[y],
0 ** 0 + 0 ** Dmat[y] + Amat[x] ** 0 +
Bmat[x] ** Bmat[y]}, {0 ** 0 + 0 ** Amat[y] + Amat[x] ** Cmat[y] +
Bmat[x] ** 0,
0 ** 0 + 0 ** Bmat[y] + Amat[x] ** Dmat[y] + Bmat[x] ** 0,
0 ** 0 + 0 ** Amat[y] + Amat[x] ** 0 + Bmat[x] ** Cmat[y],
0 ** 0 + 0 ** Bmat[y] + Amat[x] ** 0 +
Bmat[x] ** Dmat[y]}, {0 ** 0 + 0 ** Cmat[y] + Cmat[x] ** Amat[y] +
Dmat[x] ** 0,
0 ** 0 + 0 ** Dmat[y] + Cmat[x] ** Bmat[y] + Dmat[x] ** 0,
0 ** 0 + 0 ** Cmat[y] + Cmat[x] ** 0 + Dmat[x] ** Amat[y],
0 ** 0 + 0 ** Dmat[y] + Cmat[x] ** 0 +
Dmat[x] ** Bmat[y]}, {0 ** 0 + 0 ** Amat[y] + Cmat[x] ** Cmat[y] +
Dmat[x] ** 0,
0 ** 0 + 0 ** Bmat[y] + Cmat[x] ** Dmat[y] + Dmat[x] ** 0,
0 ** 0 + 0 ** Amat[y] + Cmat[x] ** 0 + Dmat[x] ** Cmat[y],
0 ** 0 + 0 ** Bmat[y] + Cmat[x] ** 0 + Dmat[x] ** Dmat[y]}}


And similarly, from Matrix multiplication in Block Form symbolic calculation by Mathematica, defining:

blockMultiply[mats__] := Inner[Dot, mats];


and applying this (and FullSimplify) to Matrix3 and Matrix4, we see:

FullSimplify[blockMultiply[Matrix3, Matrix4]]={{0 . 0 + 0 . Cmat[y] + Amat[x] . Amat[y] + Bmat[x] . 0,
0 . 0 + 0 . Dmat[y] + Amat[x] . Bmat[y] + Bmat[x] . 0,
0 . 0 + 0 . Cmat[y] + Amat[x] . 0 + Bmat[x] . Amat[y],
0 . 0 + 0 . Dmat[y] + Amat[x] . 0 + Bmat[x] . Bmat[y]}, {0 . 0 +
0 . Amat[y] + Amat[x] . Cmat[y] + Bmat[x] . 0,
0 . 0 + 0 . Bmat[y] + Amat[x] . Dmat[y] + Bmat[x] . 0,
0 . 0 + 0 . Amat[y] + Amat[x] . 0 + Bmat[x] . Cmat[y],
0 . 0 + 0 . Bmat[y] + Amat[x] . 0 + Bmat[x] . Dmat[y]}, {0 . 0 +
0 . Cmat[y] + Cmat[x] . Amat[y] + Dmat[x] . 0,
0 . 0 + 0 . Dmat[y] + Cmat[x] . Bmat[y] + Dmat[x] . 0,
0 . 0 + 0 . Cmat[y] + Cmat[x] . 0 + Dmat[x] . Amat[y],
0 . 0 + 0 . Dmat[y] + Cmat[x] . 0 + Dmat[x] . Bmat[y]}, {0 . 0 +
0 . Amat[y] + Cmat[x] . Cmat[y] + Dmat[x] . 0,
0 . 0 + 0 . Bmat[y] + Cmat[x] . Dmat[y] + Dmat[x] . 0,
0 . 0 + 0 . Amat[y] + Cmat[x] . 0 + Dmat[x] . Cmat[y],
0 . 0 + 0 . Bmat[y] + Cmat[x] . 0 + Dmat[x] . Dmat[y]}}


Is there a way to preserve the order? Perhaps somehow using NonCommutativeMultiply, or something else?

You may add a definition to "Dot" for a zero term and use "Inner".

Unprotect[Dot];

Inner[Dot, Matrix3, Matrix4] // MatrixForm

• The problem with this that MMA expands e.g.: a Matrix1 to {{a Amat[x], a Bmat[x]}, {a Cmat[x], a Dmat[x]}}automatically. Commented Mar 4 at 17:14