Você está na página 1de 39

Functional Programming

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)

A more common notation is

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 , -

x4 - x2 + 1 = , 8x, -3, 3<, PlotRange 3,

AspectRatio 1, PlotStyle 88Black, Thick<<, AxesLabel 8x, y<E


y
3

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]:=

Axes True, Frame False, ContourStyle 8Thick<, AxesLabel 8x, y<E


y
3

Out[2]=

x
-3

-2

-1

-1

-2

-3

Functional Programming Languages


Functional Programming Languages has always been the natural choice for implementing computer derived solutions for mathematical
problems including Numerical Analysis, Combinatorics and Algorithms

Haskell
Implementation of the Quick Sort algorithm in Haskell. Demonstrates polymorphic types, pattern matching, list comprehension and
immutability

qsort :: Ord a => [a] -> [a]


qsort []
= []
qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater
where
lesser = [ y | y <- xs, y < p ]
greater = [ y | y <- xs, y >= p ]

Scala
Implementation of the Quick Sort algorithm in Scala. Demonstrates polymorphic types, pattern matching, object-oriented support and partial
functions application

def qsort[T <% Ordered[T]](list:List[T]):List[T] = {


list match {
case Nil Nil
case p::xs
val (lesser,greater) = xs partition (_ <= p)
qsort(lesser) ++ (p :: qsort(greater))
}
}

FunctionalProgramming-Egypt-2010.nb

def qsort[T <% Ordered[T]](list:List[T]):List[T] = {


list match {
case Nil Nil
case p::xs
val (lesser,greater) = xs partition (_ <= p)
qsort(lesser) ++ (p :: qsort(greater))
}
}

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

Out[6]= 80, 1, 2, 3, 4, 5, 6, 7, 8, 9<

FunctionalProgramming-Egypt-2010.nb

Functions in Mathematica
Numeric Computations
Numeric computations through function calls

Plus@1, Exp@-Times@I , PiDDD

In[210]:=

Out[210]= 0

Or through Mathematical notation

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]:=

Timing@Sort@RandomInteger@81, 10 000 000<, 100 000DDD Short

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

E + 1, T@1D 1=, T@nD, nE


3

Log@nD
Out[13]= 91 +

=
3

LogA E
2

Graphics
Stunning graphics

In[236]:=

HParametricPlot3D@ 8Cos@ D Sin@D, Sin@D Sin@D, Cos@D<, 8, 0, 2 <,


8, 0, <, PlotPoints 100, Mesh None, ColorFunction H8x, y, z, , < Hue@DL,
ColorFunctionScaling False, Boxed False, Axes FalseD Magnify@, .5D &L &
9Sin@D Cos@D, Sin@D Cos@D, Sin@ + D Cos@ + D, , , + =
Partition@, 3D & Grid

Out[236]=

FunctionalProgramming-Egypt-2010.nb

Define Your Own Function


A Function as a Rule
Functions can be defined as a delayed assignment rule

In[15]:=

f@x_D :=

x3 - x + 1

Functions can accept multiple parameters

In[16]:=

f@x_, a_, b_D :=

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]:=

81, 2, 3< ~ Join ~ 84, 5, 6<

Out[20]= 81, 2, 3, 4, 5, 6<

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

Domains and Patterns


Domains as Patterns
Domains can be specified as patterns

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]:=

8square@2.1D, square@2D, square@2 + 3 D, square@xD, square@SomeDataType@xDD<

2
2
Out[28]= 94, 4, 4, x , x =

Patterns and Lists


Expressive patterns on lists, notice how ordering is important

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 <

Out[34]= 882, 3<, 82, 1<, 883, 4<, 81, 2<<<

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<

Out[38]= 810, 2<

Arbitrary Conditions
A condition can be specified on a pattern using Pattern /; Predicate notation

Example : Bubble Sort


By Dr Jon D Harrop, 2010 (Modified)
Using pattern matching and conditions on patterns, bubble sort can then be defines as

In[39]:=

bubbleSort@8xs___, x_, y_, ys___<D := bubbleSort@8xs, y, x, ys<D ; x y

For example

In[40]:=

bubbleSort@83, 2, 1<D

Out[40]= bubbleSort@81, 2, 3<D

We can simply extract the sorted list using the rule

In[211]:=

