Lecture Two,
15 January 2003
DEFINING FUNCTIONS

Simple One-Line Function Definition

f[x_]  :=  x^2

The above line defines a function that takes the square of its argument.   x_ (a symbol  x with an underscore) is called a pattern (which "match" anything), and := is called delayed assignment, different from assignment =.  We use the function like this (without the underscore):

f[2]

f[a]

f[1 + x]

This function takes any argument, including strings:

f["this"]

Assignment = and Delayed Assignment :=

= (or Set[ ])  : the right-hand side expression is evaluated, and result sets to the variable (expression) on the left-hand side.
:= (or SetDelayed[ ]) : the right-hand side expression without evaluation is set to the variable (expression) on the left-hand side.

a  =  3;  x  =  a + 1

?x

With Set command "=", we associate number 4 with the variable x, since a + 1 has been evaluated to 4 before set the value for x.

a  =  3;  x  :=  a  +  1

?x

With SetDelayed :=, we associated a + 1 with x, the expression a+1 is delayed for evaluation.

How to see all the variables defined/used by the user?

Clear or Remove a Function or Variable

When we say Clear[x], the value associated with x is cleared, but the variable x still exists; to remove x completely from the memory, use Remove[x].   Clear or remove symbol when it is no longer needed.

More on Function Definition

If we like to have a function that takes only integer, we can say:

g[x_Integer]  :=  x^2

{g[3],  g[x],  g[3.5]}

If an expression such as g[x] or g[3.5] is given to Mathematica for which Mathematica does not known how to evaluate, it is returned without evaluation.

We can define a function with any number of arguments:

h[a_,  b_,  c_]  :=  (a + b + c)

h[1, 2, q]

We can define function with a variable number of arguments:

v[a__]  :=  Plus[a]

The Plus[ ] function adds up its arguments.  In fact, Plus[ ] is the internal form of  addition +;  e.g.,  a + b is identical to Plus[a,b].

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

Two underscores match one or more arguments, three underscores match zero or more auguments.

Function Definition with More than One-Line of Code: Programs

If we define a function with slightly complicated code of more than one line, we can use the Module[ ] to group the code as a single unit.

\(\(\(prog[
        x_]\)\(\ \)\(:=\)\(\ \)\(Module[\ {a, b, c}, \ 
			a\  = \ 
          1; 
			b\  = \ 2; 
			c\  = \ a\  + \ b; 
			x\  + \ 
          c]\)\(	\)\)\)

Note: the variables in the first list {a,b,c} specify LOCAL variables to this function. Statements are separated by semicolon ";".   The return value of the function is last expression, x + c, without an ending semicolon.  The argument x must be treated as a constant, rather than a variable (i.e., you cannot do, e.g., x = a + b).

prog[3]

Parentheses/Brackets in Mathematica

Mathematica distinguishes carefully various form of brackets for syntactic purpose.

(   )      Round parenthesis for grouping
[  ]       Square bracket for arguments
{  }       Braces for List
[[ ]]   Double bracket for indexing

Semi-Colon vs. Coma

Semi-colon  ";" separates multiple expressions.  You can put any number of them in your code.

Coma "," separates argument list.   The number of comas are dictated by the syntax requirement.  You can not put them arbitrarily.  Examples:

x = 3;  y  =  x^2;  z  =  x + 1

func[x_]  :=  Module[{},  x^2]

Patterns

Pattern is an important concept in Mathematica's syntax:  f[x_] is a pattern.  Patterns are used for matching an expression.  So f[x_] matched any expression with an explicit f, followed by square brackets with x_ being replaced by any expression.  So f[x_] matches f[1], f[x], or f["this"], but not g[2].   If pattern matches, the definition associated with that pattern is executed.   In the above example, f[something] is replaced by something^2.  

g[x_Integer]  matches a function g with integer argument, so, it matches g[2], but not g[a] (assuming we did not say a = 3, so it is not an integer).  Unmatched patterns are not executed and returned the same as input.   h[a_, b_, c_] matches function h with three arbitrary arguments.

v[a__] (two underscores) matches function v with 1 or more arguments.  So it matches v[1], v[1,2],  or v[a,b,c].

You can test if pattern pattn match expression expr by the command:

MatchQ[expr,  pattn]

For example,

MatchQ[f[y],  f[x_]]

Here are some more examples of patterns:

f[n_]           f with any argument named n
f[n_, m_]  f with two argument
f[n_, n_]  two  idential argument
x^n_             x to any power
x_^n_          any expr to any power
a_  +  
      b_       a sum of two expressions
{a1_,  a2_}  a list of two exprs

More on Patterns  _:  _?  _/;

The function j[ ] has optional arguments with default values 1 and 2.

j[x_,  y_:  1, z_:  2]  =  jp[x, y, z]

The function below accepts only prime numbers as input:

p[n_?PrimeQ]  :=  n^2

Similarly, the following function is defined only if the input satisfies a specified condition:

h[n_Integer  /;  n >  2]  :=  n^3

We can also specify the condition at the end of the definition:

h2[n_Integer]  :=  n^3    /;  n  >  2

Multiple Definitions to the Same Symbol

We can associate several definitions, differentiated by different pattern matchings. [Similar to the concept of polymorphism and function overloading in C++.]

Remove[f];
f[n_Integer]  :=  n;
f[x_Real]  :=  Floor[x];
f[c_Complex]  :=  Re[c];
f[x_,  n_Integer]  :=  x^n;

?f

When there are multiple definitions associated with a symbol, the first one matching the input will be used.  [Mathematica tries to apply the more specific one first before apply more general one.]

Substitution Operations

A convenient way for evaluating an expression is by variable substitution.

(1 + x)^5    /.  x ->  3

While x = 3 globally sets x to 3, x -> 3 replaces x by 3 only locally at the current expression.  The symbol x itself is untouched.

The combined operator -> (minus sign followed by arrow without a space) is known as replacement Rule.   x->3 is the same as Rule[x,3].    /.  (slash followed by a period) is substitution operator.

{Sin[x], Cos[x], Exp[x]} /. x -> 0

Solve[x^2  +  3  x  - 1  ==  0, x]

x  /.  %19  //  N

Expression of the form x -> 1.2 is called a rule, and output from solving an equation gives you a list of rules.

What is the difference between { x -> 1, y -> 2}  vs { {x->1},{x->2}}?

Prefix, Postfix, and Infix Notation 
for Function Application.

We normally say Sin[x], but we could say:

Sin @ Pi

Pi  //  Sin

{a, b, c} ~Join~ {d, f}

The *fixes

f[x]          Apply function  usual form
f @ x         Prefix form
x  //  f     Postfix form
a ~f~ 
        b   Infix form (if f takes two arguments)

Clear[x, y]

Precedence of @ vs //

f @ x  +  y

x  +  y  //  f

x ~f~ y

READINGS:

On function definitions:  Sec. 1.7
On patterns: Sec. 2.3