(maxima.info)Function


Next: Macros Prev: Introduction to Function Definition Up: Function Definition
Enter node , (file) or (file)node

36.2 Function
=============

36.2.1 Ordinary functions
-------------------------

To define a function in Maxima you use the ':=' operator.  E.g.

     f(x) := sin(x)

defines a function 'f'.  Anonymous functions may also be created using
'lambda'.  For example

     lambda ([i, j], ...)

can be used instead of 'f' where

     f(i,j) := block ([], ...);
     map (lambda ([i], i+1), l)

would return a list with 1 added to each term.

   You may also define a function with a variable number of arguments,
by having a final argument which is assigned to a list of the extra
arguments:

     (%i1) f ([u]) := u;
     (%o1)                      f([u]) := u
     (%i2) f (1, 2, 3, 4);
     (%o2)                     [1, 2, 3, 4]
     (%i3) f (a, b, [u]) := [a, b, u];
     (%o3)               f(a, b, [u]) := [a, b, u]
     (%i4) f (1, 2, 3, 4, 5, 6);
     (%o4)                 [1, 2, [3, 4, 5, 6]]

   The right hand side of a function is an expression.  Thus if you want
a sequence of expressions, you do

     f(x) := (expr1, expr2, ...., exprn);

   and the value of <exprn> is what is returned by the function.

   If you wish to make a 'return' from some expression inside the
function then you must use 'block' and 'return'.

     block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)

   is itself an expression, and so could take the place of the right
hand side of a function definition.  Here it may happen that the return
happens earlier than the last expression.

   The first '[]' in the block, may contain a list of variables and
variable assignments, such as '[a: 3, b, c: []]', which would cause the
three variables 'a','b',and 'c' to not refer to their global values, but
rather have these special values for as long as the code executes inside
the 'block', or inside functions called from inside the 'block'.  This
is called dynamic binding, since the variables last from the start of
the block to the time it exits.  Once you return from the 'block', or
throw out of it, the old values (if any) of the variables will be
restored.  It is certainly a good idea to protect your variables in this
way.  Note that the assignments in the block variables, are done in
parallel.  This means, that if you had used 'c: a' in the above, the
value of 'c' would have been the value of 'a' at the time you just
entered the block, but before 'a' was bound.  Thus doing something like

     block ([a: a], expr1, ... a: a+3, ..., exprn)

   will protect the external value of 'a' from being altered, but would
let you access what that value was.  Thus the right hand side of the
assignments, is evaluated in the entering context, before any binding
occurs.  Using just 'block ([x], ...)' would cause the 'x' to have
itself as value, just as if it would have if you entered a fresh Maxima
session.

   The actual arguments to a function are treated in exactly same way as
the variables in a block.  Thus in

     f(x) := (expr1, ..., exprn);

   and

     f(1);

   we would have a similar context for evaluation of the expressions as
if we had done

     block ([x: 1], expr1, ..., exprn)

   Inside functions, when the right hand side of a definition, may be
computed at runtime, it is useful to use 'define' and possibly 'buildq'.

36.2.2 Memoizing Functions
--------------------------

A memoizing function caches the result the first time it is called with
a given argument, and returns the stored value, without recomputing it,
when that same argument is given.  Memoizing functions are often called
array function and are in fact handled like arrays in many ways:

   The names of memoizing functions are appended to the global list
'arrays' (not the global list 'functions').  'arrayinfo' returns the
list of arguments for which there are stored values, and 'listarray'
returns the stored values.  'dispfun' and 'fundef' return the array
function definition.

   'arraymake' constructs an array function call, analogous to 'funmake'
for ordinary functions.  'arrayapply' applies an array function to its
arguments, analogous to 'apply' for ordinary functions.  There is
nothing exactly analogous to 'map' for array functions, although
'map(lambda([<x>], <a>[<x>]), <L>)' or 'makelist(<a>[<x>], <x>, <L>)',
where <L> is a list, are not too far off the mark.

   'remarray' removes an array function definition (including any stored
function values), analogous to 'remfunction' for ordinary functions.

   'kill(<a>[<x>])' removes the value of the array function <a> stored
for the argument <x>; the next time <a> is called with argument <x>, the
function value is recomputed.  However, there is no way to remove all of
the stored values at once, except for 'kill(<a>)' or 'remarray(<a>)',
which also remove the function definition.

   Examples

   If evaluating the function needs much time and only a limited number
of points is ever evaluated (which means not much time is spent looking
up results in a long list of cached results) Memoizing functions can
speed up calculations considerably.
     (%i1) showtime:true$
     Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.
     (%i2) a[x]:=float(sum(sin(x*t),t,1,10000));
     Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.
     (%o2)        a  := float(sum(sin(x t), t, 1, 10000))
                   x
     (%i3) a[1];
     Evaluation took 5.1250 seconds (5.1260 elapsed) using 775.250 MB.
     (%o3)                   1.633891021792447
     (%i4) a[1];
     Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.
     (%o4)                   1.633891021792447

   As the memoizing function is only evaluated once for each input value
changes in variables the memoizing function uses are not considered for
values that are already cached:
     (%i1) a[x]:=b*x;
     (%o1)                       a  := b x
                                  x
     (%i2) b:1;
     (%o2)                           1
     (%i3) a[2];
     (%o3)                           2
     (%i4) b:2;
     (%o4)                           2
     (%i5) a[1];
     (%o5)                           2
     (%i6) a[2];
     (%o6)                           2


automatically generated by info2www version 1.2.2.9