xerus
a general purpose tensor library
indexedTensorWritable.cpp
Go to the documentation of this file.
1 // Xerus - A General Purpose Tensor Library
2 // Copyright (C) 2014-2017 Benjamin Huber and Sebastian Wolf.
3 //
4 // Xerus is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as published
6 // by the Free Software Foundation, either version 3 of the License,
7 // or (at your option) any later version.
8 //
9 // Xerus is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with Xerus. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // For further information on Xerus visit https://libXerus.org
18 // or contact us at contact@libXerus.org.
19 
26 
28 #include <xerus/indexedTensor.h>
30 
31 #include <xerus/index.h>
32 #include <xerus/tensor.h>
33 #include <xerus/tensorNetwork.h>
34 #include <xerus/misc/internal.h>
35 
36 namespace xerus {
37  namespace internal {
38  template<class tensor_type>
39  IndexedTensorWritable<tensor_type>::IndexedTensorWritable(IndexedTensorWritable &&_other ) noexcept : IndexedTensorReadOnly<tensor_type>(std::move(_other)), tensorObject(_other.tensorObject), deleteTensorObject(_other.deleteTensorObject) {
40  // Take ownership
41  _other.deleteTensorObject = false;
42  }
43 
44  template<class tensor_type>
45  IndexedTensorWritable<tensor_type>::IndexedTensorWritable(tensor_type* const _tensorObject, const std::vector<Index>& _indices, const bool _takeOwnership) :
46  IndexedTensorReadOnly<tensor_type>(_tensorObject, _indices), tensorObject(_tensorObject), deleteTensorObject(_takeOwnership) {}
47 
48 
49  template<class tensor_type>
50  IndexedTensorWritable<tensor_type>::IndexedTensorWritable(tensor_type* const _tensorObject, std::vector<Index>&& _indices, const bool _takeOwnership) :
51  IndexedTensorReadOnly<tensor_type>(_tensorObject, std::move(_indices)), tensorObject(_tensorObject), deleteTensorObject(_takeOwnership) {}
52 
53  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Destructor - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
54  template<class tensor_type>
56  if(deleteTensorObject) {
57  delete this->tensorObject;
58  }
59  }
60 
61  /*- - - - - - - - - - - - - - - - - - - - - - - - - - Other - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
62  template<class tensor_type>
64  return deleteTensorObject;
65  }
66 
67  template<>
69  if(!_rhs.uses_tensor(tensorObject)) {
70  // If LHS and RHS object don't coincide we can directly evaluate
71  this->tensorObject->reset(_rhs.get_evaluated_dimensions(indices), Tensor::Initialisation::None);
72  evaluate(std::move(*this), std::move(_rhs));
73  } else {
74  // If the tensors in fact coincide we have to use a tmp object
75  IndexedTensorMoveable<Tensor> tmpTensor(std::move(_rhs));
77  evaluate(std::move(*this), std::move(tmpTensor));
78  }
79  }
80 
81  template<>
83  _rhs.tensorObjectReadOnly->require_valid_network();
84  IndexedTensorMoveable<TensorNetwork> cpy(std::move(_rhs));
85  TensorNetwork::link_traces_and_fix(std::move(cpy));
86 
87  std::set<size_t> all;
88  for (size_t i=0; i < cpy.tensorObject->nodes.size(); ++i) {
89  all.insert(i);
90  }
91 
92  const size_t res = cpy.tensorObject->contract(all);
93 
94  std::vector<Index> externalOrder;
95  for(size_t i = 0; i < cpy.tensorObject->nodes[res].neighbors.size(); ++i) { externalOrder.emplace_back(); }
96 
97  std::vector<Index> internalOrder;
98  for(const TensorNetwork::Link& link: cpy.tensorObject->nodes[res].neighbors) {
99  INTERNAL_CHECK(link.external, "Internal Error " << link.other << " " << link.indexPosition);
100  internalOrder.emplace_back(externalOrder[link.indexPosition]);
101  }
102 
104  std::vector<Index> outOrder;
105  for (const Index &idx : indices) {
106  REQUIRE(misc::contains(cpy.indices, idx), "Every index on the LHS must appear somewhere on the RHS, here: " << cpy.indices << ' ' << indices);
107  size_t spanSum = 0;
108  for (size_t j = 0; cpy.indices[j] != idx; ++j) {
109  INTERNAL_CHECK(j < cpy.indices.size()-1, "ie");
110  spanSum += cpy.indices[j].span;
111  }
112 
113  for (size_t i=0; i < idx.span; ++i) {
114  outOrder.push_back(externalOrder[spanSum+i]);
115  }
116  }
117 
118  (*tensorObject)(outOrder) = (*cpy.tensorObject->nodes[res].tensorObject)(internalOrder);
119  }
120 
121  template<>
123  tensorObject->specialized_evaluation(std::move(*this), IndexedTensorMoveable<TensorNetwork>(new TensorNetwork(*_rhs.tensorObjectReadOnly), _rhs.indices));
124  }
125 
126  template<>
128  tensorObject->specialized_evaluation(std::move(*this), std::move(_rhs));
129  }
130 
131  template<>
133  std::unique_ptr<Tensor> reorderedRhs(new Tensor(_rhs.tensorObjectReadOnly->representation));
134  (*reorderedRhs)(this->indices) = std::move(_rhs);
135  *this->tensorObject += *reorderedRhs;
136  }
137 
138  template<>
140  std::unique_ptr<Tensor> reorderedRhs(new Tensor(_rhs.tensorObjectReadOnly->representation));
141  (*reorderedRhs)(this->indices) = std::move(_rhs);
142 
143  *this->tensorObject -= *reorderedRhs;
144  }
145 
146  template<>
148  indexed_assignement(std::move(*this) + std::move(_rhs));
149  }
150 
151  template<>
153  indexed_assignement(std::move(*this) - std::move(_rhs));
154  }
155 
156  template<>
158  REQUIRE(deleteTensorObject, "IndexedTensorMoveable must own its tensor object");
159  this->assign_indices();
160  std::vector<Index> openIndices;
161  bool allOpen = true;
162  for(const Index& idx : indices) {
163  if(idx.open()) {
164  openIndices.push_back(idx);
165  } else {
166  allOpen = false;
167  }
168  }
169  if(!allOpen) {
170  (*this->tensorObject)(openIndices) = std::move(*this);
171  this->indices = openIndices;
172  indicesAssigned = false;
173  }
174  }
175 
176 
177  // IndexedTensorReadOnly may be instanciated as
178  template class IndexedTensorWritable<Tensor>;
180  } // namespace internal
181 } // namespace xerus
static void link_traces_and_fix(internal::IndexedTensorWritable< TensorNetwork > &&_base)
Finds traces defined by the indices and internally links the corresponding indices. Also applys all fixed indices.
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.
void indexed_assignement(IndexedTensorReadOnly< Tensor > &&_rhs)
Tensor assignment with indices.
Header file for the Index class.
Header file for the IndexedTensorMoveable class.
Header file for the standard contaienr support functions.
#define REQUIRE
Definition: internal.h:33
Very general class used to represent arbitary tensor networks.
Definition: tensorNetwork.h:42
Internal representation of an readable indexed Tensor or TensorNetwork.
The main namespace of xerus.
Definition: basic.h:37
Class that handles simple (non-decomposed) tensors in a dense or sparse representation.
Definition: tensor.h:70
STL namespace.
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...
void evaluate(IndexedTensorWritable< Tensor > &&_out, IndexedTensorReadOnly< Tensor > &&_base)
bool is_owner() const
Check whether the IndexedTensorWritable has ownership of the tensor object.
Header file for the Tensor class.
std::vector< Index > indices
Vector of the associates indices.
tensor_type * tensorObject
Non-const pointer to the tensor object.
size_t get_eval_degree(const std::vector< Index > &_indices)
bool deleteTensorObject
Flag indicating, whether the IndexedTensorWritable is the owner of the tensorObject.
Header file for comfort functions and macros that should not be exported in the library.
Abstract internal representation of an read and writeable indexed Tensor or TensorNetwork.
IndexedTensorWritable()=delete
There is no usefull default constructor;.
Class used to represent indices that can be used to write tensor calculations in index notation...
Definition: index.h:43
Header file for the IndexedTensorWritable class.
void assign_indices()
Assignes the indices using the degree of the tensorObejct.
#define INTERNAL_CHECK
Definition: internal.h:37
std::vector< size_t > get_evaluated_dimensions(const std::vector< Index > &_indexOrder)
Returns the dimensionTuple the evaluation of this IndexedTensor to the given indices would have...
Header file for the TensorNetwork class.
bool indicesAssigned
Flag indicating whether the indices are assinged.
Header file for the IndexedTensor class.