Simple Programs
By supporting functional, rule-based, and procedural programming,
Mathematica has a much more powerful and flexible programming
language than most other technical computing software packages. Functional
and rule-based programming, being more powerful and concise, is usually
considered vastly superior for most applications. In fact, using the correct
Mathematica constructs instead of procedural (C- or Fortran-like)
programming can increase the speed of a program up to 50 times. To learn about
programing in Mathematica, you should consult one of the excellent books
on Mathematica programming offered by Wolfram Research and third-party
publishers. A large selection of those books is available from the
Mathematica Bookstore.
A Comparison between Procedural and Functional Programming
To demonstrate the performance differences between procedural and functional programming
in Mathematica, we'll look at some code that calculates moving averages.
The Procedural Program
A standard way to implement moving averages procedurally follows.
Set up an empty list, two iterators, and a temporary variable to store the values.
Add the appropriate number of list elements and divide them through the number
of elements.
Add the value to the list.
Return the list.
![[Graphics:../Images/index_gr_132.gif]](../Images/index_gr_132.gif)
![[Graphics:../Images/index_gr_133.gif]](../Images/index_gr_133.gif)
![[Graphics:../Images/index_gr_134.gif]](../Images/index_gr_134.gif)
![[Graphics:../Images/index_gr_135.gif]](../Images/index_gr_135.gif)
Functional Programming
Now let's look at the functional way to accomplish the same thing. The following program
divides the list of numbers into sublists and then sums the elements in each of the sublists.
![[Graphics:../Images/index_gr_136.gif]](../Images/index_gr_136.gif)
![[Graphics:../Images/index_gr_137.gif]](../Images/index_gr_137.gif)
![[Graphics:../Images/index_gr_138.gif]](../Images/index_gr_138.gif)
![[Graphics:../Images/index_gr_139.gif]](../Images/index_gr_139.gif)
Performance Differences
As you can see, the functional code is five times shorter. It is also an amazing 130 times
faster for a list with 10 thousand elements. While these gains from using functional code may
not always be that large, this is a fairly typical result. The lesson here is that you should learn
functional programming in Mathematica as soon as you can!
![[Graphics:../Images/index_gr_140.gif]](../Images/index_gr_140.gif)
![[Graphics:../Images/index_gr_141.gif]](../Images/index_gr_141.gif)
![[Graphics:../Images/index_gr_142.gif]](../Images/index_gr_142.gif)
![[Graphics:../Images/index_gr_143.gif]](../Images/index_gr_143.gif)
Porting Procedural Programs to Mathematica
To quote Bjarne Stroustrup, the creator of C++:
"Thoughtlessly applying techniques efficient in one language to
another typically leads to awkward, poorly performing, and
hard-to-maintain code. Such code is also most frustrating to write because
every line of code and every compiler error message reminds the programmer
that the language used differs from 'the old language.'...Over the basic type system
of a language, only Pyrrhic victories are possible."
Bjarne
Stroustrup, The C++ Programming Language, Third Edition (1997)
However, if you have some legacy code that you have to get running quickly,
you might have to resort to porting it. There are some
conversion tools available on our
web site. To convert code
yourself, you must change functions into modules. In pseudocode, it looks like this.
![[Graphics:../Images/index_gr_144.gif]](../Images/index_gr_144.gif)
You can refer to the moving averages program listed previously to get a general idea
of how your converted code will look.
Rule-Based Programming
Rule-based programming might well be the easiest and most intuitive way to write
mathematical or technical programs; after all, many mathematical processes, such as
differentiation and integration, are simply rewriting mathematical expressions according
to rules. Because rule-based programming is totally different from procedural or even
functional programming, it might seem very strange at first, but it is so natural and
powerful that most people prefer it after a short time.
What Is Rule-Based Programming Anyhow?
As you can guess from the name, rule-based programming is simply defining rules and
having the computer apply them to expressions. Most rules in Mathematica are
replacement rules.
In this simple example, we replace x with x squared.
![[Graphics:../Images/index_gr_145.gif]](../Images/index_gr_145.gif)
![[Graphics:../Images/index_gr_146.gif]](../Images/index_gr_146.gif)
No big deal yet, but it gets better, for example, when you have a data set and want to plot
the log of the values.
![[Graphics:../Images/index_gr_147.gif]](../Images/index_gr_147.gif)
Here, you can replace all the y values with their natural logs in one simple step.
![[Graphics:../Images/index_gr_148.gif]](../Images/index_gr_148.gif)
![[Graphics:../Images/index_gr_149.gif]](../Images/index_gr_149.gif)
Also, often rule-based programming is the most natural way to define calculations.
For example, let's define an absolute value function for real numbers.
![[Graphics:../Images/index_gr_150.gif]](../Images/index_gr_150.gif)
![[Graphics:../Images/index_gr_151.gif]](../Images/index_gr_151.gif)
Using Mathematica Functions
The Function Concept
Function[body] or body & is a pure
function. The formal parameters are # (or #1),
#2, etc. Function[![[Graphics:../Images/index_gr_154.gif]](../Images/index_gr_154.gif) ,
, ... , body] is a pure function with a list of
formal parameters.
![[Graphics:../Images/index_gr_158.gif]](../Images/index_gr_158.gif)
![[Graphics:../Images/index_gr_159.gif]](../Images/index_gr_159.gif)
![[Graphics:../Images/index_gr_160.gif]](../Images/index_gr_160.gif)
![[Graphics:../Images/index_gr_161.gif]](../Images/index_gr_161.gif)
![[Graphics:../Images/index_gr_162.gif]](../Images/index_gr_162.gif)
![[Graphics:../Images/index_gr_163.gif]](../Images/index_gr_163.gif)
![[Graphics:../Images/index_gr_164.gif]](../Images/index_gr_164.gif)
![[Graphics:../Images/index_gr_165.gif]](../Images/index_gr_165.gif)
![[Graphics:../Images/index_gr_166.gif]](../Images/index_gr_166.gif)
You can see the internal structure of a function in Mathematica using FullForm.
![[Graphics:../Images/index_gr_167.gif]](../Images/index_gr_167.gif)
![[Graphics:../Images/index_gr_168.gif]](../Images/index_gr_168.gif)
TreeForm shows the function in an easy-to-read tree format.
![[Graphics:../Images/index_gr_169.gif]](../Images/index_gr_169.gif)
![[Graphics:../Images/index_gr_170.gif]](../Images/index_gr_170.gif)
The Basic Programming Constructs
Block and Module are the two basic programming constructs in
Mathematica. Mathematica assumes that all of your variables are global.
This means that every time you use a name like x, Mathematica assumes
that you are referring to the same object. Particularly when you write programs, however,
you may not want all of your variables to be global. You may, for example, want to use the
name x to refer to two quite different variables in two different programs.
In this case, you need the x in each program to be treated as a local variable.
You can set up local variables in Mathematica using modules. Within each module,
you can give a list of variables that are to be treated as local to the module.
This defines the global variable t to have value 17.
t = 17
![[Graphics:../Images/index_gr_173.gif]](../Images/index_gr_173.gif)
The t inside the module is local, so it can be treated independently of the global
t.
Module[{t}, t = 8; Print[t]]
![[Graphics:../Images/index_gr_174.gif]](../Images/index_gr_174.gif)
The global t still has value 17.
t
![[Graphics:../Images/index_gr_175.gif]](../Images/index_gr_175.gif)
Sometimes, however, you might want variables to be global, but values to be local.
You can do this in Mathematica using Block.
Here is an expression involving x.
x^2 + 3
![[Graphics:../Images/index_gr_180.gif]](../Images/index_gr_180.gif)
This evaluates the previous expression, using a local value for x.
Block[{x = a + 1}, %]
![[Graphics:../Images/index_gr_181.gif]](../Images/index_gr_181.gif)
There is no global value for x.
x
![[Graphics:../Images/index_gr_182.gif]](../Images/index_gr_182.gif)
As described in the sections above, the variable x in a module such as
Module[{x}, body]
is always set up to refer to a unique symbol, different each time the module is used,
and distinct from the global symbol x. The x in a block such as
Block[{x}, body]
is, however, taken to be the global symbol x. What the block does is to make the
value of x local. The value x had when you entered the block is always restored
when you exit the block. And during the execution of the block, x can take on any value.
|