0% found this document useful (0 votes)
31 views

Programming in Mathematica

This document provides an introduction to programming in Mathematica for a scientific computing course. It summarizes the basic components needed for programming, including arithmetic operations, comparison operations, variables, and loops. Mathematica is chosen as the programming environment because its input/output functions are easy to use and it allows the course to focus on physical concepts rather than implementation details. The document reviews the basic arithmetic, comparison, and variable operations in Mathematica and how they can be used to implement algorithms for this course.

Uploaded by

ziloo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views

Programming in Mathematica

This document provides an introduction to programming in Mathematica for a scientific computing course. It summarizes the basic components needed for programming, including arithmetic operations, comparison operations, variables, and loops. Mathematica is chosen as the programming environment because its input/output functions are easy to use and it allows the course to focus on physical concepts rather than implementation details. The document reviews the basic arithmetic, comparison, and variable operations in Mathematica and how they can be used to implement algorithms for this course.

Uploaded by

ziloo
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Physics 367 Lecture 0

Programming in Mathematica
Lecture 0

Physics 367
Scientific Computing

August 31st, 2009

A programming language useful to this course must provide a minimal set


of components that can be used to combine numbers (computational tools),
compare quantities and act on the result of that comparison (conditional
control), repeat operations until a condition is met (loops), and contain
functions that we can use to input data, and output results (i/o). Almost
any language will suffice, but I have chosen to use Mathematica’s program-
ming environment as the vehicle for this course. The reasoning is that 1. The
input/output functions of Mathematica are easy to use, and require little
additional preparation1 2. We will be focused on the ideas, numerical and
otherwise, associated with the methods we study, and I want to draw a clear
distinction between those ideas and issues of implementation. This course
is not meant to teach you everything you need to know about programming
– we will discuss only the bare essentials needed to implement the methods
from class. Instead, we will focus on the physical motivation and tools of
analysis for a variety of techniques. My hope is that the use of Mathematica
allows us to discuss implementation in a homogeneous way, and our restric-
tion to the basic programming structure of Mathematica (as opposed to the
higher level functionality) allows for easy porting to the language of your
choice.
Here, we will review the basic operations, rendered in Mathematica, falling
under each category – we’ll look at the arithmetic operations, compar-
isons, loops and i/o. In addition, we must be able to use variable names
that can be assigned values, and there is a scoping for these construc-
tions in Mathematica similar to C. Functions, in the sense of C, exist in
Mathematica, and we will use a particular (safe) form, although depending
1
There are libraries to import audio and video, for example, in C++, but the resulting
internal representation can be more difficult to work with. In addition, the linking of
libraries is a machine-specific detail of the programming that I do not want to address.

1 of 15
0.1. ARITHMETIC OPERATIONS Lecture 0

on the context, there are faster (and slower) ways to generate functions. In
this class, we will bundle almost every set of comptutations into a function,
and this is to mimic good coding practice that is enforced in more traditional
languages (for a reason – the logic and readability one gains by breaking
calculations up into named constituents cannot be overvalued). Finally, we
will look at two important ideas for algorithm development: Recursion and
Function pointers. Both are supported in Mathematica, and these are also
available in almost any useful programming language.

0.1 Arithmetic Operations

All of the basic arithmetic operations are in Mathematica – we can add and
subtract, multiply, divide, even evaluate trigonometric functions. The only
occasional hiccup we will encounter is the distinction, made in Mathematica,
between an exact quantity and a number – in Figure 1, we can see that when
presented with 1/4, Mathematica responds by leaving the ratio alone, since
it is already reduced. What we are most interested in is the actual numerical
value. In order to force Mathematica to provide real numbers, we can wrap
expressions in the N function, as in In[5], or we can specify decimal places,
as in In[6] of Figure 1.
Mathematica is aware of most mathematical constants, like π and e, and
when necessary, I’ll tell you the name of any specific constant of interest.
Finally, all angles used in trigonometric functions (and returned by arc-trig
functions) are in radians.

0.2 Comparison Operations

We will use most comparison operations, and Mathematica outputs True or


False to any of the common ones – we can determine whether a number is
greater than, less than, or equal to another number using >, <, == (notice
that equality requires a double equals sign to distinguish it from assignment).
We denote “less than or equal to” with <=, and similarly for “greater than or
equal to” (>=). The logical “not” operation is denoted !, so that inequality is
tested using != (not equal). Finally, we can string together the True/False
output with “AND” (denoted &&) and “OR” (||). Some examples are shown
on the right in Figure 1.

