This question is closely related to questions 83720, 17460, and 11298.
How would you write the operator
F = Through[#1[#2]] &
in the prettiest, fastest, or most poetic way? It just looks clumsy the way I've written it.
Also, can you think of any pitfalls? Edge cases where this function does not behave regularly?
What F
does is to apply a list of functions to a list of values:
F[{Sin, Cos, Tan}, {x, y}]
(* {{Sin[x], Sin[y]}, {Cos[x], Cos[y]}, {Tan[x], Tan[y]}} *)
benchmarks of solutions
Here's a benchmark of all solutions, sorted from fastest to slowest.
(* random functions and random data *)
a = Table[Function[x, Evaluate[x + RandomReal[]]], {10^4}];
b = RandomReal[{0, 1}, 10^4];
original post: very fast
F = Through[#1[#2]] &;
c0 = F[a, b]; // AbsoluteTiming // First
(* 0.506063 *)
contracted syntax: a little bit slower
F = Through@*Construct;
c1 = F[a, b]; // AbsoluteTiming // First
(* 0.85128 *)
dataset query: still a bit slower
F = Query[#1][#2] &;
c2 = F[a, b]; // AbsoluteTiming // First
(* 1.45958 *)
explicit outer-product construction: terribly slow
F = Outer[Construct, ##] &;
c3 = F[a, b]; // AbsoluteTiming // First
(* 83.0245 *)
check that all solutions agree on the result:
c0 == c1 == c2 == c3
(* True *)
Listable
in the examples you're giving (Cos
,Sin
andTan
). For a list of non-listable functions you'd needF = Through[(Map /@ #1)[#2]] &
. $\endgroup$