40 template<
class tensor_type>
42 tensorObjectReadOnly(_other.tensorObjectReadOnly),
43 indices(std::move(_other.indices))
47 template<
class tensor_type>
49 : tensorObjectReadOnly(_tensorObjectReadOnly), indices(
std::move(_indices)) { }
53 template<
class tensor_type>
59 template<
class tensor_type>
61 REQUIRE(degree() == 0,
"cannot cast tensors of degree > 0 to value_t. did you mean frob_norm() or similar?");
62 return (*tensorObjectReadOnly)[0];
65 template<
class tensor_type>
67 return _otherTensor == tensorObjectReadOnly;
70 template<
class tensor_type>
72 return tensorObjectReadOnly->
degree();
75 template<
class tensor_type>
77 assign_indices(degree());
80 template<
class tensor_type>
82 if(!indicesAssigned) {
83 size_t dimensionCount = 0;
84 for(
size_t i = 0; i < indices.size(); ++i) {
85 Index& idx = indices[i];
90 dimensionCount += idx.
span;
95 for(
size_t j = 0; j < i; ++j) {
96 if(indices[j] == idx) {
97 REQUIRE(indices[j].open(),
"An index must not appere more than twice!");
98 indices[j].open(
false);
104 if(open) { idx.
open(
true); }
109 REQUIRE(dimensionCount >= _degree,
"Order determined by Indices is to small. Order according to the indices " << dimensionCount <<
", according to the tensor " << _degree);
110 REQUIRE(dimensionCount <= _degree,
"Order determined by Indices is to large. Order according to the indices " << dimensionCount <<
", according to the tensor " << _degree);
112 misc::erase(indices, [](
const Index& _idx) {
return _idx.
span == 0; });
113 indicesAssigned =
true;
117 template<
class tensor_type>
121 size_t dimensionCount = 0;
122 for(
size_t i = 0; i < indices.size(); ++i) {
123 Index& idx = indices[i];
126 REQUIRE(dimensionCount+idx.
span <= tensorObjectReadOnly->dimensions.size(),
"Order determined by Indices is to large: " << dimensionCount+idx.
span <<
" > " << tensorObjectReadOnly->dimensions.size());
128 for(
size_t j = 0; j < idx.
span; ++j) {
133 REQUIRE(dimensionCount >= degree(),
"Order determined by Indices is to small. Order according to the indices " << dimensionCount <<
", according to the tensor " << degree());
134 REQUIRE(dimensionCount <= degree(),
"Order determined by Indices is to large. Order according to the indices " << dimensionCount <<
", according to the tensor " << degree());
138 template<
class tensor_type>
140 std::vector<size_t> evalDimensions;
141 evalDimensions.reserve(_indexOrder.size());
145 size_t trueOrder = 0;
146 for(
const Index& idx : indices) {
147 if(idx.open()) {trueOrder += idx.span; }
151 for(
const Index& idx : _indexOrder) {
152 if(idx.actual_span(trueOrder) == 0) {
continue; }
154 REQUIRE(misc::count(indices, idx) == 1,
"All indices of evaluation target must appear exactly once. Here " << misc::count(indices, idx) <<
" " << indices <<
" " << _indexOrder);
157 size_t indexPos = 0, dimCount = 0;
158 while(indices[indexPos] != idx) {
159 dimCount += indices[indexPos++].span;
162 REQUIRE(indices[indexPos].open(),
"Index appearing on the LHS of assignment must be open on RHS");
163 REQUIRE(dimCount+indices[indexPos].span <= tensorObjectReadOnly->dimensions.size(),
"Order determined by Indices is to large. Tensor has " << tensorObjectReadOnly->dimensions.size() <<
" indices at least " << dimCount+indices[indexPos].span);
166 for(
size_t i = 0; i < indices[indexPos].span; ++i) {
167 evalDimensions.emplace_back(tensorObjectReadOnly->dimensions[dimCount+i]);
170 return evalDimensions;
181 template<
class tensor_type>
192 template<
class tensor_type>
194 return operator*(_factor, std::move(_tensor));
201 template<
class tensor_type>
227 return operator+(std::move(_rhs), std::move(_lhs));
250 return (-1.0)*
operator-(std::move(_rhs), std::move(_lhs));
260 std::unique_ptr<IndexedTensorMoveable<TensorNetwork>> result;
261 if(!_lhs.tensorObjectReadOnly->specialized_sum(result, std::move(_lhs), std::move(_rhs))
262 && !_rhs.tensorObjectReadOnly->specialized_sum(result, std::move(_rhs), std::move(_lhs))) {
265 return std::move(*result);
277 return std::move(_lhs)+(-1*std::move(_rhs));
292 if(!_lhs.tensorObjectReadOnly->specialized_contraction(result, std::move(_lhs), std::move(_rhs)) && !_rhs.tensorObjectReadOnly->specialized_contraction(result, std::move(_rhs), std::move(_lhs))) {
293 _lhs.assign_indices();
294 result->tensorObject =
new TensorNetwork(*_lhs.tensorObjectReadOnly);
295 result->tensorObjectReadOnly = result->tensorObject;
296 result->indices = _lhs.indices;
297 result->deleteTensorObject =
true;
298 TensorNetwork::add_network_to_network(std::move(*result), std::move(_rhs));
300 return std::move(*result);
306 if(!_lhs.tensorObjectReadOnly->specialized_contraction(result, std::move(_lhs), std::move(_rhs)) && !_rhs.tensorObjectReadOnly->specialized_contraction(result, std::move(_rhs), std::move(_lhs))) {
307 _lhs.assign_indices();
308 result->tensorObject = _lhs.tensorObject;
309 result->tensorObjectReadOnly = _lhs.tensorObjectReadOnly;
310 result->indices = _lhs.indices;
311 result->deleteTensorObject =
true;
312 _lhs.deleteTensorObject =
false;
313 TensorNetwork::add_network_to_network(std::move(*result), std::move(_rhs));
315 return std::move(*result);
319 return operator*(std::move(_rhs), std::move(_lhs));
329 template<
class tensor_type>
343 for(
const Index& idx : _indices) {
344 INTERNAL_CHECK(idx.flags[Index::Flag::ASSINGED],
"Internal Error");
345 if(!idx.fixed() && misc::count(_indices, idx) != 2) { degree += idx.span; }
Header file for CHECK and REQUIRE macros.
void indexed_plus_equal(IndexedTensorReadOnly< tensor_type > &&_rhs)
Tensor add_assignment with indices.
Internal representation of an read and write and moveable indexed Tensor or TensorNetwork.
Header file for the Index class.
Header file for the IndexedTensorReadOnly class.
Header file for the IndexedTensorMoveable class.
Header file for the standard contaienr support functions.
IndexedTensorMoveable< Tensor > operator+(IndexedTensorReadOnly< Tensor > &&_lhs, IndexedTensorReadOnly< Tensor > &&_rhs)
Very general class used to represent arbitary tensor networks.
bool open() const
Checks whether the index is open.
Internal representation of an readable indexed Tensor or TensorNetwork.
The main namespace of xerus.
Class that handles simple (non-decomposed) tensors in a dense or sparse representation.
void indexed_minus_equal(IndexedTensorReadOnly< tensor_type > &&_rhs)
Tensor subtract_assignment with indices.
void perform_traces()
: Performes all traces induces by the current indices and therby also evaluates all fixed indices...
template value_t frob_norm< Tensor >(const IndexedTensorReadOnly< Tensor > &_idxTensor)
Header file for the Tensor class.
double one_norm(const double *const _x, const size_t _n)
: Computes the one norm =||x||_1
tensor_type * tensorObject
Non-const pointer to the tensor object.
std::bitset< NUM_FLAGS > flags
Bitset of all possible flags the index may possess.
size_t get_eval_degree(const std::vector< Index > &_indices)
void set_span(const size_t _degree)
Returns the span this index actually represents in a tensor of given order.
size_t assingedDimension
The product of the external dimensions this index correstponds to. Only set for assinged indices...
IndexedTensorMoveable< Tensor > operator-(IndexedTensorReadOnly< Tensor > &&_lhs, IndexedTensorReadOnly< Tensor > &&_rhs)
size_t degree() const
Returns the degree of the associated tensorObejct.
Header file for comfort functions and macros that should not be exported in the library.
value_t frob_norm(const IndexedTensorReadOnly< tensor_type > &_idxTensor)
Returns the frobenious norm of the associated tensorObejct.
template IndexedTensorMoveable< TensorNetwork > operator/(IndexedTensorReadOnly< TensorNetwork > &&_tensor, const value_t _divisor)
double value_t
The type of values to be used by xerus.
template IndexedTensorMoveable< TensorNetwork > operator*(IndexedTensorReadOnly< TensorNetwork > &&_tensor, const value_t _factor)
Class used to represent indices that can be used to write tensor calculations in index notation...
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 the TensorNetwork class.
const tensor_type * tensorObjectReadOnly
Pointer to the associated Tensor/TensorNetwork object.
template value_t frob_norm< TensorNetwork >(const IndexedTensorReadOnly< TensorNetwork > &_idxTensor)
IndexedTensorReadOnly()=delete
There is no usefull default constructor.