Functional Programming in Mathematica
Functional Programming in Mathematica
in Mathematica
An Introduction
Hossam Karim
ITWorx
FunctionalProgramming-Egypt-2010.nb
About
Work for an Egyptian Software Services Company
Design software for the Bioinformatics and Telecommunications industries
Use Mathematica every day
Implement prototypes and proof of concepts
Design and implement solutions and algorithms
Validate implementations' feasibility, performance and correctness
Code, concepts and algorithms provided in this presentation are not related or affiliated by any means to my employer nor my clients. All the material in this presentations
are samples not suitable for production, and are provided for the sole purpose of demonstration.
FunctionalProgramming-Egypt-2010.nb
The Function
Functions in Mathematics
Function Definition
A Function f is a mapping from the domain X to the co-domain Y and is defined by
f : X Y
The curve y 2 = x 4 - x 2 + 1 can be defined as function by the triple notation
: R, R, : x,
x4 - x2 + 1
> : x R>
(1)
where R is the domain of real numbers and also the co-domain, alternatively,
f : R R, x
x4 - x2 + 1
(2)
f HxL =
Plotting a Function
Mathematica supports both function and curve plotting
x4 - x2 + 1
(3)
FunctionalProgramming-Egypt-2010.nb
Function plot
In[1]:=
PlotA9
x4 - x2 + 1 , -
Out[1]=
x
-3
-2
-1
-1
-2
-3
FunctionalProgramming-Egypt-2010.nb
Curve Plot
ContourPlotAy2 x4 - x2 + 1, 8x, -3, 3<, 8y, -3, 3<,
In[2]:=
Out[2]=
x
-3
-2
-1
-1
-2
-3
Haskell
Implementation of the Quick Sort algorithm in Haskell. Demonstrates polymorphic types, pattern matching, list comprehension and
immutability
Scala
Implementation of the Quick Sort algorithm in Scala. Demonstrates polymorphic types, pattern matching, object-oriented support and partial
functions application
FunctionalProgramming-Egypt-2010.nb
Mathematica
Implementation of the Quick Sort algorithm in Mathematica. Demonstrates pattern matching, pattern guards and rule based programming
In[3]:=
ClearAll@qsortD;
qsort@8<D := 8<;
qsort@8p_, xs___<D :=
8Cases@8xs<, y_ ; y <= pD, Cases@8xs<, y_ ; y > pD< .
8lesser_, greater_<
8qsort@lesserD, p, qsort@greaterD< Flatten
In[6]:=
qsort@80, 9, 1, 8, 3, 6, 2, 7, 5, 4<D
FunctionalProgramming-Egypt-2010.nb
Functions in Mathematica
Numeric Computations
Numeric computations through function calls
In[210]:=
Out[210]= 0
In[8]:=
1 + -
Out[8]= 0
Arbitrary precision
In[9]:=
N@, 100D
Out[9]= 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
Calculus
Symbolic Calculus
1
In[10]:=
Sin@D
Out[10]= -2 EllipticFA
- , 2E
Accurate results
In[11]:=
% FullSimplify
1
Out[11]=
Sin@D
Algorithms
Optimized algorithms
FunctionalProgramming-Egypt-2010.nb
In[12]:=
Out[12]//Short=
80.04, 89, 400, 418, 657, 719, 859, 947, 1057, 1061, 99 982,
9 998 951, 9 998 953, 9 999 009, 9 999 077, 9 999 123, 9 999 227, 9 999 236, 9 999 314, 9 999 497<<
Algorithm analysis
2n
In[13]:=
T@nD . RSolveA9T@nD TA
Log@nD
Out[13]= 91 +
=
3
LogA E
2
Graphics
Stunning graphics
In[236]:=
Out[236]=
FunctionalProgramming-Egypt-2010.nb
In[15]:=
f@x_D :=
x3 - x + 1
In[16]:=
x3 + a x + b
10
FunctionalProgramming-Egypt-2010.nb
Calling a Function
Default Form
Default Form, notice the square brackets
In[17]:=
f@2D
Out[17]=
Prefix Form
Prefix Form, using the @ sign
In[18]:=
f2
Out[18]=
Postfix Form
Postfix Form, using the // sign
In[19]:=
2 Sin
Out[19]= 0
Infix Form
Infix Form, function surrounded by ~ sign
In[20]:=
Multiple Arguments
Function call with multiple actual arguments
FunctionalProgramming-Egypt-2010.nb
In[223]:=
Magnify@ChemicalData@"Ethanol", "MoleculePlot"D, 1D
Out[223]=
11
12
FunctionalProgramming-Egypt-2010.nb
In[22]:=
ClearAll@squareD;
square@i_IntegerD := i2
square@i_RealD := Floor@iD2
square@i_ComplexD := Re@iD2
square@a_SymbolD := a2
square@SomeDataType@a_DD := a2
In[28]:=
2
2
Out[28]= 94, 4, 4, x , x =
One or more
__
Zero or more
In[29]:=
In[34]:=
ClearAll@listOpD;
listOp@8<D := 8<
listOp@8x_, y_<D := 8y, x<
listOp@8x_, xs__<D := 8xs<
listOp@l : 88__< ...<D := Reverse@lD
___
H* flip a tuple *L
H* drop the first element *L
H* match a list of lists *L
8listOp@81, 2, 3<D, listOp@81, 2<D, listOp@8 81, 2<, 83, 4< <D <
FunctionalProgramming-Egypt-2010.nb
Guards on Patterns
Guards on Domains
Guards can be specified using the Pattern ? Predicate notation
In[35]:=
ClearAll@collatzD;
collatz@n_Integer ? EvenQD := n 2 H* Matches only even integers *L
collatz@n_IntegerD := 3 n + 1 H* Matches all integers *L
In[38]:=
8collatz@3D, collatz@4D<
Arbitrary Conditions
A condition can be specified on a pattern using Pattern /; Predicate notation
In[39]:=
For example
In[40]:=
bubbleSort@83, 2, 1<D
In[211]:=
13
14
FunctionalProgramming-Egypt-2010.nb
Pure Functions
Defining a Pure Function
The Notation
A function that squares its argument
In[41]:=
x x2
2
Out[41]= FunctionAx, x E
In[42]:=
Ix x2 M@3D
Out[42]= 9
In[43]:=
8x, y<
x2 + y2
@3, 4D
Out[43]= 5
In[44]:=
2 &@3D
Out[44]= 9
In[45]:=
Out[45]= 5
12 + 22 &@3, 4D
FunctionalProgramming-Egypt-2010.nb
Higher-Order Functions
Map
Map as a function call
In[46]:=
2
2
2
2
Out[46]= 9a , b , c , d =
In[47]:=
Ix x2 M 8a, b, c, d<
2
2
2
2
Out[47]= 9a , b , c , d =
In[48]:=
Hx-L2
2 2
H-8 + 3 L 2
Out[48]= 99, ,
x2
x-1+ -
=, 92
2 2
=, 9 , ,
==
Gamma@D
Or a composed function
In[215]:=
H
O
C
H
H
O
C
N
N
H
N
N
N
N
C
H
O
Out[215]=
C
H
C
O
O
H
15
16
FunctionalProgramming-Egypt-2010.nb
In[50]:=
ClearAll@tux, browsersD;
8tux, browsers< = 9
, 9
==;
Manipulate@
Map@
ImageCompose@tux, ImageResize@, Scaled@scaleDD, 8horizontal, vertical<D &, browsers
D GraphicsRow,
8scale, 0.5, 1<,
8horizontal, 60, 200, 10<,
8vertical, 60, 200, 10<
D
scale
horizontal
vertical
Out[52]=
Select
In[53]:=
Fold
In[54]:=
Out[54]= a + b + c + d
FunctionalProgramming-Egypt-2010.nb
In[218]:=
Manipulate@
8
Fold@F@1, 2D &, x, Take@8a,
TreeForm@, AspectRatio
Fold@F@2, 1D &, x, Take@8a,
TreeForm@, AspectRatio
< GraphicsRow Magnify@,
8step, 0, 4, 1<
D
b, c, d<, stepDD
1.2, PlotLabel
b, c, d<, stepDD
1.2, PlotLabel
1D &,
step
Fold Left
Fold Right
F
Out[218]=
Power Set
In[56]:=
In[57]:=
FoldList@8set, element< set H ~ Append ~ element & setL, 88<<, 8, , <D Column
88<<
88<, 8<<
Out[57]= 88<, 8<, 8<, 8, <<
88<, 8<, 8<, 8<, 8, <, 8, <, 8, <, 8, , <<
NestWhileList
In[58]:=
NestWhileListAx
, 32, i i 1E
2
Out[58]= 832, 16, 8, 4, 2, 1<
Pascal Triangle
Pascal triangle can be defined using binomials
17
18
FunctionalProgramming-Egypt-2010.nb
In[59]:=
81<
81, 1<
81, 2, 1<
Out[59]=
81, 3, 3, 1<
81, 4, 6, 4, 1<
In[60]:=
tuples@8<
8x_<D := 8<
tuples@8x_, y_, ys___<D := 8x + y< ~ Join ~ tuples@8y, ys<D
pascal@h_D := NestWhileList@81< ~ Join ~ tuples@D ~ Join ~ 81< &, 81<, Length@D < h &D
pascal@9D Column@, CenterD &
81<
81, 1<
81, 2, 1<
81, 3, 3, 1<
81, 4, 6, 4, 1<
Out[63]=
81, 5, 10, 10, 5, 1<
81, 6, 15, 20, 15, 6, 1<
81, 7, 21, 35, 35, 21, 7, 1<
81, 8, 28, 56, 70, 56, 28, 8, 1<
In[64]:=
ClearAll@hexagon, renderD;
2k
hexagon@x_, y_D := PolygonATableA9SinA
2k
E + x, CosA
Length@lD
render@l_ListD := GraphicsA9HueA
1
1
Out[67]=
1
1
1
3 n + 1 Problem
2
3
1
3
1
4
FunctionalProgramming-Egypt-2010.nb
3 n + 1 Problem
In[68]:=
n2
EvenQ@nD
3 n + 1 OddQ@nD
NestWhileList@collatz, 200, m m 1D
collatz := n
Out[69]= 8200, 100, 50, 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1<
In[70]:=
Manipulate@
MapIndexed@
Text@Style@1, Blue, Italic, 45 - 2DD &, NestWhileList@collatz, x, m m != 1DD,
8x, 10, 100, 10<
D
Out[70]=
70 35 106 53 160
80 40 20 10 5 16 8 4 2 1
,
19
20
FunctionalProgramming-Egypt-2010.nb
data Tree a =
Empty | Node (Tree a) a (Tree a) deriving(Show, Eq)
insert :: Ord a => a -> Tree a -> Tree a
insert n Empty = Node Empty n Empty
insert n (Node left x right)
| n < x
= Node (insert n left) x right
| otherwise = Node left x (insert n right)
inorder :: Ord a => Tree a -> [a]
inorder Empty = []
inorder (Node left x right) =
inorder left ++ [x] ++ inorder right
bst :: Ord a => [a] -> Tree a
bst [] = Empty
bst (x : xs) = foldr(insert) (insert x Empty) xs
Mathematica
The same algorithm in Mathematica syntax
In[71]:=
In[80]:=
FunctionalProgramming-Egypt-2010.nb
In[82]:=
ClearAll@tupleD;
tuple@nilD := 8<
tuple@node@nil, x_, nilDD := 8<
tuple@node@l : node@_, a_, _D, x_, nilDD := tuple@lD ~ Join ~ 8x a<
tuple@node@nil, x_, r : node@_, b_, _DDD := 8x b< ~ Join ~ tuple@rD
tuple@node@l : node@_, a_, _D, x_, r : node@_, b_, _DDD :=
tuple@lD ~ Join ~ 8x a, x b< ~ Join ~ tuple@rD
Then
In[88]:=
In[89]:=
88,3,10,1,0,4,6,5,9,12,2,7,13,11<
Out[89]=
10
12
11
13
21
22
FunctionalProgramming-Egypt-2010.nb
In[214]:=
step
91
57
99
43
92
Out[214]=
11
50
48
FunctionalProgramming-Egypt-2010.nb
In[91]:=
CasesA9a2 , b3 , c4 , d5 , e6 =, _2 E
2
Out[91]= 9a =
In[92]:=
2
4
6
Out[92]= 9a , c , e =
In[93]:=
4
6
Out[93]= 9b , d =
In[94]:=
Decompose an expression
In[95]:=
Match rules
23
24
FunctionalProgramming-Egypt-2010.nb
In[96]:=
ClearAll@gD;
g = 8
,
i,
a,
<;
GraphPlot@g,
,
j,
b
VertexLabeling True, AspectRatio 0.2D Magnify@, 1.5D &
Out[98]=
In[99]:=
Example: Palindrome
Generate a sequence of probable palindrome integers
In[100]:=
Out[101]= 877, 154, 605, 1111, 2222, 4444, 8888, 17 776, 85 547, 160 105, 661 166, 1 322 332, 3 654 563, 7 309 126, 13 528 163<
In[102]:=
isPalindrome@seq_ListD := seq . 8
8<
8x_< True,
8x_, xs___, y_< x == y && isPalindrome@8xs<D
<
In[103]:=
Out[103]= 877, 1111, 2222, 4444, 8888, 661 166, 3 654 563<
FunctionalProgramming-Egypt-2010.nb
In[104]:=
In[105]:=
runLengthEncoding@8a, a, a, b, b, c, c, c, c, a, a<D
In[106]:=
ClearAll@ruleD;
rule = 8head___, 8x_, n_<, 8x_, m_<, tail___< 8head, 8x, n + m<, tail<;
Second, generate a list tuples of the form 88e1 , 1<, 8e2 , 1<, ..., 8en , 1<<
In[108]:=
Out[108]= 88a, 1<, 8a, 1<, 8a, 1<, 8b, 1<, 8b, 1<, 8c, 1<, 8c, 1<, 8c, 1<<
In[109]:=
% . rule
Out[109]= 88a, 2<, 8a, 1<, 8b, 1<, 8b, 1<, 8c, 1<, 8c, 1<, 8c, 1<<
25
26
FunctionalProgramming-Egypt-2010.nb
In[225]:=
Out[225]= XMLObject@DocumentD@8<,
XMLElement@v, 8id root<, 8XMLElement@v, 8id a<, 8XMLElement@v, 8id a1, cost 1<, 8<D,
XMLElement@v, 8id a2, cost 2<, 8<D, XMLElement@v, 8id a3, cost 3<, 8<D<D,
XMLElement@v, 8id b<, 8XMLElement@v, 8id b1, cost 4<, 8<D, XMLElement@v, 8id b2, cost 5<, 8<D,
XMLElement@v, 8id b3, cost 6<, 8<D<D, XMLElement@v, 8id c<, 8XMLElement@v, 8id c1, cost 7<, 8<D,
XMLElement@v, 8id c2, cost 8<, 8<D, XMLElement@v, 8id c3, cost 9<, 8<D<D<D, 8<D
The XML document represents a graph, each vertex v is represented as an element. Children of an element are connected to the parent, the
hierarchy represents the edges. The following functions use Mathematica XML support to create a garph representation of the XML document and plot it
In[226]:=
Recursively walk the element structure and create a Mathematica graph representation
In[231]:=
rec@root@xmlDD
Out[231]= 88root a, 0<, 8root b, 0<, 8root c, 0<, 8a a1, 1<, 8a a2, 2<,
8a a3, 3<, 8b b1, 4<, 8b b2, 5<, 8b b3, 6<, 8c c1, 7<, 8c c2, 8<, 8c c3, 9<<
FunctionalProgramming-Egypt-2010.nb
In[232]:=
27
a1
c3
a2
c2
2
8
a
c
0
0
7
root
Out[232]=
a3
c1
0
b
4
b1
6
5
b3
b2
Sequence Alignment
In[118]:=
In[119]:=
In[124]:=
28
FunctionalProgramming-Egypt-2010.nb
In[125]:=
In[126]:=
FunctionalProgramming-Egypt-2010.nb
for $x in doc("books.xml")/bookstore/book
where $x/price>30
order by $x/title
return $x/title
XML in Mathematica
Mathematica XML Support
Import the XML document
In[127]:=
29
30
FunctionalProgramming-Egypt-2010.nb
In[128]:=
In[140]:=
Out[140]= 8Everyday Italian, Harry Potter, XQuery Kick Start, Learning XML<
In[141]:=
Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan, Erik T. Ray<
In[142]:=
Hdoc@xmlD e@"book"DL ~
return ~ Hbs
HHdata@"author"D@D . 8a_< aL Hdata@"title"D@D . 8t_< tLL & bs
L
8James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan< XQuery Kick Start,
Erik T. Ray Learning XML<
In[143]:=
Hdoc@xmlD e@"book"DL ~
where ~ Hb b data@"price", ToExpression@D > 30 &DL ~
return ~ data@"title"D
FunctionalProgramming-Egypt-2010.nb
In[144]:=
Hdoc@xmlD e@"book"DL ~
where ~ Hb b attribute@"category", == "COOKING" &DL ~
return ~ data@"title"D
In[145]:=
Hdoc@xmlD e@"book"DL ~
where ~ Hb H
Hb data@"price", ToExpression@D > 40 &DL && Hb attribute@"category", == "WEB" &DL
L L~
return ~ data@"title"D
In[146]:=
Hdoc@xmlD e@"book"DL ~
where ~ Hb b attribute@"category", == "WEB" &DL ~
orderBy ~ HOrder@1 data@"title"D, 2 data@"title"DD < 0 &L ~
return ~ data@"title"D
All books in WEB category, ordered by title in ascending order, formatted as { title price } list
In[147]:=
Hdoc@xmlD e@"book"DL ~
where ~ Hb b attribute@"category", == "WEB" &DL ~
orderBy ~ HOrder@1 data@"title"D, 2 data@"title"DD > 0 &L ~
return ~ Hbs
HHdata@"title"D@D . 8t_< tL Hdata@"price"D@D . 8p_< pLL & bs
L
31
32
FunctionalProgramming-Egypt-2010.nb
Example: SQL
Establish a Database Connection
H* HSQL memory db *L
Needs@"DatabaseLink`"D
bookstore = OpenSQLConnection@D;
In[148]:=
In[150]:=
Out[152]= 8BOOK<
In[153]:=
In[155]:=
In[156]:=
Out[156]//TableForm=
1
2
3
4
Everyday Italian
Harry Potter
XQuery Kick Start
Learning XML
2005
2005
2003
2003
30.
29.99
49.99
39.95
FunctionalProgramming-Egypt-2010.nb
CloseSQLConnection@bookstoreD
33
34
FunctionalProgramming-Egypt-2010.nb
In[158]:=
RotationTransform@D
Cos@D -Sin@D 0
Cos@D 0 E
0
0
1
In[159]:=
2
Out[161]= y Cos@D + x Sin@D Hx Cos@D - y Sin@DL
In[162]:=
2
Out[162]= x y
FunctionalProgramming-Egypt-2010.nb
In[163]:=
Out[163]=
-6
-4
-2
-2
-4
-6
In[165]:=
2
Out[165]= 9x y , x +
3 y 2 SinA
J 3 x - yNE=
2
35
36
FunctionalProgramming-Egypt-2010.nb
ShowA
ContourPlotA
Hrotate@y Sin@xD, 1 DL Evaluate,
8x, -2 , 2 <, 8y, -2 , 2 <,
Frame False,
Exclusions 99rotate@y Sin@xD, 1 D Evaluate, x2 + y2 > 25==,
1
ContourStyle [email protected], HueA
E=
Out[233]=
FunctionalProgramming-Egypt-2010.nb
Graph Instance
In[193]:=
Dynamic@gD;
g = graph@8
8vertex@D vertex 8, , <<,
8vertex@D vertex 81 , 2 , 3 <<,
8vertex@D vertex 81 , 2 , 3 <<,
8vertex@D vertex 81 , 2 , 3 <<<D;
37
38
FunctionalProgramming-Egypt-2010.nb
Graph Plot
In[219]:=
Out[219]=
chains@gD Dynamic
8VertexT@D,
8VertexT@D,
8VertexT@D,
8VertexT@D,
In[220]:=
Out[220]=
VertexT@D,
VertexT@D,
VertexT@D,
VertexT@D,
VertexT@2 D<,
VertexT@1 D<,
VertexT@3 D<,
VertexT@2 D<,
8VertexT@D,
8VertexT@D,
8VertexT@D,
8VertexT@D,
VertexT@D,
VertexT@D,
VertexT@D,
VertexT@D,
VertexT@3 D<,
VertexT@2 D<,
VertexT@1 D<,
VertexT@3 D<<
8GraphPlot@, VertexRenderingFunction
vrfD Magnify@, 1D &< & toRules chains g Partition@, 3D & TableForm Dynamic
FunctionalProgramming-Egypt-2010.nb
Example: Sound
The Sound of Mathematics
In[198]:=
39