bubbleSort@83, 2, 1<D . _@sorted_D sorted

Out[211]= 81, 2, 3<

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

Square function applied at 3

In[42]:=

Ix x2 M@3D

Out[42]= 9

A function with a list as its argument

In[43]:=

8x, y<

x2 + y2

@3, 4D

Out[43]= 5

The (# &) Notation


The notation is programmatically equivalent to the notation
Square function applied at 3

In[44]:=

2 &@3D

Out[44]= 9

A pure function with 2 arguments, notice the numbering after #

In[45]:=
Out[45]= 5

12 + 22 &@3, 4D

FunctionalProgramming-Egypt-2010.nb

Higher-Order Functions
Map
Map as a function call

In[46]:=

MapAx x2 , 8a, b, c, d<E

2
2
2
2
Out[46]= 9a , b , c , d =

Using the ( /@ ) Notation

In[47]:=

Ix x2 M 8a, b, c, d<

2
2
2
2
Out[47]= 9a , b , c , d =

The mapped function can be composed of any type of expression

In[48]:=

8Mean@D, Variance@D, PDF@, xD< &


8NormalDistribution@, D, MaxwellDistribution@D, GammaDistribution@, D<
x2

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]:=

HChemicalData@"Caffeine", D Magnify@, .5D &L & 8


"CHColorStructureDiagram", "CHStructureDiagram", "ColorStructureDiagram", "StructureDiagram",
"MoleculePlot", "SpaceFillingMoleculePlot"< Partition@, 3D & Grid@, Frame AllD &

H
O

C
H

H
O

C
N

N
H

N
N

Or used inside a manipulation

N
N
C

H
O

Out[215]=

C
H

C
O

O
H

15

16

FunctionalProgramming-Egypt-2010.nb

Or used inside a manipulation

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]:=

Select@8-1, 3, -2, 5, 0<, n 0 < nD

Out[53]= 83, 5<

Fold
In[54]:=

Fold@8x, y< x + y, 0, 8a, b, c, d<D

Out[54]= a + b + c + d

Folding to the left or to the right

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 &,

"Fold Left"D &,

"Fold Right"D &

step

Fold Left

Fold Right
F

Out[218]=

Power Set

In[56]:=

Fold@8set, element< set H ~ Append ~ element & setL, 88<<, 8, , <D

Out[56]= 88<, 8<, 8<, 8<, 8, <, 8, <, 8, <, 8, , <<

One more time

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]:=

Table@Binomial@n, kD, 8n, 0, 4<, 8k, 0, n<D Column@, CenterD &

81<
81, 1<
81, 2, 1<
Out[59]=
81, 3, 3, 1<
81, 4, 6, 4, 1<

This can defined using the pattern

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<

And nicely manipulated,

In[64]:=

ClearAll@hexagon, renderD;
2k
hexagon@x_, y_D := PolygonATableA9SinA

2k
E + x, CosA

E + y=, 8k, 6<EE


6

Length@lD
render@l_ListD := GraphicsA9HueA

E, hexagon@0, 0D, Text@Style@, White, Bold, 10 DD=E & l

GraphicsRow@, ImageSize 850 * Length@D, 30<, Spacings 82, 0<D &


Manipulate@
Graphics@Hrender@D & pascal@hDL GraphicsColumn@, Alignment Center, Spacings 80, -8<D &D
Magnify@, 1.5D &,
8h, 1, 5, 1<
D

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

Example: Binary Search Tree


Haskell
Haskell approach to Algebraic Data Types and Pattern Matching

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]:=

ClearAll@tree, insert, inorder, bstD;


tree = nil
node@_, _, _D;
insert@n_, nilD := node@nil, n, nilD;
insert@n_, node@l_, x_, r_DD ; n < x := node@Hinsert@n , lDL , x , rD;
insert@n_, node@l_, x_, r_DD := node@l, x, Hinsert@n, rDLD;
inorder@nilD := 8<;
inorder@node@l_, x_, r_DD := inorder@lD ~ Join ~ 8x< ~ Join ~ inorder@rD;
bst@8<D := nil
bst@8x_, xs___<D := Fold@insert@2, 1D & , insert@x, nilD, 8xs<D;

In[80]:=

inorder bst@88, 3, 10, 1, 6, 9, 12, 4, 7, 13, 11<D

Out[80]= 81, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13<