2 of 15
0.2. COMPARISON OPERATIONS Lecture 0

Arithmetic Operations Logical Operations

In[1]:= 3 ! 5 In[1]:= 3 ! 5
Out[1]= 8 Out[1]= True

In[2]:= 4 " 20 In[2]:= 7 " 5


Out[2]= 80 Out[2]= True

In[3]:= N!Pi " E# In[3]:= 1 ! 2 && 2 # 3


Out[3]= 1.15573 Out[3]= False

In[4]:= Sin!.1# In[4]:= 1 ! 2 !! 2 # 3


Out[4]= 0.0998334 Out[4]= True

In[5]:= 1"4 In[5]:= 3 $ 3


1 Out[5]= True
Out[5]=
4
2 % 3
1.0 " 4.0
In[6]:=

In[6]:= Out[6]= True


Out[6]= 0.25

Figure 1: Examples of basic arithmetic input and output and logical oper-
ations.

3 of 15
0.3. VARIABLES Lecture 0

0.3 Variables

Unlike C++, variables in Mathematica can be instantiated by definition,


and do not require explicit typedef-ing. So setting a variable is as easy as
typing x = 5.0. The variable has this value (subject to scoping) until it
is changed, or “cleared” (closest to delete that exists in Mathematica) by
typing x = .
Variables, for us, will be “doubles” by default, and always take numerical
values. We can define tables and arrays, again by giving values to a variable
name. In Figure 2, we see a few different ways of defining variables – first
we define and set the variable p to have value 5 – Mathematica will print
an output in general, and in the case of defining variables, it prints an
output that reminds us of the variable’s value. To suppress printing output,
we use a semicolon at the end of a line – in the second example on the left
in Figure 2, we define q to have value 7, and the semicolon tells Mathematica
to just set the value without extra verbiage. As a check, if we input q, and
allow output, we get the correct value.

Defining Variables Setting Variables


In[1]:= p ! 5 In[1]:= q ! 9;
Out[1]= 5 q
In[2]:=

In[2]:= p Out[2]= 9

Out[2]= 5 q ! 10;
In[3]:=

In[3]:= q ! 7; In[4]:= q

x ! !1.0, 2.0, 3.0, 4.0" Out[4]= 10

!1., 2., 3., 4."


In[4]:=

Out[4]= x ! Table!j^2, "j, 1.0, 10.0, 2.0#$


!1., 9., 25., 49., 81."
In[5]:=

x Out[5]=

!1., 2., 3., 4."


In[5]:=

Out[5]= x!!2$$
In[6]:=

y ! Table#j, !j, 1.0, 8.0, 1.0"$ Out[6]= 9.

!1., 2., 3., 4., 5., 6., 7., 8."


In[6]:=

Out[6]= x!!2$$ ! 3.0


In[7]:=

y Out[7]= 3.

!1., 2., 3., 4., 5., 6., 7., 8."


In[7]:=

Out[7]= x
!1., 3., 25., 49., 81."
In[8]:=

Out[8]=

Figure 2: Examples of defining and setting variable values.

We can define tables of fixed length by specifying the appropriate values for
each entry, using {...}, as in the definition of x on the left in Figure 2.

4 of 15
0.3. VARIABLES Lecture 0

The Mathematica command Table[f[j],{j,start,end,step}] can also


be used to generate tables that have values related to index number by the
function f[j] – in the definition of the array variable y, we use f[j] = j
for iterator j.
Once a variable or table has been defined by giving it a value, the value can
be accessed (by typing the name of the variable as input) or changed (using
the operator =) as shown on the right in Figure 2.
Variables can be used with the normal arithmetic operations, their value
replaces the variable name internally, just as in any programming language.
In Figure 3, we define x and y, and add them. We can perform operations
on elements of arrays, or on the arrays themselves (so the final example
in Figure 3 adds each element of the lists X and Y – note that you cannot
add together lists of different size).

In[1]:= x ! 2;
y ! 3;

In[3]:= x " y
Out[3]= 5

In[4]:= X ! Table!Sin!j", #j, 0.0, Pi, Pi $ 10%"

Out[4]= !0., 0.309017, 0.587785, 0.809017,

0.587785, 0.309017, 1.22465 ! 10"16 "


0.951057, 1., 0.951057, 0.809017,

Y ! Table!2.0 # j, #j, 1, 11, 1%"


