Error In Assigning Values to Two-Variable Function

Please migrate this question if it is not appropriate for Math.SE (I fear it is not).

In the following snippet, $f(i,j)$ is a procedure that compares the value of $i$ and $j$ before deciding what to return.

The code

sum(sum(f(i, j), j = 1 .. 5), i = 1 .. 5);

gives the error

Error, (in f) cannot determine if this expression is true or false: i <= j

My understanding is that Maple has not yet assigned a value to either of $i$ and $j$, and so cannot make the comparison. The suggested fix for this is to use unevaluation quotes like so

sum(sum('f'(i, j), j = 1 .. 5), i = 1 .. 5);

but this gives a new error

Error, (in f) cannot determine if this expression is true or false: i <= 1

Apparently the quotes allow it to understand $j$, but not $i$. I've tried various other combinations of unevaluation quotes around f and around sum, but I get similar errors each time. How can I get this code to run?

-

sum('sum('f'(i, j), j = 1 .. 5)', i = 1 .. 5);

-
That works perfectly. Thank you. – Austin Mohr Apr 28 '12 at 17:51

The sum command is intended (most) for symbolic summation, such as this,

sum(i,i=1..N);
1        2   1     1
- (N + 1)  - - N - -
2            2     2

factor(%);
1
- N (N + 1)
2


Your example, on the other hand, involves explicit finite bounds on the range of summation. The add command is designed for that kind of task, without requiring unevaluation quotes. Eg.,

add(add(f(i, j), j = 1 .. 5), i = 1 .. 5);


The sum command can fall back to doing explicit adding of a finite number of terms, but only after it first tries symbolic summation.

Judging by the error messages you cite, the problem seems to be akin to premature evaluation. Under Maple's normal evaluation rules, the arguments to a Maple procedure call get evaluated before being passed in. In the case of a procedure call f(i,j) which performs the conditional check i<j an error will occur if i and j do not have numeric values. But that is precisely what may happen when sum(f(i,j)...) causes f(i,j) to be evaluated under these normal rules.

Suppose, for example, that your f is defined like this,

f:=proc(a,b) if a<b then sin(x) else 0 end if; end proc:


in which case explicitly calling f(i,j) alone will produce this error,

f(i,j);
Error, (in f) cannot determine if this expression is true or false: i < j


And that is just what happens when you call the sum(...) version without adequate delaying of the evaluation of the argument f(i,j). There are a few workarounds. One way, which you've been shown, is to use right single-quotes, also known as unevaluation quotes. Those can delay evaluation long enough, until i and j are supplied with actual numeric values. The biggest problem with such a workaround is that the number and location of uneval quotes required to handle nested sum calls can get messy and harder to explain.

Another workaround is to put a check into the procedure f. In the case that f is called with symbolic names (as opposed to numeric values) then it returns an unevaluated function call to itself. This can allow both sum and add to be used. Eg.,

f:=proc(a,b) if not( type(a,numeric) and type(b,numeric) ) then
return 'procname'(args);
else
if a<b then sin(x); else 0; end if;
end if;
end proc:

f(i,j); # no error!

f(i, j)

sum(sum(f(i, j), j = 1 .. 5), i = 1 .. 5);

10 sin(x)


What is useful about the add command is that it has so-called special evaluation rules. That means that Maple does not evaluate the arguments in function calls to add before passing them in. So f doesn't actually get called for unassigned symbolic names i and j. Eg,

f:=proc(a,b) if a<b then sin(x); else 0; end if; end proc:

add(add(f(i, j), j = 1 .. 5), i = 1 .. 5);

10 sin(x)


This topic is a FAQ. Eg, here. See also the Error Message Guide, here.

-