Next: Simplifications and Transformation Up: Maple Procedures Previous: Variable Number of

Returning Unevaluated

The MAX procedure that we have just written works for numerical arguments only. If you try the Maple function max you will see that it also works for symbolic arguments. Consider


> MAX(1,2,x);
Error, (in MAX) cannot evaluate boolean
> max(1,2,x);

                                   max(2, x)

Maple cannot execute the procedure MAX because it cannot compute whether args[i] < maximum for a non-numeric value. We want MAX of some numbers to compute the answer, but otherwise, we want MAX(x,y) to stay as MAX(x,y) so we can compute with MAX(x,y) symbolically just like sin(x) stays as sin(x).

Also, our MAX procedure that we wrote only works for numbers of type numeric. It would be nice if MAX knew that for instance.

To help us write such a MAX function, we will make use of the signum function which provides a more powerful comparison of two real values. The signum function returns if it can show that the , +1 if , otherwise it returns unevaluated, i.e. it returns signum(x). For example


> signum(sqrt(2)-1);
                                       1

> signum(sqrt(2)-Pi);
                                       -1

> signum(a-b);
                                 signum(a - b)

Let us employ the signum function to make our MAX function smarter and also let our MAX function handle symbolic arguments.


MAX := proc() local a,i,j,n,s;
    n := nargs;
    # First, put the arguments in an array
    a := array(1..n); 
    for i to n do a[i] := args[i] od;
    # Compare a[i] with a[j] for 1 <= i < j <= n
    i := 1;
    while i < n do
        j := i+1;
        while j <= n do
            s := signum(a[i]-a[j]);
            if s = 1 then # i.e. a[i] >= a[j]               
                a[j] := a[n]; n := n-1;
            elif s = -1 then # i.e. a[i] < a[j]
                a[i] := a[j]; a[j] := a[n]; j := n; n := n-1; i := i-1;
            else # cannot determine the sign
                j := j+1
            fi
        od;
        i := i+1
    od;
    if n = 1 then RETURN(a[1]) fi;
    'MAX'( seq(a[i], i=1..n) );
end;

What is most interesting about the above code is the last line. The back quotes ' are used to prevent the MAX function call from executing as otherwise it would go into an infinite loop. Instead, the unevaluated function call MAX( ... ) is returned, indicating that the maximum could not be computed. However, some simplifications may have taken place. For example


> MAX( x, 1, sqrt(2), x+1 );
                                            1/2
                                MAX(x + 1, 2   )


bondaren@thsun1.jinr.ru