On 11/15/08, van Nek <van.nek at arcor.de> wrote:
> tellsimp tells me that defining rules on + and * might not work.
As it happens, tellsimpafter handles + and * differently than tellsimp ...
tellsimpafter gathers up all the operands of one type, then all of another
type, etc. (I think that makes sense for any commutative operator,
but at present it works only for + and *.)
Here is an initial attempt at some rules for vector addition.
I've omitted various details, such as making sure all vectors
added together have the same number of elements.
(%i1) load ("./vector_identities.mac");
xx + ww partitions `sum'
yy vv partitions `product'
(%o1) ./vector_identities.mac
(%i2) vector(1) + vector(2);
(%o2) vector(3)
(%i3) vector(1) - vector(2);
(%o3) vector(- 1)
(%i4) vector(1) - vector(2) + 1 + a;
(%o4) a + vector(- 1) + 1
(%i5) a*vector(1) - 5*vector(2) + 1 + a;
(%o5) vector(a - 10) + a + 1
(%i6) vector(1, 2, 3) - vector(x, y, z) + a + b + c;
(%o6) vector(1 - x, 2 - y, 3 - z) + c + b + a
(%i7) 5*a*vector(x, y) - 6*b*vector(u, v);
(%o7) vector(5 a x - 6 b u, 5 a y - 6 b v)
> Generally I do not plan do create builtin simplifications for vectors.
> For better readability vector expressions should only be nicely
> displayed when typed in and only be simplified if
> the user asks explicitely for it. An explicit function should do the work.
OK by me for now, but after we get the identities straight,
let's revisit this point.
best,
Robert Dodier
PS.
$ cat vector_identities.mac
/* copyright 2008 by Robert Dodier
* I release this work under terms of the GNU GPL
*/
matchdeclare (ww, vector_termp);
matchdeclare (xx, lambda ([e], not vector_termp (e)));
tellsimpafter (ww + xx, add_vector_nonvector (ww, xx));
matchdeclare (vv, vectorp);
matchdeclare (yy, lambda ([e], not vectorp (e)));
defmatch (vector_nonvector_product_match, vv*yy);
vector_termp (e) := vectorp (e) or vector_nonvector_productp (e);
vectorp (e) := not atom(e) and op(e)='vector;
vector_nonvector_productp (e) := vector_nonvector_product_match (e) # false;
add_vector_nonvector (ww, xx) :=
if op(ww) = 'vector
then ww + xx
else
(lambda ([e], if op(e)='vector then e else
distribute_times_over_vector (e)),
map (%%, ww),
xx + apply ('vector, apply ("+", map (args, args (%%)))));
distribute_times_over_vector (e) :=
(vector_nonvector_product_match (e),
ev (apply ('vector, yy * args (vv)), %%));