Defining functions

Mathematica

There are two important things to know about functions in Mathematica. The first is that functions always use square brackets for their arguments to distinguish from parentheses which are used for grouping. The second is that built-in functions always begin with a capital, like Sin[x], so you can use lower-case names without fear of a conflict.

Here a function f is defined. Notice that in function definitions, the variables on the left-hand side are marked with an underscore, as in x_. This indicates that x is part of the function definition and not some expression to be evaluated.

In[5]:= f[x_] := x^2
In[6]:= f[3]
Out[6]= 9

Another thing to note is the use := instead of = for the assignment. This is a kind of "delayed assignment" operator that only evaluates the right hand side when necessary.

Delayed assignment can be used to create recursively defined functions, like the Fibonacci sequence (where later values of the function are defined in terms of earlier values).

In[1]:= f[0] = 0

Out[1]= 0

In[2]:= f[1] = 1

Out[2]= 1

In[3]:= f[n_] := f[n-1] + f[n-2]

In[4]:= f[6]

Out[4]= 8

Maxima

Functions are defined in a very natural way, using the := operator.

(C4) f(x) := x^2;

               2
(D4)  f(x) := x
(C5) f(3);
(D5)  9

Axiom

In Axiom, functions are created using the "delayed assignment" operator, ==.

(1) -> f(x) == x**2
                                                                   Type: Void
(2) -> f(3)
   Compiling function f with type PositiveInteger -> PositiveInteger

   (2)  9
                                                        Type: PositiveInteger
(3) -> f(-5)
   Compiling function f with type Integer -> Integer

   (3)  25
                                                        Type: PositiveInteger

Delayed assignment can also be used to create recursively defined functions, like the Fibonacci sequence (where later values of the function are defined in terms of earlier values).

(1) -> f(0) == 0
                                                                   Type: Void
(2) -> f(1) == 1
                                                                   Type: Void
(3) -> f(n) == f(n-1) + f(n-2)
                                                                   Type: Void
(4) -> f(6)
   Compiling function f with type Integer -> NonNegativeInteger
   Compiling function f as a recurrence relation.

   (4)  8
                                                        Type: PositiveInteger

Octave

Since Octave is not a computer algebra system, functions are defined as programs (i.e. like functions in any other programming language).

octave:5> function y = f(x)
> y = x .^ 2;
> endfunction
octave:6> f(3)
ans = 9

For simple functions, the definition can be done on a single line instead:

octave:5> function y = f(x); y = x .^ 2; endfunction
octave:6> f(3)
ans = 9

Notice that in each of these forms, we use the .* operator. The basic data type in Octave is the matrix, and the usual operators +, -, *, /, ^ all operate in the natural way for matrices. There are three new operators .*, ./, .^ which act componentwise (the way addition and subtraction work).

Defining functions using these operators allows us to apply them to whole vectors or matrices of values at a time:

octave:7> f( [ 1 2 3 4 5 ] )
ans =

   1   4   9  16  25

Functions for rounding and truncating

Mathematica

Mathematica has several functions for rounding. Floor[] rounds numbers down (towards minus infinity), Ceiling[] rounds them up, and Round[] rounds to the nearest integer.

One important note about Round[]! For even numbers, it rounds exact halves down. For odd numbers it rounds them up. So 2.5 rounds down to 2, while 3.5 rounds up to 4. This is a useful behavior in many statistical or numerical analysis situations.

In[1]:= f[x_] := Round[x]

In[2]:= f[2.3]

Out[2]= 2

In[3]:= f[2.6]

Out[3]= 3

In[4]:= g[x_] := Floor[x]

In[5]:= g[2.9]

Out[5]= 2

In[6]:= h[x_] := Ceiling[x]

In[7]:= h[2.1]

Out[7]= 3

Maxima

The functions for rounding and truncating in Maxima are currently implemented within the internal LISP code. That means that you have to precede the function calls with a ? mark, and that they don’t work one every type (like bigfloats). They work fine for integers and reals, however. It also means you can’t graph them. Starting with version 5.9.3 of Maxima, there are ceiling() and floor() functions (without the ? marks) that work more normally.

The most commonly-used functions are ?floor() for rounding down (toward minus infinity), ?ceiling() for rounding up, and ?round() for rounding to the nearest integer.

One important note about ?round()! For even numbers, it rounds exact halves down. For odd numbers it rounds them up. So 2.5 rounds down to 2, while 3.5 rounds up to 4. This is a useful behavior in many statistical or numerical analysis situations.

(%i1) f(x) := ?round(x);

(%o1)                          f(x) := ROUND(x)
(%i2) f(2.3);

(%o2)                                  2
(%i3) f(2.6);

(%o3)                                  3
(%i4) g(x) := ?floor(x);

(%o4)                          g(x) := FLOOR(x)
(%i5) g(2.9);

(%o5)                                  2
(%i6) h(x) := ?ceiling(x);

(%o6)                         h(x) := CEILING(x)
(%i7) h(2.1);

(%o7)                                  3

Piecewise defined functions

Mathematica

The /; syntax lets us place conditions on a function. This allows us to create piecewise defined functions. The following function is y=x for negative values and y=x^2 for positive values.

In[1]:= lineQuad[x_] := x /; x<0

In[2]:= lineQuad[x_] := x^2 /; x>=0

In[3]:= lineQuad[-3]

Out[3]= -3

In[4]:= lineQuad[2]

Out[4]= 4

Maxima

A piecewise defined function may be defined in Maxima using an if-then structure. The following function is y=x for negative values and y=x^2 for positive values.

(%i1) lineQuad(x) := if x<0  then x else x^2;
                                                         2
(%o1)               lineQuad(x) := if x < 0 then x else x
(%i2) lineQuad( -3 );
(%o2)                                 - 3
(%i3) lineQuad( 2 );
(%o3)                                  4

Octave

There is a clever way to create piecewise defined functions in Octave. It uses the way the comparison operators work; they return 1 when true and 0 when false (and operate this way coordinate wise on vectors and matrices). The following function is y=x for negative values and y=x^2 for positive values.

octave:1> function y = lineQuad(x)
> y = (x<0) .* x  +  (x>=0) .* x.^2;
> endfunction
octave:2> lineQuad( [ -3 -2 -1 0 1 2 3 ] )
ans =

  -3  -2  -1   0   1   4   9