An Introduction To MATHEMATICA
Kevin Perry
SEAS / MECA
About the MECA clusters
The Hardware
There are two public clusters of Silicon Graphics workstations here at the
Multimedia Engineering Computation Atelier (MECA). Both rooms are open
24 hrs/ 7 days.
- The Indys (E423)
MIPS R4600 CPU chip, at 100 MHz.
1024x1280 pixel, 24-bit color display
32 Meg memory
Audio/video hardware
- The Personal IRISes (E417)
MIPS R2000 CPU chip, at 36 MHz.
1024x1280 pixel, 24-bit color display
16 Meg memory
The Software
The SGI workstations use the X11 Windowing System. Here are some hints for
getting started with navigating in this environment:
- The mouse cursor MUST be inside the window you wish to type in.
- Holding down the right mouse button always gives you a menu; when the
cursor is over the background, you get the Window Manager Menu.
- To logout, choose "Log Out" from the Window Manager Menu. Then answer "Yes"
to the confirmation window that will appear.
- Use the left mouse button on the edge of a window, to drag the window
around.
-Use the left mouse button on a scrollbar to scroll.
"What is MATHEMATICA?"
Background
MATHEMATICA was originally created by Steven Wolfram. It is a product of
Wolfram Research, Inc. Versions are available for most popular operating
systems, including SGI, Sun, NeXT, Mac, DOS, and Windows. We are currently
running release 2.2.2
Overview of uses
MATHEMATICA is...
- an arithmetic, symbolic and algebraic calculator
- a language for developing transformation rules,
to express general mathematical relationships
- an interactive environment for numerical,
symbolic and graphical exploration
- a tool for preparing input to other programs,
or to process output from other programs
A Friendly Warning
"Like cars and knives and most other useful things, symbolic manipulation
systems in general, and MATHEMATICA in particular, are inherently dangerous
and not for the reckless."
Division of Labor
MATHEMATICA is divided into two parts, the "kernel" and the "front-end". The
front-end, also known as the Notebook Interface, is the graphical user
interface. When you type in a command, the Notebook acts as your intermediary,
and passes the commands to be evaluated on to the kernel. The Notebook
handles formatting of text, and allows for un-evaluated text fields, and other
nice things, all of which make documents such as this one possible! The
kernel is where the mathematics really takes place. It may run on the same
machine as the front-end, or on a different machine.
Getting Started
Sources of Help
The first way to get help, is to use MATHEMATICA's online help facilities (
more about those later).
Another excellent source of information is the book "Mathematica, A System
for Doing Mathematics by Computer", by Steven Wolfram, published by Addison-
Wesley. This book is highly recommended for anyone who wants to use
MATHEMATICA seriously. It is available at the University Store.
A copy of my lecture notes for this course, and pointers to some other useful
information, are available via the World Wide Web, at:
http://www.princeton.edu/~perry/math.html
A short document about getting started with MATHEMATICA is available from the
CIT Info Center, or MECA staff.
Beginning
To start MATHEMATICA, type "mathematica" at the UNIX prompt.
% mathematica
You may also specify the name of a file for it to load, if you have saved one
from a previous session.
% mathematica mywork.ma
When the notebook window has opened on your screen, move the mouse cursor
into the white input region, and enter your commands. To tell MATHEMATICA to
evaluate a command, you must press the key while holding down the
key.
the first evaluation will take a while, because it must first start the
MATHEMATICA kernel.
By default, it will start a remote kernel on the machine ERNIE.
More about the Notebook Interface
Here's the point where we take a look at the menus provided by the notebook
interface...
Advanced Beginning
To run a session where your terminal talks directly to the MATHEMATICA kernel,
without the notebook interface, type "math" at the UNIX prompt. Note that
this will only work on a machine which is licensed to run the kernel, e.g.
phoenix or ernie. Also, if you wish to do graphics in this mode, you must
make sure that your DISPLAY environment variable is set appropriately:
phoenix% setenv DISPLAY picasso:0
phoenix% math
When it is ready and waiting for input, you will see the MATHEMATICA prompt:
In[1]:=
Things You Can Do!
You can do arithmetic:
32545 + 1237
27 * 10.3
You can work with exact numbers and fractions:
2^80
23453/102406 + 37821/332216
FactorInteger[390390]
You can get approximate numerical results to any precision:
N[23453/102406 + 37821/332216]
N[Sqrt[2], 17]
You can use complex numbers and special functions:
(2 + 3 I )^2
Conjugate[2 + 3 I]
BesselJ[1, 2.0*Pi]
...and much, much more!
Syntax and Grammar
Naming
The names of all built-in MATHEMATICA functions begin with capital letters.
They tend not to abbreviate names, beyond what is normal mathematical practice,
and multi-word names have internal capitalization. Some examples are: Sin,
Log, Sqrt, Random, Eigenvalues, FactorInteger.
Arithmetic
addition: 2 + 2
subtraction: 4 - 1
multiplication: 3 * 2
...and also: 3 2
division: 15/2
exponentiation: 4^2
factorial: 4!
Grammar
a list: { 1, 2, 3, 4 }
a function: f[x, y]
a list element: v[[1]]
parentheses for grouping: 2*(3 + 5)
a rule: x -> 5
a definition: f[x_] := 2 x + 5
an assignment: x = 42
Special Symbols
help: ?
verbose help: ??
help wildcards: *, @
some examples...
?Sqrt
??Sqrt
?S@@
?S*
History substitution (re-using previous output): %
...for example:
3 * 7
5 * %
6 * %%
7 * %1
Advanced Function Shorthand
Postfix: x // f
ReplaceAll: (x^2 + 3 x) /. x -> (a+b)
Map: Factorial /@ {1, 2, 3}
Apply: Times @@ a+b+c
(more about these later!...)
Common Constants
Some of the most useful mathematical constants are built-in:
Pi
E
GoldenRatio
EulerGamma
Infinity
ComplexInfinity
All About Lists
We use lists in MATHEMATICA to represent such things as vectors, arrays,
matrices, sets, and so forth. For example, here is a 3-vector:
v = { 1, 4, 2 }
...and a 2x2 matrix
m = { { 1, 2 }, { 3, 4 } }
List indices start at 1, not 0. Indexing is done thus:
v[[1]]
m[[2]][[2]]
...or...
m[[2,2]]
Here are some simple ways to create a list:
Range[10]
Array[Factorial, 6]
Table[x^2, {x, 4, 12}]
This last example has as its second argument, an "iterator list", which
defines the iterator variable ("x"), and its range; you can specify either a
maximum; or a min and max; or min, max, and step size. These three iterator
lists are equivalent: {x, 12}, {x, 1, 12}, {x, 1, 12, 1}.
A matrix is just a list of lists, so we can create one thus:
Table[Table[x^2-y, {x, 3}], {y, 0.0, 2.0, 0.5}]
Here are some simple list operations:
mylist = Range[13]
Drop[mylist, 3]
Take[mylist, 3]
Append[mylist, 3]
Prepend[mylist, 3]
Partition[mylist, 3]
Basic Calculations
Algebra
define a polynomial expression:
poly = (1 - x^2)(2 + 3x)
...and perform some manipulations on it:
Expand[poly]
Factor[poly]
solns = Solve[poly == 0, x]
poly /. x -> 2
poly /. solns[[1]]
Coefficient[Expand[poly], x^2]
Here are some more useful algebraic manipulations:
Simplify[x^3 + 3x^2 + 3x + 1]
quot = Together[1/(1+x) + 2/(1-x)]
Apart[quot]
Numerator[quot]
Denominator[quot]
More about solving equations:
Solve[x^2 == 1, x]
Solve[{x + 2y == 3, 2x - y == 5}, {x, y}]
Solve[{x + 2y == 3, 2x - y == 5}, x, y]
Solve[2 x^2 == 3, x]
NSolve[2 x^2 == 3, x]
FindRoot[2 x^2 == 3, {x, 3}]
Solve[2 x^2 == 3 && Modulus == 7, x]
Calculus
Here is an expression:
expr = 2 + 3x + x^2 - Log[x]
We can differentiate it...
D[expr, x]
D[expr, x, x]
Integrate it...
Integrate[expr, x]
Integrate[expr, {x, 0, 1}]
NIntegrate[expr, {x, 0, 1}]
... but be careful about precision and accuracy measurements for numerical
integration
NIntegrate[expr, {x, 0, 1},
WorkingPrecision->25, AccuracyGoal->20]
Options[NIntegrate]
Infinite integration bounds are done like this:
Integrate[Exp[-x], {x, 0, Infinity}]
We can also ask for the total differential of a multi-variable expression:
Dt[x^2 + y^2, x]
Differential Equations
The derivative of an unknown function, y, can be represented by:
y'
Thus , we can solve differential equations like this:
DSolve[y'[x] + y[x] == 1, y[x], x]
Or, for a functional representation of y:
DSolve[y'[x] + y[x] == 1, y, x]
Or use numerical methods:
NDSolve[{y'[x] == y[x], y[0] == 1}, y, {x,0,2}]
Other Common Tasks
...such as limits, residues, constrained optimization, matrices:
Limit[Sin[x]/x, x->0]
Limit[1/x, x->0, Direction->1]
Residue[1/x, {x, 0}]
ConstrainedMax[x - y, {x < 2y, x < 4}, {x, y}]
ConstrainedMin[x - y, {x > 3y, x > 2}, {x, y}]
mat = {{1, 2},{3, 4}}
Det[mat]
Eigenvalues[mat]
Eigenvectors[mat]
"My Polynomial"]
SetOptions[Plot, PlotRange->All]
Options[Plot]
What is wrong with this command?
Plot[{poly, D[poly, x]}, {x, -5, 5}]
The Plot command "Holds" its first argument, for delayed evaluation.
Sometimes, as above, this is not the desired behavior. In this case, we must
use "Evaluate" to force early evaluation of the argument. This behavior of
Plot is controlled by its attributes:
Attributes[Plot]
Here are two functions plotted on the same graph:
Plot[{Sin[x], Cos[x]}, {x, 0, 2Pi}]
Here are four separate graphs:
plots = {Plot[Sin[x], {x, 0, Pi}],
Plot[Cos[x], {x, 0, Pi}],
Plot[Tan[x], {x, 0, Pi}],
Plot[Cot[x], {x, 0, Pi}]}
Here they are arranged together in a 2x2 array:
Show[GraphicsArray[Partition[plots, 2]]]
Printing Graphs
Graphics may be sent directly to the printer, or saved to a PostScript format
file:
myplot = Plot[poly, {x, -4, 4}]
LaserPrint[myplot]
PSFile["myplot.ps", myplot]
Or, a notebook cell may be selected, and printed using the File/Print
Selection menu item. The notebook printing mechanism allows you to change the
printer options. To find out the name of the default printer, use the
command:
Environment["PRINTER"]
Plotting Data
Lists of data may be read in from files, or created inside MATHEMATICA. Here'
s an example data set:
mylist = Array[Prime, 50]
Such a list may be plotted with the ListPlot command:
ptgraph = ListPlot[mylist]
lngraph = ListPlot[mylist, PlotJoined->True,
Prolog->Thickness[0]]
Here are the two versions of the graph, drawn together:
Show[ptgraph, lngraph]
We can find a quadratic fit to this data:
fitpoly[x_] = Fit[mylist, {1, x, x^2}, x]
...and graph the polynomial against the data:
Show[Plot[fitpoly[x], {x, 0, 26},
PlotRange->All, Prolog->Thickness[0]],
ListPlot[mylist]]
we can also make a list of (x,y) pairs, and graph that:
xy = Table[{j, j^2}, {j, -3, 3, .2}]
ListPlot[xy]
3D Plotting
The basic 3D plotting command is "Plot3D":
p3d = Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 2.5}]
Show[p3d, Mesh->False]
Options[Plot3D]
There is also a list version, for plotting data:
z = Table[2x - y^2, {x, 0, 6, .5}, {y, 0, 6, .5}];
ListPlot3D[z]
There are also functions to make contour plots and density plots; here are
some examples:
ContourPlot[x Sin[y], {x, 0, 3}, {y, 0, 3}]
DensityPlot[x Sin[y], {x, 0, 3}, {y, 0, 3}]
ListContourPlot[z]
ListDensityPlot[z]
Input and Output
Reading, Writing Notebooks
Use the Open, Save and Save As items in the File menu on the menu bar.
To read a Notebook file created on a different type of machine, use the Open
Special item, and select "Ignore .mb auxiliary file".
Reading Command Files
To read and execute a MATHEMATICA command file (NOT a Notebook file):
<> list.m
We can examine the contents of this file by doing:
!!junk.m
This List can then be loaded back in using the Get operator:
newlist = <>> "out.data"]
Each of these methods produces the same file format:
!!out.data
This file can be read back into a MATHEMATICA list easily:
newlist = ReadList["out.data", Number]
We can specify other list formats, e.g. read it as a list of pairs of
numbers:
newlist = ReadList["out.data", {Number, Number}]
Advanced Topic: MathLink
It is also possible (though messy) to write a C program which interfaces with
MATHEMATICA directly. The program must be written according to the MathLink
specifications, and compiled with the MathLink library module, available in
the MATHEMATICA application directory. There is support both for programs
which start a copy of the kernel, and send it expressions to evaluate, and for
programs which can be called by MATHEMATICA, to perform calculations not
easily implemented inside MATHEMATICA. See the appropriate manuals for
details.
Contexts and Packages
What is a Context?
Just as files in the UNIX file system are organized into a hierarchy of
directories, MATHEMATICA commands are organized into a hierarchy of Contexts.
A Context is simply a named collection of MATHEMATICA commands. Context names
are marked by a trailing `. When you start a session, there are typically two
active Contexts: the System` context holds all the built-in commands, and the
Global` context holds any definitions that you make. The list of currently
active contexts is stored in the variable $ContextPath.
$ContextPath
What is a Package?
A Package is a special type of Context, which is used to encapsulate a group
of closely related commands. Package Contexts provide automated loading of
dependent Packages.
MATHEMATICA provides a large number of useful Packages, which you can load
and use. Loading one of these Package files into your MATHEMATICA session
will define a new Context, named after the Package, add that context to the $
ContextPath, and load some definitions into it.
For example, one of the available Packages contains functions for working
with permutations. Let's load it:
<
Fancy Graphics
Animated Graphs
First, make a bunch of plots:
Table[Plot[Sin[t x], {x, 0, 2Pi}], {t, 1, 5, .2}]
...then select all the plots, and choose the
"Graph/Animate Selected" menu item.
Interactive 3D graphics
Before trying this, you need to issue the command:
xhost localhost
at the UNIX prompt on your workstation. It only works on SGI machines.
Live[Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 2}]]
Another way to do this is:
ThreeScript["file.3ps", %]
...and then, at the UNIX prompt, type
live file.3ps
Drawing Shapes
We can make pictures of geometric shapes by building up lists of MATHEMATICA
graphics primitives. Some of these primitives are, for example: Point[], Line[
], Polygon[], Rectangle[], Circle, Disk[]. One packages that utilizes these
is the Shapes package:
<
Defining Transformations
A Simple Function
Functions are defined by transformation rules, which map a list of arguments
to an output value. We've already seen expressions, such as:
expr = 3 x + 7
Here is a function representing the same expression:
f[x_] := 3 x + 7
Note the "x_", (called "x-blank") which represents any expression, and names
it x; and the delayed-evaluation operator, ":=", which leaves the right-hand
side in its symbolic form, instead of evaluating it immediately (which might
cause a value to be substituted for x). We can now evaluate this function in
various ways:
f[0]
f[5]
f[t]
f[a+b]
We can define a piecewise-linear function, by overriding this definition for
some values of x, using a Conditional operator:
f[x_] := x + 9 /; x > 1
f[5]
Plot[f[x], {x, -5, 5}]
The Factorial Function
Here is a very simplistic definition of the factorial function. We give it an
explicit value at 0, and define the value for x recursively in terms of x-1.
Since the right-hand side of the first line is a constant, there's no need to
use the delayed-evaluation operator.
fac[0] = 1
fac[x_] := x*fac[x-1]
The major problem with this is that for any argument that is not a positive
integer, it dies an ugly death:
fac[5]
fac[4.2]
fac[-3]
fac[a]
Here is a better definition of the factorial function. It relies on a Pattern
object which matches only integer arguments and a Conditional, to restrict the
domain of the recursive definition.
factorial[0] = 1
factorial[x_Integer] := x*factorial[x-1] /; x > 0
We can extend this definition to cover all integers, defining it in terms of
the Euler Gamma function:
factorial[x_Integer] := Gamma[x+1] /; x < 0
We can also allow for real-number values:
factorial[x_Real] := Gamma[x+1]
Also, Patterns can be built to match more complicated expressions. For
instance, to write a function ExponentOf, which returns the exponent part of
an expression, we could define:
ExponentOf[_^p_] := p
ExponentOf[_] := 1
Programming Concepts
Control Structures
MATHEMATICA has functions to perform all of the usual program control
operations needed for procedural programming. Note that these are actual
functions, not special keywords.
Do [ expression, {iterator, min, max} ]
Do[Print[i!], {i, 2, 10}]
For [ init_expr, test_expr, iterate_expr, body_expr ]
For[i = 2, i < 10, i++, Print[i!]]
If [ test_expr, if_true, if_false, if_neither ]
abs[x_] := If[x < 0, -x, x, "x isn't a number"]
Which[test, value, test, value, ... ]
signum[x_] := Which[x < 0, -1, x > 0, 1, True, 0]
A Simple Program
As an example, let's say we wanted to build a table of primes. One way to
tell if a number is prime, is to examine the EulerPhi function. Here is a
short program that builds a list of primes less than some specified number:
primes[max_] :=
Module[ {t={}, j},
For[j=2, j <= max, j++,
If[EulerPhi[j] == j-1, AppendTo[t, j]]
];
Return[t]
]
However, a more functional approach is usually more efficient. We could re-
code this as:
primes[max_] :=
Flatten[Position[Map[
Function[j, EulerPhi[j]==j-1], Range[max]], True]]
This uses the "pure function" operator, Function, which takes a symbol (or
list of symbols) to use as formal parameters, and a function body expression
in terms of the formal parameters. As an example, we could write the squaring
function as a pure function like this:
Function[x, x^2]
and use it to evaluate 42^2 like this:
Function[x, x^2][42]
This is useful for defining inline functions for use with such operators as
Map and Apply, as in the above "primes" example.
Advanced Examples
Recommended Reading
The book "Programming in Mathematica", by Roman Maeder, published by Addison-
Wesley, is full of useful examples and programming tips, for getting the most
out of Mathematica.
Example Programming Techniques
The Run-Length Encoding Problem
As an example of some advanced programming techniques in MATHEMATICA, let's
examine some solutions of the Run-Length Encoding problem. These solutions
were written by various people, as entries in a competition to create "the
most elegant solution" to this problem, at a MATHEMATICA conference, a few
years ago. Note that none of them uses a traditional procedural programming
model. Procedural programming is generally the least efficient approach in
MATHEMATICA.
The problem: create a program which takes an arbitrary list of integers as
input, and produces a new list, which consists of {value, run-length} pairs
describing the given input string. This is known as Run-Length Encoding, or
RLE Compression. For example, the imput string
{ 7, 8, 8, 9, 9, 9, 9, 5, 5, 5, 5, 9, 9, 9 }
should produce the output string
{{ 7, 1 }, { 8, 2 }, { 9, 4 }, { 5, 4 }, { 9, 3 }}
Here's an input cell with that data, to use as a test, or make up your own...
data = { 7, 8, 8, 9, 9, 9, 9, 5, 5, 5, 5, 9, 9, 9 }
Example 1: Syntactic Method
encode1[{r___, w:(x_)..}] :=
Append[encode[{r}], {x, Length[{w}]}
encode1[{}] := {}
encode1[data]
Example 2: Algebraic Method
SetAttributes[iMul, Flat]
iMul[{a_, m_}, {a_, n_}] := iMul[{a, m+n}]
encode2[x_] := List @@ iMul @@ ({#,1}&/@x)
encode2[data]
Example 3: Replacement Rule Method
encode3[s_] := {s,{}} //. {
{{x_,t___}, {h___,{x_y_}}} -> {{t},{h,{x,y+1}}},
{{x_,t___}, {h___}} -> {{t},{h,{x,1}}},
{{},{h___}} -> {h}
}
encode3[data]
Example 4: Functional Method
encode4[x_] :=
(Transpose[{x[[#]], #-Drop[Prepend[#,0],-1]}])&[
Flatten[Append[Position
[((Apply[Unequal,#])& /@ Partition[x,2,1]),
True, Length[x]],1]
]
encode4[{}] := {}
encode4[data]