Visualizing a Binary Search Tree


In order to be able to visualize a BST, we need to convert the tree of nodes into a {src dst, ...} representation. Using our structure, the
binary search tree of the list {8, 3, 10, 1, 6} is
In[81]:=

bst@88, 3, 10, 1, 6<D

Out[81]= node@node@node@nil, 1, nilD, 3, node@nil, 6, nilDD, 8, node@nil, 10, nilDD

We can then define

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]:=

tuple@bst@88, 3, 10, 1, 6, 9, 12, 4, 7, 13, 11<DD

Out[88]= 83 1, 3 6, 6 4, 6 7, 8 3, 8 10, 10 9, 10 12, 12 11, 12 13<

Plotting the BST

In[89]:=

TreePlot@tuple@bst@88, 3, 10, 1, 0, 4, 6, 5, 9, 12, 2, 7, 13, 11<DD,


Automatic, 8, VertexLabeling True, DirectedEdges True,
PlotLabel "88,3,10,1,0,4,6,5,9,12,2,7,13,11<", VertexRenderingFunction
H8ps, v< 8White, EdgeForm@8Black, Thick<D, Disk@ps, .2D, Black, Text@v, psD<LD

88,3,10,1,0,4,6,5,9,12,2,7,13,11<

Out[89]=

10

12

11

We can then visualize a random BST construction step by step

13

21

22

FunctionalProgramming-Egypt-2010.nb

In[214]:=

With@8l = RandomInteger@81, 100<, 10D DeleteDuplicates<,


Manipulate@
8
Text@Style@Framed@lD, 12, Bold, Black DD,
TreePlot@
tuple bst Take@l, stepD,
Automatic, l@@1DD, VertexLabeling True, DirectedEdges True, VertexRenderingFunction
H8ps, v< 8White, EdgeForm@8Black, Thick<D, Disk@ps, .2D, Black, Text@v, psD<L,
ImageSize 8400, 300<, ImagePadding 1
D,
Text@Style@Framed@inorder bst Take@l, stepDD, 12, Bold, BlueDD
< Column@, CenterD &,
8step, 2, Length@lD, 1<
D
D

step

891, 57, 43, 99, 92, 50, 11, 48, 89<

91

57

99

43

92

Out[214]=

11

50

48

811, 43, 48, 50, 57, 91, 92, 99<

FunctionalProgramming-Egypt-2010.nb

Pattern Matching and Transformation


Matching Cases
Match Cases

In[91]:=

CasesA9a2 , b3 , c4 , d5 , e6 =, _2 E

2
Out[91]= 9a =

Match Cases with a predicate

In[92]:=

CasesA9a2 , b3 , c4 , d5 , e6 =, _n_ ; EvenQ@nDE

2
4
6
Out[92]= 9a , c , e =

Match Cases with a predicate and a transformation rule

In[93]:=

CasesA9a2 , b3 , c4 , d5 , e6 =, x_n_ ; OddQ@nD xn+1 E

4
6
Out[93]= 9b , d =

Pattern Matching and Rules


Swap is simple

In[94]:=

8a, b< . 8x_, y_< 8y, x<

Out[94]= 8b, a<

Decompose an expression

In[95]:=

x Sin@D - y Cos@D . Ha_ Sin@_D - b_ Cos@_DL 8a, b, <

Out[95]= 8x, y, <

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]=

Use delayed rules

In[99]:=

H* find the children of the vertex in the Graph g *L


. 8 H x_L 8x< , _ 8< < & g Flatten

Out[99]= 8a, b<

Example: Palindrome
Generate a sequence of probable palindrome integers

In[100]:=

alg196@n_IntegerD := n + HIntegerDigits@nD Reverse FromDigitsL


NestWhileList@alg196, 77, < 10 000 000 &D

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<

Recursively test if a sequence is a palindrome

In[102]:=

isPalindrome@seq_ListD := seq . 8
8<
8x_< True,
8x_, xs___, y_< x == y && isPalindrome@8xs<D
<

Test the sequence

In[103]:=

Select@NestWhileList@alg196, 77, < 10 000 000 &D, isPalindrome@IntegerDigits@DD &D

Out[103]= 877, 1111, 2222, 4444, 8888, 661 166, 3 654 563<

Example: Run Length Encoding


