Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
DumbContractor.h
Go to the documentation of this file.
1
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
38 public:
45 double Contract(const TensorNetwork &network, Types::qubit_t qubit) override {
46 std::vector<Eigen::Index> keys;
47 std::unordered_map<Eigen::Index, Eigen::Index> keysKeys;
48
49 TensorsMap tensors =
50 InitializeTensors(network, qubit, keys, keysKeys, false);
51
52 Eigen::Index minId = std::numeric_limits<Eigen::Index>::max();
53
54 if (contractTheLowestTensorId) {
55 for (const auto &tensor : tensors) {
56 if (tensor.first < minId) minId = tensor.first;
57 }
58 }
59
60 // auto it = tensors.begin();
61
62 // while there is more than one tensor...
63 while (tensors.size() > 1) {
64 Eigen::Index tensor1Id;
65 Eigen::Index tensor2Id;
66
67 if (contractTheLowestTensorId) {
68 tensor1Id = minId;
69 auto it = tensors.find(tensor1Id);
70 ++it;
71 if (it == tensors.end()) it = tensors.begin();
72
73 tensor2Id = it->first;
74 } else {
75 auto it = tensors.begin();
76 tensor1Id = it->first;
77 ++it;
78 tensor2Id = it->first;
79 }
80
81 // you could even comment out this loop and it should work
82 // the unconnected tensors will still be contracted, the contraction
83 // result is the outer product this is a good chance to test the
84 // contraction that involves outer products, as the other contractors
85 // avoid it
86
87 const auto &tensor = tensors[tensor1Id];
88 Eigen::Index resultRank = std::numeric_limits<Eigen::Index>::max();
89 for (Eigen::Index ti = 0;
90 ti < static_cast<Eigen::Index>(tensor->connections.size()); ++ti) {
91 const auto nextTensorId = tensor->connections[ti];
92 if (nextTensorId != TensorNode::NotConnected) {
93 tensor2Id = nextTensorId;
94
95 const Eigen::Index newRank =
96 GetResultRank(tensor, tensors[nextTensorId]);
97
98 if (newRank <= resultRank) {
99 if (newRank < resultRank) {
100 tensor2Id = nextTensorId;
101 resultRank = newRank;
102 }
103 }
104 }
105 }
106
107 // it = tensors.find(tensor2Id);
108 //++it;
109 // if (it == tensors.end())
110 // it = tensors.begin();
111
112 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
113
114 if (resultRank == 0) {
115 if (tensors.size() == 1 || tensor->contractsTheNeededQubit)
116 return std::real(tensor->tensor->atOffset(0));
117 // erasing this tensor happens because (not the case anymore, it's
118 // avoided) the tensor network might be a disjoint one and a subnetwork
119 // is contracted that does not contain the needed qubit
120 tensors.erase(tensor1Id);
121
122 if (contractTheLowestTensorId) {
123 minId = std::numeric_limits<Eigen::Index>::max();
124 for (const auto &tensor : tensors) {
125 if (tensor.first < minId) minId = tensor.first;
126 }
127 }
128 }
129 }
130
131 return std::real(tensors.begin()->second->tensor->atOffset(0));
132 }
133
134 void SetContractTheLowestTensorId(bool c) { contractTheLowestTensorId = c; }
135
137 return contractTheLowestTensorId;
138 }
139
145 std::shared_ptr<ITensorContractor> Clone() const override {
146 auto cloned = std::make_shared<DumbContractor>();
147
148 cloned->maxTensorRank = maxTensorRank;
149 cloned->enableMultithreading = enableMultithreading;
150 cloned->contractTheLowestTensorId = contractTheLowestTensorId;
151
152 return cloned;
153 }
154
155 private:
156 bool contractTheLowestTensorId = true;
157};
158
159} // namespace TensorNetworks
160
161#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:151