33 std::atomic<uint64> Index::idThreadInitCounter(0);
34 thread_local
uint64 Index::idCounter = (idThreadInitCounter++)<<54;
41 REQUIRE(_i >= 0,
"Negative valueId= " <<_i<<
" given");
45 flags[Flag::FIXED] =
true;
49 REQUIRE(_i >= 0,
"Negative valueId= " <<_i<<
" given");
53 flags[Flag::FIXED] =
true;
65 REQUIRE(!
flags[Flag::FIXED] ||
span == 1,
"Fixed indices must have span one.");
66 if(
flags[Flag::INVERSE_SPAN]) {
67 REQUIRE(!
flags[Flag::FIXED],
"Fixed indices must not have inverse span.");
68 REQUIRE(
span <= _degree,
"Index with inverse span would have negative actual span. Tensor degree: " << _degree <<
", inverse span " <<
span);
71 }
else if(
flags[Flag::FRACTIONAL_SPAN] ) {
72 REQUIRE(!
flags[Flag::FIXED],
"Fixed indices must not have fractional span.");
73 REQUIRE(_degree%
span == 0,
"Fractional span must divide the tensor degree. Here tensor degree = " << _degree <<
", span = " <<
span);
81 if(
flags[Flag::INVERSE_SPAN]) {
82 REQUIRE(!
flags[Flag::FIXED],
"Fixed indices must not have inverse span.");
83 REQUIRE(
span <= _degree,
"Index with inverse span would have negative actual span. Tensor degree: " << _degree <<
", inverse span " <<
span);
86 if(
flags[Flag::FRACTIONAL_SPAN] ) {
87 REQUIRE(!
flags[Flag::FIXED],
"Fixed indices must not have fractional span.");
88 REQUIRE(_degree%
span == 0,
"Fractional span must divide the tensor degree. Here tensor degree = " << _degree <<
", span = " <<
span);
91 REQUIRE(!
flags[Flag::FIXED] ||
span == 1,
"Fixed indices must have span one.");
97 #ifndef XERUS_DISABLE_RUNTIME_CHECKS 98 if(
flags[Index::Flag::FIXED]) {
99 REQUIRE(!
flags[Flag::INVERSE_SPAN],
"Fixed indices must not have inverse span.");
100 REQUIRE(!
flags[Flag::FRACTIONAL_SPAN],
"Fixed indices must not have fractional span.");
101 REQUIRE(
span == 1,
"Fixed indices must have span one.");
106 return flags[Index::Flag::FIXED];
112 REQUIRE(
flags[Index::Flag::ASSINGED],
"Check for index openness only allowed if the index is assinged.");
113 return flags[Index::Flag::OPEN];
118 flags[Flag::OPEN] = _open;
124 REQUIRE(
flags[Index::Flag::ASSINGED],
"Check for index dimension only allowed if the index is assinged.");
130 REQUIRE(
flags[Index::Flag::FIXED],
"fixed_position() must only be called for fixed indices.");
136 REQUIRE(
flags.none(),
"Cannot apply ^ operator to an index that has any flag set.");
142 REQUIRE(
flags.none(),
"Cannot apply & operator to an index that has any flag set.");
148 REQUIRE(
flags.none(),
"Cannot apply & operator to an index that has any flag set.");
154 for(
const Index& idx : _indices) {
155 if(!idx.open()) {
return false; }
176 _out <<
"index#" << _idx.
valueId << (_idx.
flags[Index::Flag::INVERSE_SPAN] ?
"&" : (_idx.
flags[Index::Flag::FRACTIONAL_SPAN] ?
"/" :
"^")) << _idx.
span;
Header file for CHECK and REQUIRE macros.
static bool all_open(const std::vector< Index > &_indices)
: Checks whether all indices in _indices are open. This is naturally only usefull for assinged indice...
Header file for the Index class.
size_t actual_span(const size_t _degree) const
Returns the span this index actually represents in a tensor of given order.
Flag
Enum defining the possible flags an Index my possess.
bool open() const
Checks whether the index is open.
The main namespace of xerus.
Index operator^(const size_t _span) const
: Allow the creation of Indices covering more than one dimension using the power operator. E.g. A(i^2) = B(i^2) + C(i^2), defines A as the entriewise sum of the matrices B and C.
size_t fixed_position() const
: Returns the fixed position of a fixed index.
std::ostream & operator<<(std::ostream &_out, const xerus::Index &_idx)
Allows to pretty print indices, giving the valueId and span.
bool operator==(const Index &_a, const Index &_b)
Two Indices are equal if their valueId coincides. Fixed indices are never equal.
std::bitset< NUM_FLAGS > flags
Bitset of all possible flags the index may possess.
void set_span(const size_t _degree)
Returns the span this index actually represents in a tensor of given order.
uint64 valueId
Unqiue ID of the index. In case the fixed flag is set, this is the fixed position.
size_t assingedDimension
The product of the external dimensions this index correstponds to. Only set for assinged indices...
bool operator<(const Index &_a, const Index &_b)
The Comparision operator is needed for indices to be orderable in std::set, the valueId is used...
Header file for comfort functions and macros that should not be exported in the library.
Index operator/(const size_t _span) const
: Allow the creation of Indices covering an x-th fraction of the indices. E.g. A(i&0) = B(i/2...
bool operator!=(const Index &_a, const Index &_b)
Two Indices are equal if their valueId coincides. Fixed indices are never equal.
Class used to represent indices that can be used to write tensor calculations in index notation...
Index operator &(const size_t _span) const
: Allow the creation of Indices covering all but x dimensions using the and operator. E.g. A() = B(i&0) * C(i&0), defines A as the full contraction between B and C, indifferent of the actual degree of B and C.
size_t dimension() const
Returns the (mult)Dimension assinged to this index.
size_t span
The span states how many dimensions are covered by the index.
bool fixed() const
Checks whether the Index represents a fixed number.
Header file for global shorthand notations of elementary integer types and attribute lists...
Index()
Empty constructor that creates a new Index with new ID. Use this to create indices.