Up to Main Lab Page | Next Lesson - Text in Maple | Previous Lesson - Fixed Point Iteration |
The syntax is:
proc (< argseq >) [local < nseq >; global < nseq >;]
< statement sequence >end;
[ ] indicates optional parameters.
If variables are not declared explicitly as local or global in the preamble, the
following rules are used to determine whether a variable is local or global:
The syntax is:
RETURN([ < expression >, < expression >, ... ] );
This will terminate execution of the procedure and return the value of the expression's.
> f := proc(x)
> if x >= 0 then RETURN(sqrt(x)); else RETURN(FAIL); fi
> end;
Note how we assign a name 'f ' to the procedure using the assignment operator
:=.
We may now call the procedure, using the name f assigned to it,
as we would any function.
The arguments of the function will be the arguments of the procedure.
> f(2);
> evalf(f(2));
> f(-1);
> f(x);
Notice that the last case returns an error since Maple can't decide whether the
unassigned variable name x is negative or not.
For a more complex example we will write a procedure which generates a sequence
of points (x, f (x)), around a given point, a,
as in lesson 9.
This procedure will use the global vairiable numpoints to indicate how
many points to process.
> points := proc(f, a) local g, p, i; global numpoints;
> g := (x -> ((-1)^x*10^(-x))) + a;
> p := [[g(i), evalf((f@g)(i))] $ i = 1..numpoints];
> RETURN(p);
> end;
We can now call the function, and use it in any way we would normally use its
output, an ordered set of points.
> numpoints := 10;
> points(x -> x^2, 1);
> f := x -> x/2;
> plot(points(f, 1), style=point);
Note that we had to set the value of numpoints globally first.
f and a are the arguments to the function and are supplied at
run time by the calling routine.
The local and global declarations are, strictly speaking, unecessary. This is
because the local variables g and p are assigned values
within the procedure, and so are local by default, whereas i
is the controling variable of a loop.
The global variable numpoints is not in either of these catagories and
so is global by default.
Try running the routine with numpoints not set to any value, why
might this be useful?
The syntax of the assignment of g is somewhat convoluted:
g := (x -> ((-1)^x*10^(-x))) + a;
This is because of a bug (feature?) of Maple. If we use the more normal
assignment
g := x -> (-1)^x*10^(-x) + a;
Maple does not evaluate a as the local parameter, but rather uses the global
value of a.
Since g, p and i are local they have no existence outside of the
procedure. Thus if we want to record the outpout (p) we must assign
the result of the procedure to a global variable name, q in this example.
> q := points(x->x/2,2);
> p;
> i;
> g;
> q;
Note that none of g, p or i have any value set.
On the other hand any global value of these variables will have no affect on
the procedure:
> g := 2;
> i := x -> x^47;
> p := 342;
> points(x->x/2,2);
> p;
> i;
> g;
This generates an error due to incorrect data typing. Things can get even worse
if incorrect data typing generates an incorrect answer, rather than an error.
Suppose we incorrectly pass an expression rather than a function.
> points(x^2, 2);
This produces an incorrect answer.
Conveniantly Maple provides an easy way to do data typing in procedures.
The arguments to a procedure may be given a specific data type.
If any of these variables is then assigned an incorrect type Maple generates
a (trappable) error of the form:
Error, procedure name expects its 1st argument, arg1, to be of type
type1, but received type2
Of course if you trap the error you can provide your own error handling.
(see Maple help on procedure and traperror).
The syntax for declaring a variable to be of a given data type is in the declaration is:
variable name :: data type
Maple accepts a wide range of data types, take the link to see some of them.
For example in our procedure above we could type f as an operator
and a as type numeric.
> points := proc(f::operator, a::numeric) local g, p, i; global numpoints;
> g := (x -> ((-1)^x*10^(-x))) + a;
> p := [[g(i), evalf((f@g)(i))] $ i = 1..numpoints];
> RETURN(p);
> end;
Now try our new, more robust, procedure.
> points(x -> x^2, 2);
> points(2, x -> x^2);
> points(x^2, 2);
type(expression, type)type returns a boolean value, either true or false. For example
We can use type to improve our original sqrt example.
This procedure checks to see if x is a numeric value, if it is the
procedure acts as before, returning sqrt or FAIL. If x is not numeric
the procedure returns the expression sqrt(x).
> f := proc(x)
> if type(x, numeric) then
> if x >= 0 then
> RETURN(sqrt(x));
> else
> RETURN(FAIL);
> fi;
> else
> RETURN(sqrt(x));
> fi;
> end;
> f(2);
> f(-1);
> f(x);
> diff(f(x), x);
In the last case we see that Maple is even smart enough to differentiate the
proceduraly defined expression f.
This is because the diff function calls the porcedure to find the value of
f, and was able to work with this value (sqrt(x)).
Of course if f did not return a valid expression diff would still fail.
Inputs should be a function, and two starting values. Make sure that these are
valid starting values at the beginnning of the function, return FAIL if they
are not.
Your routine should include data typing.
Up to Main Lab Page | Next Lesson - Text in Maple | Previous Lesson - Fixed Point Iteration | Top of this Lesson |