I have a collection of 5-element vectors each of which corresponds to an {x,y} location from a (20 x 21) grid. Because of that I represent that data as a (5 x 20 x 21)-sized tensor called W.

I also have a set of 128 (5 x 5)-sized matrices which I've packed as a (128 x 5 x 5) tensor called R.

I then want to compute for each vector in W and each matrix in R the product Transpose[w].r.w (which is a scalar) and obtain a (128 x 20 x 21)-sized tensor. Finally, I only care about the sum over the 128 matrices, which will be a (20 x 21)-sized matrix.

I can compute that operation with the following command which leaves me very unsatisfied since it seems somewhat inelegant:

Total[Outer[#1.#2.#1 &, TensorTranspose[W, {3, 2, 1}], R, 2, 1], {3}]

It seems to me that there should be a way to not use TensorTranspose, and that the Total should be redundant if I were to use Inner. However I don't see a clean way to use level specifications to get the answer I want. Any ideas? (preferably ones that are efficient too!).

If you have to know, this implements a 5-sensor broadband delay-and-sum beamscanner. W holds the steering vectors for each location to scan, and R are the covariance matrices for each frequency band.



Perhaps I'm missing something, but can't you sum the covariance matrices at the start?

result =  With[{r = Total @ R}, Map[#.r.# &, Transpose[W, {3, 2, 1}], {2}]]

This is several hundred times faster than the original.


Take care!! With the instruction:

Total[Outer[#1.#2.#1 &, TensorTranspose[W, {3, 2, 1}], R, 2, 1], {3}]

you are effectively doing:


If you really want to do:


Then you should:

Total[Outer[TensorTranspose[#1, {3, 2, 1}].#2.#1 &, W, R, 2, 1], {3}]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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