21.  Functional Operation  (Apply and Map)

2016-07-08

$Version

21.1	Applying Functions to Lists or Other Expressions 		(Apply)

In  f[{a,b,c}]  one is giving a list as the argument to a function. Often one needs to apply a function directly to the elements of a list,  rather than to the list as a whole. This can be done just by appying the command   Apply  to   f[{a,b,c}].   Apply just  replaces  the  head  of  the expression it is acting on.

Clear[f]; f[{a, b, c}]

Apply[f, {a,b,c}]

Apply[Plus, {a,b,c} ]

Exp[{a,b,c}]

Apply[Exp, {a,b,c}]

Exp::argx : Exp called with 3 arguments; 1 argument is expected. >>

The operator   Exp   cannot be used in Apply[],since the result would be an exponential function with 3 
simultaneous arguments.  Now an example of a simple program is given, in which  Apply is used to advantage:

21.1.1  A definition for the arimthmic mean

mymean[list_] := Apply[Plus, list]/Length[list]

mymean[{a,b,c,d}]

list=RandomReal[{0,1},10]

mymean[list]

Using the second argument to RandomReal and related functions is generally quicker than creating lists of randoms using Table.

mymean[RandomReal[{0,1},100]]

21.1.2   A definition for the product of several matrices

There is a law for generating a set of matrices, e.g.

matlaw={{1,k},{0,k}}

