- added documentation for the idx, coloridx and lorentzidx classes
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 12 Feb 2001 20:54:53 +0000 (20:54 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Mon, 12 Feb 2001 20:54:53 +0000 (20:54 +0000)
- idx_intersect() works correctly when indices appear multiple times
- g~mu_mu = D-2 (instead of D-dim(P))

ginac/color.cpp
ginac/coloridx.cpp
ginac/coloridx.h
ginac/idx.cpp
ginac/idx.h
ginac/lorentzidx.cpp
ginac/lorentzidx.h
ginac/lortensor.cpp
ginac/simp_lor.cpp

index 8e7ecda9e47486383709792dab6c503844071184..5a9229b189e0f2d075d1188a7799bcab9d564e1e 100644 (file)
@@ -510,9 +510,9 @@ ex color::simplify_ncmul(const exvector & v) const
                                                *it1=numeric(40)/numeric(3);
                                                *it2=_ex1();
                                        } else {
-                                               int sig1, sig2; // unimportant, since symmetric
-                                               ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,false,&sig1);
-                                               ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,false,&sig2);
+                                               int dummy; // sign unimportant, since symmetric
+                                               ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,&dummy);
+                                               ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,&dummy);
                                                *it1=numeric(5)/numeric(3)*color(color_delta8,idx1,idx2);
                                                *it2=_ex1();
                                        }
@@ -538,8 +538,8 @@ ex color::simplify_ncmul(const exvector & v) const
                                                *it2=_ex1();
                                        } else {
                                                int sig1, sig2;
-                                               ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,true,&sig1);
-                                               ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,true,&sig2);
+                                               ex idx1=permute_free_index_to_front(col1.seq,iv_intersect,&sig1);
+                                               ex idx2=permute_free_index_to_front(col2.seq,iv_intersect,&sig2);
                                                *it1=numeric(sig1*sig2*5)/numeric(3)*color(color_delta8,idx1,idx2);
                                                *it2=_ex1();
                                        }
