namespace GiNaC {
#endif // ndef NO_NAMESPACE_GINAC
+GINAC_IMPLEMENT_REGISTERED_CLASS(clifford, lortensor)
+
//////////
// default constructor, destructor, copy constructor assignment operator and helpers
//////////
clifford::clifford()
{
debugmsg("clifford default constructor",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
- name=autoname_prefix()+ToString(serial);
- tinfo_key=TINFO_clifford;
+ tinfo_key = TINFO_clifford;
}
clifford::~clifford()
clifford::clifford(const clifford & other)
{
debugmsg("clifford copy constructor",LOGLEVEL_CONSTRUCT);
- copy (other);
+ copy(other);
}
const clifford & clifford::operator=(const clifford & other)
void clifford::copy(const clifford & other)
{
- indexed::copy(other);
- name=other.name;
- serial=other.serial;
+ inherited::copy(other);
}
void clifford::destroy(bool call_parent)
{
- if (call_parent) {
- indexed::destroy(call_parent);
- }
+ if (call_parent) inherited::destroy(call_parent);
}
//////////
// public
-clifford::clifford(const std::string & initname)
+clifford::clifford(const std::string & n, const ex & mu) : inherited(lortensor_symbolic, n, mu)
{
- debugmsg("clifford constructor from string",LOGLEVEL_CONSTRUCT);
- name=initname;
- serial=next_serial++;
+ debugmsg("clifford constructor from string,ex",LOGLEVEL_CONSTRUCT);
tinfo_key=TINFO_clifford;
}
void clifford::printraw(std::ostream & os) const
{
debugmsg("clifford printraw",LOGLEVEL_PRINT);
- os << "clifford(" << "name=" << name << ",serial=" << serial
- << ",indices=";
+ os << "clifford(" << "indices=";
printrawindices(os);
os << ",hash=" << hashvalue << ",flags=" << flags << ")";
}
void clifford::printtree(std::ostream & os, unsigned indent) const
{
debugmsg("clifford printtree",LOGLEVEL_PRINT);
- os << std::string(indent,' ') << name << " (clifford): "
- << "serial=" << serial << ","
+ os << std::string(indent,' ') << " (clifford): "
<< seq.size() << "indices=";
printtreeindices(os, indent);
os << ", hash=" << hashvalue
printindices(os);
}
-void clifford::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
- debugmsg("clifford print csrc",LOGLEVEL_PRINT);
- print(os,upper_precedence);
-}
-
bool clifford::info(unsigned inf) const
{
- return indexed::info(inf);
+ return inherited::info(inf);
}
// protected
int clifford::compare_same_type(const basic & other) const
{
- GINAC_ASSERT(other.tinfo() == TINFO_clifford);
- const clifford *o = static_cast<const clifford *>(&other);
- if (serial==o->serial) {
- return indexed::compare_same_type(other);
- }
- return serial < o->serial ? -1 : 1;
+ GINAC_ASSERT(is_of_type(other,clifford));
+ // only compare indices
+ return exprseq::compare_same_type(other);
}
-ex clifford::simplify_ncmul(const exvector & v) const
+bool clifford::is_equal_same_type(const basic & other) const
{
- return simplified_ncmul(v);
+ GINAC_ASSERT(is_of_type(other,clifford));
+ // only compare indices
+ return exprseq::is_equal_same_type(other);
}
-unsigned clifford::calchash(void) const
+ex clifford::simplify_ncmul(const exvector & v) const
{
- hashvalue=golden_ratio_hash(golden_ratio_hash(0x55555556U ^
- golden_ratio_hash(tinfo_key) ^
- serial));
- setflag(status_flags::hash_calculated);
- return hashvalue;
+ return simplified_ncmul(v);
}
//////////
// non-virtual functions in this class
//////////
-void clifford::setname(const std::string & n)
-{
- name = n;
-}
-
-// private
-
-std::string & clifford::autoname_prefix(void)
-{
- static std::string * s = new std::string("clifford");
- return *s;
-}
+// none
//////////
// static member variables
//////////
-// private
+// none
+
+//////////
+// friend functions
+//////////
-unsigned clifford::next_serial=0;
+/** Construct an object representing a Dirac gamma matrix. The index must
+ * be of class lorentzidx.
+ *
+ * @param mu Index
+ * @return newly constructed object */
+clifford clifford_gamma(const ex & mu)
+{
+ return clifford("gamma", mu);
+}
//////////
// global constants
#define __GINAC_CLIFFORD_H__
#include <string>
-#include "indexed.h"
-#include "ex.h"
+#include "lortensor.h"
#ifndef NO_NAMESPACE_GINAC
namespace GiNaC {
#endif // ndef NO_NAMESPACE_GINAC
-/** Base class for clifford object */
-class clifford : public indexed
+
+/** This class holds an object representing an element of the Clifford
+ * algebra (the Dirac gamma matrices). These objects only carry Lorentz
+ * indices. Spinor indices are always hidden in our implementation. */
+class clifford : public lortensor
{
+ GINAC_DECLARE_REGISTERED_CLASS(clifford, lortensor)
+
+// friends
+
+ friend clifford clifford_gamma(const ex & mu);
+
// member functions
// default constructor, destructor, copy constructor assignment operator and helpers
// other constructors
public:
- explicit clifford(const std::string & initname);
+ clifford(const std::string & n, const ex & mu);
// functions overriding virtual functions from base classes
public:
void printraw(std::ostream & os) const;
void printtree(std::ostream & os, unsigned indent) const;
void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
bool info(unsigned inf) const;
+ // ex eval(int level=0) const;
protected:
int compare_same_type(const basic & other) const;
+ bool is_equal_same_type(const basic & other) const;
ex simplify_ncmul(const exvector & v) const;
- unsigned calchash(void) const;
+ ex thisexprseq(const exvector & v) const;
+ ex thisexprseq(exvector * vp) const;
// new virtual functions which can be overridden by derived classes
// none
// non-virtual functions in this class
-public:
- void setname(const std::string & n);
-private:
- std::string & autoname_prefix(void);
-
-// member variables
+ // none
-protected:
- std::string name;
- unsigned serial; // unique serial number for comparision
-private:
- static unsigned next_serial;
+ // member variables
+ // none
};
// global constants
extern const clifford some_clifford;
extern const std::type_info & typeid_clifford;
-// utility functions
+// global functions
inline const clifford &ex_to_clifford(const ex &e)
{
return static_cast<const clifford &>(*e.bp);
}
+clifford clifford_gamma(const ex & mu);
+
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#endif // ndef NO_NAMESPACE_GINAC
// public
-color::color() : type(invalid), representation_label(0)
+color::color() : inherited(TINFO_color), type(invalid), representation_label(0)
{
debugmsg("color default constructor",LOGLEVEL_CONSTRUCT);
- tinfo_key=TINFO_color;
}
color::~color()
// protected
+/** Construct object without any color index. This constructor is for internal
+ * use only. Use the color_ONE() function instead.
+ * @see color_ONE */
color::color(color_types const t, unsigned rl) : type(t), representation_label(rl)
{
debugmsg("color constructor from color_types,unsigned",LOGLEVEL_CONSTRUCT);
GINAC_ASSERT(all_of_type_coloridx());
}
+/** Construct object with one color index. This constructor is for internal
+ * use only. Use the color_T() function instead.
+ * @see color_T */
color::color(color_types const t, const ex & i1, unsigned rl)
: inherited(i1), type(t), representation_label(rl)
{
GINAC_ASSERT(all_of_type_coloridx());
}
+/** Construct object with two color indices. This constructor is for internal
+ * use only. Use the color_delta8() function instead.
+ * @see color_delta8 */
color::color(color_types const t, const ex & i1, const ex & i2, unsigned rl)
: inherited(i1,i2), type(t), representation_label(rl)
{
GINAC_ASSERT(all_of_type_coloridx());
}
+/** Construct object with three color indices. This constructor is for internal
+ * use only. Use the color_f(), color_d() and color_h() functions instead.
+ * @see color_f
+ * @see color_d
+ * @see color_h */
color::color(color_types const t, const ex & i1, const ex & i2, const ex & i3,
unsigned rl) : inherited(i1,i2,i3), type(t), representation_label(rl)
{
GINAC_ASSERT(all_of_type_coloridx());
}
+/** Construct object with arbitrary number of color indices. This
+ * constructor is for internal use only. */
color::color(color_types const t, const exvector & iv, unsigned rl)
: inherited(iv), type(t), representation_label(rl)
{
printindices(os);
}
-void color::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
- debugmsg("color print csrc",LOGLEVEL_PRINT);
- print(os,upper_precedence);
-}
-
bool color::info(unsigned inf) const
{
return inherited::info(inf);
int color::compare_same_type(const basic & other) const
{
GINAC_ASSERT(other.tinfo() == TINFO_color);
- const color *o = static_cast<const color *>(&other);
- if (type==o->type) {
- if (representation_label==o->representation_label) {
- return inherited::compare_same_type(other);
- }
- return representation_label < o->representation_label ? -1 : 1;
+ const color &o = static_cast<const color &>(other);
+
+ if (type != o.type) {
+ // different type
+ return type < o.type ? -1 : 1;
}
- return type < o->type ? -1 : 1;
+
+ if (representation_label != o.representation_label) {
+ // different representation label
+ return representation_label < o.representation_label ? -1 : 1;
+ }
+
+ return inherited::compare_same_type(other);
}
bool color::is_equal_same_type(const basic & other) const
{
GINAC_ASSERT(other.tinfo() == TINFO_color);
- const color *o = static_cast<const color *>(&other);
- if (type!=o->type) return false;
- if (representation_label!=o->representation_label) return false;
+ const color &o = static_cast<const color &>(other);
+
+ if (type != o.type) return false;
+ if (representation_label != o.representation_label) return false;
return inherited::is_equal_same_type(other);
}
return color(type,vp,representation_label);
}
+/** Check whether all indices are of class coloridx or a subclass. This
+ * function is used internally to make sure that all constructed color
+ * objects really carry color indices and not some other classes. */
bool color::all_of_type_coloridx(void) const
{
- // used only inside of ASSERTs
for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
if (!is_ex_of_type(*cit,coloridx)) return false;
}
// friend functions
//////////
+/** Construct an object representing the unity element of su(3).
+ *
+ * @param rl Representation label
+ * @return newly constructed object */
color color_ONE(unsigned rl)
{
return color(color::color_ONE,rl);
}
+/** Construct an object representing the generators T_a of SU(3). The index
+ * must be of class coloridx.
+ *
+ * @param a Index
+ * @param rl Representation label
+ * @return newly constructed object */
color color_T(const ex & a, unsigned rl)
{
return color(color::color_T,a,rl);
}
+/** Construct an object representing the antisymmetric structure constants
+ * f_abc of SU(3). The indices must be of class coloridx.
+ *
+ * @param a First index
+ * @param b Second index
+ * @param c Third index
+ * @return newly constructed object */
color color_f(const ex & a, const ex & b, const ex & c)
{
return color(color::color_f,a,b,c);
}
+/** Construct an object representing the symmetric structure constants d_abc
+ * of SU(3). The indices must be of class coloridx.
+ *
+ * @param a First index
+ * @param b Second index
+ * @param c Third index
+ * @return newly constructed object */
color color_d(const ex & a, const ex & b, const ex & c)
{
return color(color::color_d,a,b,c);
}
+/** This returns the linear combination d_abc+I*f_abc.
+ *
+ * @param a First index
+ * @param b Second index
+ * @param c Third index
+ * @return newly constructed object */
ex color_h(const ex & a, const ex & b, const ex & c)
{
return color(color::color_d,a,b,c)+I*color(color::color_f,a,b,c);
}
+/** Construct an object representing the unity matrix delta8_ab in su(3).
+ * The indices must be of class coloridx.
+ *
+ * @param a First index
+ * @param b Second index
+ * @return newly constructed object */
color color_delta8(const ex & a, const ex & b)
{
return color(color::color_delta8,a,b);
}
+/** Given a vector of color (and possible other) objects, split it up
+ * according to the object type (structure constant, generator etc.) and
+ * representation label while preserving the order within each group. If
+ * there are non-color objetcs in the vector, the SU(3) generators T_a get
+ * sorted into the "unknown" group together with the non-color objects
+ * because we don't know whether these objects commute with the generators.
+ *
+ * @param v Source vector of expressions
+ * @param delta8vec Vector of unity matrices (returned)
+ * @param fvec Vector of antisymmetric structure constants (returned)
+ * @param dvec Vector of symmetric structure constants (returned)
+ * @param Tvecs Vectors of generators, one for each representation label (returned)
+ * @param ONEvecs Vectors of unity elements, one for each representation label (returned)
+ * @param unknownvec Vector of all non-color objects (returned)
+ *
+ * @see color::color_types
+ * @see recombine_color_string */
void split_color_string_in_parts(const exvector & v, exvector & delta8vec,
exvector & fvec, exvector & dvec,
exvectorvector & Tvecs,
}
}
+/** Merge vectors of color objects sorted by object type into one vector,
+ * retaining the order within each group. This is the inverse operation of
+ * split_color_string_in_parts().
+ *
+ * @param delta8vec Vector of unity matrices
+ * @param fvec Vector of antisymmetric structure constants
+ * @param dvec Vector of symmetric structure constants
+ * @param Tvecs Vectors of generators, one for each representation label
+ * @param ONEvecs Vectors of unity elements, one for each representation label
+ * @param unknownvec Vector of all non-color objects
+ * @return merged vector
+ *
+ * @see color::color_types
+ * @see split_color_string_in_parts */
exvector recombine_color_string(exvector & delta8vec, exvector & fvec,
exvector & dvec, exvectorvector & Tvecs,
exvectorvector & ONEvecs, exvector & unknownvec)
*/
}
+/** Calculate the trace over the (hidden) indices of the su(3) Lie algebra
+ * elements (the SU(3) generators and the unity element) of a specified
+ * representation label in a string of color objects.
+ *
+ * @param v Vector of color objects
+ * @param rl Representation label
+ * @return value of the trace */
ex color_trace(const exvector & v, unsigned rl)
{
GINAC_ASSERT(rl<MAX_REPRESENTATION_LABELS);
return e;
}
+/** Perform some simplifications on an expression containing color objects. */
ex simplify_color(const ex & e)
{
// all simplification is done on expanded objects
return sum;
}
-void append_exvector_to_exvector(exvector & dest, const exvector & source)
-{
- for (exvector::const_iterator cit=source.begin(); cit!=source.end(); ++cit) {
- dest.push_back(*cit);
- }
-}
-
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#endif // ndef NO_NAMESPACE_GINAC
-
typedef std::vector<exvector> exvectorvector;
#endif
-/** Base class for color object */
+
+/** This class holds an object carrying color indices (of class coloridx).
+ * It can represent the generators T_a and structure constants f_abc/d_abc
+ * of SU(3), the unity element ONE of the Lie algebra of SU(3), or the
+ * unity matrix delta8. Together, these objects are used to implement the
+ * Lie algebra su(3), as required for calculations in quantum
+ * chromodynamics. A representation label (an unsigned integer) is used to
+ * distinguish elements from different Lie algebras (only objects with the
+ * same representation label "interact" with each other). */
class color : public indexed
{
GINAC_DECLARE_REGISTERED_CLASS(color, indexed)
friend ex simplify_pure_color_string(const ex & e);
friend ex simplify_color(const ex & e);
-
// types
public:
+ /** Type of object */
typedef enum {
- invalid, // not properly constructed by one of the friend functions
- color_T,
- color_f,
- color_d,
- color_delta8,
- color_ONE
+ invalid, /**< not properly constructed */
+ color_T, /**< one of the generators T_a of SU(3) (these are non-commutative) */
+ color_f, /**< one of the antisymmetric structure constants f_abc of SU(3) */
+ color_d, /**< one of the symmetric structure constants d_abc of SU(3) */
+ color_delta8, /**< the unity matrix */
+ color_ONE /**< the unity element of su(3) */
} color_types;
// member functions
void printraw(std::ostream & os) const;
void printtree(std::ostream & os, unsigned indent) const;
void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
bool info(unsigned inf) const;
ex eval(int level=0) const;
protected:
// member variables
protected:
- color_types type;
- unsigned representation_label; // to distiguish independent color matrices coming from separated fermion lines
+ color_types type; /**< Type of object (generator, structure constant etc.) */
+ unsigned representation_label; /**< Representation label to distiguish independent color matrices coming from separated fermion lines */
};
// global constants
ex brute_force_sum_color_indices(const ex & e);
-void append_exvector_to_exvector(exvector & dest, const exvector & source);
-
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#endif // ndef NO_NAMESPACE_GINAC
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 of indices for color algebra objects, to tell them apart from
+ * other index families like Lorentz indices. The color indices are the
+ * indices of the SU(3) generators T_a, so they lie in the range of 0 to 7.
+ * Note that this kind of index is different from the indices carried by
+ * elements of a specific matrix representation of su(3). Such indices are
+ * always hidden in our implementation and we are not concerned with them. */
class coloridx : public idx
{
GINAC_DECLARE_REGISTERED_CLASS(coloridx, idx)
{
debugmsg("idx default constructor",LOGLEVEL_CONSTRUCT);
serial=next_serial++;
- name="index"+ToString(serial);
+ name=autoname_prefix()+ToString(serial);
}
idx::~idx()
{
debugmsg("idx constructor from bool",LOGLEVEL_CONSTRUCT);
serial = next_serial++;
- name = "index"+ToString(serial);
+ name = autoname_prefix()+ToString(serial);
}
/** Construct symbolic index with specified name.
if (symbolic) {
serial = next_serial++;
if (!(n.find_string("name", name)))
- name = "index" + ToString(serial);
+ name = autoname_prefix() + ToString(serial);
} else {
serial = 0;
n.find_unsigned("value", value);
int idx::compare_same_type(const basic & other) const
{
GINAC_ASSERT(is_of_type(other,idx));
- const idx & o=static_cast<const idx &>(const_cast<basic &>(other));
+ const idx &o = static_cast<const idx &>(&other);
if (covariant!=o.covariant) {
// different co/contravariant
return covariant ? -1 : 1;
}
+
if ((!symbolic) && (!o.symbolic)) {
// non-symbolic, of equal type: compare values
if (value==o.value) {
}
return value<o.value ? -1 : 1;
}
+
if (symbolic && o.symbolic) {
// both symbolic: compare serials
if (serial==o.serial) {
}
return serial<o.serial ? -1 : 1;
}
+
// one symbolic, one value: value is sorted first
return o.symbolic ? -1 : 1;
}
bool idx::is_equal_same_type(const basic & other) const
{
GINAC_ASSERT(is_of_type(other,idx));
- const idx & o=static_cast<const idx &>(const_cast<basic &>(other));
+ const idx &o = static_cast<const idx &>(other);
- if (covariant!=o.covariant) return false;
- if (symbolic!=o.symbolic) return false;
+ if (covariant != o.covariant) return false;
+ if (symbolic != o.symbolic) return false;
if (symbolic && o.symbolic) return serial==o.serial;
return value==o.value;
}
// non-virtual functions in this class
//////////
-// none
+// private
+
+std::string & idx::autoname_prefix(void)
+{
+ static std::string * s = new std::string("index");
+ return *s;
+}
//////////
// static member variables
void setname(const std::string & n) {name=n;}
std::string getname(void) const {return name;}
+private:
+ std::string & autoname_prefix(void);
+
// member variables
protected:
- unsigned serial;
+ unsigned serial; /**< Unique serial number for comparing symbolic indices */
bool symbolic; /**< Is index symbolic? */
std::string name; /**< Symbolic name (if symbolic == true) */
unsigned value; /**< Numeric value (if symbolic == false) */
// public
+/** Construct indexed object with one index. The index must be of class idx
+ * or a subclass.
+ *
+ * @param i1 The index
+ * @return newly constructed indexed object */
indexed::indexed(const ex & i1) : inherited(i1)
{
debugmsg("indexed constructor from ex",LOGLEVEL_CONSTRUCT);
GINAC_ASSERT(all_of_type_idx());
}
+/** Construct indexed object with two indices. The indices must be of class
+ * idx or a subclass.
+ *
+ * @param i1 First index
+ * @param i2 Second index
+ * @return newly constructed indexed object */
indexed::indexed(const ex & i1, const ex & i2) : inherited(i1,i2)
{
debugmsg("indexed constructor from ex,ex",LOGLEVEL_CONSTRUCT);
GINAC_ASSERT(all_of_type_idx());
}
+/** Construct indexed object with three indices. The indices must be of class
+ * idx or a subclass.
+ *
+ * @param i1 First index
+ * @param i2 Second index
+ * @param i3 Third index
+ * @return newly constructed indexed object */
indexed::indexed(const ex & i1, const ex & i2, const ex & i3)
: inherited(i1,i2,i3)
{
GINAC_ASSERT(all_of_type_idx());
}
+/** Construct indexed object with four indices. The indices must be of class
+ * idx or a subclass.
+ *
+ * @param i1 First index
+ * @param i2 Second index
+ * @param i3 Third index
+ * @param i4 Fourth index
+ * @return newly constructed indexed object */
indexed::indexed(const ex & i1, const ex & i2, const ex & i3, const ex & i4)
: inherited(i1,i2,i3,i4)
{
GINAC_ASSERT(all_of_type_idx());
}
+/** Construct indexed object with a specified vector of indices. The indices
+ * must be of class idx or a subclass.
+ *
+ * @param iv Vector of indices
+ * @return newly constructed indexed object */
indexed::indexed(const exvector & iv) : inherited(iv)
{
debugmsg("indexed constructor from exvector",LOGLEVEL_CONSTRUCT);
return inherited::info(inf);
}
-exvector indexed::get_indices(void) const
-{
- return seq;
-
- /*
- idxvector filtered_indices;
- filtered_indices.reserve(indices.size());
- for (idxvector::const_iterator cit=indices.begin(); cit!=indices.end(); ++cit) {
- if ((*cit).get_type()==t) {
- filtered_indices.push_back(*cit);
- }
- }
- return filtered_indices;
- */
-}
-
// protected
/** Implementation of ex::diff() for an indexed object. It always returns 0.
}
}
+/** Check whether all indices are of class idx or a subclass. This function
+ * is used internally to make sure that all constructed indexed objects
+ * really carry indices and not some other classes. */
bool indexed::all_of_type_idx(void) const
{
- // used only inside of ASSERTs
for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
if (!is_ex_of_type(*cit,idx)) return false;
}
namespace GiNaC {
#endif // ndef NO_NAMESPACE_GINAC
-/** Base class for non-commutative indexed objects */
+
+/** Base class for objects with indices. */
class indexed : public exprseq
{
GINAC_DECLARE_REGISTERED_CLASS(indexed, exprseq)
void print(std::ostream & os, unsigned upper_precedence=0) const;
void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const;
bool info(unsigned inf) const;
- exvector get_indices(void) const;
+
+ /** Return the vector of indices on this object. */
+ exvector get_indices(void) const {return seq;}
+
protected:
ex derivative(const symbol & s) const;
int compare_same_type(const basic & other) const;
#include "lorentzidx.h"
#include "lst.h"
+#include "symbol.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
lorentzidx::lorentzidx(bool cov, bool oonly, unsigned dimp)
: idx(cov), orthogonal_only(oonly), dim_parallel_space(dimp)
{
- debugmsg("lorentzidx constructor from bool",LOGLEVEL_CONSTRUCT);
+ debugmsg("lorentzidx constructor from bool,bool,unsigned",LOGLEVEL_CONSTRUCT);
// serial is incremented in idx::idx(bool)
if (oonly) {
name="muorth"+ToString(serial);
// none
+//////////
+// global functions
+//////////
+
+/** Return the global symbol that represents the dimension D of spacetime. */
+ex Dim(void)
+{
+ static symbol *d = new symbol("dim");
+ return *d;
+}
+
//////////
// global constants
//////////
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 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 space with integral dimension P and the
+ * orthogonal space is a Euclidean space with (possibly complex) dimension
+ * D-P. The dimension D of spacetime is represented by the global symbol
+ * that is returned by the Dim() function. */
class lorentzidx : public idx
{
GINAC_DECLARE_REGISTERED_CLASS(lorentzidx, idx)
return static_cast<const lorentzidx &>(*e.bp);
}
+ex Dim(void);
+
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#endif // ndef NO_NAMESPACE_GINAC
#include "operators.h"
#include "tinfos.h"
#include "power.h"
-#include "symbol.h"
+#include "archive.h"
#include "utils.h"
#include "config.h"
namespace GiNaC {
#endif // ndef NO_NAMESPACE_GINAC
+GINAC_IMPLEMENT_REGISTERED_CLASS(lortensor, indexed)
+
//////////
// default constructor, destructor, copy constructor assignment operator and helpers
//////////
// public
-lortensor::lortensor()
+lortensor::lortensor() : inherited(TINFO_lortensor), type(invalid)
{
debugmsg("lortensor default constructor",LOGLEVEL_CONSTRUCT);
serial=next_serial++;
name=autoname_prefix()+ToString(serial);
- tinfo_key=TINFO_lortensor;
}
lortensor::~lortensor()
void lortensor::copy(const lortensor & other)
{
- indexed::copy(other);
+ inherited::copy(other);
type=other.type;
name=other.name;
serial=other.serial;
void lortensor::destroy(bool call_parent)
{
- if (call_parent) {
- indexed::destroy(call_parent);
- }
+ if (call_parent) inherited::destroy(call_parent);
}
//////////
// protected
+/** Construct object without any Lorentz index. This constructor is for
+ * internal use only. */
lortensor::lortensor(lortensor_types const lt, const std::string & n) : type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
- tinfo_key=TINFO_lortensor;
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
+ tinfo_key = TINFO_lortensor;
}
-lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu) : indexed(mu), type(lt), name(n)
+/** Construct object with one Lorentz index. This constructor is for
+ * internal use only. Use the lortensor_vector() or lortensor_symbolic()
+ * functions instead.
+ * @see lortensor_vector
+ * @see lortensor_symbolic */
+lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu) : inherited(mu), type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string,ex",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
GINAC_ASSERT(all_of_type_lorentzidx());
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
tinfo_key=TINFO_lortensor;
}
-lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu) : indexed(mu,nu), type(lt), name(n)
+/** Construct object with two Lorentz indices. This constructor is for
+ * internal use only. Use the lortensor_g(), lortensor_delta() or
+ * lortensor_symbolic() functions instead.
+ * @see lortensor_g
+ * @see lortensor_delta
+ * @see lortensor_symbolic */
+lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu) : inherited(mu,nu), type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string,ex,ex",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
GINAC_ASSERT(all_of_type_lorentzidx());
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
tinfo_key=TINFO_lortensor;
}
-lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu, const ex & rho) : indexed(mu,nu,rho), type(lt), name(n)
+/** Construct object with three Lorentz indices. This constructor is for
+ * internal use only. Use the lortensor_symbolic() function instead.
+ * @see lortensor_symbolic */
+lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu, const ex & rho) : inherited(mu,nu,rho), type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string,ex,ex,ex",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
GINAC_ASSERT(all_of_type_lorentzidx());
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
tinfo_key=TINFO_lortensor;
}
-lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu, const ex & rho, const ex & sigma) : indexed(mu,nu,rho,sigma), type(lt), name(n)
+/** Construct object with four Lorentz indices. This constructor is for
+ * internal use only. Use the lortensor_epsilon() or lortensor_symbolic()
+ * functions instead.
+ * @see lortensor_epsilon
+ * @see lortensor_symbolic */
+lortensor::lortensor(lortensor_types const lt, const std::string & n, const ex & mu, const ex & nu, const ex & rho, const ex & sigma) : inherited(mu,nu,rho,sigma), type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string,ex,ex,ex,ex",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
GINAC_ASSERT(all_of_type_lorentzidx());
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
tinfo_key=TINFO_lortensor;
}
-lortensor::lortensor(lortensor_types const lt, const std::string & n, const exvector & iv) : indexed(iv), type(lt), name(n)
+/** Construct object with arbitrary number of Lorentz indices. This
+ * constructor is for internal use only. Use the lortensor_symbolic()
+ * function instead.
+ *
+ * @see lortensor_symbolic */
+lortensor::lortensor(lortensor_types const lt, const std::string & n, const exvector & iv) : inherited(iv), type(lt), name(n)
{
debugmsg("lortensor constructor from lortensor_types,string,exvector",LOGLEVEL_CONSTRUCT);
- serial=next_serial++;
GINAC_ASSERT(all_of_type_lorentzidx());
+ if (lt == lortensor_symbolic)
+ serial = next_serial++;
+ else
+ serial = 0;
tinfo_key=TINFO_lortensor;
}
tinfo_key=TINFO_lortensor;
}
+
+//////////
+// archiving
+//////////
+
+/** Construct object from archive_node. */
+lortensor::lortensor(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
+{
+ debugmsg("lortensor constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ unsigned int ty;
+ if (!(n.find_unsigned("type", ty)))
+ throw (std::runtime_error("unknown lortensor type in archive"));
+ type = (lortensor_types)ty;
+ if (type == lortensor_symbolic) {
+ serial = next_serial++;
+ if (!(n.find_string("name", name)))
+ name = autoname_prefix() + ToString(serial);
+ } else
+ serial = 0;
+}
+
+/** Unarchive the object. */
+ex lortensor::unarchive(const archive_node &n, const lst &sym_lst)
+{
+ ex s = (new lortensor(n, sym_lst))->setflag(status_flags::dynallocated);
+
+ if (ex_to_lortensor(s).type == lortensor_symbolic) {
+ // If lortensor is in sym_lst, return the existing lortensor
+ for (unsigned i=0; i<sym_lst.nops(); i++) {
+ if (is_ex_of_type(sym_lst.op(i), lortensor) && (ex_to_lortensor(sym_lst.op(i)).name == ex_to_lortensor(s).name))
+ return sym_lst.op(i);
+ }
+ }
+ return s;
+}
+
+/** Archive the object. */
+void lortensor::archive(archive_node &n) const
+{
+ inherited::archive(n);
+ n.add_unsigned("type", type);
+ if (type == lortensor_symbolic)
+ n.add_string("name", name);
+}
+
+
//////////
// functions overriding virtual functions from bases classes
//////////
os << "lortensor(type=" << (unsigned)type
<< ",indices=";
printrawindices(os);
+ os << ",serial=" << serial;
os << ",hash=" << hashvalue << ",flags=" << flags << ")";
}
case lortensor_g:
os << "g";
break;
- case lortensor_rankn:
- os << name;
- break;
- case lortensor_rank1:
- os << name;
- break;
- case lortensor_rank2:
- os << name;
+ case lortensor_delta:
+ os << "delta";
break;
case lortensor_epsilon:
os << "epsilon";
break;
+ case lortensor_symbolic:
+ os << name;
+ break;
case invalid:
default:
os << "INVALID_LORTENSOR_OBJECT";
printindices(os);
}
-void lortensor::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
-{
- debugmsg("lortensor print csrc",LOGLEVEL_PRINT);
- print(os,upper_precedence);
-}
-
bool lortensor::info(unsigned inf) const
{
- return indexed::info(inf);
+ return inherited::info(inf);
}
ex lortensor::eval(int level) const
int lortensor::compare_same_type(const basic & other) const
{
GINAC_ASSERT(is_of_type(other,lortensor));
- const lortensor *o = static_cast <const lortensor *> (&other);
- if (type==o->type) {
- if (type==lortensor_rankn) {
- if (serial!=o->serial) {
- return serial < o->serial ? -1 : 1;
- }
+ const lortensor &o = static_cast<const lortensor &>(other);
+
+ if (type!=o.type) {
+ // different type
+ return type < o.type ? -1 : 1;
+ }
+
+ if (type == lortensor_symbolic) {
+ // symbolic, compare serials
+ if (serial != o.serial) {
+ return serial < o.serial ? -1 : 1;
}
- return indexed::compare_same_type(other);
}
- return type < o->type ? -1 : 1;
+
+ return inherited::compare_same_type(other);
}
bool lortensor::is_equal_same_type(const basic & other) const
{
GINAC_ASSERT(is_of_type(other,lortensor));
- const lortensor *o=static_cast<const lortensor *> (&other);
- if (type!=o->type) return false;
- if (type==lortensor_rankn) {
- if (serial!=o->serial) return false;
- }
- return indexed::is_equal_same_type(other);
+ const lortensor &o = static_cast<const lortensor &>(other);
+
+ if (type != o.type) return false;
+ if (type == lortensor_symbolic && serial != o.serial) return false;
+ return inherited::is_equal_same_type(other);
}
unsigned lortensor::return_type(void) const
// protected
-void lortensor::setname(const std::string & n)
-{
- name = n;
-}
-
+/** Check whether all indices are of class lorentzidx or a subclass. This
+ * function is used internally to make sure that all constructed Lorentz
+ * tensors really carry Lorentz indices and not some other classes. */
bool lortensor::all_of_type_lorentzidx(void) const
{
for (exvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++ cit) {
- if (!is_ex_of_type(*cit,lorentzidx)) {
- return false;
- }
+ if (!is_ex_of_type(*cit,lorentzidx)) return false;
}
return true;
}
// friend functions
//////////
+/** Construct an object representing the metric tensor g. The indices must
+ * be of class lorentzidx.
+ *
+ * @param mu First index
+ * @param nu Second index
+ * @return newly constructed object */
lortensor lortensor_g(const ex & mu, const ex & nu)
{
return lortensor(lortensor::lortensor_g,"",mu,nu);
}
+/** Construct an object representing the unity matrix delta. The indices
+ * must be of class lorentzidx.
+ *
+ * @param mu First index
+ * @param nu Second index
+ * @return newly constructed object */
+lortensor lortensor_delta(const ex & mu, const ex & nu)
+{
+ return lortensor(lortensor::lortensor_delta,"",mu,nu);
+}
+
+/** Construct an object representing the four-dimensional totally
+ * antisymmetric tensor epsilon. The indices must be of class lorentzidx.
+ *
+ * @param mu First index
+ * @param nu Second index
+ * @param rho Third index
+ * @param sigma Fourth index
+ * @return newly constructed object */
lortensor lortensor_epsilon(const ex & mu, const ex & nu, const ex & rho, const ex & sigma)
{
return lortensor(lortensor::lortensor_epsilon,"",mu,nu,rho,sigma);
}
-lortensor lortensor_rank1(const std::string & n, const ex & mu)
+/** Construct an object representing a symbolic Lorentz vector. The index
+ * must be of class lorentzidx.
+ *
+ * @param n Symbolic name
+ * @param mu Index
+ * @return newly constructed object */
+lortensor lortensor_vector(const std::string & n, const ex & mu)
{
- return lortensor(lortensor::lortensor_rank1,n,mu);
+ return lortensor(lortensor::lortensor_symbolic,n,mu);
}
-lortensor lortensor_rank2(const std::string & n, const ex & mu, const ex & nu)
+/** Construct an object representing a symbolic Lorentz tensor of arbitrary
+ * rank. The indices must be of class lorentzidx.
+ *
+ * @param n Symbolic name
+ * @param iv Vector of indices
+ * @return newly constructed object */
+lortensor lortensor_symbolic(const std::string & n, const exvector & iv)
{
- return lortensor(lortensor::lortensor_rank2,n,mu,nu);
+ return lortensor(lortensor::lortensor_symbolic,n,iv);
}
ex simplify_lortensor_mul(const ex & m)
return m;
}
+/** Perform some simplifications on an expression containing Lorentz tensors. */
ex simplify_lortensor(const ex & e)
{
// all simplification is done on expanded objects
return sum;
}
- // simplification of commutative product=commutative product of simplifications
+ // simplification of (commutative) product
if (is_ex_exactly_of_type(e_expanded,mul)) {
return simplify_lortensor_mul(e);
}
return e_expanded;
}
-ex Dim(void)
-{
- static symbol * d=new symbol("dim");
- return *d;
-}
-
//////////
// global constants
//////////
namespace GiNaC {
#endif // ndef NO_NAMESPACE_GINAC
-/** Base class for lortensor object */
+
+/** This class holds an object carrying Lorentz indices (of class
+ * lorentzidx). It can represent a general (symbolic) tensor of type
+ * (p,q), or one of the constant tensors g (the metric), delta (unity
+ * matrix) or epsilon (4-dimensional totally antisymmetric tensor). */
class lortensor : public indexed
{
+ GINAC_DECLARE_REGISTERED_CLASS(lortensor, indexed)
+
+// friends
+
friend lortensor lortensor_g(const ex & mu, const ex & nu);
- // friend lortensor lortensor_delta(const ex & mu, const ex & nu);
+ friend lortensor lortensor_delta(const ex & mu, const ex & nu);
friend lortensor lortensor_epsilon(const ex & mu, const ex & nu,
const ex & rho, const ex & sigma);
- // friend lortensor lortensor_rankn(const string & n, const exvector & iv);
- friend lortensor lortensor_rank1(const std::string & n, const ex & mu);
- friend lortensor lortensor_rank2(const std::string & n, const ex & mu, const ex & nu);
+ friend lortensor lortensor_vector(const string & n, const ex & mu);
+ friend lortensor lortensor_symbolic(const string & name, const exvector & iv);
+
friend ex simplify_lortensor_mul(const ex & m);
friend ex simplify_lortensor(const ex & e);
- // types
+// types
+
public:
typedef enum {
- invalid,
- lortensor_g,
- lortensor_rankn,
- lortensor_rank1,
- lortensor_rank2,
- // lortensor_delta,
- lortensor_epsilon
+ invalid, /**< not properly constructed */
+ lortensor_g, /**< metric tensor */
+ lortensor_delta, /**< unity matrix */
+ lortensor_epsilon, /**< four-dimensional totally antisymmetric tensor */
+ lortensor_symbolic /**< general symbolic Lorentz tensor */
} lortensor_types;
- // member functions
+// member functions
// default constructor, destructor, copy constructor assignment operator and helpers
public:
lortensor(lortensor_types const lt, const std::string & n, const exvector & iv);
lortensor(lortensor_types const lt, const std::string & n, unsigned s, const exvector & iv);
lortensor(lortensor_types const lt, const std::string & n, unsigned s, exvector * ivp);
-
+
//functions overriding virtual functions from base classes
public:
basic * duplicate() const;
void printraw(std::ostream & os) const;
void printtree(std::ostream & os, unsigned indent) const;
void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
bool info(unsigned inf) const;
ex eval(int level=0) const;
protected:
//non virtual functions in this class
public:
- void setname(const std::string & n);
+ void setname(const std::string & n) {name = n;}
std::string getname(void) const {return name;}
protected:
bool all_of_type_lorentzidx(void) const;
//member variables
protected:
- lortensor_types type;
- std::string name;
- unsigned serial;
+ lortensor_types type; /**< Type of object */
+ std::string name; /**< Name of symbolic tensor */
+ unsigned serial; /**< Unique serial number for comparing symbolic tensors */
private:
static unsigned next_serial;
};
}
lortensor lortensor_g(const ex & mu, const ex & nu);
+lortensor lortensor_delta(const ex & mu, const ex & nu);
+lortensor lortensor_epsilon(const ex & mu, const ex & nu,
+ const ex & rho, const ex & sigma);
+lortensor lortensor_vector(const string & n, const ex & mu);
+lortensor lortensor_symbolic(const string & name, const exvector & iv);
+
ex simplify_lortensor_mul(const ex & m);
ex simplify_lortensor(const ex & e);
-ex Dim(void);
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#include "simp_lor.h"
#include "ex.h"
#include "mul.h"
-#include "symbol.h"
#include "debugmsg.h"
#include "utils.h"
return e_expanded;
}
-//ex Dim(void) // now in lortensor.cpp
-//{
-// static symbol * d=new symbol("dim");
-// return *d;
-//}
-
//////////
// helper classes
//////////
public:
bool operator()(const spmapkey & lh, const spmapkey & rh) const
{
- /*
- cerr << "spmapkey_is_less" << endl;
- cerr << "lh=((" << lh.first.first
- << "," << lh.first.second << "),";
- lh.second.printraw(cerr);
- cerr << ")" << endl;
-
- cerr << "rh=((" << rh.first.first
- << "," << rh.first.second << "),";
- rh.second.printraw(cerr);
- cerr << ")" << endl;
- */
bool res = lh.first<rh.first
|| (!(rh.first<lh.first) && lh.second.compare(rh.second)<0);
- // cout << "result=" << res << endl;
return res;
}
};
simp_lor lor_vec(const std::string & n, const ex & mu);
ex simplify_simp_lor_mul(const ex & m, const scalar_products & sp);
ex simplify_simp_lor(const ex & e, const scalar_products & sp=scalar_products());
-ex Dim(void);
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
return 0;
}
+/** Append one exvector to another */
+void append_exvector_to_exvector(exvector & dest, const exvector & source)
+{
+ dest.reserve(dest.size() + source.size());
+ dest.insert(dest.end(), source.begin(), source.end());
+}
+
//////////
// `construct on first use' chest of numbers
//////////
return sigma;
}
+void append_exvector_to_exvector(exvector & dest, const exvector & source);
+
// Collection of `construct on first use' wrappers for safely avoiding
// internal object replication without running into the `static
// initialization order fiasco'. This chest of numbers helps speed up