plot2d and quad_qags feeding non-numeric input to user function
Subject: plot2d and quad_qags feeding non-numeric input to user function
From: Robert Dodier
Date: Tue, 26 Jul 2011 15:12:16 -0600
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