Up | Next | Prev | PrevTail | Tail |
This package allows a user to find the canonical form of expressions involving dummy variables. In that way, the simplification of polynomial expressions can be fully done. The indeterminates are general operator objects endowed with as few properties as possible. In that way the package may be used in a large spectrum of applications.
The possibility to handle dummy variables and to manipulate dummy summations are important features in many applications. In particular, in theoretical physics, the possibility to represent complicated expressions concisely and to realize simplifications efficiently depend on both capabilities. However, when dummy variables are used, there are many more ways to express a given mathematical objects since the names of dummy variables may be chosen almost arbitrarily. Therefore, from the point of view of computer algebra the simplification problem is much more difficult. Given a definite ordering, one is, at least, to find a representation which is independent of the names chosen for the dummy variables otherwise, simplifications are impossible. The package does handle any number of dummy variables and summations present in expressions which are arbitrary multivariate polynomials and which have operator objects eventually dependent on one (or several) dummy variable(s) as some of their indeterminates. These operators have the same generality as the one existing in REDUCE. They can be noncommutative, anticommutative or commutative. They can have any kind of symmetry property. Such polynomials will be called in the following dummy polynomials. Any monomial of this kind will be called dummy monomial. For any such object, the package allows to find a well defined normal form in one-to-one correspondance with it.
In section 2, the convention for writing dummy summations is explained and the available declarations to introduce or suppress dummy variables are given.
In section 3, the commands allowing to give various algebraic properties to the operators are described.
In section 4, the use of the function canonical
is explained and illustrated.
For references, see [BL85, BC82, But82, Leo80, Leo84, Leo91, Lin91, McK78, RT89, Sim71b, Sim71a, BC94, Cap97].
The use of DUMMY requires that the package ASSIST version 2.2 be available. It is loaded automatically when DUMMY is loaded.
A dummy variable (let us name it dv
) is an identifier which runs from the integer \(i_1\) to
another integer \(i_2\). To the extent that no definite space is defined, \(i_1\) and \(i_2\) are assumed to be
some integers which are the same for all dummy variables.
If f
is any REDUCE operator, then the simplest dummy summation associated to dv
is
the sum
dv
can
appear as many times we want since the operator f
may depend on an arbitrary
number of variables. So, the package is potentially applicable to many contexts.
For instance, it is possible to add rules of the kind one encounters in tensor
calculus.
Obviously, there are as many ways we want to express the same quantity. If the name of
another dummy variable is dum
then the previous expression is written as
f
is the identity operator. So, a generic dummy
polynomial will be a sum of dummy monomials of the kind To declare dummy variables, two commands are available:
i.
dummy_base
\(\langle \)idp\(\rangle \);where \(\langle \)idp\(\rangle \) is the name of any unassigned identifier.
ii.
dummy_names
\(\langle \)d\(\rangle \),\(\langle \)dp\(\rangle \),\(\langle \)dpp\(\rangle \), …;The first one declares idp_1
,…,idp_n
as dummy variables i.e. all variables of the
form idp_xxx
where \(xxx\) is a number will be dummy variables, such as idp_1
,
idp_2
,…, idp_23
. The second one gives special names for dummy variables. All
other identifiers which may appear are assumed to be free. However, there is a
restriction: named and base dummy variables cannot be declared simultaneously.
The above declarations are mutually exclusive. Here is an example showing
that:
dummy_base dv; ==> dv % dummy indices are dv1, dv2, dv3, ... dummy_names i,j,k; ==> ***** The created dummy base dv must be cleared
When this is done, an expression like
op(dv1)*sin(dv2)*abs(i)*op(dv2)$
means a sum over \(dv_1,dv_2\). To clear the dummy base, and to create the dummy names \(i,j,k\) one is to do
clear_dummy_base; ==> t dummy_names i,j,k; ==> t % dummy indices are i,j,k.
When this is done, an expression like
op(dv1)*sin(dv2)*abs(x)*op(i)^3*op(dv2)$
means a sum over \(i\). Similarly, the command clear_dummy_names
clears earlier
defined named dummy variables.
One should keep in mind that every application of the above commands erases the
previous ones. It is also possible to display the declared dummy names using
show_dummy_names
:
show_dummy_names(); ==> {i,j,k}
To suppress all dummy variables one can enter
clear_dummy_names; clear_dummy_base;
All dummy variables should appear at first level as arguments of operators. For instance, if \(i\) and \(j\) are dummy variables, the expression
rr:= op(i,j)-op(j,j)
is allowed but the expression
op(i,op(j)) - op(j,op(j))
is not allowed. This is because dummy variables are not detected if they appear at a level
larger than 1. Apart from that there is no restrictions. Operators may be commutative,
noncommutative or even anticommutative. Therefore they may be elements of an
algebra, they may be tensors, spinors, grassman variables, etc. \(\ldots \) By default they are
assumed to be commutative and without symmetry properties. The REDUCE
command noncom
declaration is taken into account and, in addition, the command
anticom at1, at2;
makes the operators \(at_1\) and \(at_2\) anticommutative.
One can also give symmetry properties to them. The usual declarations symmetric
and
antisymmetric
are taken into account. Moreover and most important they can be
endowed with a partial symmetry through the command symtree
. Here are three
illustrative examples for the \(r\) operator:
symtree (r,{!+, 1, 2, 3, 4}); symtree (r,{!*, 1, {!-, 2, 3, 4}}); symtree (r, {!+, {!-, 1, 2}, {!-, 3, 4}});
The first one makes the operator (fully) symmetric. The second one declares it
antisymmetric with respect to the three last indices. The symbols !*, !+ and !- at the
beginning of each list mean that the operator has no symmetry, is symmetric or is
antisymmetric with respect to the indices inside the list. Notice that the indices are not
denoted by their names but merely by their natural order of appearance. 1 means the first
written argument of \(r\), 2 its second argument etc. The first command is equivalent to the
declaration symmetric
except that the number of indices of \(r\) is restricted to 4 i.e. to the
number declared in symtree
. In the second example \(r\) is stated to have no
symmetry with respect to the first index and is declared to be antisymmetric with
respect to the three last indices. In the third example, \(r\) is made symmetric with
respect to the interchange of the pairs of indices 1,2 and 3,4 respectively and is
made antisymmetric separately within the pairs \((1,2)\) and \((3,4)\). It is the symmetry of
the Riemann tensor. The anticommutation property and the various symmetry
properties may be suppressed by the commands remanticom
and remsym
.
To eliminate partial symmetry properties one can also use symtree
itself.
For example, assuming that \(r\) has the Riemann symmetry, to eliminate it do
symtree (r,{!*, 1, 2, 3, 4});
However, notice that the number of indices remains fixed and equal to 4 while with
remsym
it becomes again arbitrary.
canonical
Operator canonical
is the most important functionality of the package. It can be
applied on any polynomial whether it is a dummy polynommial or not. It returns a
normal form uniquely determined from the current ordering of the system. If
the polynomial does not contain any dummy index, it is rewriten taking into
account the various operator properties or symmetries described above. For
instance,
symtree (r, {!+, {!-, 1, 2}, {!-, 3, 4}}); aa:=r(x3,x4,x2,x1)$ canonical aa; ==> - r(x1,x2,x3,x4).
If it contains dummy indices, canonical
takes also into account the various
dummy summations, makes the relevant simplifications, eventually rename
the dummy indices and returns the resulting normal form. Here is a simple
example:
operator at1,at2; anticom at1,at2; dummy_names i,j,k; ==> t show_dummy_names(); ==> {i,j,k} rr:=at1(i)*at2(k) -at2(k)*at1(i)$ canonical rr; => 2*at1(i)*at2(j)
It is important to notice, in the above example, that in addition to the summations over
indices \(i\) and \(k\), and of the anticommutativity property of the operators, canonical
has
replaced the index \(k\) by the index \(j\). This substitution is essential to get full simplification.
Several other examples are given in the test file and, there, the output of canonical
is
explained.
As stated in the previous section, the dependence of operators on dummy indices is limited to first level. An erroneous result will be generated if it is not the case as the subsequent example illustrates:
operator op; dummy_names i,j; rr:=op(i,op(j))-op(j,op(j))$ canonical rr; ==> 0
Zero is obtained because, in the second term, canonical
has replaced \(j\) by \(i\) but has
left \(op(j)\) unchanged because it does not recognize the index \(j\) which is inside. This
fact has also the consequence that it is unable to simplify correctly (or at all)
expressions which contain some derivatives. For instance (\(i\) and \(j\) are dummy
indices):
aa:=df(op(x,i),x) -df(op(x,j),x)$ canonical aa; ==> df(op(x,i),x) - df(op(x,j),x)
instead of zero. A second limitation is that canonical
does not add anything to
the problem of simplifications when side relations (like Bianchi identities) are
present.
Up | Next | Prev | PrevTail | Front |