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