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