Vous êtes sur la page 1sur 30

mmatutorial.

nb

A Brief Mathematica Tutorial


Steven Tschantz
4/19/02

1. Notebooks and Kernel


Mathematica is two programs; a notebook editor and a computational kernel. The notebook editor is also your means of
communicating with the kernel. When you type into an input cell and evaluate by pressing enter (or shift-return), the data
from that cell is sent to the kernel which evaluates the input. The results of the calculation (if any) is then put into the
notebook directly after the input cell, replacing any previous output that may have been at that point. If you evaluate input
cells in order from the beginning of a notebook, the notebook will exhibit a complete record of your calculations. Subdividing this record into sections and annotating the calculation with text cells allows for complete documentation of your work.
Of course, no one types perfectly nor does one usually know exactly what calculations he will want to do. Thus you will
often go back, edit an input and reevaluate to get a new result. The inputs to and outputs from the kernel are numbered to
assist you in recovering the sequence of evaluations that got you to a given result, but these numbers are not saved with the
notebook and you will not know the order of evaluation if you want to reevaluate the notebook. To maintain the continuity
of your record of calculations you must be aware of what side effects of calculations recorded later in the notebook may be
affecting the reevaluation of an earlier input. In general, you are safe if every definition on which a given calculation
depends has either never been changed or you have also reevaluated those definitions.
One problem that can occur is if you start a new notebook with definitions from another notebook having already been
evaluated by the kernel. You can avoid inadvertently using definitions not recorded in your notebook by quitting the kernel
(in the kernel menu) and starting the notebook calculations with a fresh kernel. Another problem that can occur is when a
calculation assumes a variable is undefined but later you defined a value for the variable. When you try to reevaluate the
calculation without clearing the variable you may get unexpected (and unreproducible) results. The symbols % and %%
(etc.) represent the previous output and the second previous output (etc.) and as such are always being redefined. If you
use % then you have to evaluate the earlier input(s) before reevaluating an input containing these special symbols.
While the editor is basically what-you-see-is-what-you-get, the kernel state is entirely a function of the history of evaluations you have performed. You need to make sure the notebook adequately reflects the sequence of evaluations that led to
a given result, if you every want to reproduce the calculation.

It's best if you keep your notebook input cells in an order which, if reevaluated with a new kernel, would give the same results.

mmatutorial.nb

Puzzle
To see the problems that can occur, consider that the following inputs and outputs arose in some order of evaluation. Can
you determine an order of evaluation that would reproduce these results?

Input A
tablen = Table@i ^ 2, 8i, 1, n<D

81, 4, 9, 16, 25, 36, 49, 64, 81, 100<

A table of the first 10 squares. {1,4,9,16,25,36,49,64,81,100}

Input B
n=5
5

Five. 5

Input C
b = na + 1

1 + 5 H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 L

A polynomial. 1 + 5 H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 L

Input D
prodab = a b

a H1 + 5 H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 LL

A polynomial. a H1 + 5 H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 LL

Input E
n = 10
10

Ten. 10

mmatutorial.nb

Input F
a =.

No printed result.

Input G
prodab = a b

b H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 L

A polynomial. b H1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5 L

Input H
sumn = Sum@i ^ 2, 8i, 1, n<D
1
n H1 + nL H1 + 2 nL
6

A general formula for the sum of squares.

1
6

n H1 + nL H1 + 2 nL

Input I
a = ExpandAll@Hx + 1L ^ nD
1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5

The binomial expansion of a fifth power. 1 + 5 x + 10 x2 + 10 x3 + 5 x4 + x5

Answer
HEABIGCFD
a =.
b =.
n =.
sumn =.
prodab =.
tablen =.

mmatutorial.nb

