From: Christian Bauer Date: Mon, 12 Feb 2001 20:54:53 +0000 (+0000) Subject: - added documentation for the idx, coloridx and lorentzidx classes X-Git-Tag: release_0-7-2~13 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=7cbe7effc515e4575b4d1fd1d6d75f0148eb8a89 - added documentation for the idx, coloridx and lorentzidx classes - idx_intersect() works correctly when indices appear multiple times - g~mu_mu = D-2 (instead of D-dim(P)) --- diff --git a/ginac/color.cpp b/ginac/color.cpp index 8e7ecda9..5a9229b1 100644 --- a/ginac/color.cpp +++ b/ginac/color.cpp @@ -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; diff --git a/ginac/coloridx.cpp b/ginac/coloridx.cpp index a227ea9b..368aef08 100644 --- a/ginac/coloridx.cpp +++ b/ginac/coloridx.cpp @@ -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); diff --git a/ginac/coloridx.h b/ginac/coloridx.h index 78bd356a..ad190c11 100644 --- a/ginac/coloridx.h +++ b/ginac/coloridx.h @@ -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) diff --git a/ginac/idx.cpp b/ginac/idx.cpp index 2fc851c7..926f427d 100644 --- a/ginac/idx.cpp +++ b/ginac/idx.cpp @@ -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(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; diff --git a/ginac/idx.h b/ginac/idx.h index c9b319ee..2941fa96 100644 --- a/ginac/idx.h +++ b/ginac/idx.h @@ -32,12 +32,14 @@ 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 diff --git a/ginac/lorentzidx.cpp b/ginac/lorentzidx.cpp index 734c2fea..500fcb85 100644 --- a/ginac/lorentzidx.cpp +++ b/ginac/lorentzidx.cpp @@ -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()); diff --git a/ginac/lorentzidx.h b/ginac/lorentzidx.h index 582cdc0b..f644fa2b 100644 --- a/ginac/lorentzidx.h +++ b/ginac/lorentzidx.h @@ -31,6 +31,11 @@ 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 diff --git a/ginac/lortensor.cpp b/ginac/lortensor.cpp index 89b2d578..6677360c 100644 --- a/ginac/lortensor.cpp +++ b/ginac/lortensor.cpp @@ -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(); diff --git a/ginac/simp_lor.cpp b/ginac/simp_lor.cpp index 89ed758c..5f6fbdbe 100644 --- a/ginac/simp_lor.cpp +++ b/ginac/simp_lor.cpp @@ -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; } }