#pragma once #include #include #include #include #include #include "euclidean.hpp" #include "measurement.hpp" #include "octree.hpp" #include "quantity.hpp" #include "random.hpp" #include "spin.hpp" #include "transformation.hpp" template class Model { public: R s0; std::vector*> s; Octree dict; std::function&, const Spin&)> Z; std::function&)> B; Rng rng; Model(U L, std::function&, const Spin&)> Z, std::function&)> B) : s0(L), Z(Z), B(B), rng(), dict(L, std::floor(L)) {} void step(double T, Transformation* t0, measurement& A) { std::queue*> queue; queue.push(t0); std::set*> cluster = t0->current(); while (!queue.empty()) { Transformation* t = queue.front(); queue.pop(); for (Spin* s : t->toConsider()) { if (!cluster.contains(s)) { double ΔE = t->ΔE(s); if (ΔE > 0 && 1.0 - exp(-ΔE / T) > rng.uniform(0, 1)) { cluster.insert(s); queue.push(t->createNew(T, cluster, s, rng)); } } } A.plain_site_transformed(*this, *t); t->apply(); delete t; } } void resize(double T, double P) {} void wolff(double T, std::vector> gs, measurement& A, unsigned N) { for (unsigned i = 0; i < N; i++) { Gen& g = rng.pick(gs); Transformation* t = g(*this, rng); A.pre_cluster(*this, i, t); this->step(T, t, A); A.post_cluster(*this); } } };