Taking the product of a list of matrices

Dot@@data should do what you're looking for. It replaces the main Head, List, with Dot, which just multiplies all of the matrices—which used to comprise the List data—together.

data = Table[RandomInteger[5, {2, 2}], 5];

MatrixForm /@ data

enter image description here

Dot @@ data // MatrixForm

enter image description here


This question reminded me something I did some time ago when I was computing Lyapunov exponents of maps, i.e. discrete dynamical systems. Let me share it here.

What I needed was to compute the matrix product successively from the end (I wanted to be able to plot a convergence plot), i.e. have access to data[[5]], data[[4]].data[[5]] etc. I had $10^4$ matrices in one go and repeated it for $10^5$ realisations, so forming a Table explicitly was numerically very expensive. So I came up with this solution:

v[1] = Last[data];
v[n_] := v[n] = data[[Length[data] - (n - 1)]].v[n - 1]

which, even when Length@data is huge, gives almost instant access to any step.

While this in fact gives an answer to your question, as v[Length@data] will give the same result as Dot@@data, it is of course less elegant and efficient than Dot@@data. But in case you would like to look into the intermediate steps (noting that the multiplications are done starting from the end of the matrices stored in data) this will provide them.


EDIT: In case one wants to access the intermediate steps starting from the beginning of data, i.e. to access the accumulative dot product:

p[1] = First[data];
p[n_] := p[n] = p[n - 1].data[[n]]