#2., 4., 6., 8., 10.,
In[5]:=

Out[5]=
12., 14., 16., 18., 20., 22.$

In[6]:= X!!2"" # Y!!1""


Out[6]= 0.618034

X " Y
#2., 4.30902, 6.58779, 8.80902, 10.9511,
In[7]:=

Out[7]=
13., 14.9511, 16.809, 18.5878, 20.309, 22.$

Figure 3: Using arithmetic operations with variables, list elements, and lists.

5 of 15
0.4. CONTROL STRUCTURES Lecture 0

0.4 Control Structures

The most important tools for us will be the if-then-else, while and for op-
erations. These can be used with logical operations to perform instructions
based on certain variable values.
The if-then-else construction operates as you would expect – we perform
instructions if a certain logical test returns True, and other instructions
(else) if it is False. The Mathematica structure is:

If[test, op-if-test-true, op-if-test-false]

In Figure 4, we define and set the value of x to 4. Then we use the If


statement to check the value of x – if x is less than or equal to 4, then we
set x to 5, else we set x to −1.

If Statement While Statement For Statement


In[1]:= x ! 4; In[1]:= x ! "1 In[1]:= For!x ! "1, x # 4, x ! x $ 1,

"
Print!x";
If!x " 4, Out[1]= !1
In[2]:=
x ! 5;
, In[2]:= While!x # 4, !1
Print!x";
";
x ! #1; 0

"
x ! x $ 1;
1
In[3]:= x 2
!1
5 3
Out[3]= 0
4
1
2
3
4

Figure 4: Using Mathematica’s If, While and For.

Using While is similar in form – we perform instructions while a specified test


yields True, and stop when the logical test returns False. The Mathematica
command that carries out the While “loop” is

While[test, op-if-test-true]

An example in which we set x to −1 and then add one to x if its value is


less than or equal to four is shown in Figure 4. In this example, we also

6 of 15
0.5. FUNCTIONS Lecture 0

encounter the i/o function Print[x], which prints the value of the variable
x.
Finally, “for loops” perform instructions repeatedly while an iterator counts
from a specified start value to a specified end value – more generally, the
iterator is given some initial value, and a logical test is performed on a func-
tion of the iterator – while the logical test is true, operations are performed.
We can construct a “for loop” from a While loop, so the two are, in a sense
complimentary. In Mathematica, the syntax is:

For[ j = initialval, f[j], j-update, operations]

where j is the iterator, f[j] represents a logical test on some provided


function of j, j-update is a rule for incrementing j, and operations is the
set of instructions to perform while f[j] returns True – each execution of
operations increments j according to j-update. This is easier done than
said – an example of using the for loop is shown in Figure 4. That example
produces the same results as the code in the While example in Figure 4.

0.5 Functions

Writing programs requires the ability to break, in our case, computational


instructions into logically isolated blocks – this aids in reading, and debug-
ging a program. These isolated blocks are called “functions”, generically, a
name for anything that takes in input and provides output. Mathematica
provides a few different ways to define programming functions. We will focus
on the Module form of function definition – the basic idea is:

functionname[input1 , input2 ] := Module[ { local variables },


operations;
Return[value];
]

Examples of the Module in action are shown below, but morally, the impor-
tant thing to remember is that we now have a function that can be called
with some inputs, returns some output, and has hidden local variables that
are not accessible to the “outside world”.

7 of 15
0.5. FUNCTIONS Lecture 0

In[1]:= HelloWorld!name_" :!
Module!#localvarx, localvary$,
localvarx ! 1.0;
localvary ! name;
Print!"Hello ", localvary";

"
Return!localvarx";

In[2]:= X ! HelloWorld!"Joel""
Hello Joel
Out[2]= 1.

In[3]:= Y ! HelloWorld!33";
Hello 33

In[4]:= Y
Out[4]= 1.

In[5]:= localvarx
Out[5]= localvarx

Figure 5: Example of defining, and then calling, a function in Mathematica


using Module.

8 of 15
0.5. FUNCTIONS Lecture 0

In Figure 5, we define the function HelloWorld, that takes a single argument