@@ -567,8 +567,8 @@ ex color::simplify_ncmul(const exvector & v) const
                                        const color & dref=ex_to_color(*it2);
                                        exvector iv_intersect=idx_intersect(dref.seq,iv);
                                        if (iv_intersect.size()==2) {
-                                               int sig; // unimportant, since symmetric
-                                               ex free_idx=permute_free_index_to_front(dref.seq,iv,false,&sig);
+                                               int dummy; // sign unimportant, since symmetric
+                                               ex free_idx=permute_free_index_to_front(dref.seq,iv,&dummy);
                                                *it1=color(color_T,free_idx,rl);
                                                *(it1+1)=color(color_ONE,rl);
                                                *it2=numeric(5)/numeric(6);
@@ -584,7 +584,7 @@ ex color::simplify_ncmul(const exvector & v) const
                                        exvector iv_intersect=idx_intersect(fref.seq,iv);
                                        if (iv_intersect.size()==2) {
                                                int sig;
-                                               ex free_idx=permute_free_index_to_front(fref.seq,iv,true,&sig);
+                                               ex free_idx=permute_free_index_to_front(fref.seq,iv,&sig);
                                                *it1=color(color_T,free_idx,rl);
                                                *(it1+1)=color(color_ONE,rl);
                                                *it2=numeric(sig*3)/numeric(2)*I;
index a227ea9b32f7bdceebbb6c7a659aea3705ab40c9..368aef08ba6d74707c505f59264ba735fd5d9bdf 100644 (file)
@@ -87,6 +87,10 @@ void coloridx::destroy(bool call_parent)
 
 // public
 
+/** Construct symbolic color index, using an automatically generated unique name.
+ *
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 coloridx::coloridx(bool cov) : idx(cov)
 {
        debugmsg("coloridx constructor from bool",LOGLEVEL_CONSTRUCT);
@@ -95,18 +99,33 @@ coloridx::coloridx(bool cov) : idx(cov)
        tinfo_key=TINFO_coloridx;
 }
 
+/** Construct symbolic color index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 coloridx::coloridx(const std::string & n, bool cov) : idx(n,cov)
 {
        debugmsg("coloridx constructor from string,bool",LOGLEVEL_CONSTRUCT);
        tinfo_key=TINFO_coloridx;
 }
 
+/** Construct symbolic color index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 coloridx::coloridx(const char * n, bool cov) : idx(n,cov)
 {
        debugmsg("coloridx constructor from char*,bool",LOGLEVEL_CONSTRUCT);
        tinfo_key=TINFO_coloridx;
 }
 
+/** Construct numeric color index with specified value.
+ *
+ *  @param v Numeric index value
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 coloridx::coloridx(unsigned v, bool cov) : idx(v,cov)
 {
        debugmsg("coloridx constructor from unsigned,bool",LOGLEVEL_CONSTRUCT);
index 78bd356a3b2cce88ae6c0c83c9f49b4858193b96..ad190c1181536199a2b479241f6da98c4967df57 100644 (file)
@@ -32,6 +32,8 @@
 namespace GiNaC {
 #endif // ndef NO_NAMESPACE_GINAC
 
+/** Class of indices for color algebra (SU(3)) objects, to tell them apart
+ *  from other index families like Lorentz indices. */
 class coloridx : public idx
 {
        GINAC_DECLARE_REGISTERED_CLASS(coloridx, idx)
index 2fc851c78aa6e9afa411f0df2ec834fce4d81a9b..926f427d86f6ee6efe84e95e01fb08b33a29978a 100644 (file)
@@ -94,6 +94,10 @@ void idx::destroy(bool call_parent)
 
 // public
 
+/** Construct symbolic index, using an automatically generated unique name.
+ *
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 idx::idx(bool cov) : inherited(TINFO_idx), symbolic(true), covariant(cov)
 {
        debugmsg("idx constructor from bool",LOGLEVEL_CONSTRUCT);
@@ -101,6 +105,11 @@ idx::idx(bool cov) : inherited(TINFO_idx), symbolic(true), covariant(cov)
        name = "index"+ToString(serial);
 }
 
+/** Construct symbolic index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 idx::idx(const std::string & n, bool cov) : inherited(TINFO_idx),  
        symbolic(true), name(n), covariant(cov)
 {
@@ -108,12 +117,22 @@ idx::idx(const std::string & n, bool cov) : inherited(TINFO_idx),
        serial = next_serial++;
 }
 
+/** Construct symbolic index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 idx::idx(const char * n, bool cov) : inherited(TINFO_idx), symbolic(true), name(n), covariant(cov)
 {
        debugmsg("idx constructor from char*,bool",LOGLEVEL_CONSTRUCT);
        serial = next_serial++;
 }
 
+/** Construct numeric index with specified value.
+ *
+ *  @param v Numeric index value
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 idx::idx(unsigned v, bool cov) : inherited(TINFO_idx), symbolic(false), value(v), covariant(cov)
 {
        debugmsg("idx constructor from unsigned,bool",LOGLEVEL_CONSTRUCT);
@@ -319,6 +338,8 @@ unsigned idx::calchash(void) const
 
 // public
 
+/** Check whether the index forms a co-/contravariant pair with another
+ *  index (i.e. same name/value but opposite co-/contravariance). */
 bool idx::is_co_contra_pair(const basic & other) const
 {
        // like is_equal_same_type(), but tests for different covariant status
@@ -331,21 +352,7 @@ bool idx::is_co_contra_pair(const basic & other) const
        return value==o.value;
 }    
 
-bool idx::is_symbolic(void) const
-{
-       return symbolic;
-}
-
-unsigned idx::get_value(void) const
-{
-       return value;
-}
-
-bool idx::is_covariant(void) const
-{
-       return covariant;
-}
-
+/** Toggle co-/contravariance of index. */
 ex idx::toggle_covariant(void) const
 {
        idx * i_copy=static_cast<idx *>(duplicate());
@@ -379,6 +386,16 @@ const std::type_info & typeid_idx = typeid(some_idx);
 // other functions
 //////////
 
+/** Bring a vector of indices into a canonic order. This operation only makes
+ *  sense if the object carrying these indices is either symmetric or totally
+ *  antisymmetric with respect to the indices.
+ *
+ *  @param iv Index vector
+ *  @param antisymmetric Whether the object carrying the indices is antisymmetric (symmetric otherwise)
+ *  @return the sign introduced by the reordering of the indices. For symmetric
+ *          objects this is always +1. For antisymmetric objects this is either
+ *          +1 or -1 or 0 (if two equal indices were encountered). If the index
+ *          vector was unchanged this function returns INT_MAX. */
 int canonicalize_indices(exvector & iv, bool antisymmetric)
 {
        if (iv.size()<2) {
@@ -388,6 +405,7 @@ int canonicalize_indices(exvector & iv, bool antisymmetric)
 
        bool something_changed=false;
        int sig=1;
+
        // simple bubble sort algorithm should be sufficient for the small number of indices needed
        exvector::const_iterator last_idx=iv.end();
        exvector::const_iterator next_to_last_idx=iv.end()-1;
@@ -404,37 +422,56 @@ int canonicalize_indices(exvector & iv, bool antisymmetric)
                        }
                }
        }
+
        return something_changed ? sig : INT_MAX;
 }
 
+/** Build a vector of indices as the set intersection of two other index
+ *  vectors (i.e. the returned vector contains the indices which appear in
+ *  both source vectors). */
 exvector idx_intersect(const exvector & iv1, const exvector & iv2)
 {
-       // build a vector of symbolic indices contained in iv1 and iv2 simultaneously
-       // assumes (but does not test) that each index occurs at most twice
+       // Create union vector
+       exvector iv_union;
+       iv_union.reserve(iv1.size() + iv2.size());
+       iv_union.insert(iv_union.end(), iv1.begin(), iv1.end());
+       iv_union.insert(iv_union.end(), iv2.begin(), iv2.end());
+
+       // Sort it
+       canonicalize_indices(iv_union);
+
+       // Look for duplicates
        exvector iv_intersect;
-       for (exvector::const_iterator cit1=iv1.begin(); cit1!=iv1.end(); ++cit1) {
-               GINAC_ASSERT(is_ex_of_type(*cit1,idx));
-               if (ex_to_idx(*cit1).is_symbolic()) {
-                       for (exvector::const_iterator cit2=iv2.begin(); cit2!=iv2.end(); ++cit2) {
-                               GINAC_ASSERT(is_ex_of_type(*cit2,idx));
-                               if ((*cit1).is_equal(*cit2)) {
-                                       iv_intersect.push_back(*cit1);
-                                       break;
-                               }
-                       }
+       exvector::const_iterator cit = iv_union.begin(), citend = iv_union.end();
+       ex e;
+       if (cit != citend)
+               e = *cit++;
+       while (cit != citend) {
+               if (e.is_equal(*cit)) {
+                       iv_intersect.push_back(e);
+                       do {
+                               cit++;
+                       } while (cit != citend && e.is_equal(*cit));
+                       if (cit == citend)
+                               break;
                }
+               e = *cit++;
        }
        return iv_intersect;
 }
 
-#define TEST_PERMUTATION(A,B,C,P) \
-       if ((iv3[B].is_equal(iv2[0]))&&(iv3[C].is_equal(iv2[1]))) { \
-               if (antisymmetric) *sig=P; \
-               return iv3[A]; \
-       }
-
-ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2,
-                               bool antisymmetric, int * sig)
+/** Given a vector iv3 of three indices and a vector iv2 of two indices
+ *  where iv2 is a subset of iv3, return the (free) index that is in iv3
+ *  but not in iv2 and the sign introduced by permuting that index to the
+ *  front.
+ *
+ *  @param iv3 Vector of 3 indices
+ *  @param iv2 Vector of 2 indices, must be a subset of iv3
+ *  @param sig Returns the sign introduced by permuting the free index to the
+ *             front if the object carrying the indices was antisymmetric (if
+ *             it's symmetric, you can just ignore the returned value).
+ *  @return the free index (the one that is in iv3 but not in iv2) */
+ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2, int * sig)
 {
        // match (return value,iv2) to iv3 by permuting indices
        // iv3 is always cyclic
@@ -443,6 +480,12 @@ ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2,
        GINAC_ASSERT(iv2.size()==2);
 
        *sig=1;
+
+#define TEST_PERMUTATION(A,B,C,P) \
+       if ((iv3[B].is_equal(iv2[0]))&&(iv3[C].is_equal(iv2[1]))) { \
+               *sig=P; \
+               return iv3[A]; \
+       }
        
        TEST_PERMUTATION(0,1,2,  1);
        TEST_PERMUTATION(0,2,1, -1);
@@ -453,6 +496,12 @@ ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2,
        throw(std::logic_error("permute_free_index_to_front(): no valid permutation found"));
 }
        
+/** Substitute one index in a vector of expressions.
+ *
+ *  @param v Vector to substitute in (will be modified)
+ *  @param is Index being substituted
+ *  @param ir Index to replace by
+ *  @return number of performed substitutions */
 unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir)
 {
        exvector::iterator it;
@@ -472,6 +521,12 @@ unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir)
        return replacements;
 }
 