Perform run length encoding on a finite sequence
By Frank Zizza, 1990
Use replace repeated (//.)

FunctionalProgramming-Egypt-2010.nb

In[104]:=

runLengthEncoding@l_ListD := Map@8, 1< &, lD .


8head___, 8x_, n_<, 8x_, m_<, tail___< 8head, 8x, n + m<, tail<

In[105]:=

runLengthEncoding@8a, a, a, b, b, c, c, c, c, a, a<D

Out[105]= 88a, 3<, 8b, 2<, 8c, 4<, 8a, 2<<

How does the magic happen?


First define the magical rule

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]:=

Map@8, 1< &, 8a, a, a, b, b, c, c, c<D

Out[108]= 88a, 1<, 8a, 1<, 8a, 1<, 8b, 1<, 8b, 1<, 8c, 1<, 8c, 1<, 8c, 1<<

Keep applying the transformation until the input is exhausted

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

Example: Mathematica in Bioinformatics


XML in Mathematica
Mathematica supports a large variety of data formats, XML happens to be one of them

In[225]:=

xml = Import@"~workpresentationMathematica-Conference-2010codexmlgraph.xml", "XML"D

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]:=

ClearAll@root, id, cost, recD;


root@XMLObject@_D@_, r_, _DD := r
id@XMLElement@_, as_, 8___<DD := "id" . as
cost@XMLElement@_, 8as__<, 8___<DD := "cost" . 8as, _ "0"<
rec@e : XMLElement@"v", _, cs : 8___<DD :=
H8id e id , cost < & HcsLL ~ Join ~ Hrec cs Flatten@, 1D &L

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<<

Plot the extracted graph

FunctionalProgramming-Egypt-2010.nb

In[232]:=

27

rec@root@xmlDD GraphPlot@, VertexLabeling True, EdgeLabeling TrueD & Magnify@, 1D &

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]:=

xml = Import@"~workpresentationMathematica-Conference-2010codexmlsequenceML.xml", "XML"D;

In[119]:=

ClearAll@root, sequenceList, sequence, elementD;


root@XMLObject@_D@_, r_, _DD := r
sequenceList@XMLElement@"sequenceML", _, seqs_DD := sequence seqs
sequence@e : XMLElement@"sequence", 8"seqID" id_<, cs_DD :=
8
seqID id,
name element@"name", csD,
description element@"description", csD,
aminoAcidSequence element@"aminoAcidSequence", csD
<
element@name_, elements_D :=
Cases@elements, HXMLElement@n_, 8<, 8value_<D ; n === name valueLD First

In[124]:=

root@xmlD sequenceList First

Out[124]= 8seqID gi58374180gbAAW72226.1, name HA,

description Influenza A virus HAduckShandong0932004HH5N1LL, aminoAcidSequence


MEEIVLLLAIVSLVKSDQICIGYHANNSTEQVDTIMEKNVTVTHAQDILEKTHNGKLCDLDGVKPLILRDCSVAGWLLGNPMCDEFINVPEWSYIVEKANPAND
LCYPGDFNDYEELKHLLSRINHFEKIQIIPKSSWSDHEASSGVSSACPYNGKSSFFRNVVWLIKKNSSYPTIKRSYNNTNQEDLLILWGIHHPNDAAE
QTKLYQNPTTYISVGTSTLNQRLVPKIATRSKVNGQSGRMEFFWTILKPNDAINFESNGNFIAPEYAYKIVKKGDSAIMKSELEYGNCNTKCQTPMGA
INSSMPFHNIHPLTIGECPKYVKSNRLVLATGLRNTPQRERRRKKRGLFGAIAGFIEGGWQGMVDGWYGYHHSNEQGSGYAADKESTQKAIDGVTNKV
NSIIDKMNTQFEAVGREFNNLERRIENLNKKMEDGFLDVWTYNAELLVLMENERTLDFHDSNVKNLYDKVRLQLRDNAKELGNGCFEFYHKCDNECME
SVKNGTYDYPRYSEEARLNREEISGVKLESMGTYQILSIYSTVASSLALAIMVAGLSLWMCSNGSLQCRICI<

28

FunctionalProgramming-Egypt-2010.nb

In[125]:=

8first, last< = Hroot@xmlD sequenceListL . 8x_, ___, y_< 8x, y<

