From the documentation, Thread's behavior on functions where the first parameter is a List and the second is an atomic expression, is this:
Thread[f[{a, b, c}, x]]
(* {f[a, x], f[b, x], f[c, x]} *)
If the second argument of 'f' is not atomic, it is possible to thread over its first argument {a,b,c} while treating the 2nd argument as if it were atomic? For example, consider:
M = Table[i + j, {i, 1, 3}, {j, 1, 2}]
(* {{2, 3}, {3, 4}, {4, 5}} *)
Then,
Thread[f[{a, b, c}, M]]
(* {f[a, {2, 3}], f[b, {3, 4}], f[c, {4, 5}]} *)
This is understandable because M is not atomic so For example:
g[p_, M_ /; Dimensions[M] == {3, 2}] := {p, M}
Threading over g
Doesn't work as intended:
Thread[g[{a, b, c}, M]]
(* {{a, {2, 3}}, {b, {3, 4}}, {c, {4, 5}}} *)
Worse still, the result above is due to a coincidence: Length@M==3. If this is not the case, Thread returns an error:
Thread::tdlen: Objects of unequal length in f[{a,b,c},{{2,3,4,5},{3,4,5,6}}] cannot be combined. >>
I've also considered wrapping M in some variation of Hold, but none yield atomic expressions. Is there a way to force Thread to treat the 2nd argument of the function as atomic?
The ultimate goal is to SetAttributes
of the function to Listable
.
f[#, M] & /@ {a, b, c}
? $\endgroup$ReleaseHold@Thread[f[{a, b, c}, Hold@M]]
do what you want? $\endgroup$Thread
. The goal seems to thread a function over a list in a certain way, andThread
was just used as a seemingly most straightforward way to obtain the desired result. At least, this is how I interpreted it from the start. $\endgroup$