35 std::vector<Eigen::Index> &keys,
36 std::unordered_map<Eigen::Index, Eigen::Index> &keysKeys,
37 bool fillKeys =
true,
bool contract =
true)
override {
48 for (
const auto &tensor : network.
GetTensors()) {
52 const auto firstQubit = tensor->qubits[0];
53 if (qubitGroup.find(firstQubit) == qubitGroup.end())
56 const auto tensorId = tensor->GetId();
57 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
60 for (
const auto &[tensor1Id, tensor1] : tensors) {
63 const auto qubitsNr = tensor1->qubits.size();
68 const auto tensor2Id = tensor1->connections[0];
69 const auto &tensor2 = tensors[tensor2Id];
72 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
74 tensors.erase(tensor2Id);
79 const auto tensor2Id = tensor1->connections[0];
80 const auto tensor3Id = tensor1->connections[1];
82 if (tensor2Id == tensor3Id) {
83 const auto &tensor2 = tensors[tensor2Id];
86 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
88 tensors.erase(tensor2Id);
94 for (
const auto &[tensorId, tensor] : tensors) {
96 keysKeys[tensorId] = keys.size();
97 keys.push_back(tensorId);
103 for (
const auto &tensor : network.
GetTensors()) {
107 const auto firstQubit = tensor->qubits[0];
108 if (qubitGroup.find(firstQubit) == qubitGroup.end())
111 const auto tensorId = tensor->GetId();
112 tensors[tensorId] = tensor->CloneWithoutTensorCopy();
115 keysKeys[tensorId] = keys.size();
116 keys.push_back(tensorId);
129 Eigen::Index tensor1Id, Eigen::Index tensor2Id,
130 Eigen::Index resultRank) {
131 const auto &tensor1 = tensors[tensor1Id];
132 const auto &tensor2 = tensors[tensor2Id];
135 std::vector<std::pair<size_t, size_t>> indices;
136 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
137 if (tensor1->connections[i] == tensor2Id)
138 indices.emplace_back(i, tensor1->connectionsIndices[i]);
142 const auto resultNode = std::make_shared<TensorNode>();
144 std::make_shared<Utils::Tensor<>>(std::move(tensor1->tensor->Contract(
146 resultNode->SetId(tensor1Id);
148 const auto newRank = resultNode->GetRank();
150 resultNode->connections.resize(newRank);
151 resultNode->connectionsIndices.resize(newRank);
152 resultNode->qubits.resize(newRank);
161 bool properQubit =
false;
164 for (
size_t i = 0; i < tensor1->connections.size(); ++i) {
165 if (qubit == tensor1->qubits[i])
168 const auto connectedTensorId = tensor1->connections[i];
169 if (connectedTensorId != tensor2Id) {
171 const auto otherTensorIndex = tensor1->connectionsIndices[i];
173 resultNode->connections[pos] = connectedTensorId;
174 resultNode->connectionsIndices[pos] = otherTensorIndex;
175 resultNode->qubits[pos] = tensor1->qubits[i];
182 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
188 for (
size_t i = 0; i < tensor2->connections.size(); ++i) {
189 if (qubit == tensor2->qubits[i])
192 const auto connectedTensorId = tensor2->connections[i];
193 if (connectedTensorId != tensor1Id) {
195 const auto otherTensorIndex = tensor2->connectionsIndices[i];
197 resultNode->connections[pos] = connectedTensorId;
198 resultNode->connectionsIndices[pos] = otherTensorIndex;
199 resultNode->qubits[pos] = tensor2->qubits[i];
203 tensors[connectedTensorId]->connections[otherTensorIndex] = tensor1Id;
204 tensors[connectedTensorId]->connectionsIndices[otherTensorIndex] = pos;
210 resultNode->contractsTheNeededQubit = properQubit ||
211 tensor1->contractsTheNeededQubit ||
212 tensor2->contractsTheNeededQubit;
215 tensors.erase(tensor2Id);
216 tensors[tensor1Id] = resultNode;
223 const std::shared_ptr<TensorNode> &tensor2) {
226 const Eigen::Index tensor1Id = tensor1->GetId();
227 const Eigen::Index tensor2Id = tensor2->GetId();
229 for (
size_t i = 0; i < tensor1->connections.size(); ++i)
230 if (tensor1->connections[i] != tensor2Id)
233 for (
size_t i = 0; i < tensor2->connections.size(); ++i)
234 if (tensor2->connections[i] != tensor1Id)