Out[125]= 88seqID gi58374180gbAAW72226.1, name HA,

description Influenza A virus HAduckShandong0932004HH5N1LL, aminoAcidSequence


MEEIVLLLAIVSLVKSDQICIGYHANNSTEQVDTIMEKNVTVTHAQDILEKTHNGKLCDLDGVKPLILRDCSVAGWLLGNPMCDEFINVPEWSYIVEKANPA
NDLCYPGDFNDYEELKHLLSRINHFEKIQIIPKSSWSDHEASSGVSSACPYNGKSSFFRNVVWLIKKNSSYPTIKRSYNNTNQEDLLILWGIHHPN
DAAEQTKLYQNPTTYISVGTSTLNQRLVPKIATRSKVNGQSGRMEFFWTILKPNDAINFESNGNFIAPEYAYKIVKKGDSAIMKSELEYGNCNTKC
QTPMGAINSSMPFHNIHPLTIGECPKYVKSNRLVLATGLRNTPQRERRRKKRGLFGAIAGFIEGGWQGMVDGWYGYHHSNEQGSGYAADKESTQKA
IDGVTNKVNSIIDKMNTQFEAVGREFNNLERRIENLNKKMEDGFLDVWTYNAELLVLMENERTLDFHDSNVKNLYDKVRLQLRDNAKELGNGCFEF
YHKCDNECMESVKNGTYDYPRYSEEARLNREEISGVKLESMGTYQILSIYSTVASSLALAIMVAGLSLWMCSNGSLQCRICI<,
8seqID gi108671045gbABF93441.1, name hemagglutinin,
description Influenza A virus HSt Jude H5N1 influenza seed virus 163222L, aminoAcidSequence
MEKIVLLLAIVSLVKSDQICIGYHANNSTEQVDTIMEKNVTVTHAQDILEKTHNGKLCDLDGVKPLILRDCSVAGWLLGNPMCDEFLNVPEWSYIVEKINPA
NDLCYPGNFNDYEELKHLLSRINHFEKIQIIPKSSWSDHEASSGVSSACPYQGRSSFFRNVVWLIKKNNAYPTIKRSYNNTNQEDLLVLWGIHHPN
DAAEQTRLYQNPTTYISVGTSTLNQRLVPKIATRSKVNGQSGRMEFFWTILKPNDAINFESNGNFIAPENAYKIVKKGDSTIMKSELEYGNCNTKC
QTPIGAINSSMPFHNIHPLTIGECPKYVKSNRLVLATGLRNSPQIETRGLFGAIAGFIEGGWQGMVDGWYGYHHSNEQGSGYAADKESTQKAIDGV
TNKVNSIIDKMNTQFEAVGREFNNLERRIENLNKKMEDGFLDVWTYNAELLVLMENERTLDFHDSNVKNLYDKVRLQLRDNAKELGNGCFEFYHRC
DNECMESVRNGTYDYPQYSEEARLKREEISGVKLESIGTYQILSIYSTVASSLALAIMVAGLSLWMCSNGSLQCRICI<<

In[126]:=

SequenceAlignment@aminoAcidSequence . first, aminoAcidSequence . lastD

Out[126]= 8ME, 8E, K<, IVLLLAIVSLVKSDQICIGYHANNSTEQVDTIMEKNVTVTHAQDILEKTHNGKLCDLDGVKPLILRDCSVAGWLLGNPMCDEF,

8I, L<, NVPEWSYIVEK, 8A, I<, NPANDLCYPG, 8D, N<, FNDYEELKHLLSRINHFEKIQIIPKSSWSDHEASSGVSSACPY,


8N, Q<, G, 8K, R<, SSFFRNVVWLIKKN, 8SS, NA<, YPTIKRSYNNTNQEDLL, 8I, V<, LWGIHHPNDAAEQT, 8K, R<,
LYQNPTTYISVGTSTLNQRLVPKIATRSKVNGQSGRMEFFWTILKPNDAINFESNGNFIAPE, 8Y, N<, AYKIVKKGDS, 8A, T<,
IMKSELEYGNCNTKCQTP, 8M, I<, GAINSSMPFHNIHPLTIGECPKYVKSNRLVLATGLRN, 8T, S<, PQ, 8R, I<, E, 8RRRKK, T<,
RGLFGAIAGFIEGGWQGMVDGWYGYHHSNEQGSGYAADKESTQKAIDGVTNKVNSIIDKMNTQFEAVGREFNNLERRIENLNKKMEDGFLDVWTYNAELLVLMEN
ERTLDFHDSNVKNLYDKVRLQLRDNAKELGNGCFEFYH, 8K, R<, CDNECMESV, 8K, R<, NGTYDYP,
8R, Q<, YSEEARL, 8N, K<, REEISGVKLES, 8M, I<, GTYQILSIYSTVASSLALAIMVAGLSLWMCSNGSLQCRICI<

