summaryrefslogtreecommitdiff
path: root/lib/include/wolff/cluster.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/include/wolff/cluster.hpp')
-rw-r--r--lib/include/wolff/cluster.hpp118
1 files changed, 60 insertions, 58 deletions
diff --git a/lib/include/wolff/cluster.hpp b/lib/include/wolff/cluster.hpp
index 805e2c3..055cdf3 100644
--- a/lib/include/wolff/cluster.hpp
+++ b/lib/include/wolff/cluster.hpp
@@ -1,120 +1,122 @@
-#pragma once
+#ifndef WOLFF_CLUSTER_H
+#define WOLFF_CLUSTER_H
#include <random>
#include <cmath>
#include <vector>
-#include <stack>
+#include <queue>
#include "types.h"
-#include "state.hpp"
+#include "system.hpp"
#include "graph.hpp"
-#include "meas.h"
+#include "measurement.hpp"
template <class R_t, class X_t>
-void flip_cluster(state_t<R_t, X_t>& s, v_t v0, const R_t& r, std::mt19937& rand, wolff_measurement<R_t, X_t>& m) {
+void wolff_cluster_flip(wolff_system<R_t, X_t>& S, v_t i0, const R_t& r,
+ std::mt19937& rng, wolff_measurement<R_t, X_t>& A) {
std::uniform_real_distribution<double> dist(0.0, 1.0);
- std::stack<v_t> stack;
- stack.push(v0);
+ std::queue<v_t> queue;
+ queue.push(i0);
- std::vector<bool> marks(s.g.nv, false);
+ std::vector<bool> marks(S.G.nv, false);
- while (!stack.empty()) {
- v_t v = stack.top();
- stack.pop();
+ while (!queue.empty()) {
+ v_t i = queue.front();
+ queue.pop();
- if (!marks[v]) { // don't reprocess anyone we've already visited!
- marks[v] = true;
+ if (!marks[i]) { // don't reprocess anyone we've already visited!
+ marks[i] = true;
X_t si_new;
-#ifndef NOFIELD
- R_t R_new;
+#ifndef WOLFF_NO_FIELD
+ R_t s0_new;
- bool v_is_ghost = (v == s.nv); // ghost site has the last index
+ bool we_are_ghost = (i == S.nv);
- if (v_is_ghost) {
- R_new = r.act(s.R); // if we are, then we're moving the transformation
+ if (we_are_ghost) {
+ s0_new = r.act(S.s0);
} else
#endif
{
- si_new = r.act(s.spins[v]); // otherwise, we're moving the spin at our site
+ si_new = r.act(S.s[i]);
}
- for (const v_t &vn : s.g.v_adj[v]) {
- double dE, prob;
+ for (const v_t &j : S.G.adj[i]) {
+ double dE, p;
-#ifndef NOFIELD
- bool vn_is_ghost = (vn == s.nv); // any of our neighbors could be the ghost
+#ifndef WOLFF_NO_FIELD
+ bool neighbor_is_ghost = (j == S.nv);
- if (v_is_ghost || vn_is_ghost) { // this is a ghost-involved bond
- X_t rs_old, rs_new;
+ if (we_are_ghost || neighbor_is_ghost) {
+ X_t s0s_old, s0s_new;
v_t non_ghost;
- if (vn_is_ghost) {
- // if our neighbor is the ghost, the current site is a normal
- // spin - rotate it back!
- rs_old = s.R.act_inverse(s.spins[v]);
- rs_new = s.R.act_inverse(si_new);
- non_ghost = v;
+ if (neighbor_is_ghost) {
+ non_ghost = i;
+ s0s_old = S.s0.act_inverse(S.s[i]);
+ s0s_new = S.s0.act_inverse(si_new);
} else {
- /* if we're the ghost, we need to rotate our neighbor back in
- both the old and new ways */
- rs_old = s.R.act_inverse(s.spins[vn]);
- rs_new = R_new.act_inverse(s.spins[vn]);
- non_ghost = vn;
+ non_ghost = j;
+ s0s_old = S.s0.act_inverse(S.s[j]);
+ s0s_new = s0_new.act_inverse(S.s[j]);
}
-#ifdef SITE_DEPENDENCE
- dE = s.H(non_ghost, rs_old) - s.H(non_ghost, rs_new);
+#ifdef WOLFF_SITE_DEPENDENCE
+ dE = S.B(non_ghost, s0s_old) - S.B(non_ghost, s0s_new);
#else
- dE = s.H(rs_old) - s.H(rs_new);
+ dE = S.B(s0s_old) - S.B(s0s_new);
#endif
-#ifdef FINITE_STATES
- prob = H_probs[state_to_ind(rs_old)][state_to_ind(rs_new)];
+#ifdef WOLFF_FINITE_STATES
+ p = finite_states_Bp[finite_states_enum(s0s_old)]
+ [finite_states_enum(s0s_new)];
#endif
// run measurement hooks for encountering a ghost bond
- m.ghost_bond_added(non_ghost, rs_old, rs_new, dE);
+ A.ghost_bond_visited(S, non_ghost, s0s_old, s0s_new, dE);
} else // this is a perfectly normal bond!
#endif
{
-#ifdef BOND_DEPENDENCE
- dE = s.J(v, s.spins[v], vn, s.spins[vn]) - s.J(v, si_new, vn, s.spins[vn]);
+#ifdef WOLFF_BOND_DEPENDENCE
+ dE = S.Z(i, S.s[i], j, S.s[j]) - S.Z(i, si_new, j, S.s[j]);
#else
- dE = s.J(s.spins[v], s.spins[vn]) - s.J(si_new, s.spins[vn]);
+ dE = S.Z(S.s[i], S.s[j]) - S.Z(si_new, S.s[j]);
#endif
-
-#ifdef FINITE_STATES
- prob = J_probs[state_to_ind(s.spins[v])][state_to_ind(si_new)][state_to_ind(s.spins[vn])];
+#ifdef WOLFF_FINITE_STATES
+ p = finite_states_Zp[finite_states_enum(S.s[i])]
+ [finite_states_enum(si_new)]
+ [finite_states_enum(S.s[j])];
#endif
// run measurement hooks for encountering a plain bond
- m.plain_bond_added(v, s.spins[v], si_new, vn, s.spins[vn], dE);
+ A.plain_bond_visited(S, i, si_new, j, dE);
}
#ifndef FINITE_STATES
- prob = 1.0 - exp(-dE / s.T);
+ p = 1.0 - exp(-dE / S.T);
#endif
- if (dist(rand) < prob) {
- stack.push(vn); // push the neighboring vertex to the stack
+ if (dist(rng) < p) {
+ queue.push(j); // push the neighboring vertex to the queue
}
}
-#ifndef NOFIELD
- if (v_is_ghost) {
- m.ghost_site_transformed(s.R, R_new);
- s.R = R_new;
+#ifndef WOLFF_NO_FIELD
+ if (we_are_ghost) {
+ A.ghost_site_transformed(S, s0_new);
+ S.s0 = s0_new;
} else
#endif
{
- m.plain_site_transformed(v, s.spins[v], si_new);
- s.spins[v] = si_new;
+ A.plain_site_transformed(S, i, si_new);
+ S.s[i] = si_new;
}
}
}
}
+#endif
+