7#include <initializer_list>
17#define ADD_DEBUG_TENSOR(X, Y) \
19 for(unsigned i = 0; i < Tensor(X).size(); ++i) Y->emplace_back(std::string(#X) + Tensor::coordinates_to_string(Tensor(X).coords(i)), Tensor(X)[i]);
21#define ADD_DEBUG_TENSOR_NAMED(X, Y, Z) \
23 for(unsigned i = 0; i < X.size(); ++i) Y->emplace_back(Z + Tensor::coordinates_to_string(X.coords(i)), X[i]);
33 std::shared_ptr<int> m_ptr;
39 bool isUpper()
const {
return m_isUpper; };
44 uint64_t
ptr()
const {
return uint64_t(m_ptr.get()); }
46 struct Dim :
public std::vector<unsigned> {
47 Dim(
unsigned a) : std::vector<unsigned>({a}) {}
48 Dim(
unsigned a,
unsigned b) : std::vector<unsigned>({a, b}) {}
49 Dim(
unsigned a,
unsigned b,
unsigned c) : std::vector<unsigned>({a, b, c}) {}
50 Dim(
unsigned a,
unsigned b,
unsigned c,
unsigned d) : std::vector<unsigned>({a, b, c, d}) {}
54 explicit Tensor(
const std::vector<Expression> &elements);
58 template <
class TYPE>
Tensor(
const std::initializer_list<TYPE> &elements,
const std::vector<unsigned> &
dim) : m_dim(
dim) {
60 for(
auto &x : elements)
append(x);
63 template <
class TYPE>
Tensor(
const std::vector<TYPE> &elements,
const std::vector<unsigned> &
dim) : m_dim(
dim) {
65 for(
auto &x : elements)
append(x);
94 void st(
const bool simplify =
false);
103 int metricSgn(
const std::vector<unsigned> &coordinates)
const;
114 unsigned index(
const std::vector<unsigned> &_co)
const;
119 const std::vector<unsigned> &
dims()
const {
return m_dim; }
122 void print(
const bool &eval =
false)
const;
132 template <
class... ARGS>
static std::vector<unsigned>
dim(
const ARGS &...args) {
133 std::vector<unsigned> rt;
134 auto up = std::tuple<ARGS...>(args...);
135 for_each(up, [&rt](
const unsigned &f) { rt.emplace_back(f); });
140 std::vector<unsigned> m_dim;
141 std::vector<unsigned> m_symmetrisedCoordinates;
142 std::vector<unsigned> m_uniqueElements;
143 std::vector<Expression> m_elements;
165 std::vector<Tensor::Index> m_indices;
176 unsigned size()
const {
return m_tensor.size(); }
(Internal) class to aide in the resolution of the dependencies of expression trees.
Wrapper class for shared_ptrs to virtual expressions for use in conjunction with operators to build e...
Virtual base class for other expression tree components.
Index(bool isUpper=false)
bool operator!=(const Tensor::Index &other) const
bool operator==(const Tensor::Index &other) const
Index(const std::shared_ptr< int > &index, bool isUpper=false)
friend std::ostream & operator<<(std::ostream &out, const Index &index)
void resolve(ASTResolver &resolver) const override
Resolve the dependencies of a tree using an ASTResolver, which keeps track of parameters,...
std::string to_string(const ASTResolver *resolver) const override
Called to convert the Expression tree into source code.
complex_t operator()() const override
Evaluate the expression using the tree, will generally be very slow but ocassionally useful for debug...
TensorExpression(const Tensor &tensor)
Tensor(const Tensor::Dim &dim)
unsigned nElements() const
Expression get(const unsigned &co) const
const Expression & operator()(const unsigned &a, const unsigned &b) const
const std::vector< unsigned > coords(const unsigned &index) const
int metricSgn(const unsigned &index) const
void append(const real_t &value)
void append(const std::string &value)
std::string to_string(const ASTResolver *resolver=nullptr) const
Tensor(const std::vector< TYPE > &elements, const std::vector< unsigned > &dim)
void append(const Expression &expression)
unsigned symmetrisedIndex(const std::vector< unsigned > &_co) const
const Expression operator()(const unsigned &a) const
void append(const complex_t &value)
const std::vector< unsigned > & uniqueElements() const
Tensor(const std::vector< Expression > &elements)
Expression & operator()(const unsigned &a)
TensorProxy access to class members High level access is done via these commands, i....
void st(const bool simplify=false)
const Expression & operator[](const unsigned &i) const
Expression & operator[](const unsigned &i)
Low level access of elements, either by coordinates or by index ///.
void operator+=(const Tensor &rhs)
static std::vector< unsigned > index_to_coordinates(const unsigned &index, const std::vector< unsigned > &dim)
Expression & operator[](const std::vector< unsigned > &co)
Expression get(const std::vector< unsigned > &_co) const
const Expression & operator[](const std::vector< unsigned > &co) const
Tensor(const std::vector< unsigned > &dim)
TensorProxy operator()(const Tensor::Index &a, const Tensor::Index &b) const
TensorProxy operator()(const Tensor::Index &a, const Tensor::Index &b, const Tensor::Index &c) const
unsigned index(const std::vector< unsigned > &_co) const
Tensor(const std::initializer_list< TYPE > &elements, const std::vector< unsigned > &dim)
static unsigned coordinates_to_index(const std::vector< unsigned > &coords, const std::vector< unsigned > &dim)
void imposeSymmetry(std::vector< unsigned > indices)
void operator-=(const Tensor &rhs)
int metricSgn(const std::vector< unsigned > &coordinates) const
void print(const bool &eval=false) const
bool rankMatches(const Tensor &other)
const std::string dimString() const
TensorProxy operator()(const Tensor::Index &a, const Tensor::Index &b, const Tensor::Index &c, const Tensor::Index &d) const
TensorProxy operator()(const std::vector< Tensor::Index > &indices) const
Expression get(const unsigned &co)
void imposeSymmetry(unsigned indexA, unsigned indexB)
TensorProxy operator()(const Tensor::Index &a) const
static std::vector< unsigned > dim(const ARGS &...args)
Expression & operator()(const unsigned &a, const unsigned &b)
const std::vector< unsigned > & dims() const
static std::string coordinates_to_string(const std::vector< unsigned > &coordinates)
Utility class that wraps a tensor and a set of indices such that tensor operations can be performed.
const Tensor & tensor() const
TensorProxy reorder(const std::vector< Tensor::Index > &indices)
TensorProxy(const Tensor &tensor, const std::vector< Tensor::Index > &indices)
std::vector< Tensor::Index > indices() const
Complex< real_t > operator/(const Complex< real_t > &lhs, const R2_t &rhs)
Complex< real_t > operator*(const Complex< real_t > &lhs, const R2_t &rhs)
std::complex< real_t > complex_t
Expression dot(const Tensor &A, const Tensor &B)
std::ostream & operator<<(std::ostream &os, const CompiledExpressionBase &expression)
const Tensor LeviCivita(const unsigned &rank=4)
Complex< real_t > operator+(const Complex< real_t > &lhs, const R2_t &rhs)
Complex< real_t > operator-(const Complex< real_t > &lhs, const R2_t &rhs)
Tensor Identity(const unsigned &rank=4)
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Dim(unsigned a, unsigned b)
Dim(unsigned a, unsigned b, unsigned c, unsigned d)
Dim(unsigned a, unsigned b, unsigned c)