2. Assignments
One of the best ways of keeping long calculations organized is to give names to the intermediate results. By implementing
a calculation in small incremental steps, you can check that each step computes what was intended. Giving good names to
the intermediate results makes the intent of each step of a computation more clear and aids in correcting or modifying and
rerunning a part of the computation.
There are two forms of assignments in Mathematica, an immediate assignment = which evaluates the expression on the
right-hand side and assigns the value to the named variable (or pattern), and a delayed assignment := which assigns the
unevaluate expression to the named variable (or pattern) and reevaluates the right hand side each time the value is required.
The left hand side of an assignment can be a simple variable name. Mathematica functions start with capital letters, so you
should use an initial lower case letter. On the other hand, single letter symbols are often convenient for temporary variables, index variables, and other instances where a variable should not have a value, so it is generally better to use longer
names you won't be tempted to reuse in a different context.
Mathematica allows you to define functions using assignments when the left hand side is a function applied to dummy
arguments represented as a variable followed by the underscore. Function arguments are always delimited by brackets [].
The underscore declares a pattern variable which will be assigned the value of the argument when evaluating the right hand
side (where you don't use the underscore after the variable). Even more elaborate pattern definitions may be used on the
left hand sides of assignments, and conditions may be attached to definitions that allow definitions by cases. In assigning
to a simple variable, you usually want the right hand side evaluated once and that value used from then on, hence you want
a simple = assignment. In defining a function, you will usually want to wait until you have a value for the argument before
evaluating the right hand side and you would generally use a := delayed assignment.
A semicolon serves as a separator of statements within a sequence of expressions, the result of which is the result of last
expression. A semicolon after a calculation suppresses output of the result of the calculation. Thus if an intermediate result
will generate a long or uninteresting output you may follow the input by a semicolon. A delayed assignment generates no
output anyway (has a Null value) and so a semicolon would make no difference (unless the delayed assignment is part of a
larger expression).
The assignments = and := are of course different than the equality relation used to write equations, which in Mathematica is
written as ==. Unary functions can also be applied in postfix notation (as an after thought) as in x//f which stands for f[x].

Go ahead and assign the values of intermediate results to appropriately


named variables so you can refer to the variable later in your
calculation.
Examples
discountrate = 0.10
0.1

mmatutorial.nb

futurevalue = 100
100
timeinterval = 20
20
currentvalue = futurevalue H1 discountrateL ^ timeinterval
12.1577
discountrate = 0.05
0.05
currentvalue
12.1577

The computation has already been made and currentvalue is a numerical value.
currentvalue2 := futurevalue H1 discountrateL ^ timeinterval

No value is computed until currentvalue2 is called upon.


currentvalue2
35.8486
discountrate = 0.01
0.01
currentvalue2
81.7907

A better procedure is define currentvalue explicitly as a function of the discountrate variable.


currentvalue3@dr_D := futurevalue H1 drL ^ timeinterval
currentvalue3@0.01D
81.7907
currentvalue3@0.10D
12.1577

mmatutorial.nb

Plot@currentvalue3@drD, 8dr, 0, 0.2<, PlotRange 80, 100<D;


100
80
60
40
20

0.05

0.1

0.15

0.2

Note that without clearing the former definition of currentvalue, you cannot redefine it as a function.
currentvalue@dr_, fv_, t_D := fv H1 drL ^ t
SetDelayed::write : Tag Real in 12.1577@dr_, fv_, t_D is Protected.

$Failed
Clear@currentvalueD

currentvalue@dr_, fv_, t_D := fv H1 drL ^ t

discountrate
0.01
currentvalue@discountrate, futurevalue, timeintervalD
81.7907

For another example of the difference between immediate and delayed evaluation consider the following.
roll1 = 8Random@Integer, 81, 6<D, Random@Integer, 81, 6<D<

85, 4<

This is one random roll of dice stored (as a list) in roll1.


roll1

85, 4<
rollagain := 8Random@Integer, 81, 6<D, Random@Integer, 81, 6<D<

This defines rollagain to produce new numbers each time it is called.


rollagain
82, 3<

mmatutorial.nb

rollagain
82, 5<

Table@rollagain, 810<D

885, 2<, 86, 2<, 85, 1<, 86, 1<, 82, 3<, 86, 1<, 86, 2<, 81, 3<, 85, 1<, 81, 5<<

3. Rules
An alternative to making a fixed assignment to the value of a variable is to define a rule which specifies a value for the
variable to be substituted only when called upon explicitly. Thus x->4 is a substitution rule specifying that x is to be
replaced by 4 (the -> is converted to an arrow) and if we substitute in an expression such as x^2+2x+3 using this rule, say
x^2+2x+3/.x->4, only then will each occurrence of x be replaced by 4.
xrule = x 4
x4
expr = x ^ 2 + 2 x + 3
3 + 2 x + x2
exprvalue = expr . xrule
27

As with assignments, patterns may be used on the left-hand side of a rule. There is also a delayed rule :> where the righthand side is evaluated when substituted. Then /. operator is actually ReplaceAll, it replaces each occurrence of the lefthand side of a rule by the corresponding right-hand side. A list of rules (included in braces) can be used to specify several
simultaneous substitutions. Replace applies only to the whole expression (or optionally subexpressions and specified
depths). There is a ReplaceRepeated operation denoted by //. which repeatedly applies rules until there are no more
instances of a left-hand side of a rule.
The solution sets of a system of equations is returned by the Solve command as a list of lists of substitution rules. If there
is no solution then the empty list is returned. If the equations are satisfied identically, then there is one solution set consisting of an empty list of substitution rules.

Use rules and substitution to define particular instances of values of variables for variables which you might also want to use as free variables in
expressions and equations.
Examples
Solving a system of equations

mmatutorial.nb

eqns = 8x ^ 2 + y ^ 2

2 y + 24, x + y

8x2 + y2 == 24 + 2 y, x + y == 8<

8<

solns = Solve@eqns, 8x, y<D

88x 3, y 5<, 8x 4, y 4<<

On the other hand we might want y as a function of x for each equation.


ysoln1 = Solve@eqns@@1DD, yD

99y 1

!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!
25 x2 =, 9y 1 + 25 x2 ==

ysoln2 = Solve@eqns@@2DD, yD

88y 8 x<<

Thus we have the bottom and top halves of a circle and a line expressed as y equal to some function of x. The solutions
provided by Solve are lists of rules variable->value. Substituting in an expression using a list of rules is denoted by
expr/.rules. Rather than retyping the expressions we use the rules to define the functions. We use immediate assignments
so that the right hand side substitutions are applied immediately in making the definition.
circlebottom@x_D = y . ysoln1@@1DD
1

!!!!!!!!!!!!!!!
25 x2

circletop@x_D = y . ysoln1@@2DD
1+

!!!!!!!!!!!!!!!
25 x2

linefcn@x_D = y . ysoln2@@1DD
8x

mmatutorial.nb

Plot@8circlebottom@xD, circletop@xD, linefcn@xD<, 8x, 5, 8<, AspectRatio Automatic,


Epilog 8PointSize@0.03D, Point@8x, y<D . solns@@1DD, Point@8x, y<D . solns@@2DD<D;
Plot::plnr : circlebottom@xD is not a machinesize real number at x = 5.337258180501912`.
Plot::plnr : circlebottom@xD is not a machinesize real number at x = 5.052878378493442`.
Plot::plnr : circlebottom@xD is not a machinesize real number at x = 5.020832093525231`.
General::stop : Further output of Plot::plnr will be suppressed during this calculation.

12.5

10

7.5

2.5

-4

-2

-2.5

4. Lists and Matrices


A list in Mathematica is delimited by braces {} (and the order of elements matters. If alist is a list then alist[[i]] accesses
the i-th element of the list, if i is positive and at most the length of the list, or the |i|-th from last element of the list if i is
negative. The length of a list is given by the function Length, list can be joined by Join, or added to by Append or Prepend.
A matrix is a list of lists of the same length. Lists of matrices of the same size can be used as rank 3 tensors, etc. The
function Dimensions returns a list of integers giving the number of elements in the outermost list, followed by the number
of elements in each list of the list, etc. up to the rank of the tensor. For a matrix, Dimensions gives the dimensions {m,n} of
the matrix. The i-th row of matrix M is M[[i]], the i-th siblist of M. The i,j-th entry is M[[i,j]] (which is also M[[i]][[j]]).
For the j-th column you need to extract the j-th element from every row vector in the list M. Since Transpose gives the
transpose of a matrix, Transpose[M][[j]] is an easy way to get the j-th column. The inverse of a nonsingular square matrix
is Inverse[M], the determinent of a square matrix is Det[M].
Matrix multiplication is denoted by a dot (.), if M1 has as many columns as M2 has rows, then M1.M2 is their product (and
in general if the last dimension of M1 is the same as the first dimension of M2 these will be contracted). A list can be
thought of as either a row vector or a column vector.

mmatutorial.nb

10

Matrices can be input as literally a list of lists or by using a formatted input array. To output a list of lists as a matrix you
can use the function MatrixForm applied to the matrix. Similarly, TableForm prints as a table of values without the braces.
A list or matrix may be constructed using basic list operations or the Table function, if you have a formula for the i-th or i,jth entry. To construct a length 10 vector whose i-th entry if f[i] you can say Table[f[i],{i,1,10}], the second argument is
Mathematica's way of expressing an index variable with a start and end value (or you can write {i,start,end,increment} to
step by values other than 1). For matrices you would have two iterators, Table[f[i,j],{i,1,10},{j,1,5}] to make an 10 by 5
matrix.
Scalar multiplication of vectors and addition of vectors works as one would expect because times and plus thread over lists
as explained in the next section.
Every expression is a generalized list. The i-th argument of an expression e=f[x1,...xn] is given by e[[i]]. The function at
the head of this expression is Head[e], or e[[0]]. The function List doesn't actually evaluate anything but is used to represent a list.

Lists are used to represent vectors and matrices with all the usual functions for manipulating lists and operating on vectors and matrices.
Examples
Here is a matrix valued function.
rotateby@theta_D := 88Cos@thetaD, Sin@thetaD<, 8Sin@thetaD, Cos@thetaD<<;
MatrixForm@rotateby@Pi 4DD

i
j
j
j
j
j
j
k

1
!!!!
2
1
!!!!
2

1
!!!!
2
1
!!!!
2

y
z
z
z
z
z
z
{

MatrixForm@rotateby@Pi 2DD

0 1
N
1 0

Here are some vectors.


vectora = 82, 1<;
vectorb = 81, 3<;
General::spell1 : Possible spelling error: new symbol name "vectorb" is similar to existing symbol "vectora".

vectorab = vectora + vectorb


General::spell :
Possible spelling error: new symbol name "vectorab" is similar to existing symbols 8vectora, vectorb<.

83, 4<

mmatutorial.nb

11

Here we illustrate the parallelogram rule for vector addition, and rotation by 45 degrees taking vectora to the same direction
as vectorb.
Show@Graphics@8RGBColor@1, 0, 0D,
Line@880, 0<, vectora, vectorab, vectorb, 80, 0<<D, RGBColor@0, 1, 0D,
Line@880, 0<, vectorab<D, RGBColor@0.5, 0, 0D, Line@880, 0<, rotateby@Pi 4D.vectora,
rotateby@Pi 4D.vectorab, rotateby@Pi 4D.vectorb, 80, 0<<D,
RGBColor@0, 0.5, 0D, Line@880, 0<, rotateby@Pi 4D.vectorab<D,
RGBColor@0, 0, 0D, Text@"A", vectora, 82, 0<D, Text@"B", vectorb, 80, 2<D,
Text@"A+B", vectorab, 81, 1<D, Text@"A'", rotateby@Pi 4D.vectora, 81, 1<D,
Text@"B'", rotateby@Pi 4D.vectorb, 82, 0<D,
Text@"A'+B'", rotateby@Pi 4D.vectorab, 81, 0<D<,
AspectRatio Automatic, Axes True, AxesOrigin 80, 0<DD;
A'+B'

A+B

B
B'

A'

-1

vectora.vectorb
5
Sqrt@vectora.vectoraD Sqrt@vectorb.vectorbD 1 Sqrt@2D
5
Sqrt@vectorb.vectorbD Sqrt@vectora.vectoraD

!!!
2

Simplify@Sqrt@2D Hrotateby@Pi 4D.vectoraLD

81, 3<

vectorb
True

Simplify@Sqrt@2D Hrotateby@Pi 4D.vectoraLD

mmatutorial.nb

12

Here are some other matrices and tables.


amat = Table@i + 3 Hj 1L, 8i, 1, 3<, 8j, 1, 3<D

881, 4, 7<, 82, 5, 8<, 83, 6, 9<<


MatrixForm@amatD

i1 4 7z
y
j
j
j
z
2 5 8z
j
z
z
j
j
z
k3 6 9{

MatrixForm@Transpose@amatDD

1 2 3y
i
j
z
j
j
z
4 5 6z
j
z
j
z
j
z
7
8
9
k
{
Det@amatD
0

ptlist = Table@rotateby@j Pi 4D.80, 1<, 8j, 0, 7<D

1
1
980, 1<, 9 !!! , !!! =, 81, 0<,
2
2
1
1
1
1
1
1
9 !!! , !!! =, 80, 1<, 9 !!! , !!! =, 81, 0<, 9 !!! , !!! ==
2
2
2
2
2
2
TableForm@ptlistD
0

1
!!!!
2

1
!!!!
2

1
!!!!
2

1
!!!!
2

1
1
!!!!
2

1
!!!!
2
1
!!!!
2

1
!!!!
2

mmatutorial.nb

13

Show@Graphics@8RGBColor@0.5, 0.5, 1D, Polygon@ptlistD<, AspectRatio AutomaticDD;

ptlist2 = Transpose@rotateby@Pi 8D.Transpose@ptlistDD

Cos@ 8 D
Sin@ 8 D
Cos@ 8 D
Sin@ 8 D

E, CosA E=, 9

=,
!!!
!!!
!!!
!!!
8
8
2
2
2
2
Sin@ 8 D
Cos@ 8 D
Sin@ 8 D
Cos@ 8 D

+
,

=,
9CosA E, SinA E=, 9
!!!
!!!
!!!
!!!
8
8
2
2
2
2
Sin@ 8 D
Cos@ 8 D
Sin@ 8 D
Cos@ D

,
+
=,
9SinA E, CosA E=, 9 !!!8 +
!!!
!!!
!!!
8
8
2
2
2
2

99SinA

9CosA

Sin@ 8 D
Cos@ 8 D
Sin@ 8 D
Cos@ D

,
+
==
E, SinA E=, 9 !!!8
!!!
!!!
!!!
8
8
2
2
2
2

Dimensions@ptlist2D
88, 2<

mmatutorial.nb

14

Show@Graphics@8RGBColor@1, 0.2, 0.2D, Polygon@ptlist2D<, AspectRatio AutomaticDD;

5. Threading and Mapping over Lists


The programmers of Mathematica made addition of vectors (lists) and scalar multiplication of vectors speciaal cases of a
more general mechanism for extending various operations to list operations. Functions with the attribute Listable automatically Thread over list arguments. A function usually defined only for numbers is extended to vectors (or lists) by applying
the function componentwise. For a unary function like Abs, this means that the absolute value of a list of numbers is simly
the list of absolute values. For a binary function like Plus, if the arguments are lists of the same length, then corresponding
elements of the arguments are added together and a list of results is returned (the vector sum). On the other hand, if only
one of the arguements of a binary function is a list, then the function is applied with the same numerical argument combined with each element of the list. Thus Times with a constant and list argument multiplies each element of the list by the
constant (scalar multiplication). Functions of more than two arguments can also be Listable. Alternatively, when it is
desired to exchange a function applied to a list for the list of function values on elements of the list, the function Thread can
be used. Finally, to apply a function to each element of a list directly, the Map function is used with first argument the
(pure) function to use and second argument the list to Map over. To apply a function to a list of lists of arguments componentwise the function MapThread can be used.

Examples
Here are the attributes of Plus
Attributes@PlusD

8Flat, Listable, NumericFunction, OneIdentity, Orderless, Protected<

So vector addition works.

mmatutorial.nb

15

81, 2, 3< + 82, 4, 6<


83, 6, 9<

Similarly scalar multiplication works.


4 81, 2, 3<
84, 8, 12<

But we also have


81, 2, 3< 82, 4, 6<
82, 8, 18<

4 + 81, 2, 3<
85, 6, 7<

Let us define a function that applies only when the argument is a number, by using the pattern a_?NumberQ as the argument. The numerical integration would not work for symbolic or list arguments.
numf@a_ ? NumberQD := NIntegrate@E ^ x ^ 3, 8x, 0, a<D;
numf@1D
0.807511

Applied to a list of numbers this function does not evaluate.


numf@80, 1, 2, 3<D
numf@80, 1, 2, 3<D

If we want to take this expression and Thread numf over the list argument we take
Thread@numf@80, 1, 2, 3<DD

80., 0.807511, 0.892954, 0.89298<

Perhaps a more natural way of expressing the same computation is to skip constructing the intermediate nonevaluating
numf[{0,1,2,3}] and simply tell Mathematica to evaluate numf on each element of the list {0,1,2,3}.
Map@numf, 80, 1, 2, 3<D

80., 0.807511, 0.892954, 0.89298<

Note that the first argument of Map is just the function, not an expression involving the function. When using Map, it is
often convenient to skip assigning to a function and give an expression defining the function. The function Function takes
two arguments, a dummy variable (or variable list) and an expression defining a function in terms of that variable (or
variables). Thus we could also have written

mmatutorial.nb

16

Map@Function@a, NIntegrate@E ^ x ^ 3, 8x, 0, a<DD, 80, 1, 2, 3<D

80., 0.807511, 0.892954, 0.89298<

Fianlly, it is also possible to define a pure function without using the dummy variable. The symbol # stands for the argument of a pure function. A Function that uses # for its argument has short-hand notation consisting of the expression
followed by an ampersand &. The only problem with such an anonymous function definition is that such expressions
cannot be nested (you can't use an anonymous function inside an anonymous function). Again we have
Map@NIntegrate@E ^ x ^ 3, 8x, 0, #<D &, 80, 1, 2, 3<D

80., 0.807511, 0.892954, 0.89298<

Applying Listable function to matrices applies the function to each element of the matrix.
Abs@881, 2, 3<, 84, 5, 6<, 87, 8, 9<<D MatrixForm

1 2 3y
i
z
j
j
z
j
4 5 6z
z
j
z
j
z
j
7
8
9
{
k

To Map over the elements of a matrix, rather than over the list of its row vectors, a third argument is used to specify how
deep in the expression to Map.
Map@NIntegrate@E ^ x ^ 3, 8x, 0, #<D &,
881, 2, 3<, 84, 5, 6<, 87, 8, 9<<, 82<D MatrixForm

0.807511
0.892954
i
j
j
j
j
j
0.89298
2.59472
1052
j
j
j
j
146
0.89298
k 6.25947 10

2.02255 1010 y
z
z
z
z
5.96394 1091 z
z
z
z
z
0.89298
{

Here's an example of MapThread.


numf2@a_ ? NumberQ, b_ ? NumberQD := NIntegrate@E ^ x ^ 3, 8x, a, b<D;

Thread@f2@81, 0, 1<, 80, 1, 2<DD


8f2@1, 0D, f2@0, 1D, f2@1, 2D<

Thread@numf2@81, 0, 1<, 80, 1, 2<DD


81.3419, 0.807511, 0.0854423<

MapThread@numf2, 881, 0, 1<, 80, 1, 2<<D

81.3419, 0.807511, 0.0854423<

mmatutorial.nb

17

6. Modules and Procedural Programming


The classic programming style of subroutines with local variables, functions that return values and may have additional
global side-effects is upported by Mathematica modules. Remember that all of Mathematica's objects are functions applied
to arguments. With various functions, in particular control structures, arguments are evaluated after interpreting the function (if at all) instead of evaluated and passed to the function as values. The Module function takes a list of local variables,
with optional initialization, as its first argument, and (usually) a sequence of assignments and function calls separated by
semicolons. The definition of a function by a Module will ordinarily be made by := in order to delay execution of the
module until arguments are supplied, and to have the Module reevaluated each time the function is called. The result of the
last expression in the Module is the value of the Module (unless this is followed by a semicolon, in which case the value
would be Null). The standard control structures are represented in Mathematica by the functions If, Do, While, For,
Switch, and Which.
The If statement has first argument a test, the "then" statements to execute if the test evaluates to True, optional "else"
statements to execute if the test evaluates to False, and an optional fourth argument to define a result if the test returns
neither True nor False. If there is no fourth argument and the test returns neither True nor False, the If returns unevaluated,
awaiting values for symbolic variables in the test perhaps. Usually you want to avoid this possibility and unevaluated If's
probably represent an error in the test.
The Do command is like the Table command except that the first argument is evaluated for each value in the second
argument range specification and the result is Null and not the list of all results. Thus the Do command only makes sense if
the statements in the first argument actually have some side-effects, assigning to variables or producing output say.
The While and For commands are similar. The While command takes a test as first argument which is evaluated at the
beginning of each time through the loop to determine whether to exit the loop. The second argument is the body of the
loop. Any counting in a While loop must be done explicitly. The For command on the other hand takes four arguments,
the first intended for initializing the loop, the second a test for exiting the loop, the third a statement intended for incrementing a loop variable at the end of the loop and the fourth the body of the loop to be executed. Thus the following three
looping commands have essentially the same output (and only slightly different side-effects on the loop variable)..
Do@Print@i, " ", i ^ 2D, 8i, 1, 5<D
1 1
2 4
3 9
4 16
5 25

mmatutorial.nb

18

i = 1; While@i 5, Print@i, " ", i ^ 2D; i = i + 1D


1 1
2 4
3 9
4 16
5 25

For@i = 1, i 5, i = i + 1, Print@i, " ", i ^ 2DD


1 1
2 4
3 9
4 16
5 25

The Switch command allows evaluating an expression and testing it against a sequence of patterns, evaluating the statements corresponding to the first pattern that matches. The Which command performs a sequence of tests and evaluates the
statements corresponding to the first successful test.
Mathematica also has a Break command which allows immediate termination of a loop, Throw and Catch, and if you are
really a nonstructured programmer it has Goto and Label.

Example
fib@n_D := Module@8a, b, i<,
a = 0;
b = 1;
For@i = 1, i n, i = i + 1, 8a, b< = 8b, a + b<D;
aD;

Table@fib@iD, 8i, 0, 10<D

80, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55<


Timing@Table@fib@iD, 8i, 0, 100<D;D

80.25 Second, Null<

Timing@Table@Fibonacci@iD, 8i, 0, 100<D;D

80.15 Second, Null<

mmatutorial.nb

19

7. Functional Programming
Instead of thinking of a program as a sequence of steps that change values in storage locaations (variables), it is useful to
think of programs as compositions of functions. Input to a program can be arguments of a function call and the result is the
value of the function. By designing a program as a composition of simpler functions one can give a precise statement of
what each of the subfunctions is supposed to do and verify that the composition satisfies the specification of the program.
Each function becomes a program and each program can be used as a function in a more complicated program. The key is
to avoid functions that produce side-effects, except for the rare case of a functrion that is supposed to produce an output.
The syntax for assignments with a pattern on the left-hand side automatically makes the formal parameters in the definition
of a function local variables in the definition. Alternatively, the Function function takes a variable or a list of formal
variables to treat as formal parameters as its first argument and an expression (in those parameters) defining the function as
a second argument. Thus one can define a function of formal parameters without making an assignment. This is particularly useful for simple expressions defining expressions to mapped over lists or as conditions for Select and then the shorthand notation with # as argument and ending in & to denote a function is convenient. The only other subtle point is for
functions that evaluate their arguments in a non-standard way, e.g., control structures like If or functions using a (possibly
global) variable as an iterator like Table.

Example
Here is a function for drawing stars of various sizes, locations, and number of vertices. First we might define a function to
locate equally spaced points on a unit circle.
pointatangle@th_D := 8Cos@thD, Sin@thD<;
pointatangle@Pi 3D

1
,
2

!!!
3
=
2

A regular n-gon would have n vertices with angular spacing of 2Pi/n. Range[n] gives the list {1,2,...,n}. Scalar multiplying
this vector by 2Pi/n gives a list of the angles we want.
regularpolygon@n_D := Map@pointatangle, Range@nD 2 Pi nD;
regularpolygon@6D
99

1
,
2

!!!
!!!
!!!
!!!
3
1
3
1
3
1
3
=, 9 ,
=, 81, 0<, 9 ,
=, 9 ,
=, 81, 0<=
2
2
2
2
2
2
2

We can Show a Graphics object that has a such a regular polygon, preceeded by a color specification, and specifying equal
scales on both axes by declaring AspectRatio->Automatic.

mmatutorial.nb

20

Show@Graphics@8RGBColor@1, 1, 0D, Polygon@regularpolygon@6DD<, AspectRatio AutomaticDD;

A star will have equally spaced points but we connect points out of sequence with a constant angle between successive
points.
star1@n_, k_D := Map@pointatangle, Range@nD k 2 Pi nD;
star1@7, 3D
99CosA

6
6
12
12
18
18
E, SinA
E=, 9CosA
E, SinA
E=, 9CosA
E, SinA
E=,
7
7
7
7
7
7
24
24
30
30
36
36
9CosA
E, SinA
E=, 9CosA
E, SinA
E=, 9CosA
E, SinA
E=, 81, 0<=
7
7
7
7
7
7

Show@Graphics@8RGBColor@1, 1, 0D, Polygon@star1@7, 3DD<, AspectRatio AutomaticDD;

mmatutorial.nb

21

The Polygon command takes a list of points a colors points inside the closed path connecting each point to the next with the
last point connecting back to the first, at least if it is a simple closed curve. Here we see some white triangles. What
Mathematica counts is the winding number of the curve about the point coloring those with an odd winding number. While
this could be useful, this wasn't what was intended. The solution is to create the star as the union of a list of triangles.
star2@n_, k_D :=
Map@Append@#, 80, 0<D &, Transpose@8star1@n, kD, RotateRight@star1@n, kD, 1D<DD;
star2@7, 3D
999CosA

6
6
E, SinA
E=, 81, 0<, 80, 0<=,
7
7
12
12
6
6
99CosA
E, SinA
E=, 9CosA
E, SinA
E=, 80, 0<=,
7
7
7
7
18
18
12
12
99CosA
E, SinA
E=, 9CosA
E, SinA
E=, 80, 0<=,
7
7
7
7
24
24
18
18
99CosA
E, SinA
E=, 9CosA
E, SinA
E=, 80, 0<=,
7
7
7
7
30
30
24
24
99CosA
E, SinA
E=, 9CosA
E, SinA
E=, 80, 0<=,
7
7
7
7
36
36
30
30
99CosA
E, SinA
E=, 9CosA
E, SinA
E=, 80, 0<=,
7
7
7
7
36
36
981, 0<, 9CosA
E, SinA
E=, 80, 0<==
7
7

Show@Graphics@8RGBColor@1, 1, 0D, Map@Polygon, star2@7, 3DD<, AspectRatio AutomaticDD;

But we wanted to make stars of various sizes and locations as well. Let's also allow rotating (to get points up say). Here
we want to map a function onto the points in each triangle in the list, i.e., at the second level of star2[n,k].
rotmat@th_D := 88Cos@thD, Sin@thD<, 8Sin@thD, Cos@thD<<;
relocatepoint@rot_, size_, loc_, p_D := loc + size rotmat@rotD.p;

mmatutorial.nb

22

star3@n_, k_, rot_, size_, loc_D :=


Map@relocatepoint@rot, size, loc, #D &, star2@n, kD, 82<D;

Show@Graphics@8RGBColor@1, 1, 0D, Map@Polygon, star3@7, 3, Pi 2, 0.5, 81, 1<DD<,


AspectRatio Automatic, Axes True, AxesOrigin 80, 0<DD;
1.4
1.2
1
0.8
0.6

0.6

0.8

1.2

1.4

randompoint := 8Random@D, Random@D<;


randomsize := Random@D 10;
randomcolor := RGBColor@Random@D, Random@D, Random@DD;
mystar := 8randomcolor, Map@Polygon, star3@7, 3, Pi 2, randomsize, randompointDD<;

mmatutorial.nb

23

Show@Graphics@8Table@mystar, 8100<D<,
AspectRatio Automatic, Axes True, AxesOrigin 80, 0<DD;
1

0.8

0.6

0.4

0.2

0.2

0.4

0.6

0.8

Plot@Sin@xD, 8x, 0, 2 Pi<D;


1

0.5

1
-0.5

-1

mmatutorial.nb

24

Show@%,
Graphics@8RGBColor@1, 1, 0D, Table@Map@Polygon, star3@7, 3, Pi 2, 0.2, 8x, Sin@xD<DD,
8x, 0, 2 Pi, Pi 6<D<D, AspectRatio AutomaticD;
1
0.5

-0.5
-1

8. Patterns and Object-Oriented Programming


Mathematica keeps a list of definitions made and uses these definitions in its evaluation of expressions. Evaluating a
simple variable gives the defined value. A symbol can be defined as a function to be applied to arguments. More often,
function definitions are given as a rule to replace the function applied to arguments by the value of the defining expression
after the formal parameters are replaced by the corresponding arguments. The number of arguments of a function is
specified in the definition of the function. A function definition may depend on the number or types of arguments. A
definition of a function by cases is facilitated by allowing the left-hand side of a definition to specify more than just a
formal parameter list. By allowing more general patterns, Mathematica allows function definitions that apply only for
certain forms of arguments, searching its definitions for a pattern that matches the expression to be evaluated and substituting the result of that definition if such a pattern match is found. Mathematica also allows computed conditions on definitions to determine when to apply a definition.
For example, we might want to define a function which evaluates differently if the argument is a number or if it is a list.
angleof@z_ ? NumberQD := Arg@zD;
angleof@8x_, y_<D := ArcTan@x, yD;
angleof@3. + 4. ID
0.927295
angleof@83., 4.<D
0.927295

A pattern variable is indicated by a variable folowed by the underscore and is a formal parameter in the definition. The
pattern var_ matches any expression. A pattern var_symb matches an expression expr if the "head" of the expression is
symb, that is, if expr is an Integer, Rational, Real, Complex, String etc. for basic types of objects or if expr is is the function
symb applied to arguments. A pattern var_?cond applies the function cond to the argument and matches iff the result is
true. The parameters in a function definition can be expressions involving pattern variables to be matched against the
arguments. The notation /;test after a definition causes the test to be evaluated after a match has been made and substitutes
only if the test result is true.

mmatutorial.nb

25

trianglenum@n_IntegerD := Sum@i, 8i, 1, n<D ; n > 0;


trianglenum@4D
10
trianglenum@4.0D
trianglenum@4.D

Rules for simplifying expressions involving your functions can be programmed using such pattern matching definitions.
You can even define how Mathematica functions should evaluate when applied to your functions by making rules explicitly tagged as involving your function by preceeding them with symb/: which translates to a variant of a Set or SetDelayed
assignment. Thus if we define
cuberoot@x_ ? NumberQD := Sign@xD Abs@xD ^ H1 3L;
cuberoot : Sign@cuberoot@x_DD := Sign@xD;
cuberoot : Abs@cuberoot@x_DD := cuberoot@Abs@xDD;
cuberoot : cuberoot@x_D ^ n_Integer :=
cuberoot@xD ^ Mod@n, 3D x ^ Floor@n 3D ; n > 2 n < 0;

then cuberoot of a real number will always give a real cube root and various expressions involving this new function will
evaluate correctly.
cuberoot@2D
213
cuberoot@2.D
1.25992
Sign@cuberoot@x ^ 2DD
Sign@xD2
1 cuberoot@xD
cuberoot@xD2
x
cuberoot@xD ^ 100
x33 cuberoot@xD

mmatutorial.nb

26

? cuberoot
Global`cuberoot
Sign@cuberoot@x_DD ^:= Sign@xD
Abs@cuberoot@x_DD ^:= cuberoot@Abs@xDD
cuberoot : cuberoot@x_Dn_Integer := cuberoot@xDMod@n,3D xFloor@ 3 D ; n > 2 n < 0
n

cuberoot@x_ ? NumberQD := Sign@xD Abs@xD13

One of the better uses of Mathematica's pattern matching facility is in defining functions that act on different sorts of
compound data types by cases. By wrapping each different type of object by a different function, similar operations on
different types of objects can be defined depending on pattern matching the different wrapping functions. For instance, we
might specify a triangle by the coordinates of its three vertices or define a rectangle with sides parallel to the axes by the
lower left and upper right corners. We can take a function triangle of three arguments to represent a triangle given by
vertices, but the function never evaluates, it is simply a listing of vertices wrapped by a triangle function. Likewise, we can
have the function Rectangle with two arguments giving opposite corners of the rectangle. We can define an area function
that correctly returns the areas of such geometrical objects having to know what type each object is because we define the
area function by cases for each type of object we have. Similarly we could define perimeter and a number of other geometrical operations on general figures.
area@triangle@8x1_, y1_<, 8x2_, y2_<, 8x3_, y3_<DD :=
Abs@Det@88x1, x2, x3<, 8y1, y2, y3<, 81, 1, 1<<DD 2;
perimeter@triangle@8x1_, y1_<, 8x2_, y2_<, 8x3_, y3_<DD := Sqrt@Hx2 x1L ^ 2 + Hy2 y1L ^ 2D +
Sqrt@Hx3 x2L ^ 2 + Hy3 y2L ^ 2D + Sqrt@Hx1 x3L ^ 2 + Hy1 y3L ^ 2D;

area@Rectangle@8llx_, lly_<, 8urx_, ury_<DD := Abs@Hurx llxL Hury llyLD;


perimeter@Rectangle@8llx_, lly_<, 8urx_, ury_<DD := 2 HAbs@urx llxD + Abs@ury llyDL;
area@Circle@r_, 8x_, y_<DD := Pi r ^ 2;
perimeter@Circle@r_, 8x_, y_<DD := 2 Pi r;

Map@area, 8triangle@80, 0<, 81, 0<, 81, 1<D, Rectangle@80, 0<, 81, 1<D, Circle@1, 80, 0<D<D

1
, 1, =
2

In essence, the area function can be applied to objects of many different types, each object type needs to have defined its
own area. This is the rudimentary idea behind object-oriented programming. Since each object type has its own wrapping
function, each object type must define all of the functions that apply to that type. Language support for constructing new
object types using inheritence is not built-into Mathematica so certain things which are convenient in object-oriented
programming languages must be explicitly programmed in Mathematica.

mmatutorial.nb

27

9. Useful Functions, Packages, and Help


Before embarking on any major Mathematica programming project, it is best to look through the built-in functions and
standard packages to see if such functionality is already available. At the very least, you can see what similar functions
might be useful in your project and get ideas for representing your objects.
As an example, consider finding the (local) minimum value of a function f[x]. You could try to take the derivative and
solve (perhaps numerically) for where the derivative is zero but you wouldn't necessarily be sure you found a minimum or a
maximum or merely a horizontal tangent inflection point. If the function is not given with a symbolic derivative then a
steepest descent search algorithm using sloopes of secants might be possible. Looking through the Mathematica functions
reveals they've already programmed a FindMinimum command, which may suffice to handle the situations you were
interested in.
FindMinimum@x ^ 2 x, 8x, 1<D

80.25, 8x 0.5<<

FindMinimum@Sin@xD + Abs@x Pi 2D, 8x, 0, 1<D

81., 8x 1.5708<<

As another example, there are a large number of statistical functions in various standard packages. Loading the package
defining continuous distributions is best accomplished by using the Needs function
Needs@"Statistics`ContinuousDistributions`"D;

which loads the package if it has not already been loaded. This package contains definition of a number of distributions
and functions for evaluating the CDF, PDF, Mean, Variance, etc. of these distributions. Thus
dist = NormalDistribution@, D
NormalDistribution@, D

is a standard normal distribution with


Mean@distD

StandardDeviation@distD

and PDF given by


PDF@dist, tD
HtL2
2 2

!!!!!!!
2

mmatutorial.nb

28

Other distributions are defined by other functions with various parameters. They can be used interchangably in the various
functions that can be applied to distributions.
To find out what a particular function does, what functions are available, or what features the standard packages have, you
should use the Help Browser listed under the Help menu. You can get information on all the built-in functions, look up
standard packages, or read the entire Mathematica manual in the Help Browser. There's too much of Mathematica for
anyone to know everything but it is easy to look things up.
To get basic information on built-in functions or information on definitions you've made, you can use ?symb.
? dist
Global`dist
dist = NormalDistribution@, D

10. Tricks?
There are enumerable quirks in the Mathematica system. You will develop your own short-hand ways of specifying various
calculations. And there are plenty of things that can only be classified as special tricks. My recommendation is not to use
tricks. At least not until you've tried a straightforward and more understandable approach.
One of the programming techniques I employ is to write out the conditions for the function I want to calculate and then let
Mathematica solve those conditions for the desired expression. As an example, suppose I want to program the quadratic
formula, solving for the roots in terms of the coefficients of a quadratic polynomial. Take a, b, and c as the coefficients
with variable x.
poly@x_D := a x ^ 2 + b x + c;

Then we express the condition on the x values we want to find.


equation = poly@xD

c + b x + a x2 == 0

Now ask Mathematica to solve. It must surely know the quadratic formula.
solutions = Solve@equation, xD
99x

!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!
!!!!
b + b2 4 a c
b2 4 a c
=, 9x
==
2a
2a

And now I can define my function to return one or both of these roots.
quadformula@a_, b_, c_D = x . solutions
9

!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!
!!!!
b + b2 4 a c
b2 4 a c
,
=
2a
2a

mmatutorial.nb

29

quadformula@1, 3, 2D
81, 2<

This was a simple example, but suppose I wanted the formula for the distance between a point (x1,y1) and a line y=mx+b.
Do you know the formula off-hand? And even if I knew the formula I might make a mistake typing it in. Instead, let's use
Mathematica to solve the problem.
apoint = 8x1, y1<

8x1, y1<

aline = y

mx+ b

y == b + m x
pointonline = 8x, y . Solve@aline, yD@@1DD<

8x, b + m x<

distancebetween = Sqrt@#.# &@apoint pointonlineDD

################
########
######
"################################
2
Hx + x1L2 + Hb
mx+
y1L

xvalueoffoot = x . Solve@D@distancebetween, xD

0, xD@@1DD

b m + x1 + m y1
1 + m2

footofperp = pointonline . x xvalueoffoot

m Hb m + x1 + m y1L
b m + x1 + m y1
, b+
=
1 + m2
1 + m2

distancetoline = distancebetween . Thread@8x, y< footofperpD

2
m Hb m%%%%%%%%%%%%%%%%
+ x1 + m%%%%%%%%
y1L
b m + x1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ m y1 2
%%%%%%%%%
$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N + Jb%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ y1
N%
Jx1
2
2
1+m
1+m

Simplify@%D
2
Hb + m x1
y1L%%%%%
%%%%%%%%%%%%%%%%
$%%%%%%%%%%%%%%%%
1 + m2

linedistance@8x1_, y1_<, 8m_, b_<D = %

Hb + m x1
y1L%%%%%
%%%%%%%%%%%%%%%%
$%%%%%%%%%%%%%%%%
1 + m2
2

linedistance@81, 1<, 82, 1<D


2
!!!
5

mmatutorial.nb

30

N@%D
0.894427
Show@
Graphics@8RGBColor@0, 1, 0D, Line@pointonline . 88x 1<, 8x 1<<D, RGBColor@0, 0, 1D,
PointSize@0.05D, Point@apointD, RGBColor@1, 0, 0D, Line@8apoint, footofperp<D< .
Thread@8x1, y1< 81, 1<D . Thread@8m, b< 82, 1<D,
AspectRatio Automatic, Axes True, AxesOrigin 80, 0<DD;
3

-1

-0.5

0.5

-1

Vous aimerez peut-être aussi