36 std::unordered_map<Eigen::Index, Eigen::Index> &keysKeys,
bool fillKeys =
true,
bool contract =
true)
override
49 for (
const auto &tensor : network.
GetTensors())
54 const auto firstQubit = tensor->qubits[0];
55 if (qubitGroup.find(firstQubit) == qubitGroup.end())
58 const auto tensorId = tensor->GetId();
59 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
62 for (
const auto &[tensor1Id, tensor1] : tensors)
66 const auto qubitsNr = tensor1->qubits.size();
72 const auto tensor2Id = tensor1->connections[0];
73 const auto &tensor2 = tensors[tensor2Id];
76 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
78 tensors.erase(tensor2Id);
85 const auto tensor2Id = tensor1->connections[0];
86 const auto tensor3Id = tensor1->connections[1];
88 if (tensor2Id == tensor3Id)
90 const auto &tensor2 = tensors[tensor2Id];
93 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
95 tensors.erase(tensor2Id);
101 for (
const auto &[tensorId, tensor] : tensors)
105 keysKeys[tensorId] = keys.size();
106 keys.push_back(tensorId);
114 for (
const auto &tensor : network.
GetTensors())
119 const auto firstQubit = tensor->qubits[0];
120 if (qubitGroup.find(firstQubit) == qubitGroup.end())
123 const auto tensorId = tensor->GetId();
124 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
128 keysKeys[tensorId] = keys.size();
129 keys.push_back(tensorId);
140 inline Eigen::Index
ContractNodes(
Types::qubit_t qubit, PassedTensorsMap &tensors, Eigen::Index tensor1Id, Eigen::Index tensor2Id, Eigen::Index resultRank)
142 const auto &tensor1 = tensors[tensor1Id];
143 const auto &tensor2 = tensors[tensor2Id];
146 std::vector<std::pair<size_t, size_t>> indices;
147 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
148 if (tensor1->connections[i] == tensor2Id)
149 indices.emplace_back(i, tensor1->connectionsIndices[i]);
153 const auto resultNode = std::make_shared<TensorNode>();
154 resultNode->tensor = std::make_shared<Utils::Tensor<>>(tensor1->tensor->Contract(*(tensor2->tensor), indices,
enableMultithreading));
155 resultNode->SetId(tensor1Id);
157 const auto newRank = resultNode->GetRank();
159 resultNode->connections.resize(newRank);
160 resultNode->connectionsIndices.resize(newRank);
161 resultNode->qubits.resize(newRank);
170 bool properQubit =
false;
173 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
175 if (qubit == tensor1->qubits[i])
178 const auto connectedTensorId = tensor1->connections[i];
179 if (connectedTensorId != tensor2Id)
182 const auto otherTensorIndex = tensor1->connectionsIndices[i];
184 resultNode->connections[pos] = connectedTensorId;
185 resultNode->connectionsIndices[pos] = otherTensorIndex;
186 resultNode->qubits[pos] = tensor1->qubits[i];
193 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
199 for (
size_t i = 0; i < tensor2->connections.size(); ++i)
201 if (qubit == tensor2->qubits[i])
204 const auto connectedTensorId = tensor2->connections[i];
205 if (connectedTensorId != tensor1Id)
208 const auto otherTensorIndex = tensor2->connectionsIndices[i];
210 resultNode->connections[pos] = connectedTensorId;
211 resultNode->connectionsIndices[pos] = otherTensorIndex;
212 resultNode->qubits[pos] = tensor2->qubits[i];
216 tensors[connectedTensorId]->connections[otherTensorIndex] = tensor1Id;
217 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
223 resultNode->contractsTheNeededQubit = properQubit || tensor1->contractsTheNeededQubit || tensor2->contractsTheNeededQubit;
226 tensors.erase(tensor2Id);
227 tensors[tensor1Id] = resultNode;
232 static inline size_t GetResultRank(
const std::shared_ptr<TensorNode> &tensor1,
const std::shared_ptr<TensorNode> &tensor2)
236 const Eigen::Index tensor1Id = tensor1->GetId();
237 const Eigen::Index tensor2Id = tensor2->GetId();
239 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
240 if (tensor1->connections[i] != tensor2Id)
243 for (
size_t i = 0; i < tensor2->connections.size(); ++i)
244 if (tensor2->connections[i] != tensor1Id)