Monday, June 17, 2013

ApplyAll Applies a Function to all Subexpressions at Level One

ApplyAll

Instead of applying a function f to an entire expression, i.e. replacing the Head of the expression with f, use ApplyAll like Map to apply the function to each subexpression at level 1 of the expression. Apply defaults to Level 0 (the Head) and ApplyAll is just a convenient shorthand for Apply[ f, expr, 1].

Here is a typical example of ApplyAll. You have a List of number pairs and you want to perform some arithmetical operation such as add, multiply, divide, raise one to the power of the other, etc. (To remember the syntax of RandomReal I think of its arguments sequentially in English: "give me random reals between 1 and 20, 10 of them with length 2" (i.e. a 10 x 2 array).)

pairs=RandomReal[{0,1},{20,2}]

{{0.00994214,0.0701189},{0.024718,0.24013},{0.434799,0.996965},{0.323499,0.444366},{0.799502,0.843786},{0.964146,0.254526},{0.438815,0.943254},{0.228569,0.00348145},{0.247675,0.773157},{0.879202,0.615889},{0.898872,0.232664},{0.381568,0.75334},{0.464207,0.659948},{0.843115,0.179364},{0.287139,0.636774},{0.922514,0.193705},{0.969753,0.273868},{0.012059,0.247027},{0.560162,0.962637},{0.0593815,0.331142}}

Map doesn't work. It essentially disappears because it has no effect on a List:

Plus[List[a,b]]

{a,b}

Plus/@pairs

{{0.00994214,0.0701189},{0.024718,0.24013},{0.434799,0.996965},{0.323499,0.444366},{0.799502,0.843786},{0.964146,0.254526},{0.438815,0.943254},{0.228569,0.00348145},{0.247675,0.773157},{0.879202,0.615889},{0.898872,0.232664},{0.381568,0.75334},{0.464207,0.659948},{0.843115,0.179364},{0.287139,0.636774},{0.922514,0.193705},{0.969753,0.273868},{0.012059,0.247027},{0.560162,0.962637},{0.0593815,0.331142}}

But ApplyAll works perfectly; we always use its abbreviated version:

Plus@@@pairs

{0.080061,0.264848,1.43176,0.767865,1.64329,1.21867,1.38207,0.23205,1.02083,1.49509,1.13154,1.13491,1.12416,1.02248,0.923913,1.11622,1.24362,0.259086,1.5228,0.390524}

Times@@@pairs

{0.000697132,0.00593553,0.43348,0.143752,0.674608,0.2454,0.413914,0.000795751,0.191491,0.541491,0.209135,0.287451,0.306352,0.151224,0.182842,0.178696,0.265585,0.00297889,0.539232,0.0196637}

Here is a another example of ApplyAll. I want to make a toy directed graph so I can explore the new graph functions that have superseded the Combinatorica package as of Version 8.

randomEdges=RandomInteger[{1,20},{10,2}]

{{16,5},{17,17},{10,10},{15,2},{9,8},{20,9},{19,7},{20,15},{8,20},{11,3}}

Now I want to convert the pairs of numbers into a directed graph with DirectedEdge. My first try fails, again because each subexpression is a List.

toyGraph=DirectedEdge/@randomEdges

{DirectedEdge[{16,5}],DirectedEdge[{17,17}],DirectedEdge[{10,10}],DirectedEdge[{15,2}],DirectedEdge[{9,8}],DirectedEdge[{20,9}],DirectedEdge[{19,7}],DirectedEdge[{20,15}],DirectedEdge[{8,20}],DirectedEdge[{11,3}]}

What I need is ApplyAll.

toyGraph=DirectedEdge@@@randomEdges




It is equivalent to Apply[ DirectedEdge, randomEdges, 1].

Apply[DirectedEdge,randomEdges,1]


No comments:

Post a Comment