RE: expand(), was: derivatives of matrix functions
Subject: RE: expand(), was: derivatives of matrix functions
From: Stavros Macrakis
Date: Fri, 5 Dec 2003 14:24:48 -0500
> If I entered "'integrate(1/log(x)-1/log(x)^2,x);expand(%);"
> then I asked for linearity to be applied, and I should get it.
You might have *intended* linearity to be applied, but that is not the
current definition of 'expand', which as I say is really 'distribute
multiplication/exponentiation over addition'.
Perhaps a broader definition of expand would be better, as you suggest.
There is always a tension in these discussions of "how do I do XXX in
Maxima" between answering the immediate question ("just set the
modify_semantics_bizarrely switch to 22/7, and it will work as you
expected") and discussing design of future changes so that it will be
easier/more convenient/more intuitive to do XXX. I find both kinds of
discussion interesting and useful, but it's good to keep clear which is
which.
> > You can put together a batch file to define all your
> > favorite settings, [...]
> Yes, I could do that -- now. It wouldn't help me while I'm
> figuring out (over a period of weeks) how to make Maxima do
> what I want.
Yes, you would have to figure out what you want to do and how you want
Maxima to do it, just as with any other tool.
> As a general goal, Maxima should try to do the "right
> thing" out of the box. Yes, that is vague and ill-defined.
It does *try* to do the right thing. But 35 years' experience shows
that different people want different things, hence the dauntingly large
number of parameter settings and extension mechanisms.
> I hope people are interested in defining it and making it happen.
I am hardly a defender of the status quo! As you can see from my
archived messages and the large number of bug reports I've put in, I
think many things need to be changed, some of them radically.
> At present, expand(expr) might or might not actually
> expand something. I can't believe that this is how
> people expect an algebra system to work.
You are making a lot of the word "expand". Perhaps Maxima's command
should be called product_expand to be unambiguous.
> > [...] Perhaps there should be a generic Expand that
> > knows about all possible kinds of expansion. But to
> > control its application, it should only operate on the
> > top level of an expression. [...]
OK, here is that function. It doesn't handle trigexpand because there
is currently no easy way to restrict that to the top level.
linear_functions: map('nounify,[integrate,diff,limit,sum])$
declare(generic_linear,linear)$
top_level_linear_expand(ex):=
if atom(ex) then ex
else if not member(op(ex),linear_functions)
then multthru(ex) /* Distribute * over + */
else subst(op(ex),'generic_linear,
apply('generic_linear,args(ex)))$
And here is some code that handles the full expression. I suggest you
try these out as prototypes and see whether they do what you expect them
to. Detailed comments should probably go to me, rather than the whole
mailing list.
The code is not pretty, but... I think it works.
-s
--------------------
expand_linear: [ sum,integrate,diff,limit]$
fullexpand(expr):=
block([linear_versions,
oldexpr: false,
expand_linear: map(nounify,expand_linear),
/* Set flags to maximize expansion */
logexpand: 'all,
expop: maxposex,
expon: maxnegex,
/* The following are true by default, but may have been
set otherwise by the user. */
radexpand: true,
trigexpandtimes: true,
trigexpandplus: true],
linear_versions:
makelist( (f: concat(f, "_linear"),
apply('declare,[f,[linear]]),
f),
f, expand_linear),
to_linear: map("=",expand_linear,linear_versions),
from_linear: map("=",linear_versions,expand_linear),
while (expr # oldexpr)
do ( oldexpr:expr,
expr: trigexpand(subst(to_linear,oldexpr)),
expr: subst(from_linear, expr),
expr: ev(expr,noeval) ),
expr )$