# programming

## What’s in, docs?

After using Mathematica for a while, you start to think you are on top of the richness of the language. You become familiar with a range of different functions and programming styles. But in fact, you haven’t even scratched the surface.

I can’t emphasize enough how important it is to look up the documentation from time to time, even for the functions you think you already know. There are so many options and additional arguments to workhorse functions that you might not have appreciated. Here are a few of my favorites. Some of them were noted in a question I once asked about the issue.

### Hooray for `Array`

If you want to iterate over arbitrary objects, you need `Table`

.

Table[f[i], {i, {a, b, whatever}}] {f[a], f[b], f[whatever]}

If instead the iterator increments by one each time, `Array`

is cleaner. You don’t even need to give the iterator a name.

Array[f, 3] {f[1], f[2], f[3]}

It’s easy to forget the extended forms of standard functions like this. The iterator in `Array`

does not have to start at 1. Don’t forget that the first argument gives the resulting list’s length, not the end value of the iterator.

Array[f, {3}, {5}] {f[5], f[6], f[7]}

This is a general example of the flexible pattern-matching in Mathematica, which allows separate function definitions for different numbers and types of arguments.

`Total`

ly rad

Total[somematrix, {2}]

is equivalent to `Map`

ping the `Total`

function onto the rows of the matrix.

`Partition`

magic

The third argument to `Partition`

defines the offset, so that instead of

Partition[Array[f, 5], 2] // TableForm f[1] f[2] f[3] f[4]

You get

Partition[Array[f, 5], 2, 1] // TableForm f[1] f[2] f[2] f[3] f[3] f[4] f[4] f[5]

This means that, for example

Divide @@@ Partition[somevector, 2, 1]

is equivalent to

Most[somevector]/Rest[somevector]

This question on the Mathematica.SE site shows how to generalise `Partition`

for ragged lists (i.e., those with sub-lists that are not all the same length). There are a number of different ways to do this, including using `Partition`

itself, as well as various combinations of `NestWhile`

and `Prepend`

.

`Join`

in the fun

The third argument of `Join`

is also incredibly useful. How many times have you seen complicated code with `Transpose`

and `Append`

all over the place, just to join two matrices by column, instead of by row? The default syntax for `Join`

joins the rows, but you can join by columns with just two extra keystrokes. As noted in the answers to this question, this is also usually a little faster than the little-known but highly useful `ArrayFlatten`

function.

Join[Array[g, {4, 2}], Array[f, {4, 2}]] // TableForm g[1,1] g[1,2] g[2,1] g[2,2] g[3,1] g[3,2] g[4,1] g[4,2] f[1,1] f[1,2] f[2,1] f[2,2] f[3,1] f[3,2] f[4,1] f[4,2]

Join[Array[g, {4, 2}], Array[f, {4, 2}], 2] // TableForm g[1,1] g[1,2] f[1,1] f[1,2] g[2,1] g[2,2] f[2,1] f[2,2] g[3,1] g[3,2] f[3,1] f[3,2] g[4,1] g[4,2] f[4,1] f[4,2]

### Flip and `Flatten`

There are also additional options and arguments in some other basic list-manipulation commands. For example, most experienced users know that `Flatten`

takes a level specification. For example, `Flatten[list,1]`

turns a three-dimensional tensor into a matrix.

Flatten[Array[f, {3, 3, 2}], 1] // TableForm f[1,1,1] f[1,1,2] f[1,2,1] f[1,2,2] f[1,3,1] f[1,3,2] f[2,1,1] f[2,1,2] f[2,2,1] f[2,2,2] f[2,3,1] f[2,3,2] f[3,1,1] f[3,1,2] f[3,2,1] f[3,2,2] f[3,3,1] f[3,3,2]

But did you know that the second argument can also be a matrix? This popular question on the Mathematica.SE site contains a lot of information about how it works. It can be used to `Transpose`

ragged lists, as this answer explains.

Speaking of `Transpose`

, consider what is possible using its second argument. Here is the result of a normal transpose on a three-dimensional list with dimensions 3*4*2.

t1 = Transpose[Array[f, {3, 4, 2}]]

{{{f[1, 1, 1], f[1, 1, 2]}, {f[2, 1, 1], f[2, 1, 2]}, {f[3, 1, 1], f[3, 1, 2]}}, {{f[1, 2, 1], f[1, 2, 2]}, {f[2, 2, 1], f[2, 2, 2]}, {f[3, 2, 1], f[3, 2, 2]}}, {{f[1, 3, 1], f[1, 3, 2]}, {f[2, 3, 1], f[2, 3, 2]}, {f[3, 3, 1], f[3, 3, 2]}}, {{f[1, 4, 1], f[1, 4, 2]}, {f[2, 4, 1], f[2, 4, 2]}, {f[3, 4, 1], f[3, 4, 2]}}}

Effectively it treats the list as a matrix to transpose normally: it just happens that the elements of that matrix are themselves lists.

Dimensions@t1 {4, 3, 2}

You can get a completely different result by choosing a different specification in the second argument of `Transpose`

. (The default is equivalent to specifying `{2,1,3}`

for the second argument.)

t2 = Transpose[Array[f, {3, 4, 2}], {2, 3, 1}] {{{f[1, 1, 1], f[1, 2, 1], f[1, 3, 1], f[1, 4, 1]}, {f[2, 1, 1], f[2, 2, 1], f[2, 3, 1], f[2, 4, 1]}, {f[3, 1, 1], f[3, 2, 1], f[3, 3, 1], f[3, 4, 1]}}, {{f[1, 1, 2], f[1, 2, 2], f[1, 3, 2], f[1, 4, 2]}, {f[2, 1, 2], f[2, 2, 2], f[2, 3, 2], f[2, 4, 2]}, {f[3, 1, 2], f[3, 2, 2], f[3, 3, 2], f[3, 4, 2]}}}

Dimensions@t2 {2, 3, 4}

### The Bottom Line

Bottom line? Even if you are an experienced Mathematica user, it is worth having a good look at the documentation for basic functions from time to time. You might be missing some of the power they contain in their optional arguments.