]> www.ginac.de Git - ginac.git/commitdiff
synced to head (dirac_trace()/color_trace())
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 5 Aug 2004 21:39:18 +0000 (21:39 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 5 Aug 2004 21:39:18 +0000 (21:39 +0000)
check/exam_clifford.cpp
check/exam_color.cpp
doc/tutorial/ginac.texi
ginac/clifford.cpp
ginac/clifford.h
ginac/color.cpp
ginac/color.h
ginac/indexed.cpp

index b6ec71e455317bccb9b56eed2e96372f35ac47a3..9fab75436e720ebd336836a1d2ad9d450c13d70a 100644 (file)
@@ -184,6 +184,19 @@ static unsigned clifford_check3()
        e = dirac_trace(e);
        result += check_equal(e, 4);
 
+       // traces with multiple representation labels
+       e = dirac_ONE(0) * dirac_ONE(1) / 16;
+       result += check_equal(dirac_trace(e, 0), dirac_ONE(1) / 4);
+       result += check_equal(dirac_trace(e, 1), dirac_ONE(0) / 4);
+       result += check_equal(dirac_trace(e, 2), e);
+       result += check_equal(dirac_trace(e, lst(0, 1)), 1);
+
+       e = dirac_gamma(mu, 0) * dirac_gamma(mu.toggle_variance(), 1) * dirac_gamma(nu, 0) * dirac_gamma(nu.toggle_variance(), 1);
+       result += check_equal_simplify(dirac_trace(e, 0), 4 * dim * dirac_ONE(1));
+       result += check_equal_simplify(dirac_trace(e, 1), 4 * dim * dirac_ONE(0));
+       result += check_equal_simplify(dirac_trace(e, 2), e);
+       result += check_equal_simplify(dirac_trace(e, lst(0, 1)), 16 * dim);
+
        return result;
 }
 
index 4d26a1e4151fc3c7076f92c740502725e86f1f97..a3e972add6f1633a383e16f51b39516447eecf46 100644 (file)
@@ -113,7 +113,7 @@ static unsigned color_check3()
 
        unsigned result = 0;
 
-       idx a(symbol("a"), 8), b(symbol("b"), 8), c(symbol("c"), 8), k(symbol("k"), 8);
+       idx a(symbol("a"), 8), b(symbol("b"), 8), c(symbol("c"), 8);
        ex e;
 
        e = color_ONE();
@@ -125,6 +125,18 @@ static unsigned color_check3()
        e = color_T(a) * color_T(b) * color_T(c);
        result += check_equal(color_trace(e), color_h(a, b, c) / 4);
 
+       e = color_ONE(0) * color_ONE(1) / 9;
+       result += check_equal(color_trace(e, 0), color_ONE(1) / 3);
+       result += check_equal(color_trace(e, 1), color_ONE(0) / 3);
+       result += check_equal(color_trace(e, 2), e);
+       result += check_equal(color_trace(e, lst(0, 1)), 1);
+
+       e = color_T(a, 0) * color_T(a, 1) * color_T(b, 0) * color_T(b, 1);
+       result += check_equal_simplify(color_trace(e, 0), 2 * color_ONE(1) / 3);
+       result += check_equal_simplify(color_trace(e, 1), 2 * color_ONE(0) / 3);
+       result += check_equal_simplify(color_trace(e, 2), e);
+       result += check_equal_simplify(color_trace(e, lst(0, 1)), 2);
+
        return result;
 }
 
index 9c4d15ee358bc63991650f005654ed9c9d3722d8..50e95ae9ce78d277541f5fb95b05fa55cb554414 100644 (file)
@@ -3002,20 +3002,25 @@ for example
 
 @cindex @code{dirac_trace()}
 To calculate the trace of an expression containing strings of Dirac gammas
-you use the function
+you use one of the functions
 
 @example
+ex dirac_trace(const ex & e, const std::set<unsigned char> & rls, const ex & trONE = 4);
+ex dirac_trace(const ex & e, const lst & rll, const ex & trONE = 4);
 ex dirac_trace(const ex & e, unsigned char rl = 0, const ex & trONE = 4);
 @end example
 
-This function takes the trace of all gammas with the specified representation
-label; gammas with other labels are left standing. The last argument to
+These functions take the trace over all gammas in the specified set @code{rls}
+or list @code{rll} of representation labels, or the single label @code{rl};
+gammas with other labels are left standing. The last argument to
 @code{dirac_trace()} is the value to be returned for the trace of the unity