FunctionalProgramming-Egypt-2010.nb

Example: Mathematica XQuery


XQuery
A fluent XML Query Language from W3C

XQuery FLWOR Expression


An XQuery expression is typically a for, let, where, order by and return construct

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]:=

xml = Import@"~workpresentationMathematica-Conference-2010xmlbooks.xml", "XML"D

Out[127]= XMLObject@DocumentD@8XMLObject@DeclarationD@Version 1.0, Encoding ISO-8859-1D<,

XMLElement@bookstore, 8<, 8XMLElement@book, 8category COOKING<,


8XMLElement@title, 8lang en<, 8Everyday Italian<D, XMLElement@author, 8<, 8Giada De Laurentiis<D,
XMLElement@year, 8<, 82005<D, XMLElement@price, 8<, 830.00<D<D,
XMLElement@book, 8category CHILDREN<, 8XMLElement@title, 8lang en<, 8Harry Potter<D,
XMLElement@author, 8<, 8J K. Rowling<D, XMLElement@year, 8<, 82005<D, XMLElement@price, 8<, 829.99<D<D,
XMLElement@book, 8category WEB<, 8XMLElement@title, 8lang en<, 8XQuery Kick Start<D,
XMLElement@author, 8<, 8James McGovern<D, XMLElement@author, 8<, 8Per Bothner<D,
XMLElement@author, 8<, 8Kurt Cagle<D, XMLElement@author, 8<, 8James Linn<D, XMLElement@author,
8<, 8Vaidyanathan Nagarajan<D, XMLElement@year, 8<, 82003<D, XMLElement@price, 8<, 849.99<D<D,
XMLElement@book, 8category WEB<, 8XMLElement@title, 8lang en<, 8Learning XML<D, XMLElement@
author, 8<, 8Erik T. Ray<D, XMLElement@year, 8<, 82003<D, XMLElement@price, 8<, 839.95<D<D<D, 8<D

XQuery like DSL in Mathematica


Define an XQuery like Domain Specific Language (DSL) for XML processing using Mathematica's Functional approach
The tiny language is a set of higher - order functions, each function returns a function that can act on the XML axis

29

30

FunctionalProgramming-Egypt-2010.nb

In[128]:=

ClearAll@doc, where, orderBy, e, att, attribute, data, returnD;


doc@XMLObject@DocumentD@_, root_, _DD := root;
where = Select;
orderBy = Sort;
e@n_StringD := es Cases@es, XMLElement@n , _, _D, D;
att@XMLElement@_ , rules_, _D, n_StringD := Hn . Hrules ~ Join ~ 8_ <LL;
attribute@XMLElement@_ , rules_, _D, n_StringD := 8n Hn . rulesL<;
attribute@ n_StringD := es attribute@, nD & es;
attribute@ n_String, pred_D := el pred@att@el, nDD;
data@n_StringD := es Cases@es, XMLElement@n , _, 8d_<D d, D;
data@n_String, pred_D := es HCases@es, XMLElement@n , _, 8d_<D ; pred@dD, D != 8<L;
return@es_, f_D := f es;

Mathematica XQuery DSL in Action


XPath Expressions
All book titles

In[140]:=

doc@xmlD e@"book"D data@"title"D

Out[140]= 8Everyday Italian, Harry Potter, XQuery Kick Start, Learning XML<

All book authors

In[141]:=

doc@xmlD e@"book"D data@"author"D

Out[141]= 8Giada De Laurentiis, J K. Rowling, James McGovern,

Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan, Erik T. Ray<

The return function


Return a { {author..} title} tuple

In[142]:=

Hdoc@xmlD e@"book"DL ~
return ~ Hbs
HHdata@"author"D@D . 8a_< aL Hdata@"title"D@D . 8t_< tLL & bs
L

