The programmatic side of Mathematica I

I have been playing with Mathematica 5, and have a big thick book on it from Wolfram and even a Schaum’s Outline on the program. All of these books touch on all of the functions of the program as though that was all there was to know.

But of course you can make your own user-defined functions, but material on that is harder to find. I managed to get my hands on a book published in the early 90s by Gaylord, Kamin, and Wellin, entitled Introduction to Programming with Mathematica. It does not appear that any specific version number for this program is mentioned in the text. But the publication date of 1993 would suggest that the intended version would be 2.1 or 2.2. I have version 5.2, but so far in the first few pages, I haven’t run into any trouble.

In the old days when an operating system was nothing more than a BASIC command interpreter (anyone old enough to remember the Commodore 64? or the TRS-80?), you are by default placed into an immediate mode where you can issue commands, test out command syntax or run programs written in the same language as understood by your interpreter (for the Commodore or TRS-80, that language would be BASIC). In Mathematica, that is what is happening. You are in a sort of “immediate mode” where you can issue commands or run pre-defined functions or programs, load your own functions, and so on.

The Mathematica kernel seems to allow you to enter similar commands as in this discussion without the need to press “shift-enter” to execute it as you do in the so-called “Notebook” interface. Just the “enter” key will suffice. I needed to open the kernel from the Start menu of Windows. Then I tried to test it out:

In[1]:= 39/7

        39
Out[1]= --
        7

OK, the interpreter works, and it works the way it seems to in the “Notebook” interface. You can also get help from a command by placing a question mark before it:

In[2]:= ?Plot
Plot[f, {x, xmin, xmax}] generates a plot of f as a function of x from xmin to xmax.
Plot[{f1, f2, ... }, {x, xmin, xmax}] plots several functions fi.

But the plotting of graphs  in kernel mode is a little … uh … different:

In[15]:= Plot[Sin[x], {x,0,2Pi}]

    #               ####                                                      
   1#            ####  #####                                                  
    #          ###         ###                                                
    #        ###             ###                                              
    #       ##                 ##                                             
    #     ###                   ##                                            
 0.5#    ##                      ##                                           
    #   ##                        ##                                          
    #  ##                          ###                                        
    # ##                             ##                                       
    ###                               ##                                      
    ### #  # # #  # # # #  # # #  # # ###  # # #  # # # #  # # #  # # # #  ###
  ############################################################################
    #          1           2          3  ##       4          5           6##  
    #                                     ##                             ##   
    #                                      ##                          ###    
    #                                       ##                        ##      
    #                                        ##                      ##       
-0.5#                                         ###                   ##        
    #                                           ##                ###         
    #                                            ###             ##           
    #                                              ###         ###            
    #                                                ####  #####              
  -1#                                                   ####

So, it’s probably better to use the Notebook mode for graphs…

Being a math program, you can create your own lists or generate new lists from Mathematica’s “Range” function:

Range[min,max,increment]

A “List” function can generate arbitrary lists:

In[16]:= List[1,2,3,-4,dog, cat, Sin, "Hello World!", {a, b}, Pi, {}]

Out[16]= {1, 2, 3, -4, dog, cat, Sin, Hello World!, {a, b}, Pi, {}}

In[17]:= Range[-12,15,7]

Out[17]= {-12, -5, 2, 9}

Notice the last output was for a Range command I inputted. The command asked for every 7th number between -12 and 15, including -12.

It doesn’t have loops in the pascal sense, but it has iterators, which are more compact. Here, I generate 50 random numbers:

In[18]:= Table[Random[],{50}]

Out[18]= {0.384617, 0.0481281, 0.278996, 0.161237, 0.880606, 0.587204, 0.996814, 0.0335705, 0.367147, 0.730021, 

>    0.195816, 0.707583, 0.316029, 0.030375, 0.971311, 0.607889, 0.172245, 0.461959, 0.511372, 0.001557, 0.830695, 

>    0.517233, 0.716287, 0.984279, 0.446078, 0.469105, 0.437292, 0.823042, 0.565472, 0.881901, 0.440478, 0.789472, 

>    0.198325, 0.151881, 0.244661, 0.0818886, 0.882296, 0.121506, 0.27335, 0.474, 0.71005, 0.659546, 0.761978, 

>    0.472443, 0.879355, 0.142313, 0.0456913, 0.488163, 0.433277, 0.673208}

{50} refers to the number of times the Random[] command must be repeated. Trouble is, the output looks a bit messy. You can clean this up by dividing the {50} into two dimensions, then tacking on a //TableForm modifier to the end of the whole command:

In[20]:= Table[Random[],{10},{5}]//TableForm
Out[20]//TableForm= 0.503921    0.225364   0.462814   0.985969   0.276704
                    0.613243    0.320156   0.961345   0.836671   0.519041
                    0.827408    0.256483   0.473772   0.283214   0.222593
                    0.39894     0.308651   0.763449   0.460018   0.900552
                    0.908033    0.286537   0.931285   0.096198   0.404112
                    0.0611721   0.468471   0.110229   0.127408   0.447929
                    0.148315    0.148884   0.290737   0.928888   0.320907
                    0.8924      0.816965   0.645673   0.098314   0.493461
                    0.508314    0.882225   0.638296   0.592909   0.600281
                    0.595688    0.707011   0.496711   0.196169   0.534516

This looks a bit better. {10},{5} specifies 10 rows and 5 columns. But of course you can have counters:

In[25]:= Table[i*j, {i, 1, 8}, {j, i, 8}]//TableForm
Out[25]//TableForm= 1    2    3    4    5    6    7    8
                    4    6    8    10   12   14   16
                    9    12   15   18   21   24
                    16   20   24   28   32
                    25   30   35   40
                    36   42   48
                    49   56
                    64

Here are the equivalent of two nested loops. You can think of “i” as the outer loop, and “j” as the inner loop, and I think the whole thing will make sense. And the loop syntax will accept a fourth parameter for loop increment:

In[35]:= Table[i*j, {i, 1, 8}, {j, i, 8, 2}]//TableForm
Out[35]//TableForm= 1    3    5    7
4    8    12   16
9    15   21
16   24   32
25   35
36   48
49
64

This one causes j to go to every second number. Note the change in the output. With a few more number operations, I can have 100 dice rolls in table format:

In[57]:= Table[IntegerPart[Random[]*6]+1, {10},{10}]//TableForm
Out[57]//TableForm= 6   3   6   6   4   4   5   2   5   1
                    5   5   3   2   3   1   2   1   5   6
                    2   2   6   1   2   5   6   2   4   2
                    2   1   6   1   3   2   3   5   6   2
                    1   5   2   2   6   4   3   1   5   5
                    3   6   1   3   1   6   1   3   4   4
                    5   4   4   3   4   6   3   2   4   3
                    6   1   6   4   4   2   6   1   3   3
                    5   5   6   6   6   1   2   3   3   2
                    6   2   5   6   6   1   5   2   2   5

IntegerPart[] takes the place of Trunc[] in many languages, returning the integer part of a number containing decimals. The chopping, or truncation of decimals is necessary to guarantee a dice roll between 1 and 6. Round[] is also available if you wish to experiment with it. It will round, but you will be rolling some zeroes as a result.