-element, which defaults to 4. The @code{dirac_trace()} function is a linear
-functional that is equal to the usual trace only in @math{D = 4} dimensions.
-In particular, the functional is not cyclic in @math{D != 4} dimensions when
-acting on expressions containing @samp{gamma5}, so it's not a proper trace.
-This @samp{gamma5} scheme is described in greater detail in
+element, which defaults to 4.
+
+The @code{dirac_trace()} function is a linear functional that is equal to the
+ordinary matrix trace only in @math{D = 4} dimensions. In particular, the
+functional is not cyclic in @math{D != 4} dimensions when acting on
+expressions containing @samp{gamma5}, so it's not a proper trace. This
+@samp{gamma5} scheme is described in greater detail in
 @cite{The Role of gamma5 in Dimensional Regularization}.
 
 The value of the trace itself is also usually different in 4 and in
@@ -3177,16 +3182,19 @@ expressions containing color objects:
 @end example
 
 @cindex @code{color_trace()}
-To calculate the trace of an expression containing color objects you use the
-function
+To calculate the trace of an expression containing color objects you use one
+of the functions
 
 @example
+ex color_trace(const ex & e, const std::set<unsigned char> & rls);
+ex color_trace(const ex & e, const lst & rll);
 ex color_trace(const ex & e, unsigned char rl = 0);
 @end example
 
-This function takes the trace of all color @samp{T} objects with the
-specified representation label; @samp{T}s with other labels are left
-standing. For example:
+These functions take the trace over all color @samp{T} objects in the
+specified set @code{rls} or list @code{rll} of representation labels, or the
+single label @code{rl}; @samp{T}s with other labels are left standing. For
+example:
 
 @example
     ...
index 591d0ff9f6563d083ce0e2558be9c23ac120521c..e5b6f5e90fe4ce3e2dcc0faa77ea1b1606de3b90 100644 (file)
@@ -217,6 +217,14 @@ static void base_and_index(const ex & c, ex & b, ex & i)
        }
 }
 
+/** Predicate for finding non-clifford objects. */
+struct is_not_a_clifford : public std::unary_function<ex, bool> {
+       bool operator()(const ex & e)
+       {
+               return !is_a<clifford>(e);
+       }
+};
+
 /** Contraction of a gamma matrix with something else. */
 bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
 {
@@ -235,21 +243,23 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other
                if (ex_to<clifford>(*other).get_representation_label() != rl)
                        return false;
 
+               size_t num = other - self;
+
                // gamma~mu gamma.mu = dim ONE
-               if (other - self == 1) {
+               if (num == 1) {
                        *self = dim;
                        *other = dirac_ONE(rl);
                        return true;
 
                // gamma~mu gamma~alpha gamma.mu = (2-dim) gamma~alpha
-               } else if (other - self == 2
+               } else if (num == 2
                        && is_a<clifford>(self[1])) {
                        *self = 2 - dim;
                        *other = _ex1;
                        return true;
 
                // gamma~mu gamma~alpha gamma~beta gamma.mu = 4 g~alpha~beta + (dim-4) gamam~alpha gamma~beta
-               } else if (other - self == 3
+               } else if (num == 3
                        && is_a<clifford>(self[1])
                        && is_a<clifford>(self[2])) {
                        ex b1, i1, b2, i2;
@@ -262,7 +272,7 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other
                        return true;
 
                // gamma~mu gamma~alpha gamma~beta gamma~delta gamma.mu = -2 gamma~delta gamma~beta gamma~alpha - (dim-4) gamam~alpha gamma~beta gamma~delta
-               } else if (other - self == 4
+               } else if (num == 4
                        && is_a<clifford>(self[1])
                        && is_a<clifford>(self[2])
                        && is_a<clifford>(self[3])) {
@@ -273,27 +283,45 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other
                        *other = _ex1;
                        return true;
 
+               // gamma~mu Sodd gamma.mu = -2 Sodd_R
+               // (Chisholm identity in 4 dimensions)
+               } else if (!((other - self) & 1) && dim.is_equal(4)) {
+                       if (std::find_if(self + 1, other, is_not_a_clifford()) != other)
+                               return false;
+
+                       *self = ncmul(exvector(std::reverse_iterator<exvector::const_iterator>(other), std::reverse_iterator<exvector::const_iterator>(self + 1)), true);
+                       std::fill(self + 1, other, _ex1);
+                       *other = _ex_2;
+                       return true;
+
+               // gamma~mu Sodd gamma~alpha gamma.mu = 2 gamma~alpha Sodd + 2 Sodd_R gamma~alpha
+               // (commutate contracted indices towards each other, then use
+               // Chisholm identity in 4 dimensions)
+               } else if (((other - self) & 1) && dim.is_equal(4)) {
+                       if (std::find_if(self + 1, other, is_not_a_clifford()) != other)
+                               return false;
+
+                       exvector::iterator next_to_last = other - 1;
+                       ex S = ncmul(exvector(self + 1, next_to_last), true);
+                       ex SR = ncmul(exvector(std::reverse_iterator<exvector::const_iterator>(next_to_last), std::reverse_iterator<exvector::const_iterator>(self + 1)), true);
+
+                       *self = (*next_to_last) * S + SR * (*next_to_last);
+                       std::fill(self + 1, other, _ex1);
+                       *other = _ex2;
+                       return true;
+
                // gamma~mu S gamma~alpha gamma.mu = 2 gamma~alpha S - gamma~mu S gamma.mu gamma~alpha
                // (commutate contracted indices towards each other, simplify_indexed()
                // will re-expand and re-run the simplification)
                } else {
-                       exvector::iterator it = self + 1, next_to_last = other - 1;
-                       while (it != other) {
-                               if (!is_a<clifford>(*it))
-                                       return false;
-                               ++it;
-                       }
+                       if (std::find_if(self + 1, other, is_not_a_clifford()) != other)
+                               return false;
 
-                       it = self + 1;
-                       ex S = _ex1;
-                       while (it != next_to_last) {
-                               S *= *it;
-                               *it++ = _ex1;
-                       }
+                       exvector::iterator next_to_last = other - 1;
+                       ex S = ncmul(exvector(self + 1, next_to_last), true);
 
                        *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last);
-                       *next_to_last = _ex1;
-                       *other = _ex1;
+                       std::fill(self + 1, other + 1, _ex1);
                        return true;
                }
 
@@ -559,6 +587,13 @@ static bool is_clifford_tinfo(unsigned ti)
        return (ti & ~0xff) == TINFO_clifford;
 }
 
