This question may be trivial, but I can't get past it for the life of me.

I have $n$ matrices of dimension $p_i \times N_i$, with $i$ indexing the $n$-set. I also have $n$ vectors of the appropriate length.

I'm looking to create a list of the inner products. This works (obviously):

MapThread[Dot[#1,#2]&,{nmats,nvecs}]


The problem comes in when I pass in lists of nmats. That is, I have $C$ copies of nmats stored in cnmats and want to collect the above for each. For some reason Mapping works,

MapThread[Dot[#1,#2]&,{#,nvecs}]&/@cnmats


but Threading doesnt

Thread[MapThread[Dot[#1,#2]&,{#,nvecs}]&[cnmats]]


Replacing MapThread with Table moves the error to Dot: Nonrectangular tensor encountered.

The error returned is:

Incompatible dimensions of objects at positions {2, 1} and {2, 2} of (MapThread expression);
dimensions are n and C


$C$ and $N_i$ are $O(10^5)$, $p$ is $O(1)$, so I favor Thread for the speed advantage.

Why can't I thread here? How can I implement this differently to benefit from threading?

• Possible duplicates: (14121), (37274), (45240) – Mr.Wizard Feb 28 '16 at 3:39
• Thank you sir, this will help me brush up on Threading in mathematica. – sampson Mar 6 '16 at 6:06

The issue here has been explained in the posts linked by Mr.Wizard: Thread doesn't have a Hold* attribute so the inner code i.e. MapThread[Dot[#1,#2]&,{#,nvecs}]&[cnmats] will evaluate before Thread begins to work.

I write this answer just to highlight a property of Thread, which has actually be mentioned but not emphasized in this answer, that is, like Module and Manipulate, the… er… structure to be Threaded must explicitly exists inside Thread.

This property isn't eye-catching because, as mentioned above, Thread doesn't hold its arguments so usually the structure to be Threaded will become explicit after automatic evaluation, but it'll easily show up once you tried to control the evaluation order. For example:

D[{x, y}, {x, y}]
(* Derivative[y, 0][List][x, y] *)

(* Derivative[y, 0][List][x, y] *)

(* {1, 1} *)

xy = {x, y}; Thread@Unevaluated@D[xy, xy]
(* Derivative[y, 0][List][x, y] *)


Output of the fourth sample is the same as the first two, what happened? Let's Trace it:

Thread@Unevaluated@D[xy, xy] // Trace


apparently Thread doesn't "see" the {x, y} so D[xy, xy] is still D[xy, xy] afterwards.

To fix the problem, one need to adjust the evaluation order further, here are 2 approaches:

With[{xy = {x, y}}, Thread@Unevaluated@D[xy, xy]]
Clear@xy;
Hold@Thread@Unevaluated@D[xy, xy] /. xy -> {x, y} // ReleaseHold


Back to your problem, if you want to insist on Thread (will it really be faster?), then

With[{cnmats = cnmats},