]> www.ginac.de Git - ginac.git/blobdiff - ginac/lortensor.cpp
- g~mu_mu contraction returns Dim for general Lorentz indices and Dim-dimP
[ginac.git] / ginac / lortensor.cpp
index 6677360cf7e0242ef1af6cbffa38e4ec4f745d43..e8f4f87312d9070d5e2b826affbeddb40f60bf37 100644 (file)
@@ -1,7 +1,6 @@
 /** @file lortensor.cpp
  *
- *  Implementation of GiNaCĀ“s lortensor objects.
- *  No real implementation yet, do be done.      */
+ *  Implementation of GiNaC's Lorentz tensors. */
 
 /*
  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
 #include "add.h"
 #include "mul.h"
 #include "debugmsg.h"
-#include "flags.h"
 #include "lst.h"
 #include "lortensor.h"
 #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()
-{
-       debugmsg("lortensor destructor",LOGLEVEL_DESTRUCT);
-       destroy(false);
-}
-
-lortensor::lortensor(const lortensor & other)
-{
-       debugmsg("lortensor copy constructor",LOGLEVEL_CONSTRUCT);
-       copy (other);
-}
-
-const lortensor & lortensor::operator=(const lortensor & other)
-{
-       debugmsg("lortensor operator=",LOGLEVEL_ASSIGNMENT);
-       if (this != & other) {
-               destroy(true);
-               copy(other);
-       }
-       return *this;
 }
 
 //protected
 
 void lortensor::copy(const lortensor & other)
 {
-       indexed::copy(other);
+       inherited::copy(other);
        type=other.type;
        name=other.name;
        serial=other.serial;
@@ -94,9 +71,7 @@ void lortensor::copy(const lortensor & other)
 
 void lortensor::destroy(bool call_parent)
 {
-       if (call_parent) {
-               indexed::destroy(call_parent);
-       }
+       if (call_parent) inherited::destroy(call_parent);
 }
 
 //////////
@@ -105,50 +80,94 @@ void lortensor::destroy(bool 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;
 }
 
@@ -166,24 +185,65 @@ lortensor::lortensor(lortensor_types const lt, const std::string & n, unsigned s
        tinfo_key=TINFO_lortensor;
 }
 
+
 //////////
-// functions overriding virtual functions from bases classes
+// archiving
 //////////
 
-//public
+/** 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;
+}
 
-basic * lortensor::duplicate() const
+/** Archive the object. */
+void lortensor::archive(archive_node &n) const
 {
-       debugmsg("lortensor duplicate",LOGLEVEL_DUPLICATE);
-       return new lortensor(*this);
+       inherited::archive(n);
+       n.add_unsigned("type", type);
+       if (type == lortensor_symbolic)
+               n.add_string("name", name);
 }
 
+
+//////////
+// functions overriding virtual functions from bases classes
+//////////
+
+//public
+
 void lortensor::printraw(std::ostream & os) const
 {
        debugmsg("lortensor printraw",LOGLEVEL_PRINT);
        os << "lortensor(type=" << (unsigned)type
           << ",indices=";
        printrawindices(os);
+       os << ",serial=" << serial;
        os << ",hash=" << hashvalue << ",flags=" << flags << ")";
 }
 
@@ -206,18 +266,15 @@ void lortensor::print(std::ostream & os, unsigned upper_precedence) const
        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";
@@ -226,15 +283,9 @@ void lortensor::print(std::ostream & os, unsigned upper_precedence) const
        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
@@ -270,7 +321,10 @@ ex lortensor::eval(int level) const
                                return _ex0();
                        }
                } else if (idx1.is_symbolic() && idx1.is_co_contra_pair(idx2)) {
-                       return Dim() - 2;
+                       if (idx1.is_orthogonal_only())
+                               return Dim() - idx1.get_dim_parallel_space();
+                       else
+                               return Dim();
                }
        }
        return this -> hold();
@@ -281,27 +335,31 @@ 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
@@ -330,17 +388,13 @@ ex lortensor::thisexprseq(exvector *vp) 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;
 }
@@ -365,24 +419,61 @@ unsigned lortensor::next_serial=0;
 // 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)
@@ -459,6 +550,7 @@ 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
@@ -473,7 +565,7 @@ ex simplify_lortensor(const ex & e)
                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);
        }
@@ -482,19 +574,6 @@ ex simplify_lortensor(const ex & e)
        return e_expanded;
 }
 
-ex Dim(void)
-{
-       static symbol * d=new symbol("dim");
-       return *d;
-}
-
-//////////
-// global constants
-//////////
-
-const lortensor some_lortensor;
-const std::type_info & typeid_lortensor = typeid(some_lortensor);
-
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
 #endif // ndef NO_NAMESPACE_GINAC