- Clifford traces of many gammas are a lot faster now (especially with gamma5)
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 21 May 2001 22:49:16 +0000 (22:49 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 21 May 2001 22:49:16 +0000 (22:49 +0000)
- new simplifications for color classes:
    d.abc T.b T.c = 5/6 T.a
    f.abc T.b T.c = 3/2 I T.a
- added indexed::has_dummy_index_for() member function

ginac/clifford.cpp
ginac/color.cpp
ginac/indexed.cpp
ginac/indexed.h

index bd0c896..d520822 100644 (file)
@@ -389,24 +389,62 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                        if ((num & 1) == 0 || num == 3)
                                return _ex0();
 
+                       // Tr gamma5 gamma.mu gamma.nu gamma.rho gamma.sigma = 4I * epsilon(mu, nu, rho, sigma)
+                       if (num == 5)
+                               return trONE * I * eps0123(e.op(1).op(1), e.op(2).op(1), e.op(3).op(1), e.op(4).op(1));
+
+                       // Tr gamma5 gamma.mu1 gamma.mu2 gamma.mu3 gamma.mu4 gamma.mu5 gamma.mu6 = ...
+                       if (num == 7) {
+                               ex i1 = e.op(1).op(1), i2 = e.op(2).op(1),
+                                  i3 = e.op(3).op(1), i4 = e.op(4).op(1),
+                                  i5 = e.op(5).op(1), i6 = e.op(6).op(1);
+                               return trONE * I * (lorentz_g(i1, i2) * eps0123(i3, i4, i5, i6)
+                                                 - lorentz_g(i1, i3) * eps0123(i2, i4, i5, i6)
+                                                 + lorentz_g(i1, i4) * eps0123(i2, i3, i5, i6)
+                                                 - lorentz_g(i1, i5) * eps0123(i2, i3, i4, i6)
+                                                 + lorentz_g(i1, i6) * eps0123(i2, i3, i4, i5)
+                                                 + lorentz_g(i2, i3) * eps0123(i1, i4, i5, i6)
+                                                 - lorentz_g(i2, i4) * eps0123(i1, i3, i5, i6)
+                                                 + lorentz_g(i2, i5) * eps0123(i1, i3, i4, i6)
+                                                 - lorentz_g(i2, i6) * eps0123(i1, i3, i4, i5)
+                                                 + lorentz_g(i3, i4) * eps0123(i1, i2, i5, i6)
+                                                 - lorentz_g(i3, i5) * eps0123(i1, i2, i4, i6)
+                                                 + lorentz_g(i3, i6) * eps0123(i1, i2, i4, i5)
+                                                 + lorentz_g(i4, i5) * eps0123(i1, i2, i3, i6)
+                                                 - lorentz_g(i4, i6) * eps0123(i1, i2, i3, i5)
+                                                 + lorentz_g(i5, i6) * eps0123(i1, i2, i3, i4));
+                       }
+
                        // Tr gamma5 S_2k =
                        //   I/4! * epsilon0123.mu1.mu2.mu3.mu4 * Tr gamma.mu1 gamma.mu2 gamma.mu3 gamma.mu4 S_2k
-                       ex dim = ex_to_idx(e.op(1).op(1)).get_dim();
-                       varidx mu1((new symbol)->setflag(status_flags::dynallocated), dim),
-                              mu2((new symbol)->setflag(status_flags::dynallocated), dim),
-                              mu3((new symbol)->setflag(status_flags::dynallocated), dim),
-                              mu4((new symbol)->setflag(status_flags::dynallocated), dim);
-                       exvector v;
-                       v.reserve(num + 3);
-                       v.push_back(dirac_gamma(mu1, rl));
-                       v.push_back(dirac_gamma(mu2, rl));
-                       v.push_back(dirac_gamma(mu3, rl));
-                       v.push_back(dirac_gamma(mu4, rl));
-                       for (int i=1; i<num; i++)
-                               v.push_back(e.op(i));
-
-                       return (eps0123(mu1.toggle_variance(), mu2.toggle_variance(), mu3.toggle_variance(), mu4.toggle_variance()) *
-                               dirac_trace(ncmul(v), rl, trONE)).simplify_indexed() * I / 24;
+                       ex result;
+                       for (int i=1; i<num-3; i++) {
+                               ex idx1 = e.op(i).op(1);
+                               for (int j=i+1; j<num-2; j++) {
+                                       ex idx2 = e.op(j).op(1);
+                                       for (int k=j+1; k<num-1; k++) {
+                                               ex idx3 = e.op(k).op(1);
+                                               for (int l=k+1; l<num; l++) {
+                                                       ex idx4 = e.op(l).op(1);
+                                                       vector<int> iv;
+                                                       iv.reserve(num-1);
+                                                       exvector v;
+                                                       v.reserve(num-1);
+                                                       iv.push_back(i); iv.push_back(j); iv.push_back(k); iv.push_back(l);
+                                                       for (int n=1; n<num; n++) {
+                                                               if (n == i || n == j || n == k || n == l)
+                                                                       continue;
+                                                               iv.push_back(n);
+                                                               v.push_back(e.op(n));
+                                                       }
+                                                       int sign = permutation_sign(iv);
+                                                       result += sign * eps0123(idx1, idx2, idx3, idx4)
+                                                               * dirac_trace(ncmul(v), rl, trONE);
+                                               }
+                                       }
+                               }
+                       }
+                       return result * I;
 
                } else { // no gamma5
 
@@ -418,7 +456,13 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                        if (num == 2)
                                return trONE * lorentz_g(e.op(0).op(1), e.op(1).op(1));
 
-                       // Traces of 4 or more gammas are computed recursively:
+                       // Tr gamma.mu gamma.nu gamma.rho gamma.sig = 4 (g.mu.nu g.rho.sig + g.nu.rho g.mu.sig - g.mu.rho g.nu.sig
+                       if (num == 4)
+                               return trONE * (lorentz_g(e.op(0).op(1), e.op(1).op(1)) * lorentz_g(e.op(2).op(1), e.op(3).op(1))
+                                             + lorentz_g(e.op(1).op(1), e.op(2).op(1)) * lorentz_g(e.op(0).op(1), e.op(3).op(1))
+                                             - lorentz_g(e.op(0).op(1), e.op(2).op(1)) * lorentz_g(e.op(1).op(1), e.op(3).op(1)));
+
+                       // Traces of 6 or more gammas are computed recursively:
                        // Tr gamma.mu1 gamma.mu2 ... gamma.mun =
                        //   + g.mu1.mu2 * Tr gamma.mu3 ... gamma.mun
                        //   - g.mu1.mu3 * Tr gamma.mu2 gamma.mu4 ... gamma.mun
index f06805e..234c2b9 100644 (file)
@@ -363,13 +363,13 @@ bool su3d::contract_with(exvector::iterator self, exvector::iterator other, exve
                exvector free_indices, dummy_indices;
                find_free_and_dummy(all_indices, free_indices, dummy_indices);
 
-               // d.abc*d.abc=40/3
+               // d.abc d.abc = 40/3
                if (dummy_indices.size() == 3) {
                        *self = numeric(40, 3);
                        *other = _ex1();
                        return true;
 
-               // d.akl*d.bkl=5/3*delta.ab
+               // d.akl d.bkl = 5/3 delta.ab
                } else if (dummy_indices.size() == 2) {
                        exvector a;
                        back_insert_iterator<exvector> ita(a);
@@ -380,6 +380,25 @@ bool su3d::contract_with(exvector::iterator self, exvector::iterator other, exve
                        *other = _ex1();
                        return true;
                }
+
+       } else if (is_ex_exactly_of_type(other->op(0), su3t)) {
+
+               // d.abc T.b T.c = 5/6 T.a
+               if (other+1 != v.end()
+                && is_ex_exactly_of_type(other[1].op(0), su3t)
+                && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+
+                       exvector self_indices = ex_to_indexed(*self).get_indices();
+                       exvector dummy_indices;
+                       dummy_indices.push_back(other[0].op(1));
+                       dummy_indices.push_back(other[1].op(1));
+                       int sig;
+                       ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
+                       *self = numeric(5, 6);
+                       other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+                       other[1] = _ex1();
+                       return true;
+               }
        }
 
        return false;
@@ -399,13 +418,13 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
                exvector dummy_indices;
                dummy_indices = ex_to_indexed(*self).get_dummy_indices(ex_to_indexed(*other));
 
-               // f.abc*f.abc=24
+               // f.abc f.abc = 24
                if (dummy_indices.size() == 3) {
                        *self = 24;
                        *other = _ex1();
                        return true;
 
-               // f.akl*f.bkl=3*delta.ab
+               // f.akl f.bkl = 3 delta.ab
                } else if (dummy_indices.size() == 2) {
                        int sign1, sign2;
                        ex a = permute_free_index_to_front(ex_to_indexed(*self).get_indices(), dummy_indices, sign1);
@@ -414,6 +433,25 @@ bool su3f::contract_with(exvector::iterator self, exvector::iterator other, exve
                        *other = _ex1();
                        return true;
                }
+
+       } else if (is_ex_exactly_of_type(other->op(0), su3t)) {
+
+               // f.abc T.b T.c = 3/2 I T.a
+               if (other+1 != v.end()
+                && is_ex_exactly_of_type(other[1].op(0), su3t)
+                && ex_to_indexed(*self).has_dummy_index_for(other[1].op(1))) {
+
+                       exvector self_indices = ex_to_indexed(*self).get_indices();
+                       exvector dummy_indices;
+                       dummy_indices.push_back(other[0].op(1));
+                       dummy_indices.push_back(other[1].op(1));
+                       int sig;
+                       ex a = permute_free_index_to_front(self_indices, dummy_indices, sig);
+                       *self = numeric(3, 2) * sig * I;
+                       other[0] = color_T(a, ex_to_color(other[0]).get_representation_label());
+                       other[1] = _ex1();
+                       return true;
+               }
        }
 
        return false;
index f8d0903..acbf7d4 100644 (file)
@@ -479,6 +479,17 @@ exvector indexed::get_dummy_indices(const indexed & other) const
        return dummy_indices;
 }
 
+bool indexed::has_dummy_index_for(const ex & i) const
+{
+       exvector::const_iterator it = seq.begin() + 1, itend = seq.end();
+       while (it != itend) {
+               if (is_dummy_pair(*it, i))
+                       return true;
+               it++;
+       }
+       return false;
+}
+
 exvector indexed::get_free_indices(void) const
 {
        exvector free_indices, dummy_indices;
@@ -632,6 +643,8 @@ try_again:
                if (!is_ex_of_type(*it1, indexed))
                        continue;
 
+               bool first_noncommutative = (it1->return_type() != return_types::commutative);
+
                // Indexed factor found, get free indices and look for contraction
                // candidates
                exvector free1, dummy1;
@@ -643,6 +656,8 @@ try_again:
                        if (!is_ex_of_type(*it2, indexed))
                                continue;
 
+                       bool second_noncommutative = (it2->return_type() != return_types::commutative);
+
                        // Find free indices of second factor and merge them with free
                        // indices of first factor
                        exvector un;
@@ -685,7 +700,7 @@ try_again:
                        }
                        if (contracted) {
 contraction_done:
-                               if (non_commutative
+                               if (first_noncommutative || second_noncommutative
                                 || is_ex_exactly_of_type(*it1, add) || is_ex_exactly_of_type(*it2, add)
                                 || is_ex_exactly_of_type(*it1, mul) || is_ex_exactly_of_type(*it2, mul)
                                 || is_ex_exactly_of_type(*it1, ncmul) || is_ex_exactly_of_type(*it2, ncmul)) {
index 26bf9a5..9f6af5f 100644 (file)
@@ -184,6 +184,10 @@ public:
         *  another indexed object. */
        exvector get_dummy_indices(const indexed & other) const;
 
+       /** Check whether the object has an index that forms a dummy index pair
+        *  with a given index. */
+       bool has_dummy_index_for(const ex & i) const;
+
 protected:
        void printindices(const print_context & c, unsigned level) const;
        void assert_all_indices_of_type_idx(void) const;