]> www.ginac.de Git - ginac.git/blobdiff - ginac/tensor.cpp
*** empty log message ***
[ginac.git] / ginac / tensor.cpp
index 0c36a68002423d712f4d8afa5ec903716ffba7e7..48393665ad5fc0555add8a19bba463af14abf288 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of GiNaC's special tensors. */
 
 /*
- *  GiNaC Copyright (C) 1999-2002 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -179,6 +179,13 @@ ex tensdelta::eval_indexed(const basic & i) const
        const idx & i1 = ex_to<idx>(i.op(1));
        const idx & i2 = ex_to<idx>(i.op(2));
 
+       // The dimension of the indices must be equal, otherwise we use the minimal
+       // dimension
+       if (!i1.get_dim().is_equal(i2.get_dim())) {
+               ex min_dim = i1.minimal_dim(i2);
+               return i.subs(lst(i1 == i1.replace_dim(min_dim), i2 == i2.replace_dim(min_dim)));
+       }
+
        // Trace of delta tensor is the (effective) dimension of the space
        if (is_dummy_pair(i1, i2)) {
                try {
@@ -348,8 +355,8 @@ again:
                                try {
                                        // minimal_dim() throws an exception when index dimensions are not comparable
                                        ex min_dim = self_idx->minimal_dim(other_idx);
-                                       *self = _ex1;
                                        *other = other->subs(other_idx == free_idx->replace_dim(min_dim));
+                                       *self = _ex1; // *other is assigned first because assigning *self invalidates free_idx
                                        return true;
                                } catch (std::exception &e) {
                                        return false;
@@ -459,9 +466,10 @@ again:
                        if (is_dummy_pair(*self_idx, other_idx)) {
 
                                // Contraction found, remove metric tensor and substitute
-                               // index in second object
-                               *self = (static_cast<const spinidx *>(self_idx)->is_covariant() ? sign : -sign);
+                               // index in second object (assign *self last because this
+                               // invalidates free_idx)
                                *other = other->subs(other_idx == *free_idx);
+                               *self = (static_cast<const spinidx *>(self_idx)->is_covariant() ? sign : -sign);
                                return true;
                        }
                }
@@ -491,14 +499,16 @@ bool tensepsilon::contract_with(exvector::iterator self, exvector::iterator othe
        if (is_ex_exactly_of_type(other->op(0), tensepsilon) && num+1 == other->nops()) {
 
                // Contraction of two epsilon tensors is a determinant
-               ex dim = ex_to<idx>(self->op(1)).get_dim();
+               bool variance = is_a<varidx>(self->op(1));
                matrix M(num, num);
-               for (int i=0; i<num; i++) {
-                       for (int j=0; j<num; j++) {
+               for (unsigned i=0; i<num; i++) {
+                       for (unsigned j=0; j<num; j++) {
                                if (minkowski)
                                        M(i, j) = lorentz_g(self->op(i+1), other->op(j+1), pos_sig);
-                               else
+                               else if (variance)
                                        M(i, j) = metric_tensor(self->op(i+1), other->op(j+1));
+                               else
+                                       M(i, j) = delta_tensor(self->op(i+1), other->op(j+1));
                        }
                }
                int sign = minkowski ? -1 : 1;