Maestro 0.3.11
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
DumbContractor.h
Go to the documentation of this file.
1
20
21#pragma once
22
23#ifndef __DUMB_CONTRACTOR_H_
24#define __DUMB_CONTRACTOR_H_ 1
25
26#include "BaseContractor.h"
27
28#include <boost/container_hash/hash.hpp>
29
30namespace TensorNetworks
31{
32
39{
40 public:
47 double Contract(const TensorNetwork &network, Types::qubit_t qubit) override
48 {
49 std::vector<Eigen::Index> keys;
50 std::unordered_map<Eigen::Index, Eigen::Index> keysKeys;
51
52 TensorsMap tensors = InitializeTensors(network, qubit, keys, keysKeys, false);
53
54 Eigen::Index minId = std::numeric_limits<Eigen::Index>::max();
55
56 if (contractTheLowestTensorId)
57 {
58 for (const auto &tensor : tensors)
59 {
60 if (tensor.first < minId)
61 minId = tensor.first;
62 }
63 }
64
65 // auto it = tensors.begin();
66
67 // while there is more than one tensor...
68 while (tensors.size() > 1)
69 {
70 Eigen::Index tensor1Id;
71 Eigen::Index tensor2Id;
72
73 if (contractTheLowestTensorId)
74 {
75 tensor1Id = minId;
76 auto it = tensors.find(tensor1Id);
77 ++it;
78 if (it == tensors.end())
79 it = tensors.begin();
80
81 tensor2Id = it->first;
82 }
83 else
84 {
85 auto it = tensors.begin();
86 tensor1Id = it->first;
87 ++it;
88 tensor2Id = it->first;
89 }
90
91 // you could even comment out this loop and it should work
92 // the unconnected tensors will still be contracted, the contraction
93 // result is the outer product this is a good chance to test the
94 // contraction that involves outer products, as the other contractors
95 // avoid it
96
97 const auto &tensor = tensors[tensor1Id];
98 Eigen::Index resultRank = std::numeric_limits<Eigen::Index>::max();
99 for (Eigen::Index ti = 0; ti < static_cast<Eigen::Index>(tensor->connections.size()); ++ti)
100 {
101 const auto nextTensorId = tensor->connections[ti];
102 if (nextTensorId != TensorNode::NotConnected)
103 {
104 tensor2Id = nextTensorId;
105
106 const Eigen::Index newRank = GetResultRank(tensor, tensors[nextTensorId]);
107
108 if (newRank <= resultRank)
109 {
110 if (newRank < resultRank)
111 {
112 tensor2Id = nextTensorId;
113 resultRank = newRank;
114 }
115 }
116 }
117 }
118
119 // it = tensors.find(tensor2Id);
120 //++it;
121 // if (it == tensors.end())
122 // it = tensors.begin();
123
124 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
125
126 if (resultRank == 0)
127 {
128 if (tensors.size() == 1 || tensor->contractsTheNeededQubit)
129 return std::real(tensor->tensor->atOffset(0));
130 // erasing this tensor happens because (not the case anymore, it's
131 // avoided) the tensor network might be a disjoint one and a subnetwork
132 // is contracted that does not contain the needed qubit
133 tensors.erase(tensor1Id);
134
135 if (contractTheLowestTensorId)
136 {
137 minId = std::numeric_limits<Eigen::Index>::max();
138 for (const auto &tensor : tensors)
139 {
140 if (tensor.first < minId)
141 minId = tensor.first;
142 }
143 }
144 }
145 }
146
147 return std::real(tensors.begin()->second->tensor->atOffset(0));
148 }
149
151 {
152 contractTheLowestTensorId = c;
153 }
154
156 {
157 return contractTheLowestTensorId;
158 }
159
165 std::shared_ptr<ITensorContractor> Clone() const override
166 {
167 auto cloned = std::make_shared<DumbContractor>();
168
169 cloned->maxTensorRank = maxTensorRank;
170 cloned->enableMultithreading = enableMultithreading;
171 cloned->contractTheLowestTensorId = contractTheLowestTensorId;
172
173 return cloned;
174 }
175
176 private:
177 bool contractTheLowestTensorId = true;
178};
179
180} // namespace TensorNetworks
181
182#endif // __DUMB_CONTRACTOR_H_
The Base Class Tensor Contractor.
bool enableMultithreading
A flag to indicate if multithreading should be enabled.
ITensorContractor::TensorsMap TensorsMap
TensorsMap InitializeTensors(const TensorNetwork &network, Types::qubit_t qubit, std::vector< Eigen::Index > &keys, std::unordered_map< Eigen::Index, Eigen::Index > &keysKeys, bool fillKeys=true, bool contract=true) override
Eigen::Index ContractNodes(Types::qubit_t qubit, PassedTensorsMap &tensors, Eigen::Index tensor1Id, Eigen::Index tensor2Id, Eigen::Index resultRank)
size_t maxTensorRank
The maximum rank of the tensors in the network.
static size_t GetResultRank(const std::shared_ptr< TensorNode > &tensor1, const std::shared_ptr< TensorNode > &tensor2)
The Dumb Tensor Contractor.
double Contract(const TensorNetwork &network, Types::qubit_t qubit) override
Contract the tensor network.
std::shared_ptr< ITensorContractor > Clone() const override
Clone the tensor contractor.
static constexpr Index NotConnected
Definition TensorNode.h:173
uint_fast64_t qubit_t
The type of a qubit.
Definition Types.h:23