called name – the underscore in the function definition defines the argument
of the function. The Module is set up with two local variables, one takes the
value of name (generally, a string), and the other is set to one. The function
itself prints a friendly greeting, and returns the value stored in localvarx
(i.e. one). As a check that the variable localvarx really is undefined as far as
the rest of the Mathematica “session” is concerned, the last line in Figure 5
calls localvarx – the fact that Mathematica returns the variable name,
unevaluated, indicates that it is not currently defined.
We can use all of our arithmetic, logical, and control operations inside the
function to make it do more interesting things. As an example, the two func-
tions defined in Figure 6 are used to sort an array of numbers in increasing
order.
In[1]:= Swap!inlist_, a_, b_" :! Module!#holder, outlist$,
outlist ! inlist;
holder ! outlist!!b"";
outlist!!b"" ! outlist!!a"";
outlist!!a"" ! holder;

"
Return!outlist";

outlist ! inlist; %" Nlist now stores the length of the list "&
In[2]:= InsertionSort!inlist_" :! Module!#outlist, indexx, indexy, curelm, Nlist$,

Nlist ! Length!outlist";
For!indexx ! 2, indexx # Nlist, indexx ! indexx $ 1,
curelm ! outlist!!indexx"";
indexy ! indexx % 1;
While!indexy & 0 && outlist!!indexy"" & curelm,
outlist ! Swap!outlist, indexy, indexy $ 1";

";
indexy ! indexy % 1;

";
outlist!!indexy $ 1"" ! curelm;

"
Return!outlist"

InsertionSort!#5, 2, 4, 6, 1, 3$"
!1, 2, 3, 4, 5, 6"
In[3]:=

Out[3]=

InsertionSort!#%4, 1, 7, 2, 3, %10$"
!!10, !4, 1, 2, 3, 7"
In[4]:=

Out[4]=

Figure 6: Definition of the function InsertionSort – this function takes a


list and sorts the elements of the list in increasing order.

The first function we define is Swap – this takes a list, and two numbers as
input, swaps the value of the elements of the list using the two numbers as
array indices, and returns an array with the two elements interchanged. For
the InsertionSort function, we go through the input array, and sequen-
tially generate a sorted list of size indexx-1, increasing indexx until it is
the size of the entire array. This is an inefficient, but straightforward way

9 of 15
0.6. INPUT AND OUTPUT Lecture 0

to sort lists of numbers.

0.6 Input and Output

There are a wide variety of Mathematica functions that handle various in-
put and output. We will introduce specific ones as we go, I just want to
mention two at the start that are of interest to us. The first, we have already
seen: Print[ stuff ] prints whatever you want, and can be used within a
function to tell us what is going on inside the function.
The second output command we will make heavy use of is ListPlot, this
function takes an array and generates a plot with the array values as heights
at locations given by the array index. ListPlot can be used to visualize
arrays of data, or function values. A few examples are shown in Figure 7.

0.7 Recursion

Most programming languages support a notion of “recursion” – this is the


idea that a function can call itself. Recursion can be useful when design-
ing “divide-and-conquer” algorithms. As a simple example of a recursive
function, consider DivideByTwo defined below. This function takes a num-
ber, and, if it is possible to divide the number by two, calls itself with the
input divided by two. If the number cannot be divided by two, the func-
tion returns the non-dividable-by-two input. In order to check divisibility, I
have defined the function IsDivisableByTwo – this checks divisibility using
Mathematica’s built-in Round command.
A concrete example of the function in action is shown in Figure 8 – we are
using the Print command to see what value the function DivideByTwo gets
at each call – you can see that it is called four times for the input 88.
The function DivideByTwo returns a concrete result when its input is not
divisable by two.

0.7.1 Example – MergeSort

As a more interesting example, we can accomplish the same sorting of num-


bers idea from our InsertionSort using recursion. See if you can “sort out”

10 of 15
0.7. RECURSION Lecture 0

In[1]:= X ! Table!Sin!j", #j, 0, 2 Pi, 2 Pi $ 100.0%";

In[2]:= ListPlot!X"
1.0

0.5

Out[2]=
20 40 60 80 100

!0.5

!1.0

In[3]:= Y ! Table!j^2, #j, 0, 6, 1.0%";

In[4]:= ListPlot!Y, PlotJoined " True"

35

30

25

20
Out[4]=
15

10

1 2 3 4 5 6 7

Figure 7: Plotting arrays of data.

11 of 15
0.7. RECURSION Lecture 0

div ! inx % 2;
In[1]:= IsDivisableByTwo!inx_" :! Module!#div$,

If!div " Round!div" # 0,


Return!False";
,

";
Return!True";

"

In[2]:= DivideByTwo!num_" :! Module!#oput$,


Print!num";
oput ! num;

