57 long long int CostThreshold = -1;
58 size_t rejections = 0;
60 std::vector<Eigen::Index> keys;
61 std::unordered_map<Eigen::Index, Eigen::Index> keysKeys;
65 using TensorPair = std::pair<Eigen::Index, Eigen::Index>;
66 std::unordered_set<TensorPair, boost::hash<TensorPair>> visitedPairs;
69 while (tensors.size() > 1)
72 std::uniform_int_distribution<Eigen::Index> tensor1Dist(0LL,
static_cast<Eigen::Index
>(keys.size()) - 1);
73 auto pos1 = tensor1Dist(
gen);
74 Eigen::Index tensor1Id = keys[pos1];
75 const auto tensor1 = tensors[tensor1Id];
80 std::uniform_int_distribution<Eigen::Index> tensor2Dist(0LL,
static_cast<Eigen::Index
>(tensor1->connections.size()) - 1);
81 auto pos2 = tensor2Dist(
gen);
82 Eigen::Index tensor2Id = tensor1->connections[pos2];
88 if (visitedPairs.find(std::make_pair(t1, t2)) != visitedPairs.end())
100 visitedPairs.insert(std::make_pair(t1, t2));
102 const auto tensor2 = tensors[tensor2Id];
104 const auto keysKeysIt = keysKeys.find(tensor2Id);
105 if (keysKeysIt != keysKeys.end())
106 pos2 = keysKeysIt->second;
108 const Eigen::Index resultRank =
GetResultRank(tensor1, tensor2);
111 const Eigen::Index Cost = resultRank - (tensor1->GetRank() + tensor2->GetRank()) / 2;
112 if (Cost <= CostThreshold)
117 ContractNodes(qubit, tensors, tensor1Id, tensor2Id, resultRank);
119 visitedPairs.clear();
124 if (pos1 ==
static_cast<Eigen::Index
>(keys.size()) - 1)
127 keys[pos2] = keys.back();
128 keysKeys[keys[pos2]] = pos2;
129 keysKeys.erase(tensor2Id);
130 keys.resize(keys.size() - 1);
134 if (tensors.size() == 1 || tensors[tensor1Id]->contractsTheNeededQubit)
135 return std::real(tensors[tensor1Id]->tensor->atOffset(0));
140 keys[pos1] = keys.back();
141 keysKeys[keys[pos1]] = pos1;
142 keysKeys.erase(tensor1Id);
143 keys.resize(keys.size() - 1);
145 tensors.erase(tensor1Id);
155 visitedPairs.clear();
160 return std::real(tensors.begin()->second->tensor->atOffset(0));