From 272627e1e0936e3adfd168e4e6ce31cc8954d719 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Wed, 31 Jul 2019 16:48:45 -0400 Subject: added another qualification for finishing to minimze bias --- space_wolff.hpp | 107 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 17 deletions(-) (limited to 'space_wolff.hpp') diff --git a/space_wolff.hpp b/space_wolff.hpp index b60e274..9a4b4b4 100644 --- a/space_wolff.hpp +++ b/space_wolff.hpp @@ -237,6 +237,10 @@ class quantity { double serr() const { return sqrt(this->σ()); } + + unsigned num_added() const { + return n - wait; + } }; template @@ -249,16 +253,87 @@ class model { std::function(model&, unsigned, spin)> neighbors; std::function, spin)> Z; std::function)> B; + std::vector> mats; + std::vector> steps; long double E; quantity Eq; quantity Cq; + void one_sequences(std::list>& sequences, unsigned level) { + if (level > 0) { + unsigned new_level = level - 1; + unsigned old_length = sequences.size(); + for (std::array& sequence : sequences) { + std::array new_sequence = sequence; + new_sequence[new_level] = -1; + sequences.push_front(new_sequence); + } + one_sequences(sequences, new_level); + } + } + model(unsigned L, std::function, spin)> Z, std::function)> B, std::function(model&, unsigned, spin)> ns) : L(L), s0(L), dict(L), neighbors(ns), Z(Z), B(B), Eq(1000, 1000), Cq(1000, 1000) { + std::array ini_sequence; + ini_sequence.fill(1); + std::list> sequences; + sequences.push_back(ini_sequence); + + one_sequences(sequences, D); + + sequences.pop_front(); // don't want the identity matrix! + + for (std::array sequence : sequences) { + matrix m; + for (unsigned i = 0; i < D; i++) { + for (unsigned j = 0; j < D; j++) { + if (i == j) { + m(i, j) = sequence[i]; + } else { + m(i, j) = 0; + } + } + } + + mats.push_back(m); + + vector v; + for (unsigned i = 0; i < D; i++) { + if (sequence[i] == 1) { + v(i) = 0; + } else { + v(i) = L / 2; + } + } + + steps.push_back(v); } + for (unsigned i = 0; i < D; i++) { + for (unsigned j = 0; j < D; j++) { + if (i != j) { + matrix m; + for (unsigned k = 0; k < D; k++) { + for (unsigned l = 0; l < D; l++) { + if ((k == i && l == j) || (k == j && l == i)) { + if (i < j) { + m(k, l) = 1; + } else { + m(k, l) = -1; + } + } else { + m(k, l) = 0; + } + } + } + mats.push_back(m); + } + } + } + } + void update_energy() { E = 0; for (unsigned i = 0; i < s.size(); i++) { @@ -347,31 +422,29 @@ class model { std::uniform_real_distribution t_dist(0, L); std::uniform_int_distribution r_dist(0, D - 1); std::uniform_int_distribution ind_dist(0, s.size() - 1); + std::uniform_int_distribution coin(0, mats.size() + steps.size() - 1); for (unsigned i = 0; i < N; i++) { vector t; matrix m; - for (unsigned j = 0; j < D; j++) { - t(j) = (U)t_dist(rng); - } - - unsigned flip_D1 = r_dist(rng); - unsigned flip_D2 = r_dist(rng); - - for (unsigned j = 0; j < D; j++) { - for (unsigned k = 0; k < D; k++) { - if ((j == flip_D1 && k == flip_D2) || (j == flip_D2 && k == flip_D1)) { - if (flip_D1 <= flip_D2) { - m(j, k) = -1; - } else { + unsigned flip = coin(rng); + if (flip < mats.size()) { + for (unsigned j = 0; j < D; j++) { + t(j) = (U)t_dist(rng); + } + m = mats[flip]; + } else { + for (unsigned j = 0; j < D; j++) { + for (unsigned k = 0; k < D; k++) { + if (j == k) { m(j, k) = 1; + } else { + m(j, k) = 0; } - } else if ((j == k && j != flip_D1) && j != flip_D2) { - m(j, k) = 1; - } else { - m(j, k) = 0; } } + + t = steps[flip - mats.size()]; } euclidean g(L, t, m); -- cgit v1.2.3-70-g09d2