Introduction to atensor
=======================

atensor is an algebraic tensor manipulation package. To use atensor, type load(atensor), followed by a call to the init_atensor function.

The essence of atensor is a set of simplification rules for the noncommutative (dot) product operator ("."). atensor recognizes several algebra types; the corresponding simplification rules are put into effect when the init_atensor function is called.

The capabilities of atensor can be demonstrated by defining the algebra of quaternions as a Clifford-algebra Cl(0,2) with two basis vectors. The three quaternionic imaginary units are then the two basis vectors and their product, i.e.:

         i = v     j = v     k = v  . v
              1         2         1    2

Although the atensor package has a built-in definition for the quaternion algebra, it is not used in this example, in which we endeavour to build the quaternion multiplication table as a matrix:

     (%i1) load(atensor);
     (%o1)       /share/tensor/atensor.mac
     (%i2) init_atensor(clifford,0,0,2);
     (%o2)                                done
     (%i3) atensimp(v[1].v[1]);
     (%o3)                                 - 1
     (%i4) atensimp((v[1].v[2]).(v[1].v[2]));
     (%o4)                                 - 1
     (%i5) q:zeromatrix(4,4);
                                     [ 0  0  0  0 ]
                                     [            ]
                                     [ 0  0  0  0 ]
     (%o5)                           [            ]
                                     [ 0  0  0  0 ]
                                     [            ]
                                     [ 0  0  0  0 ]
     (%i6) q[1,1]:1;
     (%o6)                                  1
     (%i7) for i thru adim do q[1,i+1]:q[i+1,1]:v[i];
     (%o7)                                done
     (%i8) q[1,4]:q[4,1]:v[1].v[2];
     (%o8)                               v  . v
                                          1    2
     (%i9) for i from 2 thru 4 do for j from 2 thru 4 do
           q[i,j]:atensimp(q[i,1].q[1,j]);
     (%o9)                                done
     (%i10) q;
                        [    1        v         v      v  . v  ]
                        [              1         2      1    2 ]
                        [                                      ]
                        [   v         - 1     v  . v    - v    ]
                        [    1                 1    2      2   ]
     (%o10)             [                                      ]
                        [   v      - v  . v     - 1      v     ]
                        [    2        1    2              1    ]
                        [                                      ]
                        [ v  . v      v        - v       - 1   ]
                        [  1    2      2          1            ]

atensor recognizes as base vectors indexed symbols, where the symbol is that stored in asymbol and the index runs between 1 and adim. For indexed symbols, and indexed symbols only, the bilinear forms sf, af, and av are evaluated. The evaluation substitutes the value of aform[i,j] in place of fun(v[i],v[j]) where v represents the value of asymbol and fun is either af or sf; or, it substitutes v[aform[i,j]] in place of av(v[i],v[j]).

Needless to say, the functions sf, af and av can be redefined.

When the atensor package is loaded, the following flags are set:

     dotscrules:true;
     dotdistrib:true;
     dotexptsimp:false;

If you wish to experiment with a nonassociative algebra, you may also consider setting dotassoc to false. In this case, however, atensimp will not always be able to obtain the desired simplifications.

Functions and Variables for atensor
===================================

 -- Function: init_atensor (ALG_TYPE, OPT_DIMS)
 -- Function: init_atensor (ALG_TYPE)

     Initializes the atensor package with the specified algebra type. ALG_TYPE can be one of the following:

     universal: The universal algebra has no commutation rules.

     grassmann: The Grassman algebra is defined by the commutation relation u.v+v.u=0.

     clifford: The Clifford algebra is defined by the commutation relation u.v+v.u=-2*sf(u,v) where sf is a symmetric scalar-valued function. For this algebra, OPT_DIMS can be up to three nonnegative integers, representing the number of positive, degenerate, and negative dimensions of the algebra, respectively. If any OPT_DIMS values are supplied, atensor will configure the values of adim and aform appropriately. Otherwise, adim will default to 0 and aform will not be defined.

     symmetric: The symmetric algebra is defined by the commutation relation u.v-v.u=0.

     symplectic: The symplectic algebra is defined by the commutation relation u.v-v.u=2*af(u,v) where af is an antisymmetric scalar-valued function. For the symplectic algebra, OPT_DIMS can be up to two nonnegative integers, representing the nondegenerate and degenerate dimensions, respectively. If any OPT_DIMS values are supplied, atensor will configure the values of adim and aform appropriately. Otherwise, adim will default to 0 and aform will not be defined.

     lie_envelop: The algebra of the Lie envelope is defined by the commutation relation u.v-v.u=2*av(u,v) where av is an antisymmetric function.

     The init_atensor function also recognizes several predefined algebra types:

     complex implements the algebra of complex numbers as the Clifford algebra Cl(0,1). The call init_atensor(complex) is equivalent to init_atensor(clifford,0,0,1).

     quaternion implements the algebra of quaternions. The call init_atensor(quaternion) is equivalent to init_atensor(clifford,0,0,2).

     pauli implements the algebra of Pauli-spinors as the Clifford-algebra Cl(3,0). A call to init_atensor(pauli) is equivalent to init_atensor(clifford,3).

     dirac implements the algebra of Dirac-spinors as the Clifford-algebra Cl(3,1). A call to init_atensor(dirac) is equivalent to init_atensor(clifford,3,0,1).

 -- Function: atensimp (EXPR)

     Simplifies an algebraic tensor expression EXPR according to the rules configured by a call to init_atensor. Simplification includes recursive application of commutation relations and resolving calls to sf, af, and av where applicable. A safeguard is used to ensure that the function always terminates, even for complex expressions.

 -- Function: alg_type

     The algebra type. Valid values are universal, grassmann, clifford, symmetric, symplectic and lie_envelop.

 -- Variable: adim
     Default value: 0

     The dimensionality of the algebra. atensor uses the value of adim to determine if an indexed object is a valid base vector.  See abasep.

 -- Variable: aform
     Default value: ident(3)

     Default values for the bilinear forms sf, af, and av. The default is the identity matrix ident(3).

 -- Variable: asymbol
     Default value: v

     The symbol for base vectors..

 -- Function: sf (U, V)

     A symmetric scalar function that is used in commutation relations. The default implementation checks if both arguments are base vectors using abasep and if that is the case, substitutes the corresponding value from the matrix aform.

 -- Function: af (U, V)

     An antisymmetric scalar function that is used in commutation relations. The default implementation checks if both arguments are base vectors using abasep and if that is the case, substitutes the corresponding value from the matrix aform.

 -- Function: av (U, V)

     An antisymmetric function that is used in commutation relations. The default implementation checks if both arguments are base vectors using abasep and if that is the case, substitutes the corresponding value from the matrix aform.

     For instance:

          (%i1) load(atensor);
          (%o1)       /share/tensor/atensor.mac
          (%i2) adim:3;
          (%o2)                                  3
          (%i3) aform:matrix([0,3,-2],[-3,0,1],[2,-1,0]);
                                         [  0    3   - 2 ]
                                         [               ]
          (%o3)                          [ - 3   0    1  ]
                                         [               ]
                                         [  2   - 1   0  ]
          (%i4) asymbol:x;
          (%o4)                                  x
          (%i5) av(x[1],x[2]);
          (%o5)                                 x
                                                 3

 -- Function: abasep (V)

     Checks if its argument is an atensor base vector. That is, if it is an indexed symbol, with the symbol being the same as the value of asymbol, and the index having a numeric value between 1 and adim.