In Mathematica™, functions have arguments set of by square brackets. There are almost 6,000 built-in functions, which covers many mathematical needs. However, it is quite common to want to define one’s own functions. Fortunately, this is extremely easy to do, as long as you keep a few guidelines in mind.

First, function arguments are set off by square brackets, not parentheses. In the example to the right, the parentheses are interpreted as setting off a symbol which is, in this case, multiplied by the symbol Sin. In the second case, with square brackets, Mathematica™ applies the function Sin to the argument. (Note: all built-in functions in Mathematica start with a capital letter. This is so that in your use of Mathematica, if you define all of your variables and functions to be symbols that start with a lower-case letter, you will never accidentally pick something that is already a built-in function.)

Second, functions are defined using Set or SetDelayed. Set takes the right-hand-side (*rhs*), evaluates it as far as possible, and then assigns the result to the symbol that is the left-hand-side (*lhs*). SetDelayed assigns the *rhs* in its unevaluated form to the symbol that is the *lhs*.

Third, function arguments need to be **patterns** in order for you to be able to plug in values for those arguments. Before we get into what we mean by “patterns,” let’s look at an example, to the right, that illustrates what happens when we *don’t* use patterns.

We start by trying to define a function, f[x], that is x squared. When we call f[x], the kernel gives us back x squared, just as we had hoped. But when we try to plug in a *value* for x of 3, the kernel says, “Nope, I haven’t seen f[3] before, so I will just give you back your expression. Nothing I can do with it!” Now we can explicitly tell the kernel that f[3] is three squared, but it’s not actually doing anything with the three in the brackets… it just recognizes that it has seen “f[3]” as a whole entity before, and spits back to you what you told it f[3] was. This is, let us say, less than useful.

What we *really* want is to define f[*anythingCanGoHereAndIWillCallItx*] to be x squared, where the x on the *rhs* is whatever was in between the brackets. Mathematica™ does this with “patterns.” The most basic pattern object is a single underscore character, _, which represents any expression. Think of this underscore as a “blank” to be filled in. As you can see in the g[_] example, the kernel now responds with x squared regardless of what is placed between the brackets. But it doesn’t know to do anything with that stuff that is between the brackets. It recognizes g[anything], because it has a blank that can be filled in, but it doesn’t know to do anything with that blank.

The way to fix that problem is to *name* the pattern. Putting a symbol in front of the underscore character tells the kernel that yes, there is a blank to be filled in, and let us call whatever is in that blank by that symbol name. You can see that in use at the right. Here, we have a function, h, with a single argument (that can take on any value), and we call that value x. Now calling h[*anything*] gives us back *anything* squared.

With those concepts in mind, we can now build up some sophisticated functions.

Below is an example of a two-parameter function: Planck’s Black Body Radiation formula, which is a function of both wavelength and temperature. Notice that there are two arguments to the function, each of which is given a different name. We can also see an example here of using replacement rules to temporarily assign values to physical constants, here Planck’s constant, the speed of light, and Boltzmann’s constant.

The plot shows some interesting unit conversions. Because everything was originally defined in SI units, the wavelength passed to the function B is assumed to be in meters. However, when discussing spectra, it is much more traditional to give the wavelength in nanometers. So notice that B is called in the Plot statement with a wavelength running from 0 to 3000 nm, but that is converted to meters in the call to B. Similarly, the units of the spectral radiance are converted to a range that make it easier to plot.

In quantum mechanics, it is common to have quite a few arguments to functions. Three spatial dimensions are common. And we also typically want our functions to depend on quantum numbers. Let’s look at the wavefunctions for a three-dimensional particle-in-a-box as an example. We have three spatial coordinates and three quantum numbers, for a total of six arguments. We could certainly set it up as a function f[x,y,z,nx,ny,nz], where we have to remember that the first three arguments are the coordinates and the last three are the quantum numbers, but there is a better approach that more directly follows traditional physical chemistry notation. We will start to build our wavefunction using a one-dimensional particle in a box.

Notice that in this function definition I placed the coordinate as an argument within the square brackets, but I placed the quantum number as a subscripted argument. This separation of quantum numbers from coordinates matches chemistry-standard notation well. And in the plot, we are looking at the first three wavefunctions (the “Evaluate” function call within the Plot statement is necessary to make the Table get evaluated first, which allows the wavefunctions to be plotted in different colors; try it without the Evaluate bit to see the difference).

Now we can use this one-dimensional wavefunction to make the three-dimensional wavefunction, as shown to the right. Take a moment to think about how this works… just because we originally defined the one-dimensional wavefunction as depending on the x coordinate doesn’t mean we are restricted to using it for that coordinate. If we call the one-dimensional wavefunction with a y instead, then the wavefunction is now oriented along that other axis. And the kernel can tell the difference between a wavefunction called with six arguments (three subscripted) and a wavefunction called with two arguments (one subscripted), so there is no ambiguity in using the same function name. Below is a three-dimensional density plot of an example wavefunction.