35 std::vector<Eigen::Index> &keys,
36 std::unordered_map<Eigen::Index, Eigen::Index> &keysKeys,
37 bool fillKeys =
true,
bool contract =
true)
override {
42 if (fillKeys) keys.reserve(network.
GetTensors().size());
47 for (
const auto &tensor : network.
GetTensors()) {
48 if (!tensor)
continue;
50 const auto firstQubit = tensor->qubits[0];
51 if (qubitGroup.find(firstQubit) == qubitGroup.end())
continue;
53 const auto tensorId = tensor->GetId();
54 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
57 for (
const auto &[tensor1Id, tensor1] : tensors) {
60 const auto qubitsNr = tensor1->qubits.size();
65 const auto tensor2Id = tensor1->connections[0];
66 const auto &tensor2 = tensors[tensor2Id];
69 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
71 tensors.erase(tensor2Id);
76 const auto tensor2Id = tensor1->connections[0];
77 const auto tensor3Id = tensor1->connections[1];
79 if (tensor2Id == tensor3Id) {
80 const auto &tensor2 = tensors[tensor2Id];
83 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
85 tensors.erase(tensor2Id);
91 for (
const auto &[tensorId, tensor] : tensors) {
93 keysKeys[tensorId] = keys.size();
94 keys.push_back(tensorId);
100 for (
const auto &tensor : network.
GetTensors()) {
101 if (!tensor)
continue;
103 const auto firstQubit = tensor->qubits[0];
104 if (qubitGroup.find(firstQubit) == qubitGroup.end())
continue;
106 const auto tensorId = tensor->GetId();
107 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
110 keysKeys[tensorId] = keys.size();
111 keys.push_back(tensorId);
123 PassedTensorsMap &tensors,
124 Eigen::Index tensor1Id,
125 Eigen::Index tensor2Id,
126 Eigen::Index resultRank) {
127 const auto &tensor1 = tensors[tensor1Id];
128 const auto &tensor2 = tensors[tensor2Id];
131 std::vector<std::pair<size_t, size_t>> indices;
132 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
133 if (tensor1->connections[i] == tensor2Id)
134 indices.emplace_back(i, tensor1->connectionsIndices[i]);
138 const auto resultNode = std::make_shared<TensorNode>();
140 std::make_shared<Utils::Tensor<>>(std::move(tensor1->tensor->Contract(
142 resultNode->SetId(tensor1Id);
144 const auto newRank = resultNode->GetRank();
146 resultNode->connections.resize(newRank);
147 resultNode->connectionsIndices.resize(newRank);
148 resultNode->qubits.resize(newRank);
157 bool properQubit =
false;
160 for (
size_t i = 0; i < tensor1->connections.size(); ++i) {
161 if (qubit == tensor1->qubits[i]) properQubit =
true;
163 const auto connectedTensorId = tensor1->connections[i];
164 if (connectedTensorId != tensor2Id) {
166 const auto otherTensorIndex = tensor1->connectionsIndices[i];
168 resultNode->connections[pos] = connectedTensorId;
169 resultNode->connectionsIndices[pos] = otherTensorIndex;
170 resultNode->qubits[pos] = tensor1->qubits[i];
177 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
183 for (
size_t i = 0; i < tensor2->connections.size(); ++i) {
184 if (qubit == tensor2->qubits[i]) properQubit =
true;
186 const auto connectedTensorId = tensor2->connections[i];
187 if (connectedTensorId != tensor1Id) {
189 const auto otherTensorIndex = tensor2->connectionsIndices[i];
191 resultNode->connections[pos] = connectedTensorId;
192 resultNode->connectionsIndices[pos] = otherTensorIndex;
193 resultNode->qubits[pos] = tensor2->qubits[i];
197 tensors[connectedTensorId]->connections[otherTensorIndex] = tensor1Id;
198 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
204 resultNode->contractsTheNeededQubit = properQubit ||
205 tensor1->contractsTheNeededQubit ||
206 tensor2->contractsTheNeededQubit;
209 tensors.erase(tensor2Id);
210 tensors[tensor1Id] = resultNode;
216 const std::shared_ptr<TensorNode> &tensor1,
217 const std::shared_ptr<TensorNode> &tensor2) {
220 const Eigen::Index tensor1Id = tensor1->GetId();
221 const Eigen::Index tensor2Id = tensor2->GetId();
223 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
224 if (tensor1->connections[i] != tensor2Id) ++rank;
226 for (
size_t i = 0; i < tensor2->connections.size(); ++i)
227 if (tensor2->connections[i] != tensor1Id) ++rank;