#include "idx.h"
#include "indexed.h"
#include "relational.h"
+#include "lst.h"
#include "numeric.h"
+#include "print.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
// 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) \
-{ \
- debugmsg(#classname " default constructor", LOGLEVEL_CONSTRUCT); \
-} \
-void classname::copy(const classname & other) \
-{ \
- inherited::copy(other); \
-} \
-DEFAULT_DESTROY(classname)
-
tensor::tensor(unsigned ti) : inherited(ti)
{
debugmsg("tensor constructor from unsigned", LOGLEVEL_CONSTRUCT); \
// 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); \
-} \
-DEFAULT_UNARCHIVE(classname) \
-void classname::archive(archive_node &n) const \
-{ \
- inherited::archive(n); \
-}
-
DEFAULT_ARCHIVING(tensor)
DEFAULT_ARCHIVING(tensdelta)
DEFAULT_ARCHIVING(tensmetric)
// functions overriding virtual functions from bases classes
//////////
-#define DEFAULT_COMPARE(classname) \
-int classname::compare_same_type(const basic & other) const \
-{ \
- /* by default, two tensors of the same class are always identical */ \
- return 0; \
-}
-
DEFAULT_COMPARE(tensor)
DEFAULT_COMPARE(tensdelta)
DEFAULT_COMPARE(tensmetric)
return inherited::compare_same_type(other);
}
-void tensdelta::print(std::ostream & os, unsigned upper_precedence) const
-{
- debugmsg("tensdelta print",LOGLEVEL_PRINT);
- os << "delta";
-}
-
-void tensmetric::print(std::ostream & os, unsigned upper_precedence) const
-{
- debugmsg("tensmetric print",LOGLEVEL_PRINT);
- os << "g";
-}
-
-void minkmetric::print(std::ostream & os, unsigned upper_precedence) const
-{
- debugmsg("minkmetric print",LOGLEVEL_PRINT);
- os << "eta";
-}
-
-void tensepsilon::print(std::ostream & os, unsigned upper_precedence) const
-{
- debugmsg("tensepsilon print",LOGLEVEL_PRINT);
- os << "eps";
-}
+DEFAULT_PRINT(tensdelta, "delta")
+DEFAULT_PRINT(tensmetric, "g")
+DEFAULT_PRINT(minkmetric, "eta")
+DEFAULT_PRINT(tensepsilon, "eps")
/** Automatic symbolic evaluation of an indexed delta tensor. */
ex tensdelta::eval_indexed(const basic & i) const
if (is_dummy_pair(i1, i2))
return i1.get_dim();
+ // Numeric evaluation
+ if (static_cast<const indexed &>(i).all_index_values_are(info_flags::integer)) {
+ int n1 = ex_to_numeric(i1.get_value()).to_int(), n2 = ex_to_numeric(i2.get_value()).to_int();
+ if (n1 == n2)
+ return _ex1();
+ else
+ return _ex0();
+ }
+
// No further simplifications
return i.hold();
}
// If contracting with the delta tensor, let the delta do it
// (don't raise/lower delta indices)
- if (is_ex_exactly_of_type(other->op(0), tensdelta))
+ if (is_ex_of_type(other->op(0), tensdelta))
return false;
// Try to contract first index
return indexed(tensepsilon(true, pos_sig), indexed::antisymmetric, i1, i2, i3, i4);
}
+ex eps0123(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig)
+{
+ if (!is_ex_of_type(i1, varidx) || !is_ex_of_type(i2, varidx) || !is_ex_of_type(i3, varidx) || !is_ex_of_type(i4, varidx))
+ throw(std::invalid_argument("indices of epsilon tensor must be of type varidx"));
+
+ ex dim = ex_to_idx(i1).get_dim();
+ if (dim.is_equal(4))
+ return lorentz_eps(i1, i2, i3, i4, pos_sig);
+ else
+ return indexed(tensepsilon(true, pos_sig), indexed::antisymmetric, i1, i2, i3, i4);
+}
+
} // namespace GiNaC