I have a problem which requires taking product of two $10\times10$ matrices. I would like to do it by considering both matrices as $5\times5$ matrices such that each entry of both matrices is actually a $2\times2$ matrix; moreover, there are variables so this is a symbolic calculation. (Side remark: matrix multiplication is not a commutative operation, i.e. $AB\neq BA$ in general.) Does anyone know how to perform this block form multiplication in Mathematica, or using any other software?
2 Answers
If I understand correctly, the main issue in your question is how to make a Dot
product of two block matrices such that the result preserves the order of the factors in the resulting block matrix, because the entries are non-commuting matrices themselves.
The problem is that the result of Dot
has multiplications of the matrix components in it, and this corresponds to the operation Times
which is orderless. Dot
preserves the order of its factors, but Times
always sorts its factors lexicographically, i.e., in a standard sorting order so that z*b
becomes b*z
and m[2]*m[1]
becomes m[1]*m[2]
, etc.
If one were to use the Dot
function for the matrix multiplication, one would have to track in what way the order of the input factors is changed when brought into the lexicographical order of Times
, and then undo that sorting.
Edit
As Mr. Wizard pointed out, it is best to us a generalization of Dot
that doesn't apply Times
to the components at all:
blockMultiply[mats__] := Inner[Dot, mats]
End edit
To show how this works, let's first define two $5\times 5$ matrices called smallMatrix[[1]]
and smallMatrix[[2]]
. I define them in one go, and show them afterwards:
smallMatrix = Table[Array[{"A", "B"}[[i]], {5, 5}], {i, 2}];
MatrixForm[smallMatrix[[1]]]
$\left( \begin{array}{ccccc} \text{A}(1,1) & \text{A}(1,2) & \text{A}(1,3) & \text{A}(1,4) & \text{A}(1,5) \\ \text{A}(2,1) & \text{A}(2,2) & \text{A}(2,3) & \text{A}(2,4) & \text{A}(2,5) \\ \text{A}(3,1) & \text{A}(3,2) & \text{A}(3,3) & \text{A}(3,4) & \text{A}(3,5) \\ \text{A}(4,1) & \text{A}(4,2) & \text{A}(4,3) & \text{A}(4,4) & \text{A}(4,5) \\ \text{A}(5,1) & \text{A}(5,2) & \text{A}(5,3) & \text{A}(5,4) & \text{A}(5,5) \\ \end{array} \right)$
MatrixForm[smallMatrix[[2]]]
$\left( \begin{array}{ccccc} \text{B}(1,1) & \text{B}(1,2) & \text{B}(1,3) & \text{B}(1,4) & \text{B}(1,5) \\ \text{B}(2,1) & \text{B}(2,2) & \text{B}(2,3) & \text{B}(2,4) & \text{B}(2,5) \\ \text{B}(3,1) & \text{B}(3,2) & \text{B}(3,3) & \text{B}(3,4) & \text{B}(3,5) \\ \text{B}(4,1) & \text{B}(4,2) & \text{B}(4,3) & \text{B}(4,4) & \text{B}(4,5) \\ \text{B}(5,1) & \text{B}(5,2) & \text{B}(5,3) & \text{B}(5,4) & \text{B}(5,5) \\ \end{array} \right)$
Now I multiply these matrices under the assumption that each of their entries is itself a (so far unspecified) matrix:
productAB = blockMultiply[smallMatrix[[1]], smallMatrix[[2]]];
productBA = blockMultiply[smallMatrix[[2]], smallMatrix[[1]]];
If you inspect these result matrices you'll see that the order of the factors is correct, and each element is a sum of (matrix) Dot
products. The results are too large to display here.
Another way to check that this works is to insert an actual pair of $10\times 10$ matrices by writing them as block matrices. I first define the big two-dimensional matrices and then use Partition
to subdivide them into blocks of size $2\times 2$:
bigMatrix = Table[Array[{"a", "b"}[[i]], {10, 10}], {i, 2}];
blockMatrix = Table[Partition[bigMatrix[[i]], {2, 2}], {i, 2}];
MatrixForm[blockMatrix[[1]]]
and similarly for MatrixForm[blockMatrix[[2]]]
.
Now we use these big matrices in the results obtained above with blockMultiply
:
AB = Flatten[
productAB /. Thread[
Flatten[smallMatrix] -> Flatten[blockMatrix, {{1, 2, 3}}]
],
{{1, 3}, {2, 4}}];
BA = Flatten[
productBA /. Thread[
Flatten[smallMatrix] -> Flatten[blockMatrix, {{1, 2, 3}}]
],
{{1, 3}, {2, 4}}];
FullSimplify[AB == bigMatrix[[1]].bigMatrix[[2]]]
(* ==> True *)
FullSimplify[BA == bigMatrix[[2]].bigMatrix[[1]]]
(* ==> True *)
This says that the block multiplications yield the same result as doing the matrix products directly (as in bigMatrix[[1]].bigMatrix[[2]]
). And the order of the multiplications is correctly captured.
The Flatten
commands appearing in the definition of AB
and BA
(for the two different orders of the factors) are perhaps a little hard to see through. With a command like Flatten[blockMatrix, {{1, 2, 3}}]
one gets a list in which the sub-blocks of the blockMatrix
appear flattened, so that they can be used in the Thread
of the ->
which replaces the small symbolic block matrices by the blocks of the big matrix. The Flatten[ ..., {{1, 3}, {2, 4}}]
removes the block matrix level and creates a $10\times 10$ matrix from the $2\times 2$ blocks.
The function blockMultiply
is intended to work for any number of arguments in a matrix multiplication, and also for any dimension as long as all adjacent factor share a common dimension as required by Dot
. So you could also repeat the above tests by splitting up the two matrices in bigMatrix
into $5\times 5$ blocks, for example.
-
$\begingroup$ Jens, why not
{a, b} = Table[Array[{"A", "B"}[[i]], {5, 5}], {i, 2}]; Inner[Dot, a, b]
? $\endgroup$ Commented Jul 5, 2012 at 7:02 -
$\begingroup$ @Mr.Wizard Because of the lateness of the hour, I guess. Thanks for the simplificiation! $\endgroup$– JensCommented Jul 5, 2012 at 7:19
-
1$\begingroup$ Thanks for the credit in the edit. IMHO it would be better to leave out the long
blockMultiply
code as I don't think it is instructive. $\endgroup$ Commented Jul 5, 2012 at 7:34 -
1$\begingroup$ @Mr.Wizard You're right - all those fireworks messed with my brain. $\endgroup$– JensCommented Jul 5, 2012 at 14:33
-
1$\begingroup$ the Pyrotechnic Mitigation Plea -- granted. ;^) $\endgroup$ Commented Jul 5, 2012 at 14:44
You are talking about tensors, right? Such a tensor can be created with e.g.
example=Array[e,{5,5,2,2}];
example//MatrixForm
All you have to do now, is to take from the example e[1,1,1,1]
etc. and replace it with the variables you want to use. The same can be done with a second exampleTensor, so that you can work with both of them (multiply etc.).
I hope this helps.
-
$\begingroup$ Sorry that my post is ambiguous. This is not about tensor - tensor of two $10\times 10$ matrices would be a $100\times 100$ matrix. What I meant was as Jens pointed out in his first two paragraphs. $\endgroup$– DannyCommented Jul 5, 2012 at 16:48
-
$\begingroup$ No problem! Thanks for the feedback! $\endgroup$ Commented Jul 5, 2012 at 18:49
$
and$$
to provide block style equations. If you have any questions about the operation of this site, please check out the FAQ, and the meta site. $\endgroup$