Out[142]= 8Giada De Laurentiis Everyday Italian, J K. Rowling Harry Potter,

8James McGovern, Per Bothner, Kurt Cagle, James Linn, Vaidyanathan Nagarajan< XQuery Kick Start,
Erik T. Ray Learning XML<

The where function


All titles with price > 30

In[143]:=

Hdoc@xmlD e@"book"DL ~
where ~ Hb b data@"price", ToExpression@D > 30 &DL ~
return ~ data@"title"D

Out[143]= 8XQuery Kick Start, Learning XML<

All titles in the COOKING category

FunctionalProgramming-Egypt-2010.nb

In[144]:=

Hdoc@xmlD e@"book"DL ~
where ~ Hb b attribute@"category", == "COOKING" &DL ~
return ~ data@"title"D

Out[144]= 8Everyday Italian<

All titles in the WEB category with price > 40

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

Out[145]= 8XQuery Kick Start<

The order by function


Order by title in descending order

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

Out[146]= 8XQuery Kick Start, Learning XML<

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

Out[147]= 8Learning XML 39.95, XQuery Kick Start 49.99<

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]:=

Create the Book table


SQLDropTable@bookstore, D & SQLTableNames@bookstoreD;
SQLCreateTable@bookstore, SQLTable@"BOOK"D, 8
SQLColumn@"ID", "DataTypeName" "INTEGER"D,
SQLColumn@"TITLE", "DataTypeName" "VARCHAR", "DataLength" 128D,
SQLColumn@"YEAR", "DataTypeName" "VARCHAR", "DataLength" 4D,
SQLColumn@"PRICE", "DataTypeName" "FLOAT"D
<D;
SQLTableNames@bookstoreD

In[150]:=

Out[152]= 8BOOK<

Load books from XML


ClearAll@booksD;
books =
Hdoc@xmlD e@"book"DL ~ return ~
Hbs
8
data@"title"D@D . 8t_< t,
data@"year"D@D . 8y_< y,
data@"price"D@D . 8p_< p

In[153]:=

< & bsL


Out[154]= 88Everyday Italian, 2005, 30.00<, 8Harry Potter, 2005, 29.99<,

8XQuery Kick Start, 2003, 49.99<, 8Learning XML, 2003, 39.95<<

Load books into the Database


MapIndexed@
SQLInsert@bookstore, "BOOK", 8"ID", "TITLE", "YEAR", "PRICE"<, 2 ~ Join ~ 1D &, booksD;

In[155]:=

Query the Database


SQLSelect@bookstore, "BOOK"D TableForm

In[156]:=

Out[156]//TableForm=

1
2
3
4

Everyday Italian
Harry Potter
XQuery Kick Start
Learning XML

2005
2005
2003
2003

Close the Database Connection

30.
29.99
49.99
39.95

FunctionalProgramming-Egypt-2010.nb

Close the Database Connection


In[157]:=

CloseSQLConnection@bookstoreD

33

34

FunctionalProgramming-Egypt-2010.nb

Example: Geometric Transformation


The RotationTransform Function
Understanding the Function

In[158]:=

RotationTransform@D

Cos@D -Sin@D 0
Cos@D 0 E
0
0
1

Out[158]= TransformationFunctionA Sin@D

In[159]:=

RotationTransform@D 8x, y<

Out[159]= 8x Cos@D - y Sin@D, y Cos@D + x Sin@D<

Creating a Replacement Rule


In[160]:=

RotationTransform@D 8x, y< . 8a_, b_< 8x a, y b<

Out[160]= 8x x Cos@D - y Sin@D, y y Cos@D + x Sin@D<

Testing Our Rule


In[161]:=

Iy == x2 M . 8x x Cos@D - y Sin@D, y y Cos@D + x Sin@D<

2
Out[161]= y Cos@D + x Sin@D Hx Cos@D - y Sin@DL

In[162]:=

Iy Cos@D + x Sin@D Hx Cos@D - y Sin@DL2 M . 90

2
Out[162]= x y

FunctionalProgramming-Egypt-2010.nb

In[163]:=

ContourPlotA9y x2 , x y2 =, 8x, -2 , 2 <, 8y, -2 , 2 <,


Axes True, Frame False, ContourStyle 88Thick, Red<, 8Thick, Blue<<E

