37 template<
bool isOperator>
41 template<
bool isOperator>
47 template<
bool isOperator>
52 std::set<size_t> toContract;
53 for(
size_t i = 0; i <
nodes.size(); ++i) {
60 const size_t numComponents =
degree()/
N;
61 const size_t numNodes =
degree()/
N+2;
62 const size_t stackSize =
nodes.size()/numNodes;
67 std::set<size_t> toContract;
68 for (
size_t currentNode = 0; currentNode < numNodes; ++currentNode) {
70 for (
size_t i = 0; i < stackSize; i++) {
71 toContract.insert(currentNode+i*numNodes);
82 for(
size_t i = 0; i < numComponents; ++i) {
87 for(
size_t i = 0; i < numComponents; ++i) {
94 nodes[0].tensorObject->reinterpret_dimensions({1});
95 nodes[0].neighbors.resize(1);
96 nodes[0].neighbors.front().other = 1;
97 nodes[0].neighbors.front().indexPosition = 0;
100 std::vector<size_t> shuffle(
N+2*stackSize);
101 for (
size_t i = 1; i+1 < numNodes; ++i) {
102 size_t leftCount = 0;
103 size_t leftDim = 1, rightDim = 1;
105 for(
size_t k = 0; k <
N+2*stackSize; ++k) {
111 shuffle[k] = stackSize;
114 shuffle[k] = stackSize+1;
117 if(link.
other == i-1) {
118 shuffle[k] = leftCount++;
124 if(otherLink.other == i) {
125 if(otherLink.indexPosition == k) {
132 shuffle[k] = stackSize+
N+otherPos;
142 nodes[i].tensorObject->reinterpret_dimensions({leftDim,
dimensions[i-1], dimensions[i-1+numComponents], rightDim});
144 nodes[i].tensorObject->reinterpret_dimensions({leftDim,
dimensions[i-1], rightDim});
147 nodes[i].neighbors.clear();
148 nodes[i].neighbors.emplace_back(i-1, i==1 ? 0 :
N+1, leftDim,
false);
150 if(isOperator) {
nodes[i].neighbors.emplace_back(0, numComponents+i-1,
dimensions[numComponents+i-1],
true); }
151 nodes[i].neighbors.emplace_back(i+1, 0, rightDim,
false);
155 nodes[numNodes-1].tensorObject->reinterpret_dimensions({1});
156 nodes[numNodes-1].neighbors.resize(1);
157 nodes[numNodes-1].neighbors.front().other = numNodes-2;
158 nodes[numNodes-1].neighbors.front().indexPosition =
N+1;
162 static_cast<TensorNetwork&
>(result) = static_cast<TensorNetwork&>(*
this);
175 template<
bool isOperator>
182 *
nodes[1].tensorObject *= _factor;
184 *
nodes[0].tensorObject *= _factor;
189 template<
bool isOperator>
196 template<
bool isOperator>
198 _me.tensorObject->require_valid_network();
200 if(_me.tensorObject->degree() == 0) {
201 std::set<size_t> toContract;
202 for(
size_t i = 0; i < _me.tensorObject->nodes.size(); ++i) {
203 toContract.insert(i);
204 _me.tensorObject->contract(toContract);
205 _me.tensorObject->reshuffle_nodes([](
const size_t _i){
return 0;});
210 const size_t numComponents = _me.tensorObject->degree()/
N;
211 const size_t numNodes = _me.tensorObject->degree()/
N+2;
212 const size_t stackSize = _me.tensorObject->nodes.size()/numNodes;
214 INTERNAL_CHECK(_me.tensorObject->nodes.size()%numNodes == 0,
"IE");
217 std::set<size_t> toContract;
218 for (
size_t currentNode = 0; currentNode < numNodes; ++currentNode) {
220 for (
size_t i = 0; i < stackSize; i++) {
221 toContract.insert(currentNode+i*numNodes);
223 _me.tensorObject->contract(toContract);
227 _me.tensorObject->reshuffle_nodes([numNodes](
const size_t _i){
return _i%(numNodes);});
229 INTERNAL_CHECK(_me.tensorObject->nodes.size() == numNodes,
"Internal Error.");
232 for(
size_t i = 0; i < numComponents; ++i) {
233 _me.tensorObject->externalLinks[i].other = i+1;
234 _me.tensorObject->externalLinks[i].indexPosition = 1;
237 for(
size_t i = 0; i < numComponents; ++i) {
238 _me.tensorObject->externalLinks[numComponents+i].other = i+1;
239 _me.tensorObject->externalLinks[numComponents+i].indexPosition = 2;
244 _me.tensorObject->nodes[0].tensorObject->reinterpret_dimensions({1});
245 _me.tensorObject->nodes[0].neighbors.resize(1);
246 _me.tensorObject->nodes[0].neighbors.front().other = 1;
247 _me.tensorObject->nodes[0].neighbors.front().indexPosition = 0;
250 std::vector<size_t> shuffle(
N+2*stackSize);
251 for (
size_t i = 1; i+1 < numNodes; ++i) {
252 size_t leftCount = 0;
253 size_t leftDim = 1, rightDim = 1;
255 for(
size_t k = 0; k <
N+2*stackSize; ++k) {
261 shuffle[k] = stackSize;
264 shuffle[k] = stackSize+1;
267 if(link.
other == i-1) {
268 shuffle[k] = leftCount++;
274 if(otherLink.other == i) {
275 if(otherLink.indexPosition == k) {
282 shuffle[k] = stackSize+
N+otherPos;
287 INTERNAL_CHECK(fullDim == _me.tensorObject->nodes[i].tensorObject->size,
"Uhh");
290 xerus::reshuffle(*_me.tensorObject->nodes[i].tensorObject, *_me.tensorObject->nodes[i].tensorObject, shuffle);
292 _me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({leftDim, _me.tensorObject->dimensions[i-1], _me.tensorObject->dimensions[i-1+numComponents], rightDim});
294 _me.tensorObject->nodes[i].tensorObject->reinterpret_dimensions({leftDim, _me.tensorObject->dimensions[i-1], rightDim});
297 _me.tensorObject->nodes[i].neighbors.clear();
298 _me.tensorObject->nodes[i].neighbors.emplace_back(i-1, i==1 ? 0 :
N+1, leftDim,
false);
299 _me.tensorObject->nodes[i].neighbors.emplace_back(0, i-1 , _me.tensorObject->dimensions[i-1],
true);
300 if(isOperator) { _me.tensorObject->nodes[i].neighbors.emplace_back(0, numComponents+i-1, _me.tensorObject->dimensions[numComponents+i-1],
true); }
301 _me.tensorObject->nodes[i].neighbors.emplace_back(i+1, 0, rightDim,
false);
305 _me.tensorObject->nodes[numNodes-1].tensorObject->reinterpret_dimensions({1});
306 _me.tensorObject->nodes[numNodes-1].neighbors.resize(1);
307 _me.tensorObject->nodes[numNodes-1].neighbors.front().other = numNodes-2;
308 _me.tensorObject->nodes[numNodes-1].neighbors.front().indexPosition =
N+1;
312 template<
bool isOperator>
314 LOG(fatal,
"TTStack not supported as a storing type");
318 template<
bool isOperator>
324 template<
bool isOperator>
330 template<
bool isOperator>
Header file for CHECK and REQUIRE macros.
void contract(const size_t _nodeId1, const size_t _nodeId2)
Contracts the nodes with indices _nodeId1 and _nodeId2.
Internal representation of an read and write and moveable indexed Tensor or TensorNetwork.
const bool cannonicalization_required
static void contract_stack(IndexedTensorWritable< TensorNetwork > &&_me)
static bool specialized_contraction_f(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other)
void reshuffle(Tensor &_out, const Tensor &_base, const std::vector< size_t > &_shuffle)
: Performs a simple reshuffle. Much less powerfull then a full evaluate, but more efficient...
Header file for the TTNetwork class (and thus TTTensor and TTOperator).
Header file for the Index class.
size_t dimension
Dimension of the link, always equals to other->tensorObject->dimensions[indexPosition].
Very general class used to represent arbitary tensor networks.
Internal representation of an readable indexed Tensor or TensorNetwork.
Header file for the TTStack class.
static bool specialized_sum_f(std::unique_ptr< internal::IndexedTensorMoveable< TensorNetwork >> &_out, internal::IndexedTensorReadOnly< TensorNetwork > &&_me, internal::IndexedTensorReadOnly< TensorNetwork > &&_other)
Specialized TensorNetwork class used to represent TTTensor and TToperators.
The main namespace of xerus.
bool canonicalized
Flag indicating whether the TTNetwork is canonicalized.
virtual bool specialized_sum(std::unique_ptr< IndexedTensorMoveable< TensorNetwork >> &_out, IndexedTensorReadOnly< TensorNetwork > &&_me, IndexedTensorReadOnly< TensorNetwork > &&_other) const override
(Internal) Calculates the sum between _me and _other and stores the result in _out. Requires that *this is the tensorObjectReadOnly of _me.
Class representing a link from a TensorNode to another node or an external index. ...
size_t degree() const
Gets the degree of the TensorNetwork.
Header file for the Tensor class.
void move_core(const size_t _position, const bool _keepRank=false)
Move the core to a new position.
void reshuffle_nodes(const std::function< size_t(size_t)> &_f)
reshuffled the nodes according to the given function
bool external
Flag indicating whether this link correspond to an external index.
size_t other
The index of the otherNode this Link links to.
virtual void specialized_evaluation(IndexedTensorWritable< TensorNetwork > &&, IndexedTensorReadOnly< TensorNetwork > &&) override
(Internal) Evaluates _other into _me. Requires that *this is the tensorObjectReadOnly of _me...
Header file for comfort functions and macros that should not be exported in the library.
const size_t futureCorePosition
std::vector< Link > externalLinks
The open links of the network in order.
size_t indexPosition
IndexPosition on the other node or index of external index.
void require_valid_network(const bool _check_erased=true) const
Sanity checks the network.
Abstract internal representation of an read and writeable indexed Tensor or TensorNetwork.
Header file for shorthand notations that are xerus specific but used throughout the library...
double value_t
The type of values to be used by xerus.
virtual value_t frob_norm() const override
Calculates the frobenious norm of the TensorNetwork.
virtual void require_correct_format() const override
Tests whether the network resembles that of a TTTensor and checks consistency with the underlying ten...
Class used to represent indices that can be used to write tensor calculations in index notation...
virtual void operator/=(const value_t _divisor) override
Performs the entrywise divison by a constant _divisor.
virtual void operator*=(const value_t _factor) override
Performs the entrywise multiplication with a constant _factor.
static constexpr const size_t N
The number of external links in each node, i.e. one for TTTensors and two for TTOperators.
virtual value_t frob_norm() const override
Calculates the frobenious norm of the TensorNetwork.
virtual TensorNetwork * get_copy() const override
Returns a new copy of the network.
virtual bool specialized_contraction(std::unique_ptr< IndexedTensorMoveable< TensorNetwork >> &_out, IndexedTensorReadOnly< TensorNetwork > &&_me, IndexedTensorReadOnly< TensorNetwork > &&_other) const override
(Internal) Calculates the contraction between _me and _other and stores the result in _out...
std::vector< TensorNode > nodes
The nodes constituting the network. The order determines the ids of the nodes.
size_t corePosition
The position of the core.
Internal class used to represent stacks of (possibly multiply) applications of TTOperators to either ...
TTStack(const bool _canno, const size_t _corePos=0)
std::vector< size_t > dimensions
Dimensions of the external indices, i.e. the dimensions of the tensor represented by the network...