oput ! DivideByTwo!oput % 2.0";


If!IsDivisableByTwo!oput" $ True,

";

"
Return!oput";

In[3]:= DivideByTwo!88"
88
44.
22.
11.
Out[3]= 11.

Figure 8: Example of recursive function definition – you must provide both


the recursive outcome (call the function again with modified input) and the
final outcome (the definition of the end point).

12 of 15
0.8. FUNCTION POINTERS Lecture 0

(no pun intended) the recursion in the definition of MergeSort below. The
helper function Merge takes two lists that are already sorted, and combines
them to form a sorted list.

In[1]:= MergeSort!inlist_" :! Module!#outlist, oleft, oright, mid$,


outlist ! inlist;
If!Length!outlist" " 1, Return!outlist"";

mid ! Floor!Length!outlist" % 2";


If!Length!outlist" # 2,

oleft ! MergeSort!Take!outlist, #1, mid$"";


oright ! MergeSort!Take!outlist, #mid $ 1, Length!outlist"$"";
";
outlist ! Merge!oleft, oright";

"
Return!outlist";

In[2]:= Merge!inla_, inlb_" :! Module!#outlist, lista, listb,

If!Length!inla" " 0, lista ! #inla$;, lista ! inla;";


index ! 1, adex ! 1, bdex ! 1$,

If!Length!inlb" " 0, listb ! #inlb$;, listb ! inlb;";

outlist ! Table!0, #j, 1, Length!lista" $ Length!listb"$";


While!adex % Length!lista" && bdex % Length!listb",
If!lista!!adex"" % listb!!bdex"",
outlist!!index"" ! lista!!adex"";
adex ! adex $ 1;
,
outlist!!index"" ! listb!!bdex"";

";
bdex ! bdex $ 1;

";
index ! index $ 1;

If!adex & Length!lista",


For!bdex ! bdex, bdex % Length!listb", bdex ! bdex $ 1,
outlist!!index"" ! listb!!bdex"";

";
index ! index $ 1;

,
For!adex ! adex, adex % Length!lista", adex ! adex $ 1,
outlist!!index"" ! lista!!adex"";

";
index ! index $ 1;

";

"
Return!outlist";

MergeSort!#10, '1, 8, 3, 5, 6, 0, '20$"


!!20, !1, 0, 3, 5, 6, 8, 10"
In[3]:=

Out[3]=

Figure 9: A recursive sorting algorithm.

0.8 Function Pointers

It is important that functions be able to call other functions – we can ac-


complish this in a few different ways. One way to make a function you write
accessible to other functions is to define it globally, and then call it. That is
the preferred method if you have a “helper” function that is not meant to be

13 of 15
0.8. FUNCTION POINTERS Lecture 0

called by “users”. The function Swap in the insertion sort example Figure 6
is such a support function – it is not meant to be called by a user of the
function InsertionSort, it is purely a matter of convenience for us, the
programmer.
But sometimes, the user must specify a set of functions for use by a program.
In this case, we don’t know or care what the names of the functions supplied
by the user are – they are user-specified, and hence should be part of the
argument of any function we write. This “variable” function is known, in
C, as a “function pointer” – a user-specifiable routine. Because of the low-
key type-checking in Mathematica, we can pass functions as arguments to
another function in the same way we pass anything. It is up to us to tell the
user what constraints their function must satisfy. As an example, suppose
we write a function that computes the time average of some user-specified
function f (t) – that is, we want to write a function that takes:

1 T
Z
TimeAverage(f ) = f (t) dt. (1)
T 0

We’ll use Mathematica’s Integrate function for now. Our function, called
TimeAverage below, takes as input the function f (t) and the period of in-
terest, T , and returns the right-hand side of (1). The code and two user test
cases is shown in Figure 10.

14 of 15
0.8. FUNCTION POINTERS Lecture 0

tavg ! %1 & T' Integrate!f!t", #t, 0, T$";


In[1]:= TimeAverage!f_, T_" :! Module!#tavg$,

"
Return!tavg";

In[2]:= userfunction1!t_" :! Sin!t"^2

In[3]:= TimeAverage!userfunction1, 2 Pi"


1
Out[3]=
2

In[4]:= userfunction2!x_" :! Sin!x" Cos!x"

In[5]:= TimeAverage!userfunction2, 2 Pi"


Out[5]= 0

Figure 10: The function TimeAverage takes a function name as its argument,
in addition to the period over which to average.

15 of 15

You might also like