If you have a list of matrices, you can apply a dot multiplication to all the matrices by changing the Head
of the list to Dot
. To illustrate this, I'll first define a set of matrices symbolically:
matrixList = With[{numberOfMatrices = 2},
Table[Array[Subsuperscript["M", Row[{#1, #2}], i] &, {2, 2}], {i,
numberOfMatrices}]
]
$\left\{\left( \begin{array}{cc} \text{M}_{11}^1 & \text{M}_{12}^1 \\ \text{M}_{21}^1 & \text{M}_{22}^1 \\ \end{array} \right),\left( \begin{array}{cc} \text{M}_{11}^2 & \text{M}_{12}^2 \\ \text{M}_{21}^2 & \text{M}_{22}^2 \\ \end{array} \right)\right\}$
This contains just two matrices for display reasons, but you can change numberOfMatrices
to anything you like.
Now the answer to your question is just:
Apply[Dot, matrixList]
$\left( \begin{array}{cc} \text{M}_{11}^1 \text{M}_{11}^2+\text{M}_{12}^1 \text{M}_{21}^2 & \text{M}_{11}^1 \text{M}_{12}^2+\text{M}_{12}^1 \text{M}_{22}^2 \\ \text{M}_{11}^2 \text{M}_{21}^1+\text{M}_{21}^2 \text{M}_{22}^1 & \text{M}_{12}^2 \text{M}_{21}^1+\text{M}_{22}^1 \text{M}_{22}^2 \\ \end{array} \right)$
Edit
I noticed that there is a significant speedup over the above method, and also over the equivalent approach using Fold
mentioned by J.M., if I partition the list of matrices beforehand and do the dot products in two steps:
With[{numberOfMatrices = 17},
matrixList1 = RandomReal[{-100, 100}, {numberOfMatrices, 2, 2}];
matrixList =
Table[Array[Subsuperscript["M", Row[{#1, #2}], i] &, {2, 2}], {i,
numberOfMatrices}]];
comparisonRule = Thread[Flatten[matrixList] -> Flatten[matrixList1]];
AbsoluteTiming[res1 = Apply[Dot, matrixList];]
(* ==> {0.060968, Null} *)
AbsoluteTiming[
res2 = Apply[Dot, Dot @@@ Partition[matrixList, UpTo[4]]];]
(* ==> {0.00059, Null} *)
(res1 /. comparisonRule) == (res2 /. comparisonRule)
(* ==> True *)
The speed gain is more dramatic for larger lists of matrices, and one may have to play with the partition size. I used the command UpTo
in Partition
to allow the remainder partition to be of variable size.
If you want to test this for larger lists, I suggest omitting the test on the last line because it will be very slow (I already tried to speed it up by using random numbers in place of the symbolic matrix elements).
The original idea was to use ParallelMap
on the partition, but the overhead due to parallelization eats up the speed gain with the tested example.