Professional Documents
Culture Documents
Slide 1 of 11
Lecture 4
Introduction to Functional Programming
Brian G. Higgins
Department of Chemical Engineering & Materials Science
University of California, Davis
April 2014, Hanoi, Vietnam
ECM6Lecture4Vitenam_2014.nb
ECM6Lecture4Vitenam_2014.nb
Functional Programming
In this lecture we will give a brief overview of functional programming in Mathematica. Here is a definition of functional programming (http://www.cs.nott.ac.uk/~gmh//faq.html)
"Functional programming is a style of programming that emphasizes the evaluation of expressions,
rather than execution of commands. The expressions in these language are formed by using functions
to combine basic values. A functional language is a language that supports and encourages programming in a functional style."
Programming languages such as FORTRAN, BASIC are often referred to as procedural languages.
The use of For loops, While loops are common constructs in procedural programming.
In procedural programming one specifies the steps the program must take to reach the desired goal.
Procedures, also known as routines, subroutines, methods, contain a series of computational steps to
be carried out.
In this lecture we will discuss the following functions: Pure functions, Map, Apply, and related functions
such Nest (NestList), FixedPoint.
To avoid function clashes evalute the following:
In[1]:=
ECM6Lecture4Vitenam_2014.nb
Pure Functions
In writing a Mathematica program it is sometimes convenient to be able to assign an operation with no
name to it. This might be useful if the operation is used infrequently.
A function without a name assigned to it is called an anonymous or pure function. In Mathematica you
specify a pure function with Function. The definition and attributes of Function are given below:
In[2]:=
? Function
Function@bodyD or body & is a pure function. The formal parameters are Hor 1L, 2, etc.
Function@x, bodyD is a pure function with a single formal parameter x.
Function@8x1 , x2 , <, bodyD is a pure function with a list of formal parameters.
In this section we will show how one defines and uses anonymous function.
g1@x_D := x3
g1@3D
27
Anonymous(Pure) Function
We can also use the anonymous function (which is specified using Function[]) to do the same thing
In[5]:=
FunctionAw, w3 E
Out[5]=
FunctionAw, w3 E
The variable in the anonymous function is the first argument (in this case w). The second argument is
the body of the function (in this case w 3 ). To apply this function to a value (or list of values ) of w we
must enclose its value in brackets after the function:
In[6]:=
Out[6]=
FunctionAw, w3 E@3D
27
We can also give the anonymous function a name (this is actually redundant), as follows:
In[7]:=
Out[7]=
name = FunctionAw, w3 E
FunctionAw, w3 E
Now if we want to evaluate the function name with w=5, say, we proceed as follows
ECM6Lecture4Vitenam_2014.nb
In[8]:=
Out[8]=
name@4D
64
name@82, 3, 4, 5<D
88, 27, 64, 125<
ECM6Lecture4Vitenam_2014.nb
H ^ 3L &@5D
125
Here are a few simple examples that show how pure functions can be implemented:
Example 1:
In[11]:=
Out[11]=
Example 2:
Pure functions can also be defined to have more than one variable. When that is the case we use #1,
#2, etc. to denote the variables. Here is an example:
Cos@1D
In[12]:=
1 + Sin@2D
&@3, 4D
Cos@3D
Out[12]=
1 + Sin@4D
Example 3:
Now take our function g that we defined in a previous lecture:
In[13]:=
1
a
Ha - 1L x +
b
x
For a fixed value of a and b, we can write g(a, b, x) as a pure function and call it pfunc
In[14]:=
Out[14]=
Note now that by defining pfunc we have transformed our original function of 3 variables to one that
takes a single argument. Thus if we want to evaluate this function for a specific value of x, say x=0.2,
all we do is
ECM6Lecture4Vitenam_2014.nb
Note now that by defining pfunc we have transformed our original function of 3 variables to one that
takes a single argument. Thus if we want to evaluate this function for a specific value of x, say x=0.2,
all we do is
In[15]:=
Out[15]=
pfunc@0.2D
261.4
ECM6Lecture4Vitenam_2014.nb
Map Function
In[17]:=
Remove@f, gD
? Map
Map@ f , exprD or f expr applies f to each element on the first level in expr.
Map@ f , expr, levelspecD applies f to parts of expr specified by levelspec.
The basic operation of Map is to wrap a given function around each element of a list and returns a list.
Thus
In[19]:=
Out[19]=
The output is a list but with the first argument of Map applied to each element of our original list. Thus
we have produced a new list in which each element is a function.
Mathematica did not evaluate these functions f[x],f[y], since no rule was specified for f. In this
case f is stored in the kernel as a Symbol, one of six atomic types used by Mathematica.
We can extend this example by defining f to be some function with a rule, say g[t_]:=t^2.
In[20]:=
g@t_D := t2
In[21]:=
Out[21]=
9x2 , y2 =
ECM6Lecture4Vitenam_2014.nb
Remove@dataPoints, myFunc1D
myFunc1@8x_, y_<D :=
Abs@yD
x2 + y2
Map@myFunc1, dataPointsD
80.199385, 0.206318, - 0.172426, 0.185172, - 0.182981<
We can do the same calculation without ever defining the function myFunc1
In[27]:=
Out[27]=
MapB
@@1DD
Abs@@@2DDD
@@1DD2 + @@2DD2
&, dataPointsF
10
ECM6Lecture4Vitenam_2014.nb
Remove@myFunc2, integralValuesD
In this example we illustrates the use of Map for efficient calculations on list of data. Consider the following list of functions:
In[29]:=
We have suppressed the output by using the semi-colon after the expression. We have generated a list
of 1000 functions. Here is what the first 5 functions look :
In[30]:=
Out[30]=
myFunc2@@Range@5DDD
90.768993 x Sin@0.661181 xD3 , 0.627862 x Sin@0.570485 xD3 ,
0.0468615 x Sin@0.113841 xD3 , 0.35992 x Sin@0.50649 xD3 , 0.945703 x Sin@0.896221 xD3 =
Note 1: Map takes each element of the the list myFunc2, and substitutes it into the first argument of
NIntegrate, and then the numerical integration is done.
Note 2: Ending the RHS of the expression with a the semicolon (;) supresses the output.
Here are the first 5 value of the integral
In[32]:=
Out[32]=
integralValues@@Range@5DDD
80.00592975, 0.00363239, 0.0000234634, 0.00229541, 0.0153726<
integralValues
90.00592975, 0.00363239, 0.0000234634, 0.00229541, 0.0153726, 0.00118521,
0.000326834, 0.000824181, 0.013277, 2.86702 10-8 , 0.00101488, 0.00906668,
0.00103362, 0.00101666, 0.00029176, 0.0000828636, 0.0183311, 0.00804102,
0.000305338, 0.0142143, 0.0140254, 0.00135766, 0.0153095, 0.000894754, 0.0124342,
0.00209115, 2.78754 10-10 , 0.00164677, 0.00827162, 0.000429945, 0.00148678,
3.45489 10-6 , 0.0106541, 0.0131496, 0.0000287917, 0.00113331, 9.0539 10-6 ,
0.00616589, 0.0103695, 0.000405898, 0.00018057, 0.0000791592, 7.56686 10-6 ,
0.00457373, 0.000551122, 0.00859689, 0.0152631, 0.00760289, 1.94124 10-6 ,
0.0000975954, 7.08544 10-7 , 0.000504507, 0.015131, 0.014122, 0.000520485,
0.0110242, 0.00586971, 0.00199233, 0.0169856, 0.000911403, 9.90629 10-8 ,
0.000537615, 0.00279646, 0.0000208286, 0.0145136, 0.00465274, 0.00661498,
0.00853557, 0.0000588386, 0.00062723, 0.0117508, 0.0109272, 0.0127529, 0.0026466,
0.0113174, 0.0117951, 0.00932683, 0.00189065, 0.016707, 0.00077999, 0.0108555,
0.00299123, 0.00164571, 0.00633398, 0.00803565, 0.00985574, 0.00871247, 0.00405964,
0.00979525, 2.03099 10-7 , 0.00121812, 0.0131072, 0.00887896, 0.00431722,
0.00709209, 0.000477385, 0.000347967, 0.00471188, 0.00657172, 0.000884978,
ECM6Lecture4Vitenam_2014.nb
11
12
ECM6Lecture4Vitenam_2014.nb
ECM6Lecture4Vitenam_2014.nb
13
14
ECM6Lecture4Vitenam_2014.nb
Apply Function
In[34]:=
Remove@myDataD
? Apply
Apply@ f , exprD or f expr replaces the head of expr by f .
Apply@ f , expr, 81<D or f expr replaces heads at level 1 of expr by f .
Apply@ f , expr, levelspecD replaces heads in parts of expr specified by levelspec.
Example 1:
Consider the following list of 10 real data points
In[37]:=
Out[37]=
We can check what the head is of the expression mydata using the function Head
In[38]:=
Out[38]=
Head@myDataD
List
As expected it is a list.
Suppose now we change the head of mydata to Plus, using Apply
In[39]:=
Out[39]=
Apply@Plus, myDataD
4.42566
Example 2:
If we change the head to Times we multiply all the elements in the list together.
In[40]:=
Out[40]=
Apply@Times, myDataD
- 95 104.3
Example 3:
To find the mean of the data in our list we could do the following
ECM6Lecture4Vitenam_2014.nb
In[41]:=
Out[41]=
Mean@myDataD
0.442566
15
16
ECM6Lecture4Vitenam_2014.nb
Nest Function
In[43]:=
As we saw in a previous lecture, many algorithms are iterative or recursive, having the form
xi+1 = f Hxi L
The function Nest is the basic function for doing iteration. The function NestList gives all the intermediate values during the iteration.
In[44]:=
? Nest
Nest@ f , expr, nD gives an expression with f applied n times to expr.
In[45]:=
? NestList
NestList@ f , expr, nD gives a list of the results of applying f to expr 0 through n times.
Example 1:
In[46]:=
Out[46]=
NestListB
&, 1, 6F
1+
1 2 3 5
8
13
:1, , , , ,
,
>
2 3 5 8 13 21
Out[47]=
NestListB
:x,
1
1+x
1
1+
1
1+
&, x, 5F
1
1+x
,
1+
1+
1
1
1+
1+x
1+
1+
1
1+
1
1+x
>
1
1
1+
1+
1+
1
1+x
Example 2:
With this in mind we use NestList with a pure function to generate the iterates of our function g@1.5, xD.
As our starting value of x we take x0 = 5 and generate 20 iterates
Consider our previous function
In[48]:=
1
a
Ha - 1L x +
b
x
ECM6Lecture4Vitenam_2014.nb
Let us determine the fixed point of this function by iterating using NestList
In[49]:=
Out[49]=
In[50]:=
Out[50]=
17
18
ECM6Lecture4Vitenam_2014.nb
Remove@gD
Mathematica has a built-in function called FixedPoint that can determine the fixed points of a function
In[52]:=
? FixedPoint
FixedPoint@ f , exprD starts with expr, then applies f repeatedly until the result no longer changes.
In[54]:=
Out[54]=
1
a
Ha - 1L x +
b
x