how to define a piecewise function



Hi Glenn,

> How do I define a piecewise function that can be manipulated by maxima?

Maxima recognizes so-called unevaluated conditionals
but it doesn't know what to do with them. However with
a little effort we can get some workable results.

'if --- quote mark tells Maxima to make an unevaluated conditional.
matchdeclare & tellsimpafter --- these set up pattern-matching rules.

(%i2) matchdeclare ([aa, bb, cc, xx], true);
(%o2) done
(%i3) tellsimpafter ('diff ('if aa then bb else cc, xx), 'if aa then
diff (bb, xx) else diff (cc, xx));
(%o3) [derivativerule1,?simpderiv]

OK, now we have a rule for the derivative of an
unevaluated conditional. (Note that the placement
of quote marks is important.) Let's try it:

(%i4) diff ('if u > 0 then f(u) else g(u), u);
(%o4) if u > 0 then 'diff(f(u),u,1) else 'diff(g(u),u,1)

Looks OK. Let's try the example you posted.
I changed if to 'if in the defn of tn.

(%i5) fn (x) := 1.39e5 * x^3 + 230 * x^2 - 522 * x + 28$
(%i6) tn (x) := block (u: 0.04625278034765223, 'if x < u then
x*fn(u)/u else fn(x))$
(%i7) diff (tn (x), x);
(%o7) if x < .04625278034765223 then 391.3725896432846
          else 417000.0*x^2+460*x-522

Let's evaluate that last expression for some values of x.

(%i8) map (lambda ([x], ''%), [0.04, 0.08, 0.12]);
(%o8) [if 0.04 < .04625278034765223 then 391.3725896432846
           else 163.6,
       if 0.08 < .04625278034765223 then 391.3725896432846
           else 2183.6,
       if 0.12 < .04625278034765223 then 391.3725896432846
           else 5538.0]

Oops --- Maxima doesn't evaluate the 'if (because it
is a noun and not a verb). Tell Maxima to try harder.

(%i9) ''%, nouns;
(%o9) [391.3725896432846,2183.6,5538.0]

Looks OK.

Unevaluated conditionals is one of my pet topics.
I am working on some code to expand Maxima's
handling of them. However it's not part of Maxima yet.

Incidentally the examples above assume Maxima 5.9.2 ---
5.9.1 and earlier versions will display 'if as mcond.

Hope this helps,
Robert Dodier