+/** Extract representation label from tinfo key (as returned by
+ *  return_type_tinfo()). */
+static unsigned char get_representation_label(unsigned ti)
+{
+       return ti & 0xff;
+}
+
 /** Take trace of a string of an even number of Dirac gammas given a vector
  *  of indices. */
 static ex trace_string(exvector::const_iterator ix, size_t num)
@@ -595,12 +630,17 @@ static ex trace_string(exvector::const_iterator ix, size_t num)
        return result;
 }
 
-ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
+ex dirac_trace(const ex & e, const std::set<unsigned char> & rls, const ex & trONE)
 {
        if (is_a<clifford>(e)) {
 
-               if (!ex_to<clifford>(e).get_representation_label() == rl)
-                       return _ex0;
+               unsigned char rl = ex_to<clifford>(e).get_representation_label();
+
+               // Are we taking the trace over this object's representation label?
+               if (rls.find(rl) == rls.end())
+                       return e;
+
+               // Yes, all elements are traceless, except for dirac_ONE and dirac_L/R
                const ex & g = e.op(0);
                if (is_a<diracone>(g))
                        return trONE;
@@ -615,8 +655,8 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                ex prod = _ex1;
                for (size_t i=0; i<e.nops(); i++) {
                        const ex &o = e.op(i);
-                       if (is_clifford_tinfo(o.return_type_tinfo(), rl))
-                               prod *= dirac_trace(o, rl, trONE);
+                       if (is_clifford_tinfo(o.return_type_tinfo()))
+                               prod *= dirac_trace(o, rls, trONE);
                        else
                                prod *= o;
                }
@@ -624,8 +664,11 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
 
        } else if (is_exactly_a<ncmul>(e)) {
 
-               if (!is_clifford_tinfo(e.return_type_tinfo(), rl))
-                       return _ex0;
+               unsigned char rl = get_representation_label(e.return_type_tinfo());
+
+               // Are we taking the trace over this string's representation label?
+               if (rls.find(rl) == rls.end())
+                       return e;
 
                // Substitute gammaL/R and expand product, if necessary
                ex e_expanded = e.subs(lst(
@@ -633,7 +676,7 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
                        dirac_gammaR(rl) == (dirac_ONE(rl)+dirac_gamma5(rl))/2
                ), subs_options::no_pattern).expand();
                if (!is_a<ncmul>(e_expanded))
-                       return dirac_trace(e_expanded, rl, trONE);
+                       return dirac_trace(e_expanded, rls, trONE);
 
                // gamma5 gets moved to the front so this check is enough
                bool has_gamma5 = is_a<diracgamma5>(e.op(0).op(0));
@@ -717,13 +760,35 @@ ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
        } else if (e.nops() > 0) {
 
                // Trace maps to all other container classes (this includes sums)
-               pointer_to_map_function_2args<unsigned char, const ex &> fcn(dirac_trace, rl, trONE);
+               pointer_to_map_function_2args<const std::set<unsigned char> &, const ex &> fcn(dirac_trace, rls, trONE);
                return e.map(fcn);
 
        } else
                return _ex0;
 }
 
