Dot Product of Block Matrices
One way is to turn them into ordinary matrices, take the dot product, and then ArrayReshape
them into the form you want.
Af = ArrayFlatten[A];
Bf = Flatten[B];
ArrayReshape[Af.Bf, {3, 1, 2}] // MatrixForm
Just to check:
ArrayReshape[Af.Bf, {3, 1, 2}] == dotdot[A, B]
(* True *)
You could use TensorContract
instead:
r1 = dotdot[A, B];
r2 = TensorTranspose[
TensorContract[TensorProduct[A, B], {{2, 5}, {4, 7}}],
{1, 3, 2}
];
r1 === r2
True
Comparison
One advantage of the TensorContract
approach is that if A
and B
are sparse arrays, then the result is also a sparse array. This is not true for the other answers. For example:
A=SparseArray @ RandomChoice[{.9,.1}->{0,1}, {5, 6, 7, 8}];
B=SparseArray @ RandomChoice[{.9,.1}->{0,1}, {6, 9, 8}];
r1 = dotdot[A, B];
r2 = TensorTranspose[
TensorContract[TensorProduct[A, B], {{2, 5}, {4, 7}}],
{1, 3, 2}
];
Normal[r1] === Normal[r2]
Head /@ {r1, r2}
True
{List, SparseArray}
I didn't include @aardvark2012's answer because ArrayReshape apparently doesn't work with sparse arrays anyway