how to define a piecewise function



> Next problem. How do I plot the piecewise function?
>
> (%i6) tn(x):=block([u],u:0.04625278034765223, if(x f(x));
> (%o6) tn(x) := block([u], u : .04625278034765223,
>                                                                x f(u)
>                                                  if x < u then ------
> else f(x))
>                                                                  u
> (%i7) plot2d([tn(x)],[x,0,0.6]);
> Maxima was unable to evaluate the predicate:
> x < .04625278034765223
> #0: tn(x=x)
>   -- an error.  Quitting.  To debug this try debugmode(true);

This is a common problem with the plotting functions.  The argument to
the plotting function is evaluated first to determine what to plot,
and then multiple times on specific arguments to determine the graph.

This is to allow things like:

    plotlist: [f(x),g(x)];

    plot2d(plotlist, ...);

You can see this clearly as follows:

   testfn(x):=if numberp(x) then (print(x),x^2) else (print(x),'(testfn(x)));

Now,

   plot2d(testfn(x),[x,0,1]);

prints first x (crucially!), then a bunch of numeric values.

The solution is to write

   plot2d('(testfn(x)), [x,0,1]);

A different solution -- which is actually good practice in general --
is to write your functions so that they work correctly for numerical
as well as symbolic arguments, e.g.

   f(x):=if numberp(x) then (if x<0 then 0 else 1) else ('f)(x);

Note that the exact syntax ('f)(...) must be followed.  Minor variants
such as 'f(x), '(f)(x), etc. do not produce the same result.

Even better:

   f(x):= block([sign: sign(x)],
               if member(sign,[pos,pz,zero])
                  then 1
               else if member(sign,[neg])
                  then 0
               else ('f)(x);

You can also use "is" with prederror:true for similar effects.  Just
remember that you can't count on trichotomy when "unknown" is a
possible answer!

          -s