Out[163]=

-6

-4

-2

-2

-4

-6

Creating a Simple Rotate Function


In[164]:=

rotate@eq_, _D := Heq . HRotationTransform@D 8x, y< . 8a_, b_< 8x a, y b<LL

In[165]:=

9rotateAy == x2 , 90 E, rotate@y == Sin@xD, 30 D= FullSimplify


1

2
Out[165]= 9x y , x +

3 y 2 SinA

J 3 x - yNE=
2

35

36

FunctionalProgramming-Egypt-2010.nb

The Rotate Function in Action


In[233]:=

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 9Thickness@0.004D, HueA

E=

E & Range@0, 360, 10D


E Magnify@, 1D &

Out[233]=

FunctionalProgramming-Egypt-2010.nb

Example: Tree Chains


Graph Algebraic Data Type
Graph Structure and supporting functions
In[167]:=

ClearAll@Graph, graph, Vertex, vertex, Leaf, leaf,


Branch, tail, branch, succ, dft, concatMap, chains, toRules, vrfD;
Vertex = VertexT@d$ : _D;
vertex@d_D := VertexT@dD;
value@VertexD := d$;
Graph = GraphT@rep$ : 88_VertexT, 8_VertexT ...<< ...<D;
graph@rep : 88_VertexT, 8_VertexT ...<< ...<D := GraphT@repD;
graph@rep : 88_VertexT 8_VertexT ...<< ...<D :=
GraphT@H . 88x_ y : 8__<< 8x, y<<L & repD;
rep@GraphD := rep$;
Leaf = LeafT@v$ : VertexD;
leaf@v : VertexD := LeafT@vD;
vertex@LeafD := v$;
Branch = BranchT@v$ : Vertex, tail$ : 8__<D;
branch@v : Vertex, 8<D := leaf@vD;
branch@v : Vertex, l : 8___<D := BranchT@v, lD;
vertex@BranchD := v$;
tail@BranchD := tail$;
succ@g : Graph, v : VertexD := Cases@rep g, 8u : Vertex, adj_< ; u == v adjD Flatten;
dft@g : Graph, v : VertexD := branch@v, dft@g, D & succ@g, vDD;
concatMap@f_, l : 8__<D := Fold@Join, 8<, 8Flatten f < & lD;
chains@g : GraphD := chains@dft@g, Hrep gL@@1DD@@1DDDD;
chains@l : LeafD := 88vertex l<<;
chains@b : BranchD := HconcatMap@8vertex b, < &, chains@DDL & tail b Flatten@, 1D &;
toRules@g : GraphD := H . 88x_, y : 8__<< HHx L & yL<L & rep g Flatten;
toRules@ch : 8_VertexT ...<D := ch . 88x_< 8<, 8x_, y_, xs___< 8Hx yL< ~ Join ~ toRules@8y, xs<D<;
toRules@chs : 88_VertexT ...< ...<D := toRules@D & chs;
vrf = 8ps, v< 8White, EdgeForm@BlackD, Disk@ps, .3D, Black, Text@value v, psD<;

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]:=

LayeredGraphPlot@g toRules, VertexRenderingFunction vrfD Magnify@, 1D & Dynamic

Out[219]=

Chains and Chains Plot


In[196]:=

chains@gD Dynamic

Out[196]= 88VertexT@D, VertexT@D, VertexT@1 D<,

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]:=

n11 = 811, 2, 7, 9, 11, 2, 7, 5, 11, 2, 7, 4, 2, 2, 2<;


a11 = n11 ;
a12 = + 12 & n11 ;
a13 = a12 ~ Join ~ a11 ;
a14 = a13 ~ Join ~ Reverse@a12 D ~ Join ~ n11 ;
s1 = Sound@SoundNote@, .1, "Flute"D & Ha14 LD;
n21 = 82, 3, 7, 2, 3, 7, 2, 3, 9, 9, 7, 3<;
a21 = n21 ;
a22 = H + 12 & n21 L . 8xs__< 8xs, xs<;
a23 = a22 ~ Join ~ a21 ~ Join ~ Reverse@H + 12 & a21 LD ~ Join ~ Reverse@a21 D;
s2 = Sound@SoundNote@, .1, "Piano"D & Ha23 LD;
EmitSound@8s1 , s2 <D

39

Você também pode gostar