X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Ftensor.cpp;h=cf0204b56319522260d5143dc3b1aea28778c270;hp=9d5feb63c4051dbe5c9d65ee3a0398fd5ada7c96;hb=745d46b8492878030cc0decd1cb9bf2de2de03ff;hpb=6d383491ac7fdc612ebc15778a2db01dbc5660d6 diff --git a/ginac/tensor.cpp b/ginac/tensor.cpp index 9d5feb63..cf0204b5 100644 --- a/ginac/tensor.cpp +++ b/ginac/tensor.cpp @@ -21,6 +21,7 @@ */ #include +#include #include "tensor.h" #include "idx.h" @@ -43,6 +44,13 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(tensepsilon, tensor) // default constructor, destructor, copy constructor assignment operator and helpers ////////// +#define DEFAULT_DESTROY(classname) \ +void classname::destroy(bool call_parent) \ +{ \ + if (call_parent) \ + inherited::destroy(call_parent); \ +} + #define DEFAULT_CTORS(classname) \ classname::classname() : inherited(TINFO_##classname) \ { \ @@ -52,11 +60,7 @@ void classname::copy(const classname & other) \ { \ inherited::copy(other); \ } \ -void classname::destroy(bool call_parent) \ -{ \ - if (call_parent) \ - inherited::destroy(call_parent); \ -} +DEFAULT_DESTROY(classname) tensor::tensor(unsigned ti) : inherited(ti) { @@ -66,7 +70,8 @@ tensor::tensor(unsigned ti) : inherited(ti) DEFAULT_CTORS(tensor) DEFAULT_CTORS(tensdelta) DEFAULT_CTORS(tensmetric) -DEFAULT_CTORS(tensepsilon) +DEFAULT_DESTROY(minkmetric) +DEFAULT_DESTROY(tensepsilon) minkmetric::minkmetric() : pos_sig(false) { @@ -86,25 +91,41 @@ void minkmetric::copy(const minkmetric & other) pos_sig = other.pos_sig; } -void minkmetric::destroy(bool call_parent) +tensepsilon::tensepsilon() : minkowski(false), pos_sig(false) +{ + debugmsg("tensepsilon default constructor", LOGLEVEL_CONSTRUCT); + tinfo_key = TINFO_tensepsilon; +} + +tensepsilon::tensepsilon(bool mink, bool ps) : minkowski(mink), pos_sig(ps) { - if (call_parent) - inherited::destroy(call_parent); + debugmsg("tensepsilon constructor from bool,bool", LOGLEVEL_CONSTRUCT); + tinfo_key = TINFO_tensepsilon; +} + +void tensepsilon::copy(const tensepsilon & other) +{ + inherited::copy(other); + minkowski = other.minkowski; + pos_sig = other.pos_sig; } ////////// // archiving ////////// +#define DEFAULT_UNARCHIVE(classname) \ +ex classname::unarchive(const archive_node &n, const lst &sym_lst) \ +{ \ + return (new classname(n, sym_lst))->setflag(status_flags::dynallocated); \ +} + #define DEFAULT_ARCHIVING(classname) \ classname::classname(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst) \ { \ debugmsg(#classname " constructor from archive_node", LOGLEVEL_CONSTRUCT); \ } \ -ex classname::unarchive(const archive_node &n, const lst &sym_lst) \ -{ \ - return (new classname(n, sym_lst))->setflag(status_flags::dynallocated); \ -} \ +DEFAULT_UNARCHIVE(classname) \ void classname::archive(archive_node &n) const \ { \ inherited::archive(n); \ @@ -113,7 +134,8 @@ void classname::archive(archive_node &n) const \ DEFAULT_ARCHIVING(tensor) DEFAULT_ARCHIVING(tensdelta) DEFAULT_ARCHIVING(tensmetric) -DEFAULT_ARCHIVING(tensepsilon) +DEFAULT_UNARCHIVE(minkmetric) +DEFAULT_UNARCHIVE(tensepsilon) minkmetric::minkmetric(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst) { @@ -121,14 +143,23 @@ minkmetric::minkmetric(const archive_node &n, const lst &sym_lst) : inherited(n, n.find_bool("pos_sig", pos_sig); } -ex minkmetric::unarchive(const archive_node &n, const lst &sym_lst) +void minkmetric::archive(archive_node &n) const { - return (new minkmetric(n, sym_lst))->setflag(status_flags::dynallocated); + inherited::archive(n); + n.add_bool("pos_sig", pos_sig); } -void minkmetric::archive(archive_node &n) const +tensepsilon::tensepsilon(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst) +{ + debugmsg("tensepsilon constructor from archive_node", LOGLEVEL_CONSTRUCT); + n.find_bool("minkowski", minkowski); + n.find_bool("pos_sig", pos_sig); +} + +void tensepsilon::archive(archive_node &n) const { inherited::archive(n); + n.add_bool("minkowski", minkowski); n.add_bool("pos_sig", pos_sig); } @@ -146,7 +177,6 @@ int classname::compare_same_type(const basic & other) const \ DEFAULT_COMPARE(tensor) DEFAULT_COMPARE(tensdelta) DEFAULT_COMPARE(tensmetric) -DEFAULT_COMPARE(tensepsilon) int minkmetric::compare_same_type(const basic & other) const { @@ -159,6 +189,19 @@ int minkmetric::compare_same_type(const basic & other) const return inherited::compare_same_type(other); } +int tensepsilon::compare_same_type(const basic & other) const +{ + GINAC_ASSERT(is_of_type(other, tensepsilon)); + const tensepsilon &o = static_cast(other); + + if (minkowski != o.minkowski) + return minkowski ? -1 : 1; + else if (pos_sig != o.pos_sig) + return pos_sig ? -1 : 1; + else + return inherited::compare_same_type(other); +} + void tensdelta::print(std::ostream & os, unsigned upper_precedence) const { debugmsg("tensdelta print",LOGLEVEL_PRINT); @@ -249,6 +292,49 @@ ex minkmetric::eval_indexed(const basic & i) const return inherited::eval_indexed(i); } +/** Automatic symbolic evaluation of an indexed epsilon tensor. */ +ex tensepsilon::eval_indexed(const basic & i) const +{ + GINAC_ASSERT(is_of_type(i, indexed)); + GINAC_ASSERT(i.nops() > 1); + GINAC_ASSERT(is_ex_of_type(i.op(0), tensepsilon)); + + // Convolutions are zero + if (static_cast(i).get_dummy_indices().size() != 0) + return _ex0(); + + // Numeric evaluation + if (static_cast(i).all_index_values_are(info_flags::nonnegint)) { + + // Get sign of index permutation (the indices should already be in + // a canonic order but we can't assume what exactly that order is) + vector v; + v.reserve(i.nops() - 1); + for (unsigned j=1; j