Mathematica Review and Help Session

Zachary Boerner - zboerner@mines.edu - 9/6/11

Clearing your notebook!

At the top of all of your notebooks, you should have the following:

Clear["Global`*"]

This clears all variables inside your notebook and across all notebooks.
Mathematica has the quirk that if you have a variable defined in a notebook, it is defined across all notebooks, so watch out for that.

Parameter Lists

Why?

Let’s say you’re given a bunch of data sets that you need to churn through your code.  You could define the data as such:

x=2;
y=3;
z=5;

(x^2)+(y^3)+(z^5)

That’s all fine and good (and can be accomplished more easily with a function), but what happens if you have a ton of variables and a ton of data points to iterate through?  That’s where parameter lists come in.

Clear[x,y,z]

A basic parameter list

parameters={x->2,y->3,z->5};

Notice that x, y, and z didn’t turn black.  If I try to call any of the values,

x

It returns ‘x’ because it doesn’t exist.  However, if I apply the parameters list to it, I get the following:

x/.parameters

Sweet!  But couldn’t we have used a function a moment ago?  Yes, but here’s a cool trick:

function[parameterList_]:=(x^2)+(y^2)+(z^2)/.parameterList

function[parameters]

To check that, I can just plug in the values:

(2^2)+(3^2)+(5^2)

Woot!  This isn’t as useful in functions, because those should still be defined using all the variables that you need, but it will come in as an important step later, when we get to modules.

Why would I ever want to use that (extended version):

When you define a variable in Mathematica, it assigns that number to that variable for all instances.  This is true across all notebooks, so if you’re working on three different notebooks at the same time, then what may be x in one notebook may not be the x you want in another notebook.

That’s where parameters come in.  It’s easy to define a notebook with parameters and then replace in the appropiate places.  Personally, I like having a list of constants and a list of values that are dependent upon the problem.  For example, G=6.67(x10^(-11)), but the mass of Mars is not the same as the mass of Earth.  Ergo, two lists.

Arrays

In field session, we showed you this:

array={0,0};

Timing[For[i=1,i<10000,i++,
AppendTo[array,{i,2*i}]
]]

This isn’t so great, because if you run this notebook, you’ll find that the previous command takes around 53 seconds.  That’s for 10,000 data points doing a very simple calculation. You tack on another 0 onto that and it might start running for minutes and another and it might start running for hours.
This is unacceptable, especially when you get into more complex calculations and longer arrays.  For example, on one of my later numerical assignments, I had 3 million data points.  That’s not going to work with AppendTo[].

Instead, we use the following:

array2=Table[{0,0},{j,100000}];

Note that I have defined a large size for the table.  This doesn’t matter as much, as long as it’s larger than the maximum number of data points you have in your code.

Timing[For[i=1,i<100000,i++,
array2[[i]]={i,2*i};
]
]

Notice that I have the loop going through an order of magnitude more points than the previous time, yet it takes three orders of magnitude less time!
This is very useful because it takes far less time.

Explanation as to why (optional)

Mathematica isn’t so smart when it comes to the AppendTo[] function.  Every time the function is called, it copies the entire array into a memory space that has room for one element more than the current size of the array.  Naturally, these write operations build up in the CPU queue and chew up a lot of processing time.  When you define a maximum size to the array, it allocates a chunk of memory and simply writes to the appropiate locations as necessary.  This is a much faster operation and saves you orders of magnitude of time.

2D Arrays

Arrays that are two-dimensional take the same form as one-dimensional arrays.  You just add on another element.