+/** Count number of times a given index appears in the index vector of an
+ *  indexed object.
+ *
+ *  @param e Indexed object
+ *  @param i Index to look for
+ *  @return number of times the index was found */
 unsigned count_index(const ex & e, const ex & i)
 {
        exvector idxv=e.get_indices();
@@ -482,8 +537,13 @@ unsigned count_index(const ex & e, const ex & i)
        return count;
 }
 
-ex subs_indices(const ex & e, const exvector & idxv_subs,
-                const exvector & idxv_repl)
+/** Substitute multiple indices in an expression.
+ *
+ *  @param e Expression to substitute in
+ *  @param idxv_subs Vector of indices being substituted
+ *  @param idxv_repl Vector of indices to replace by (1:1 correspondence to idxv_subs)
+ *  @return expression with substituted indices */
+ex subs_indices(const ex & e, const exvector & idxv_subs, const exvector & idxv_repl)
 {
        GINAC_ASSERT(idxv_subs.size()==idxv_repl.size());
        ex res=e;
index c9b319eeaedd4b8751d60a60dc13033d2b1c1608..2941fa96724fba23cfecdc36e9bca983757190d5 100644 (file)
 namespace GiNaC {
 #endif // ndef NO_NAMESPACE_GINAC
 
+
+/** This class holds one index of an indexed object. Indices can be symbolic
+ *  (e.g. "mu", "i") or numeric (unsigned integer), and they can be contravariant
+ *  (the default) or covariant. */
 class idx : public basic
 {
        GINAC_DECLARE_REGISTERED_CLASS(idx, basic)
 
-// member functions
-
        // default constructor, destructor, copy constructor assignment operator and helpers
 public:
        idx();
@@ -75,20 +77,26 @@ public:
 
        // non-virtual functions in this class
 public:
-       bool is_symbolic(void) const;
-       unsigned get_value(void) const;
-       bool is_covariant(void) const;
+       /** Check whether index is symbolic (not numeric). */
+       bool is_symbolic(void) const {return symbolic;}
+
+       /** Get numeric value of index. Undefined for symbolic indices. */
+       unsigned get_value(void) const {return value;}
+
+       /** Check whether index is covariant (not contravariant). */
+       bool is_covariant(void) const {return covariant;}
+
        void setname(const std::string & n) {name=n;}
        std::string getname(void) const {return name;}
 
        // member variables
 protected:
        unsigned serial;
-       bool symbolic;
-       std::string name;
-       unsigned value;
+       bool symbolic;    /**< Is index symbolic? */
+       std::string name; /**< Symbolic name (if symbolic == true) */
+       unsigned value;   /**< Numeric value (if symbolic == false) */
        static unsigned next_serial;
-       bool covariant; // x_mu, default is contravariant: x~mu
+       bool covariant;   /**< x_mu, default is contravariant: x~mu */
 };
 
 // global constants
@@ -106,11 +114,9 @@ inline const idx &ex_to_idx(const ex &e)
 
 int canonicalize_indices(exvector & iv, bool antisymmetric=false);
 exvector idx_intersect(const exvector & iv1, const exvector & iv2);
-ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2,
-                               bool antisymmetric, int * sig);
+ex permute_free_index_to_front(const exvector & iv3, const exvector & iv2, int * sig);
 unsigned subs_index_in_exvector(exvector & v, const ex & is, const ex & ir);
-ex subs_indices(const ex & e, const exvector & idxv_contra,
-                const exvector & idxv_co);
+ex subs_indices(const ex & e, const exvector & idxv_contra, const exvector & idxv_co);
 unsigned count_index(const ex & e, const ex & i);
 
 #ifndef NO_NAMESPACE_GINAC
index 734c2fea577df0b429ae8017cffcfe567e073291..500fcb85f271bfb7d53c30a6b139818590403b34 100644 (file)
@@ -90,6 +90,12 @@ void lorentzidx::destroy(bool call_parent)
 
 // public
 
+/** Construct symbolic Lorentz index, using an automatically generated unique name.
+ *
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @param oonly Index only lives in orthogonal space
+ *  @param dimp Dimension of parallel space
+ *  @return newly constructed index */
 lorentzidx::lorentzidx(bool cov, bool oonly, unsigned dimp)
   : idx(cov), orthogonal_only(oonly), dim_parallel_space(dimp)
 {
@@ -103,6 +109,13 @@ lorentzidx::lorentzidx(bool cov, bool oonly, unsigned dimp)
        tinfo_key=TINFO_lorentzidx;
 }
 
+/** Construct symbolic Lorentz index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @param oonly Index only lives in orthogonal space
+ *  @param dimp Dimension of parallel space
+ *  @return newly constructed index */
 lorentzidx::lorentzidx(const std::string & n, bool cov, bool oonly, unsigned dimp)
   : idx(n,cov), orthogonal_only(oonly), dim_parallel_space(dimp)
 {
@@ -111,6 +124,13 @@ lorentzidx::lorentzidx(const std::string & n, bool cov, bool oonly, unsigned dim
        tinfo_key=TINFO_lorentzidx;
 }
 
+/** Construct symbolic Lorentz index with specified name.
+ *
+ *  @param n Symbolic index name
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @param oonly Index only lives in orthogonal space
+ *  @param dimp Dimension of parallel space
+ *  @return newly constructed index */
 lorentzidx::lorentzidx(const char * n, bool cov, bool oonly, unsigned dimp)
   : idx(n,cov), orthogonal_only(oonly), dim_parallel_space(dimp)
 {
@@ -119,6 +139,11 @@ lorentzidx::lorentzidx(const char * n, bool cov, bool oonly, unsigned dimp)
        tinfo_key=TINFO_lorentzidx;
 }
 
+/** Construct numeric Lorentz index with specified value.
+ *
+ *  @param v Numeric index value
+ *  @param cov Index is covariant (contravariant otherwise)
+ *  @return newly constructed index */
 lorentzidx::lorentzidx(unsigned v, bool cov)
   : idx(v,cov), orthogonal_only(false), dim_parallel_space(0)
 {
@@ -135,8 +160,7 @@ lorentzidx::lorentzidx(const archive_node &n, const lst &sym_lst) : inherited(n,
 {
        debugmsg("lorentzidx constructor from archive_node", LOGLEVEL_CONSTRUCT);
        n.find_bool("orthogonal_only", orthogonal_only);
-       if (orthogonal_only)
-               n.find_unsigned("pdim", dim_parallel_space);
+       n.find_unsigned("pdim", dim_parallel_space);
 }
 
 /** Unarchive the object. */
@@ -159,8 +183,7 @@ void lorentzidx::archive(archive_node &n) const
 {
        inherited::archive(n);
        n.add_bool("orthogonal_only", orthogonal_only);
-       if (orthogonal_only)
-               n.add_unsigned("pdim", dim_parallel_space);
+       n.add_unsigned("pdim", dim_parallel_space);
 }
 
 //////////
@@ -270,6 +293,7 @@ bool lorentzidx::info(unsigned inf) const
 
 // public
 
+/** Create anonymous contravariant copy of a symbolic Lorentz index. */
 lorentzidx lorentzidx::create_anonymous_representative(void) const
 {
        GINAC_ASSERT(is_symbolic());
index 582cdc0bb379b4c723481d4e4a5d5682b6c15db3..f644fa2bd73b229c80a63657e838e2f1b4da0eef 100644 (file)
 namespace GiNaC {
 #endif // ndef NO_NAMESPACE_GINAC
 
+/** Class of indices for Lorentz tensors, to tell them apart from other index
+ *  families like color indices. The indices of this class also support the
+ *  case of P-O-decomposed D-dimensional spacetime, where the parallel space
+ *  is a Minkowski-like space with integral dimension P and the orthogonal
+ *  space is a Euclidean space with (possibly complex) dimension D-P. */
 class lorentzidx : public idx
 {
        GINAC_DECLARE_REGISTERED_CLASS(lorentzidx, idx)
@@ -72,14 +77,18 @@ public:
 
        // non-virtual functions in this class
 public:
-       bool is_orthogonal_only(void) const { return orthogonal_only; }
-       unsigned get_dim_parallel_space(void) const { return dim_parallel_space; }
+       /** Check whether index only lives in orthogonal space. */
+       bool is_orthogonal_only(void) const {return orthogonal_only;}
+
+       /** Return dimension of parallel space. */
+       unsigned get_dim_parallel_space(void) const {return dim_parallel_space;}
+
        lorentzidx create_anonymous_representative(void) const; 
 
        // member variables
 protected:
-       bool orthogonal_only;
-       unsigned dim_parallel_space;
+       bool orthogonal_only;        /**< Symbolic index only lives in orthogonal space? */
+       unsigned dim_parallel_space; /**< Dimension of parallel space */
 };
 
 // global constants
index 89b2d578cfbc4677d36591cf1a9d21a9af8d5a3b..6677360cf7e0242ef1af6cbffa38e4ec4f745d43 100644 (file)
@@ -270,7 +270,7 @@ ex lortensor::eval(int level) const
                                return _ex0();
                        }
                } else if (idx1.is_symbolic() && idx1.is_co_contra_pair(idx2)) {
-                       return Dim()-idx1.get_dim_parallel_space();
+                       return Dim() - 2;
                }
        }
        return this -> hold();
index 89ed758c9f1736f667e80cf2dd91c333f7f331ee..5f6fbdbe74a5b54d10332235531191dad8436bd6 100644 (file)
@@ -231,7 +231,7 @@ ex simp_lor::eval(int level) const
                        }
                } else if (idx1.is_symbolic() &&
                           idx1.is_co_contra_pair(idx2)) {
-                       return Dim()-idx1.get_dim_parallel_space();
+                       return Dim() - 2;
                }
        }