plot2d and quad_qags feeding non-numeric input to user function



On 7/26/11, Charles Russell <worwor at bellsouth.net> wrote:
> I can't use the following user-defined function in the numerical
> procedures plot2d and quad_qags because they feed it non-numeric values
> as input.  In the case of plot2d I can get around this with a discrete
> plot, but I can't find a workaround for the numeric integration. (This
> is an easy example to integrate analytically, but I am interested in the
> general case.)
>
> bell(x):= block([dum],
>       if not numberp(x) then print("bell: error, x = ",x),
>       if x <= -1 then dum : 0
>       else if x >= 1 then dum : 0
>       else dum : (1 - x^2)^2,
>       return(dum)
>       ) ;
>
> plot2d(bell, [x,-1,1]); /* OK */
> trace(bell);
> plot2d(bell(x), [x,-1,1]); /* input non-numerical */
> qags_out: quad_qags(bell(s), s, -1, 1); /* input non-numerical */
>
> (%i83) trace(bell);
> (%o83)                              [bell]
> (%i84) plot2d(bell(x), [x,-1,1]); /* input non-numerical */
> 1 Enter bell [x]
> bell: error, x =  x
> 1 Exit  bell dum
> COERCE-FLOAT-FUN: no such Lisp or Maxima function: dum
>   -- an error. To debug this try: debugmode(true);
> (%i85) qags_out: quad_qags(bell(s), s, -1, 1); /* input non-numerical */
> 1 Enter bell [s]
> bell: error, x =  s
> 1 Exit  bell dum
> COERCE-FLOAT-FUN: no such Lisp or Maxima function: dum
>   -- an error. To debug this try: debugmode(true);

Note that bell returns the symbol dum when the argument
is something other than a number.
plot2d and quad_qags evaluate their arguments, so what they
see is the return value of bell(x), which is the symbol dum.
When their first argument is a symbol, plot2d and quad_qags
try to treat that as the name of a function, which it isn't,
therefore the error.

A couple of different ways to handle this.
(1) prevent evaluation of the argument.
plot2d('(bell(x)), ....)
(2) supply just the function name.
plot2d(bell, ...)
(3) let bell return a partially-evaluated conditional expression.
bell(x) := if x < -1 then 0 elseif x > 1 then 0 else <whatever>;
Maxima is fairly comfortable with partial evaluation --
expressions which typically cause "no value for variable x"
errors in other programming languages are OK in Maxima.

HTH,
Robert Dodier