# Function with domain from data table

I have a Table with elements {{i1, j1, k1},{i2, j2, k2},...}

I wanted to store the values of {{a1, b1, c1},{a2, b2, c2},...} in a table where

a = f(i, j, k)
b = g(i, j, k)
c = h(i, j, k)


are simple functions of i, j, and k.

This seems to be quite a simple task but I can't seem to access the values properly, and am not familiar with Thread, Transpose, Interpolation, etc, so any suggestions on how to efficiently do the task would be very helpful.

• Through /@ {f, g, h} /@ {{i1, j1, k1}, {i2, j2, k2}} ? Commented May 28, 2018 at 2:49
• ... or Through[{f,g,h}@##]&@@@{{i1, j1, k1}, {i2, j2, k2}} or Through[{f, g, h} @@ #] & /@ {{i1, j1, k1}, {i2, j2, k2}}
– kglr
Commented May 28, 2018 at 4:03
• @AccidentalFourierTransform It is not quite correct. Commented May 28, 2018 at 7:15
• @kglr - In general how do I call all the Table elements {{i_n, j_n, k_n}...}? And could you elaborate a little on what exactly your syntax does? Commented May 28, 2018 at 13:02
• Sarah, Through[{f,g,h}@##]&@@@yourTable should transform each triple {i,j,k} to {f[i,j,k],g[i,j,k],h[i,j,k]}. How it works: (1) Through[{f, g, h}@arg] gives {f[arg],g[arg],h[arg]. (2) The form @@@ is short for Apply at level 1 (see Apply). So, foo@@@{{a,b,c},{u,s,t},{v,w,z}} gives {foo[a,b,c],foo[u,s,t],foo[v,w,z]}. ((In contrast, Maping foo on the same list, foo/@{{a,b,c},{u,s,t},{v,w,z}} gives {foo[{a,b,c}], foo[{u,s,t}],foo[{v,w,z}]}).
– kglr
Commented May 28, 2018 at 13:27

Let me start by generating a small sample from a table like yours, for demonstration:

table = Array[Through[{i, j, k}[#]] &, 2]

(* Out:
{{i[1], j[1], k[1]}, {i[2], j[2], k[2]}}
*)


In my view, perhaps the most immediately readable approach to your problem might be the following:

{f[##], g[##], h[##]}& @@@ table

(* Out:
{{f[i[1], j[1], k[1]], g[i[1], j[1], k[1]], h[i[1], j[1], k[1]]},
{f[i[2], j[2], k[2]], g[i[2], j[2], k[2]], h[i[2], j[2], k[2]]}}
*)


You will want to take a look at the docs for Apply if this syntax or the equivalent Apply[function, input, {1}] are unfamiliar to you.

A more compact way to generate that functional expression is the following, as suggested by @kglr in comments:

Through[{f, g, h}[##]]& @@@ table


You can convince yourself that the Through expression essentially generates a functional form equivalent to the one I first proposed above as follows:

Evaluate[ Through[{f, g, h}[##]] ] &

(* Out: {f[##1], g[##1], h[##1]} & *)


where ##1 is equivalent to ## (see SlotSequence).

table = {{i[1], j[1], k[1]}, {i[2], j[2], k[2]}};


Using ComapApply (new in 14.0)

ComapApply[{f, g, h}] /@ table


returns

{{f[i[1], j[1], k[1]], g[i[1], j[1], k[1]], h[i[1], j[1], k[1]]},
{f[i[2], j[2], k[2]], g[i[2], j[2], k[2]], h[i[2], j[2], k[2]]}}


Compare to Query

Query[All, Apply /@ {f, g, h}] @ table


(* same result *)

Since I use an older version (v12.2.0), the Co-Map-Apply can be implemented using:

list = {{i1, j1, k1}, {i2, j2, k2}, {i3, j3, k3}}

Transpose@Outer[Compose, Map[Apply][{f, g, h}], list, 1]


{{f[i1, j1, k1], g[i1, j1, k1], h[i1, j1, k1]}, {f[i2, j2, k2],
g[i2, j2, k2], h[i2, j2, k2]}, {f[i3, j3, k3], g[i3, j3, k3], h[i3, j3, k3]}}

table = {{i[1], j[1], k[1]}, {i[2], j[2], k[2]}};


Another way using BlockMap:

Transpose@BlockMap[Sequence @@ {f @@@ #, g @@@ #, h @@@ #} &, table, {2}]

{{f[i[1], j[1], k[1]], g[i[1], j[1], k[1]], h[i[1], j[1], k[1]]},
{f[i[2], j[2], k[2]], g[i[2], j[2], k[2]], h[i[2], j[2], k[2]]}}


Or using SubsetMap:

SubsetMap[{f @@ #, g @@ #, h @@ #} &, table[[#]], All] & /@ Range@Length@table

{{f[i[1], j[1], k[1]], g[i[1], j[1], k[1]], h[i[1], j[1], k[1]]},
{f[i[2], j[2], k[2]], g[i[2], j[2], k[2]], h[i[2], j[2], k[2]]}}