5
$\begingroup$

I'm looking for an efficient way of computing sums of the type $$D_{jk} = \sum_{i=1}^n A_{ij} B_{ik} C_{i}$$ for large numerical matrices $A$, $B$ and $C$.

Here is a slow solution:

DD = Table[Sum[AA[[i, j]] BB[[i, k]] CC[[i]], {i, 1, n}], {j, 1, m}, {k, 1, m}]

What's a fast way of doing it?

$\endgroup$

1 Answer 1

8
$\begingroup$
n = 4;
m = 3;
aa = Array[a, {n, m}];
bb = Array[b, {n, m}];
cc = Array[c, n];
dd = Table[Sum[aa[[i, j]] bb[[i, k]] cc[[i]], {i, 1, n}], {j, 1, m}, {k, 1, m}];

You can Transpose aa and Dot it with bb cc:

Transpose[aa].(bb cc) == dd

True

Alternatively, you can Transpose aa cc and Dot it with bb:

Transpose[aa cc].bb ==dd

True

Comparison with Table/Sum combination:

SeedRandom[1]
n = 100;
m = 50;
aa = RandomReal[1, {n, m}];
bb = RandomReal[1, {n, m}];
cc = RandomReal[1, n];
dd = Table[Sum[aa[[i, j]] bb[[i, k]] cc[[i]], {i, 1, n}], {j, 1, m}, {k, 1,   m}]; //
   RepeatedTiming // First

0.417

ee1 = Transpose[aa].( bb cc) ; // RepeatedTiming // First

0.000051

ee2 = Transpose[aa cc].bb ; // RepeatedTiming // First

0.000045

dd == ee1 == ee2

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.