Table[matlaw//MatrixForm,{k,1,3}]

The function for performing the matrix product of these matrices is defined with the help of  Apply[]:

MatrixProduct[matexpr_,{i_,imin_,imax_}]:=Apply[Dot,Table[matexpr,{i,imin,imax}]]

MatrixProduct[{{1,k},{0,k}},{k,1,3}]

21.1.3	General description of   Apply

Apply[f, {a,b,...}]	apply  f  to a list, giving f[a,b,...]

Apply[f, expr]		apply  f  to the top level of  expression  expr
f @@ expr         	praefix form of   Apply

Apply[f, expr, levels]  apply  f  at the specified  levels    in   expr

Apply  replaces the head of the expression used as the second argument by the expression given in the first argument.  In a longer version of this command the level (or levels) may be indicated at which the first argument should be applied. 
If  levels  comprises just one number (within or without braces) then the operators are replaced at just this level.
If  levels is a list ({n1,n2}) then the operators are replaced at all levels from level n1 till level n2.

Input						Output / Representation

Apply[List, a + b + c]					{a, b, c}

FullForm[a + b + c]					Plus[a, b, c]

List @@ (a + b + c)					{a, b, c}

Apply[List, a b c]					{a, b, c}

Exp[{a,b,c}]                                                                                     {(e^a),(e^b),(e^c)}

Apply[List,Exp[{a,b,c}]]                                                        {(e^a),(e^b),(e^c)}

Apply[List, Exp[a+b+c] ]				{e, a + b + c}

The last result can be understood by looking at the expression as which  Exp[a+b+c]  is stored:

FullForm[ Exp[a+b+c] ]				Power[E,Plus[a,b,c]]

lr=RandomReal[{0,1},1000000];

st = Sum[lr[[k]],{k,Length[lr]}]//Timing

Apply[Plus,lr]//Timing

One sees that the summation runs about three times faster with Apply[] than with Sum[]. In prefix form the 
summation is written as:

Plus @@ lr

In a longer version of this command the level (or levels) may be indicated at which the first argument should be applied.

m = { {a, b, c}, {b, c, d + k} }

TreeForm[m, ImageSize -> 250]

Apply[f, m]

TreeForm[%,  ImageSize -> 250]

Apply[f, m, {1} ]

TreeForm[%,  ImageSize -> 250]

Apply[f, m, 1 ]

This gives the same Treeform as above.

Apply[f, m, {0,1} ]

TreeForm[%,ImageSize->200]

Apply[f, m, {0,2} ]

TreeForm[%,ImageSize->200]

Apply[f, m, {1,2} ]

TreeForm[%,ImageSize->200]

Apply[f, m, {0,1}]

m

Apply[Exp, m, {0,1} ]

Exp::argx : Exp called with 3 arguments; 1 argument is expected. >>

General::stop: "Further output of Exp :: argx, will be suppressed during this calculation.>>"

xl = Array[x,{10}]

yl = Array[y,{10}]

xyl=Transpose[{xl,yl}]

Apply[Plus,xyl]

Apply[Plus,xyl,{1}]

xl+ yl

Apply[Plus,xyl,{2}]

Apply[Plus,xyl,{3}]

Depth[xyl]

Apply[Plus,xyl,{0,1}]

Apply[Plus,xyl,{1,2}]

Apply[Plus,xyl,{0,2}]

li = {{{0,1}},{{1,1.5}},{{2,3}}}

Apply[Flatten,li,{1}]

Line[%]

Apply[Point,li,{1}]

There is an own infix expression for  Apply[expr, list, {1}], viz.  @@@:

Point @@@ li

Apply[Circle,{{{0,0},.5},{{1,0},.4},{{0,1},2}},{1}]

cc = Circle @@@{{{0,0},.5},{{1,0},.4},{{0,1},2}}

21.2  Applying Functions to Parts of Expressions (Map)

Map[f, {a,b,...}]  		apply  f  to each element in  a list, giving  
					{f[a], f[b], ....}

Map[f, expr]        		apply  f  to the first-level parts of  expr
f  /@  expr         			praefix form of    Map

MapAll[f, expr]     		apply  f  to all parts of  expr
f  //@  expr        		praefix form of MapAll

Map[f, a + b + c ]

Map[f, {a,b,c} ]

Map[f, a b c ]

ls = {{0,1},{1,1.5},{2,3}};
Map[Point,ls]

Map[Sqrt, g[x^2, x^3] ]

TreeForm[g[x^2, x^3]]

TreeForm[%%]

m = {{a,b,c},{b,c,d}};

TreeForm[m]

Map[f, m]

Map[f, m, {2}]

MapAll[f, m]

f = Sqrt[3 x^(4j)+x^(12j)]/(x^(2j)Sqrt[3 + x^(8j)])

PowerExpand[f]

Factor[f]//PowerExpand

MapAll[Factor,f] //PowerExpand

f = (E^(-2 p κ-2 q κ+z κ-zp κ  ));

Factor[f]

Map[Factor,f,{1}]

ll = {{1,2,3,4},{5,6},{7,8},{9,10},{11,12}};

Flatten[ll]

l3 = Partition[%,3]

Reverse[l3]

Map[Reverse,%]

Map[Reverse,l3]

take2[list_] := Take[list, 2]

take2[{1,2,3}]

take2[ {{1,2,3}, {4,5,6}, {7,8,9,11}} ]

take2[{1,2,3}, {4,5,6}]

Map[take2, {{1,2,3}, {5,6,7,}, {2,1,6,6}} ]

take2[ {{1,2,3}, {5,6,7,}, {2,1,6,6}} ]

FullForm[take2[list_]:= Take[list, 2] ]

FullForm[take2[list_] ]

ne = 200;

vx = Array[x,ne];

ma=RandomReal[{1,ne},{ne,ne}];
mb=RandomReal[{1,ne},ne];

eq = ma.vx == mb//Thread;

so = Solve[eq,vx]//Flatten;

so[[{1,2}]]

sx = Transpose[so /. Rule -> List][[2]];

sx[[{1,2}]]

so  is a list containing the solutions as a substitution rule.  sx  contains only the numbers corresponding to the solutions. The operation performed below with  Map runs much faster then by the common substitution command.

sxx = vx /. so//Timing;

sxx[[1]]

sl  = Last /@ so //Timing;
sl[[1]]

lx = {"x1","x2","x3","x4","x5"};

lc = Characters[lx]

ld = lc /. "x" -> "y"

StringJoin[ld]

Map[StringJoin,ld]

Map[StringJoin,ld,{0}]

mydata=RandomReal[{0,1},{3,8}]

myfft=Map[Fourier,mydata]//Chop;

This does a FFT  (= Fast Fourier Transform)  on each row of the data.

myfft

Compare the action of   Map (= /@)    in the commands below:

Plot[{Sin[x],Cos[x],Tan[x],Cot[x]},{x,0,3}]

Show[GraphicsRow[(Plot[#1,{x,0,3},DisplayFunction->Identity]&)/@{Sin[x],Cos[x],Tan[x],Cot[x]}],DisplayFunction->$DisplayFunction,ImageSize->500]

Show[GraphicsRow[(Plot[#1,{x,0,3},DisplayFunction->Identity]&)/@{{Sin[x],Cos[x]},{Tan[x],Cot[x]}}],DisplayFunction->$DisplayFunction]

Show[GraphicsGrid[{(Plot[#1,{x,0,3},DisplayFunction->Identity]&)/@{Sin[x],Cos[x]},(Plot[#1,{x,0,3},DisplayFunction->Identity]&)/@{Tan[x],Cot[x]}}],DisplayFunction->$DisplayFunction]

Show[GraphicsGrid[Partition[(Plot[#1,{x,0,3},DisplayFunction->Identity]&)/@{Sin[x],Cos[x],Tan[x],Cot[x]},2]],DisplayFunction->$DisplayFunction]

This is  the same picrture as above.

list=Table[RandomInteger[{1,9},3],{5}]

For a function, let's say that we want the square root of the sum of
squares. If you define the function to operate on a list of three numbers,

Clear[f]
f[{x_,y_,z_}]:=Sqrt[x^2+y^2+z^2]

then just Map the function onto the elements of the list.

f/@list

Map[f,list]

If your function is defined this way

Clear[g]
g[x_,y_,z_]:=Sqrt[x^2+y^2+z^2]

then you have to Apply it to each triplet list and that function is mapped onto the list.

g@@#&/@list

Map[Apply[g,#]&,list]

g@@@list

MapAt[f, expr, {part1, part2, ...}]  	Apply  f  to specified parts of  expr

Clear[a,b, c,d]

m = {{a, b, c}, {b, c, d}};

MapAt[f, m, {{1,2}, {2,3}} ]

Position[m, b]

MapAt[f, m, %]

MapAt[f, {a,b,c,d}, { {2}, {3} } ]

t = 1 + (3 + x)^2 / x

FullForm[t]

MapAt[f, t, {{2, 1, 1}, {2, 2}} ]

Through[p[(Subscript[f, 1]), (Subscript[f, 2])]][x]  gives  p[(Subscript[f, 1])[x], (Subscript[f, 2])[x]]

Through[expr, h]	performs the transformation wherever h occurs in the head of expr.

Through  serves to distribute an operand toseveral operators.  More precisely:
Through distributes operators that appear inside the heads of expressions.

Through[(f+g+h)[x,y]]

Through[{Re,Im}[(x + I y)^2]]

ComplexExpand[%]

Scan[f, expr]  	Evaluates the result of applying f  to each element of expr 
				without constructing a new expression 
Scan[f, expr, level]  Same as above going down to  given level

sc = Scan[Print,{a,b,c}]

sc

sc = Scan[Print[#^3] &,{a,b,c}]

Scan[Print, a x^2 + b x + c]

Scan[Print, a x^2 + b x + c,2]

??Scan

By default, heads are not printed as shown in the examples above.

Scan[Print,{a,b}, Heads -> True]

21.3	Pure Functions

Function[x, body]  a pure function in which  x  is replaced with any argument one provides

Function[{x1,x2,...}, body]  a pure function that takes several  arguments

body &      a pure function in which arguments are specified as  #  or  #1,#2,#3,... etc.

In the last type of command the ampersand     &  is obligatory.

When using functional operations as  Map , one must specify a function to apply. In the examples above the "name" of a function was used to specify it. Pure functions allow one to give functions which can be applied to arguments, without having to define explicit names for the functions.

Clear[a,b,c,d,f,g,h,n,x]
h[x_] = f[x] + g[x]

Map[h, {a,b,c}]

Map[ f[#] + g[#] &, {a,b,c} ]

Function[x, x^2]

%[n]

Function[y^2, z^3]

Parameter specification  (y^2)  in Function[(y^2),(z^3)]should be a symbol or a list of symbols. >>

Map[ Function[x, x^2], a + b + c ]

Map[ #^2 &, a + b + c ]

Map[ Take[#, 2] &, {{2,1,7},{4,1,5}, {3,1,2}} ]

The postfix form of a command with several arguments may be realized with the help of a pure function.

Pi//N[#,19]&

The prefix form of a command may be realized with the help of a pure function.

list=RandomReal[{0,1},5]

Position[#,Max[#]]&  @  list

Or the pure function may be treated as if it were a normal function, whose argument must stand between square brackets.

Position[#,Max[#]]&[list]

#0 is a rarely used “parameter,” which refers to the pure function itself and thus makes it possible to create
pure recursive functions:

fact = Function[If[#1 == 0,1,#1 #0[#1 - 1]]] ;

fact[5]

But this works for nonnegative integers only; so safeguards are necessary.

fact = Function[If[Head[#1] == Integer && #1 ≥ 0,If[#1 == 0,1,#1 #0[#1 - 1]],Print["Undefined"],Print["Undefined"]]] ;

fact[5]

fact[-2]

fact[2.5]

Tests whether  a given function satisfies a differential equation mye be performed with the help of a pure function.

dg =- y(x)  (k^2)+ y''(x)

f=Exp[-k*#]&

dg /. {y -> f}

The pure function and  Map may be used for removing factors in equations. In the example below the factor exp(i ωt) can be removed in an expression by simple multiplication. But in an equation this cannot be achieved in this simple way, but it can be done with  Map.

Clear[a,b,c,ex,t,w]
ex = a E^(I w t )(b + c x)

ex E^(- I w t)

eq = ex == 0

eq E^(- I w t) //Expand //Cancel

Map[Cancel[#/E^(I w t )]&, eq]

Below all pairs where sin(x) >= 0 are taken from a list  l1 containing pairs of {cos(x), sin(x)} for x = n 2π/6, n ϵ ℕ.

l1 = Table[{Cos[k π/3],Sin[k π/3]},{k,6}]  (* macher *)

Select[%,#[[2]]>=0&]

l4 = Cases[l1, {_,x_}/;N[x]>= 0,{1}]  	(* Sakulin *)

Cases[1.22 A*x+3*b*y + Z^4,_Symbol,Infinity]

Cases[1.22 A*x+3*b*y + Z^4,_?NumberQ,Infinity]

Cases[1.22 A*x+3*b*y + Z^4,_?IntegerQ,Infinity]

Cases[1.22 A*x+3*b*y + Z^4,_Real,Infinity]

s1=a u'[x]+a u''[x]

Cases[s1,Derivative[_][u][x],-1]

s2=a D[u[x,y],y]+c D[u[x,y],x,y]

FullForm[s2]

Cases[s2,Derivative[_][u][x,y],-1]

Cases[s2,Derivative[__][u][x,y],-1]

Above the argument of Derivative[]  must contain two underscores since the list consists of several elements.

Below an index vector gives the order of the elements in a list of random numbers. The sorting is done with the
help of a pure function. Of course, the sorting alone can be done faster by sorting the random number list.

n=20;
b=RandomReal[{0,1},n]

Range[n]

iv = Sort[Range[n], b[[#1]] > b[[#2]] &]

b[[iv]]

Sort[b]//Reverse

In the following example the list  data  is distributed over sublists according to the value of the first element of  each pair; the intervals for this sublists are given in the list at the end of the Select[] command. The 
Map[Union, ..., {1}] orders the sublists according to the value of the first element of each pair.

data=Table[{RandomReal[{0,10}],x[i]},{i,15}]

Map[Union,
Select[data,Function[{sublist},sublist[[1]]<#[[2]]&&sublist[[1]]≥#[[1]]]]&/@{{0,5},{5,7},{7,9},{9,10}},{1}]

teile={5,7,9};
MapThread[Function[{low,high},Select[Sort[data],low≤#[[1]]<high&]],{Prepend[teile,0],Append[teile,10]}]

21.4	Exercises

21.1+	Define a function which computes the geometric mean of the numbers comprised in a list.
	The function must not contain loop commands.

21.2	The same as 21.1 for the harmonic mean.

21.3 +	Transform the following operator (that of the spherical Bessel functions of order L) :

  		 		[(d^2)/d(r^2)  + (2/r) d/dr  -  L (L + 1)/(r^2)  + (k^2) ]  u (r) 
  		 		
   	into that of Bessel' s differential  equation 
   
   				[(d^2)/d(r^2)  + (1/r) d/dr  -  (L^2)/(r^2)  + (k^2) ]  w (r) 
   				
   	by  commands acting on lists.

21.4+	How can one flatten a list with multiple braces from the inside out, not from the outside in as is 		accomplished by   Flatten[]   ?  For example, the list below
				   {  {{{a, b}}, {{c, d}}}, {{{p, q}}, {{r, s}}}   }
	should be transformed into:
						{{a, b, c, d}, {p, q, r, s}};
	or the list
				{{{0.3, 0.5}}, {{0.6, 1.}}, {{0.9, 1.5}}, {{1.2, 2.}}}
 	into 
				{{0.3, 0.5}, {0.6, 1.}, {0.9, 1.5}, {1.2, 2.}} .

21.5	Transform the following list by replacing  x  with  v  in the names of the lists and of the elements:
		lx = {x1,x2,x3,x4,x5}    ->     lv = {v1,v2,v3,v4,v5}.
	These replacementrs should be done by working on lx, not by just rewriting it.

21.6+	Generate 2 lists. la contains cordinates of n 3D-points as elements:
	la = {{ax1,ay1,az1}, {ax2,ay2,az2},...,{axn,ayn,azn}}.
	lb is the same with a replaced by b everywhere. Interweave the 2 lists such that 
	ll = {{ax1,ay1,az1},{bx1,by1,bz1}, {ax2,ay2,az2},...,{axn,ayn,azn},{bxn,byn,bzn}}.

21.7	A list containing four sublists is given (in reality all the elements are numbers):  
		{{x1,y1,z1}, {{x2,y2,z2}, {{x3,y3,z3}, {{x4,y4,z4}}
	1. The four sublists are regared as the coordinates of four points. 
	   Transform the above list into	 that for the corresponding graphics command.
	 2.   The four sublists are regared as the coordinates of four points of a line.
	   Transform the above list into	 that for the corresponding graphics command.

21.8	Two n x m  matrices A = (aik) and  U =  (uik) are given.   Find at least two different ways to 	
	get the system of equations, in which corresponding elements of U are set identical to 		
	those 	of A.  At least one of these methods should work without loop commands.

21.9+	Four   k x k  matrices  A,B,C,D  are given.  Form the   2k x 2k  matrix given below
	without any loop commands:   (({{A, B}, {C, D}})) .

21.10	Decompose  (2^67) + 1   or the number given in ex.13.9 into prime factors. 
	Prepare a function which multiplies the factors again by acting directly on the list of prime factors.