+ex dirac_trace(const ex & e, const lst & rll, const ex & trONE)
+{
+       // Convert list to set
+       std::set<unsigned char> rls;
+       for (lst::const_iterator i = rll.begin(); i != rll.end(); ++i) {
+               if (i->info(info_flags::nonnegint))
+                       rls.insert(ex_to<numeric>(*i).to_int());
+       }
+
+       return dirac_trace(e, rls, trONE);
+}
+
+ex dirac_trace(const ex & e, unsigned char rl, const ex & trONE)
+{
+       // Convert label to set
+       std::set<unsigned char> rls;
+       rls.insert(rl);
+
+       return dirac_trace(e, rls, trONE);
+}
+
+
 ex canonicalize_clifford(const ex & e)
 {
        // Scan for any ncmul objects
index 2959a0f7bafabe0ad92990be6fc6ba2c5e1e018c..996a844ed3d50a9475f6d5098d27e9c94fda0a3e 100644 (file)
@@ -26,6 +26,8 @@
 #include "indexed.h"
 #include "tensor.h"
 
+#include <set>
+
 namespace GiNaC {
 
 
@@ -192,6 +194,26 @@ ex dirac_gammaR(unsigned char rl = 0);
  *  @param rl Representation label */
 ex dirac_slash(const ex & e, const ex & dim, unsigned char rl = 0);
 
+/** Calculate dirac traces over the specified set of representation labels.
+ *  The computed trace is a linear functional that is equal to the usual
+ *  trace only in D = 4 dimensions. In particular, the functional is not
+ *  always cyclic in D != 4 dimensions when gamma5 is involved.
+ *
+ *  @param e Expression to take the trace of
+ *  @param rls Set of representation labels
+ *  @param trONE Expression to be returned as the trace of the unit matrix */
+ex dirac_trace(const ex & e, const std::set<unsigned char> & rls, const ex & trONE = 4);
+
+/** Calculate dirac traces over the specified list of representation labels.
+ *  The computed trace is a linear functional that is equal to the usual
+ *  trace only in D = 4 dimensions. In particular, the functional is not
+ *  always cyclic in D != 4 dimensions when gamma5 is involved.
+ *
+ *  @param e Expression to take the trace of
+ *  @param rll List of representation labels
+ *  @param trONE Expression to be returned as the trace of the unit matrix */
+ex dirac_trace(const ex & e, const lst & rll, const ex & trONE = 4);
+
 /** Calculate the trace of an expression containing gamma objects with
  *  a specified representation label. The computed trace is a linear
  *  functional that is equal to the usual trace only in D = 4 dimensions.
index e06eff44a43c659ef7bb7567f6dc04fdffc03961..3f45bba5acaaa4bf9983245f650442f46091e3a2 100644 (file)
@@ -527,12 +527,32 @@ static bool is_color_tinfo(unsigned ti, unsigned char rl)
        return ti == (TINFO_color + rl);
 }
 
-ex color_trace(const ex & e, unsigned char rl)
+/** Check whether a given tinfo key (as returned by return_type_tinfo()
+ *  is that of a color object (with an arbitrary representation label). */
+static bool is_color_tinfo(unsigned ti)
+{
+       return (ti & ~0xff) == TINFO_color;
+}
+
+/** Extract representation label from tinfo key (as returned by
+ *  return_type_tinfo()). */
+static unsigned char get_representation_label(unsigned ti)
+{
+       return ti & 0xff;
+}
+
+ex color_trace(const ex & e, const std::set<unsigned char> & rls)
 {
        if (is_a<color>(e)) {
 
-               if (ex_to<color>(e).get_representation_label() == rl
-                && is_a<su3one>(e.op(0)))
+               unsigned char rl = ex_to<color>(e).get_representation_label();
+
+               // Are we taking the trace over this object's representation label?
+               if (rls.find(rl) == rls.end())
+                       return e;
+
+               // Yes, all generators are traceless, except for color_ONE
+               if (is_a<su3one>(e.op(0)))
                        return _ex3;
                else
                        return _ex0;
@@ -543,8 +563,8 @@ ex color_trace(const ex & e, unsigned char rl)
                ex prod = _ex1;
                for (size_t i=0; i<e.nops(); i++) {
                        const ex &o = e.op(i);
-                       if (is_color_tinfo(o.return_type_tinfo(), rl))
-                               prod *= color_trace(o, rl);
+                       if (is_color_tinfo(o.return_type_tinfo()))
+                               prod *= color_trace(o, rls);
                        else
                                prod *= o;
                }
@@ -552,13 +572,16 @@ ex color_trace(const ex & e, unsigned char rl)
 
        } else if (is_exactly_a<ncmul>(e)) {
 
-               if (!is_color_tinfo(e.return_type_tinfo(), rl))
-                       return _ex0;
+               unsigned char rl = get_representation_label(e.return_type_tinfo());
 
-               // Expand product, if necessary
+               // Are we taking the trace over this string's representation label?
+               if (rls.find(rl) == rls.end())
+                       return e;
+
+               // Yes, expand product if necessary
                ex e_expanded = e.expand();
                if (!is_a<ncmul>(e_expanded))
-                       return color_trace(e_expanded, rl);
+                       return color_trace(e_expanded, rls);
 
                size_t num = e.nops();
 
@@ -597,11 +620,32 @@ ex color_trace(const ex & e, unsigned char rl)
        } else if (e.nops() > 0) {
 
                // Trace maps to all other container classes (this includes sums)
-               pointer_to_map_function_1arg<unsigned char> fcn(color_trace, rl);
+               pointer_to_map_function_1arg<const std::set<unsigned char> &> fcn(color_trace, rls);
                return e.map(fcn);
 
        } else
                return _ex0;
 }
 
+ex color_trace(const ex & e, const lst & rll)
+{
+       // Convert list to set
+       std::set<unsigned char> rls;
+       for (lst::const_iterator i = rll.begin(); i != rll.end(); ++i) {
+               if (i->info(info_flags::nonnegint))
+                       rls.insert(ex_to<numeric>(*i).to_int());
+       }
+
+       return color_trace(e, rls);
+}
+
+ex color_trace(const ex & e, unsigned char rl)
+{
+       // Convert label to set
+       std::set<unsigned char> rls;
+       rls.insert(rl);
+
+       return color_trace(e, rls);
+}
+
 } // namespace GiNaC
index 2086909e1304dd1c7a35ac9e53c658263150348c..826b4c7ffe68ae7489febb13aa82db7e705ab0f2 100644 (file)
@@ -26,6 +26,8 @@
 #include "indexed.h"
 #include "tensor.h"
 
+#include <set>
+
 namespace GiNaC {
 
 
@@ -169,6 +171,18 @@ ex color_d(const ex & a, const ex & b, const ex & c);
 /** This returns the linear combination d.a.b.c+I*f.a.b.c. */
 ex color_h(const ex & a, const ex & b, const ex & c);
 
+/** Calculate color traces over the specified set of representation labels.
+ *
+ *  @param e Expression to take the trace of
+ *  @param rls Set of representation labels */
+ex color_trace(const ex & e, const std::set<unsigned char> & rls);
+
+/** Calculate color traces over the specified list of representation labels.
+ *
+ *  @param e Expression to take the trace of
+ *  @param rll List of representation labels */
+ex color_trace(const ex & e, const lst & rll);
+
 /** Calculate the trace of an expression containing color objects with a
  *  specified representation label.
  *
index ad17a497a9dc703e52cd435d6901312071beab42..d693373cae62c6cd622495d05722aa9ce7065d99 100644 (file)
@@ -1128,6 +1128,7 @@ ex simplify_indexed(const ex & e, exvector & free_indices, exvector & dummy_indi
  *  performs contraction of dummy indices where possible and checks whether
  *  the free indices in sums are consistent.
  *
+ *  @param options Simplification options (currently unused)
  *  @return simplified expression */
 ex ex::simplify_indexed(unsigned options) const
 {
@@ -1142,6 +1143,7 @@ ex ex::simplify_indexed(unsigned options) const
  *  scalar products by known values if desired.
  *
  *  @param sp Scalar products to be replaced automatically
+ *  @param options Simplification options (currently unused)
  *  @return simplified expression */
 ex ex::simplify_indexed(const scalar_products & sp, unsigned options) const
 {