21#include <unordered_map>
44template <
typename FloatType>
46 system::ContinuousTimeIsing<graph::Sparse<FloatType>>> {
56 template <
typename RandomNumberEngine>
59 RandomNumberEngine &random_number_engine,
63 std::vector<graph::Index> index_helper;
64 index_helper.reserve(num_spin + 1);
65 index_helper.push_back(0);
72 auto &timeline = system.spin_config[i];
74 generate_poisson_points(0.5 * system.gamma * (1.0 - parameter.
s),
75 parameter.
beta, random_number_engine);
78 timeline = create_timeline(timeline, cuts);
79 assert(timeline.size() > 0);
81 index_helper.push_back(index_helper.back() + timeline.size());
87 for (
typename CTIsing::SparseMatrixXx::InnerIterator it(
88 system.interaction, i);
90 std::size_t j = it.index();
99 generate_poisson_points(std::abs(0.5 * J * parameter.
s),
100 parameter.
beta, random_number_engine);
101 for (
const auto bond : bonds) {
103 auto ki = system.get_temporal_spin_index(i, bond);
104 auto kj = system.get_temporal_spin_index(j, bond);
106 if (system.spin_config[i][ki].second *
107 system.spin_config[j][kj].second * J <
109 union_find_tree.
unite_sets(index_helper[i] + ki,
110 index_helper[j] + kj);
118 std::vector<utility::UnionFind::Node>>
123 for (
size_t k = 0; k < system.spin_config[i].size(); k++) {
124 auto index = index_helper[i] + k;
125 auto root_index = union_find_tree.
find_set(index);
126 auto position = cluster_map.find(root_index);
127 if (position == cluster_map.end()) {
128 cluster_map.emplace(root_index,
129 std::vector<utility::UnionFind::Node>{index});
131 position->second.push_back(index);
137 auto urd = std::uniform_real_distribution<>(0, 1.0);
138 for (
const auto &cluster : cluster_map) {
141 if (urd(random_number_engine) < probability) {
143 for (
auto node : cluster.second) {
144 auto i = std::distance(index_helper.begin(),
145 std::upper_bound(index_helper.begin(),
146 index_helper.end(), node)) -
148 auto k = node - index_helper[i];
149 system.spin_config[i][k].second *= -1;
160 static std::vector<CutPoint>
162 const std::vector<TimeType> &cuts) {
164 std::vector<CutPoint> concatenated_timeline;
165 auto current_spin = old_timeline.back().second;
166 for (
auto cut_point : old_timeline) {
167 if (cut_point.second != current_spin) {
168 concatenated_timeline.push_back(cut_point);
170 current_spin = cut_point.second;
174 std::vector<CutPoint> new_timeline;
175 if (concatenated_timeline.empty()) {
177 new_timeline.push_back(old_timeline[0]);
179 for (
auto cut : cuts) {
180 new_timeline.push_back(
CutPoint(cut, current_spin));
186 current_spin = concatenated_timeline.back().second;
187 auto timeline_itr = concatenated_timeline.begin();
188 auto cuts_itr = cuts.begin();
191 if (cuts_itr == cuts.end()) {
192 std::for_each(timeline_itr, concatenated_timeline.end(),
193 [&](
CutPoint it) { new_timeline.push_back(it); });
199 if (timeline_itr == concatenated_timeline.end()) {
200 std::for_each(cuts_itr, cuts.end(), [&](
TimeType it) {
201 new_timeline.push_back(CutPoint(it, current_spin));
207 if (*cuts_itr < timeline_itr->first) {
208 new_timeline.push_back(
CutPoint(*cuts_itr, current_spin));
211 new_timeline.push_back(*timeline_itr);
212 current_spin = timeline_itr->second;
224 static std::vector<CutPoint>
226 const std::vector<TimeType> &cuts) {
228 std::vector<CutPoint> new_timeline;
229 auto current_spin = old_timeline.back().second;
230 for (
auto cut_point : old_timeline) {
231 if (cut_point.second != current_spin) {
232 new_timeline.push_back(cut_point);
234 current_spin = cut_point.second;
238 if (new_timeline.empty()) {
240 new_timeline.push_back(old_timeline[0]);
242 for (
auto cut : cuts) {
243 new_timeline.push_back(
CutPoint(cut, current_spin));
250 return x.first < y.first;
252 for (
auto cut : cuts) {
253 const auto dummy_cut =
CutPoint(cut, 0);
254 auto itr = std::upper_bound(new_timeline.begin(), new_timeline.end(),
255 dummy_cut, first_lt);
257 (itr == new_timeline.begin()) ? new_timeline.end() - 1 : itr - 1;
259 new_timeline.insert(itr,
CutPoint(cut, prev_itr->second));
271 template <
typename RandomNumberEngine>
272 static std::vector<TimeType>
274 RandomNumberEngine &random_number_engine) {
275 std::uniform_real_distribution<> rand(0.0, 1.0);
276 std::uniform_real_distribution<> rand_beta(0.0, beta);
278 const TimeType coef = beta * lambda;
282 TimeType xi = rand(random_number_engine);
290 std::vector<TimeType> poisson_points(n);
291 for (
int k = 0; k < n; k++) {
292 poisson_points[k] = rand_beta(random_number_engine);
294 std::sort(poisson_points.begin(), poisson_points.end());
296 return poisson_points;
305template <
typename FloatType>
307 system::ContinuousTimeIsing<graph::CSRSparse<FloatType>>> {
319 template <
typename RandomNumberEngine>
322 RandomNumberEngine &random_number_engine,
326 std::vector<graph::Index> index_helper;
327 index_helper.reserve(num_spin + 1);
328 index_helper.push_back(0);
335 auto &timeline = system.spin_config[i];
337 generate_poisson_points(0.5 * system.gamma * (1.0 - parameter.
s),
338 parameter.
beta, random_number_engine);
341 timeline = create_timeline(timeline, cuts);
342 assert(timeline.size() > 0);
344 index_helper.push_back(index_helper.back() + timeline.size());
350 for (
typename CTIsing::SparseMatrixXx::InnerIterator it(
351 system.interaction, i);
353 std::size_t j = it.index();
362 generate_poisson_points(std::abs(0.5 * J * parameter.
s),
363 parameter.
beta, random_number_engine);
364 for (
const auto bond : bonds) {
366 auto ki = system.get_temporal_spin_index(i, bond);
367 auto kj = system.get_temporal_spin_index(j, bond);
369 if (system.spin_config[i][ki].second *
370 system.spin_config[j][kj].second * J <
372 union_find_tree.
unite_sets(index_helper[i] + ki,
373 index_helper[j] + kj);
381 std::vector<utility::UnionFind::Node>>
386 for (
size_t k = 0; k < system.spin_config[i].size(); k++) {
387 auto index = index_helper[i] + k;
388 auto root_index = union_find_tree.
find_set(index);
389 auto position = cluster_map.find(root_index);
390 if (position == cluster_map.end()) {
391 cluster_map.emplace(root_index,
392 std::vector<utility::UnionFind::Node>{index});
394 position->second.push_back(index);
400 auto urd = std::uniform_real_distribution<>(0, 1.0);
401 for (
const auto &cluster : cluster_map) {
404 if (urd(random_number_engine) < probability) {
406 for (
auto node : cluster.second) {
407 auto i = std::distance(index_helper.begin(),
408 std::upper_bound(index_helper.begin(),
409 index_helper.end(), node)) -
411 auto k = node - index_helper[i];
412 system.spin_config[i][k].second *= -1;
423 static std::vector<CutPoint>
425 const std::vector<TimeType> &cuts) {
427 std::vector<CutPoint> concatenated_timeline;
428 auto current_spin = old_timeline.back().second;
429 for (
auto cut_point : old_timeline) {
430 if (cut_point.second != current_spin) {
431 concatenated_timeline.push_back(cut_point);
433 current_spin = cut_point.second;
437 std::vector<CutPoint> new_timeline;
438 if (concatenated_timeline.empty()) {
440 new_timeline.push_back(old_timeline[0]);
442 for (
auto cut : cuts) {
443 new_timeline.push_back(
CutPoint(cut, current_spin));
449 current_spin = concatenated_timeline.back().second;
450 auto timeline_itr = concatenated_timeline.begin();
451 auto cuts_itr = cuts.begin();
454 if (cuts_itr == cuts.end()) {
455 std::for_each(timeline_itr, concatenated_timeline.end(),
456 [&](
CutPoint it) { new_timeline.push_back(it); });
462 if (timeline_itr == concatenated_timeline.end()) {
463 std::for_each(cuts_itr, cuts.end(), [&](
TimeType it) {
464 new_timeline.push_back(CutPoint(it, current_spin));
470 if (*cuts_itr < timeline_itr->first) {
471 new_timeline.push_back(
CutPoint(*cuts_itr, current_spin));
474 new_timeline.push_back(*timeline_itr);
475 current_spin = timeline_itr->second;
487 static std::vector<CutPoint>
489 const std::vector<TimeType> &cuts) {
491 std::vector<CutPoint> new_timeline;
492 auto current_spin = old_timeline.back().second;
493 for (
auto cut_point : old_timeline) {
494 if (cut_point.second != current_spin) {
495 new_timeline.push_back(cut_point);
497 current_spin = cut_point.second;
501 if (new_timeline.empty()) {
503 new_timeline.push_back(old_timeline[0]);
505 for (
auto cut : cuts) {
506 new_timeline.push_back(
CutPoint(cut, current_spin));
513 return x.first < y.first;
515 for (
auto cut : cuts) {
516 const auto dummy_cut =
CutPoint(cut, 0);
517 auto itr = std::upper_bound(new_timeline.begin(), new_timeline.end(),
518 dummy_cut, first_lt);
520 (itr == new_timeline.begin()) ? new_timeline.end() - 1 : itr - 1;
522 new_timeline.insert(itr,
CutPoint(cut, prev_itr->second));
534 template <
typename RandomNumberEngine>
535 static std::vector<TimeType>
537 RandomNumberEngine &random_number_engine) {
538 std::uniform_real_distribution<> rand(0.0, 1.0);
539 std::uniform_real_distribution<> rand_beta(0.0, beta);
541 const TimeType coef = beta * lambda;
545 TimeType xi = rand(random_number_engine);
553 std::vector<TimeType> poisson_points(n);
554 for (
int k = 0; k < n; k++) {
555 poisson_points[k] = rand_beta(random_number_engine);
557 std::sort(poisson_points.begin(), poisson_points.end());
559 return poisson_points;
CSRSparse graph: just store CSR Sparse Matrix (Eigen::Sparse) The Hamiltonian is like.
Definition csr_sparse.hpp:42
Sparse graph: two-body intereactions with O(1) connectivity The Hamiltonian is like.
Definition sparse.hpp:40
std::size_t Index
Definition graph.hpp:30
Definition algorithm.hpp:24
double FloatType
Note:
Definition compile_config.hpp:37
Continuous Time Quantum Ising system (for CSR Sparse graph)
Definition continuous_time_ising.hpp:260
Continuous Time Quantum Ising system (for Sparse graph)
Definition continuous_time_ising.hpp:42
Continuous Time Quantum Ising system.
Definition continuous_time_ising.hpp:34
static std::vector< CutPoint > create_timeline_easy(const std::vector< CutPoint > &old_timeline, const std::vector< TimeType > &cuts)
easy but inefficient version of create_timeline()
Definition continuous_time_swendsen_wang.hpp:225
typename graph::Sparse< FloatType > GraphType
Definition continuous_time_swendsen_wang.hpp:48
static std::vector< CutPoint > create_timeline(const std::vector< CutPoint > &old_timeline, const std::vector< TimeType > &cuts)
create new timeline; place kinks by ignoring old cuts and place new cuts
Definition continuous_time_swendsen_wang.hpp:161
static std::vector< TimeType > generate_poisson_points(const TimeType lambda, const TimeType beta, RandomNumberEngine &random_number_engine)
generates Poisson points with density lambda in the range of [0:beta)
Definition continuous_time_swendsen_wang.hpp:273
typename system::ContinuousTimeIsing< GraphType >::CutPoint CutPoint
Definition continuous_time_swendsen_wang.hpp:49
static void update(system::ContinuousTimeIsing< GraphType > &system, RandomNumberEngine &random_number_engine, const utility::TransverseFieldUpdaterParameter ¶meter)
continuous time Swendsen-Wang updater for transverse ising model
Definition continuous_time_swendsen_wang.hpp:58
typename system::ContinuousTimeIsing< GraphType >::TimeType TimeType
Definition continuous_time_swendsen_wang.hpp:50
static void update(system::ContinuousTimeIsing< GraphType > &system, RandomNumberEngine &random_number_engine, const utility::TransverseFieldUpdaterParameter ¶meter)
continuous time Swendsen-Wang updater for transverse ising model
Definition continuous_time_swendsen_wang.hpp:321
static std::vector< CutPoint > create_timeline_easy(const std::vector< CutPoint > &old_timeline, const std::vector< TimeType > &cuts)
easy but inefficient version of create_timeline()
Definition continuous_time_swendsen_wang.hpp:488
typename graph::CSRSparse< FloatType > GraphType
Definition continuous_time_swendsen_wang.hpp:309
typename system::ContinuousTimeIsing< GraphType >::CutPoint CutPoint
Definition continuous_time_swendsen_wang.hpp:310
typename system::ContinuousTimeIsing< GraphType >::TimeType TimeType
Definition continuous_time_swendsen_wang.hpp:311
static std::vector< CutPoint > create_timeline(const std::vector< CutPoint > &old_timeline, const std::vector< TimeType > &cuts)
create new timeline; place kinks by ignoring old cuts and place new cuts
Definition continuous_time_swendsen_wang.hpp:424
static std::vector< TimeType > generate_poisson_points(const TimeType lambda, const TimeType beta, RandomNumberEngine &random_number_engine)
generates Poisson points with density lambda in the range of [0:beta)
Definition continuous_time_swendsen_wang.hpp:536
Continuous Time Swendsen Wang updater.
Definition continuous_time_swendsen_wang.hpp:37
Definition union_find.hpp:24
Node find_set(Node node)
Definition union_find.hpp:50
std::size_t Node
Definition union_find.hpp:25
void unite_sets(Node x, Node y)
Definition union_find.hpp:34
updater paramter for transverse ising model
Definition schedule_list.hpp:74
double beta
inverse temperature
Definition schedule_list.hpp:85
double s
annealing schedule (from 0 (only transverse field) to 1 (only classical Hamiltonian))
Definition schedule_list.hpp:91