array21=(Table[i*j,{i,5},{j,10}]//MatrixForm)

In this case, I defined array2 to be a Table where each element is the product of the column index and the row index.  It has 5 rows (the first value) and 10 columns (the second index).

(array22=Table[i*j,{i,5},{j,10}])//MatrixForm

Notice that there is a difference between the above two assignments (based solely off the location of parentheses).  The first assigns the Matrix Form output to the value array21.  In the second case, it assigns the array to array22 and then outputs the result in Matrix form.  
Note what happens if I try to access an element in each:

array21[[2,3]]

array22[[2,3]]

Reduce[array21==array22]

The first one is simple the “image” of the array, whereas the second is the array itself.  They are not equal to each other.  Watch out for that.

Modules

Modules are much like functions in programming languages.  You can do all sorts of fun things inside of a module, and, as the name implies, they make your code much more modular.

Why we want to do this

What if you needed to run your probe drop on 10 different planets?  100?  What if NASA wanted to chew through your code really, really quickly?  Turns out, the way we had you do it during field session means that you have to copy and paste your code many, many times and then you have to redefine the parameters each time, as well.

What if there were an easier way, where you just plug in one value that’s given to you?

What you’ve done before:

Before, you had a function:

myFunction[x_,y_]:=(((x^2)+(y^2))/(x^2))

That’s all fine and dandy, but what happens when you need to iterate through increasing values of y?  Well, you could build a table...

Table[myFunction[3,y],{y,0,10000,.1}]

Great!  I produced a table!  What happens when that function now has things that should be dependent on other elements in the table?  All of a sudden, I can’t do the previous method.  Instead, we need to do a Module, which lets us put things into it like For loops and all sorts of crazy things.

The basic format of a module is below:

myModule[passedVariables_]:=Module[{
temporaryVariables
},
(*Code goes here*)
x
]

myModule[a]

Evaluating it putting anything in will return the value x, because that’s the only line in the module.  Great, that sounds... useful?  But watch what happens when I start being more complex.  Remember that parameter thing I mentioned?  This is where it comes in handy.

parameters1={x->3};
parameters2={x->4};
parameters3={x->15};

simpleModule[parameterList_]:=Module[{
tempY=5
},
tempY*x/.parameterList
]

simpleModule[parameters1]
simpleModule[parameters2]
simpleModule[parameters3]

Look at that!  See how easy it was for me to simply pass a list of parameters to the module?  And, to add, that tempY thing that I had in the module?  That isn’t defined outside the scope of the module!

tempY

This is useful for defining variables that you don’t want to exist outside of the scope of the module, like indexing variables.

Now here’s the cool part.  Remember how I said you could stick loops in them?  Look:

moreComplexModule[parametersList_]:=Module[{
temporaryVariables=2,
tempArray,
j
},
tempArray=Table[0,{k,10}];
For[j=1,j≤10,j++,
tempArray[[j]]=j*temporaryVariables*x/.parametersList
];
tempArray
]

moreComplexModule[parameters1]
moreComplexModule[parameters2]
moreComplexModule[parameters3]

Look at that!  I get some nice lists, the tempArray variable doesn’t exist outside the scope of the module, and I used a parameter list to boot!  This is the format you should be using for all of your later notebooks.

Plots

You should label all of your plots.  You can label the plot by using the “PlotLabel” function and label the axes using the “AxexLabel” function.  Note that for the axes, I’m using an ordered pair to define them.

You can also use the “PlotRange” option to define a certain space on the graph to take a closer look at.

Plot[x*Sin[x],{x,0,50},PlotLabel->"x*Sin(x)",AxesLabel->{"x","y"},PlotRange->{{0,10},{0,5}}]

However, if you find that it does not return what you’re looking for, you can use the “PlotRange -> All” option to force Mathematica to show as much as it possibly can of the plot.

Plot[x*Sin[x],{x,0,50},PlotLabel->"x*Sin(x)",AxesLabel->{"x","y"},PlotRange->All]

The following are how you can make the nice sections in your notebook like I did in this one.

Aborting

Finally, if you need to stop your code, but Mathematica is still responding, use Alt-. (Alt-period).  This will abort whatever cell is currently running.  If you need to take it a step further, you can go up to the “Evaluation” menu and go down to “Quit Kernel,” choosing the Local kernel.

Alt-1 gives you a major title

Alt-2 gives you a subtitle

Alt-3 gives a sub-sub title

Alt-4 is a section

Alt-5 is a subsection

Alt-6 is sub-subsection

Alt-7 is text.