From f2f7a072216dfafab89851e4ff3e0b2c3eb16663 Mon Sep 17 00:00:00 2001 From: Jaron Kent-Dobias Date: Wed, 17 Oct 2018 19:33:25 -0400 Subject: removed a lot of research code to simplify library and examples for publication --- examples/CMakeLists.txt | 13 +- examples/On.cpp | 82 ++++ examples/animate_ising.cpp | 133 ++++++ examples/include/colors.h | 34 -- examples/include/correlation.hpp | 23 - examples/include/measure.hpp | 159 ------- examples/include/randutils | 1 - examples/ising.cpp | 82 ++++ examples/simple_ising.cpp | 192 -------- examples/simple_measurement.hpp | 66 +++ examples/src/CMakeLists.txt | 4 - examples/src/models/CMakeLists.txt | 6 - examples/src/models/On/CMakeLists.txt | 29 -- examples/src/models/On/orthogonal.hpp | 202 --------- examples/src/models/On/vector.hpp | 118 ----- examples/src/models/On/wolff_On.cpp | 269 ------------ examples/src/models/ising/CMakeLists.txt | 32 -- examples/src/models/ising/ising.hpp | 84 ---- examples/src/models/ising/wolff_ising.cpp | 197 --------- .../src/models/ising/wolff_random-field_ising.cpp | 207 --------- examples/src/models/ising/z2.hpp | 53 --- examples/src/models/potts/CMakeLists.txt | 39 -- examples/src/models/potts/dihedral.hpp | 48 -- examples/src/models/potts/potts.hpp | 72 --- examples/src/models/potts/symmetric.hpp | 52 --- examples/src/models/potts/wolff_clock.cpp | 149 ------- examples/src/models/potts/wolff_potts.cpp | 210 --------- examples/src/models/roughening/CMakeLists.txt | 21 - examples/src/models/roughening/dihedral_inf.hpp | 47 -- examples/src/models/roughening/height.hpp | 75 ---- examples/src/models/roughening/wolff_cgm.cpp | 167 ------- examples/src/models/roughening/wolff_dgm.cpp | 164 ------- examples/src/tools/CMakeLists.txt | 9 - examples/src/tools/analyze_correlations.cpp | 486 --------------------- lib/include/wolff.hpp | 33 +- lib/include/wolff/cluster.hpp | 118 ++--- lib/include/wolff/finite_states.hpp | 41 +- lib/include/wolff/graph.hpp | 7 +- lib/include/wolff/meas.h | 19 - lib/include/wolff/measurement.hpp | 24 + lib/include/wolff/models/dihedral.hpp | 48 ++ lib/include/wolff/models/dihedral_inf.hpp | 47 ++ lib/include/wolff/models/height.hpp | 43 ++ lib/include/wolff/models/ising.hpp | 81 ++++ lib/include/wolff/models/orthogonal.hpp | 199 +++++++++ lib/include/wolff/models/potts.hpp | 50 +++ lib/include/wolff/models/symmetric.hpp | 51 +++ lib/include/wolff/models/vector.hpp | 108 +++++ lib/include/wolff/state.hpp | 68 --- lib/include/wolff/system.hpp | 70 +++ lib/include/wolff/types.h | 25 +- lib/src/graph.cpp | 36 +- 52 files changed, 1215 insertions(+), 3378 deletions(-) create mode 100644 examples/On.cpp create mode 100644 examples/animate_ising.cpp delete mode 100644 examples/include/colors.h delete mode 100644 examples/include/correlation.hpp delete mode 100644 examples/include/measure.hpp delete mode 160000 examples/include/randutils create mode 100644 examples/ising.cpp delete mode 100644 examples/simple_ising.cpp create mode 100644 examples/simple_measurement.hpp delete mode 100644 examples/src/CMakeLists.txt delete mode 100644 examples/src/models/CMakeLists.txt delete mode 100644 examples/src/models/On/CMakeLists.txt delete mode 100644 examples/src/models/On/orthogonal.hpp delete mode 100644 examples/src/models/On/vector.hpp delete mode 100644 examples/src/models/On/wolff_On.cpp delete mode 100644 examples/src/models/ising/CMakeLists.txt delete mode 100644 examples/src/models/ising/ising.hpp delete mode 100644 examples/src/models/ising/wolff_ising.cpp delete mode 100644 examples/src/models/ising/wolff_random-field_ising.cpp delete mode 100644 examples/src/models/ising/z2.hpp delete mode 100644 examples/src/models/potts/CMakeLists.txt delete mode 100644 examples/src/models/potts/dihedral.hpp delete mode 100644 examples/src/models/potts/potts.hpp delete mode 100644 examples/src/models/potts/symmetric.hpp delete mode 100644 examples/src/models/potts/wolff_clock.cpp delete mode 100644 examples/src/models/potts/wolff_potts.cpp delete mode 100644 examples/src/models/roughening/CMakeLists.txt delete mode 100644 examples/src/models/roughening/dihedral_inf.hpp delete mode 100644 examples/src/models/roughening/height.hpp delete mode 100644 examples/src/models/roughening/wolff_cgm.cpp delete mode 100644 examples/src/models/roughening/wolff_dgm.cpp delete mode 100644 examples/src/tools/CMakeLists.txt delete mode 100644 examples/src/tools/analyze_correlations.cpp delete mode 100644 lib/include/wolff/meas.h create mode 100644 lib/include/wolff/measurement.hpp create mode 100644 lib/include/wolff/models/dihedral.hpp create mode 100644 lib/include/wolff/models/dihedral_inf.hpp create mode 100644 lib/include/wolff/models/height.hpp create mode 100644 lib/include/wolff/models/ising.hpp create mode 100644 lib/include/wolff/models/orthogonal.hpp create mode 100644 lib/include/wolff/models/potts.hpp create mode 100644 lib/include/wolff/models/symmetric.hpp create mode 100644 lib/include/wolff/models/vector.hpp delete mode 100644 lib/include/wolff/state.hpp create mode 100644 lib/include/wolff/system.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a435b29..73922c6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,10 +1,11 @@ -add_library(wolff_examples INTERFACE) +add_executable(ising ising.cpp) +add_executable(animate_ising animate_ising.cpp) +add_executable(xy On.cpp) -target_include_directories(wolff_examples INTERFACE include) +add_compile_definitions(xy WOLFF_N=2) -add_executable(simple_ising simple_ising.cpp) -target_link_libraries(simple_ising wolff) - -add_subdirectory(src) +target_link_libraries(ising wolff) +target_link_libraries(animate_ising wolff GL GLU glut) +target_link_libraries(xy wolff) diff --git a/examples/On.cpp b/examples/On.cpp new file mode 100644 index 0000000..e045f52 --- /dev/null +++ b/examples/On.cpp @@ -0,0 +1,82 @@ + +#include +#include +#include + +#include "simple_measurement.hpp" + +#include +#include +#include + +int main(int argc, char *argv[]) { + + // set defaults + N_t N = (N_t)1e4; + D_t D = 2; + L_t L = 128; + double T = 0.8; + vector_t H; + H.fill(0.0); + q_t Hi = 0; + + int opt; + + // take command line arguments + while ((opt = getopt(argc, argv, "N:D:L:T:H:")) != -1) { + switch (opt) { + case 'N': // number of steps + N = (N_t)atof(optarg); + break; + case 'D': // dimension + D = atoi(optarg); + break; + case 'L': // linear size + L = atoi(optarg); + break; + case 'T': // temperature + T = atof(optarg); + break; + case 'H': // external field + H[Hi] = atof(optarg); + Hi++; + break; + default: + exit(EXIT_FAILURE); + } + } + + // define the spin-spin coupling + std::function &, const vector_t&)> Z = [] (const vector_t& s1, const vector_t& s2) -> double { + return s1 * s2; + }; + + // define the spin-field coupling + std::function &)> B = [&] (const vector_t& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system, vector_t> S(D, L, T, Z, B); + + std::function (std::mt19937&, const vector_t&)> gen_R = generate_rotation_uniform; + + // initailze the measurement object + simple_measurement A(S); + + // initialize the random number generator + auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + std::mt19937 rng{seed}; + + // run wolff N times + wolff, vector_t>(N, S, gen_R, A, rng); + + // print the result of our measurements + std::cout << "Wolff complete!\nThe average energy per site was " << A.avgE() / S.nv + << ".\nThe average magnetization per site was " << A.avgM() / S.nv + << ".\nThe average cluster size per site was " << A.avgC() / S.nv << ".\n"; + + // exit + return 0; +} + diff --git a/examples/animate_ising.cpp b/examples/animate_ising.cpp new file mode 100644 index 0000000..e33736e --- /dev/null +++ b/examples/animate_ising.cpp @@ -0,0 +1,133 @@ + +#include +#include +#include + +#include + +#include +#include +#include + +class draw_ising : public wolff_measurement { + private: + unsigned int frame_skip; + v_t C; + public: + draw_ising(const wolff_system& S, unsigned int window_size, unsigned int frame_skip, int argc, char *argv[]) : frame_skip(frame_skip){ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(window_size, window_size); + glutCreateWindow("wolff"); + glClearColor(0.0,0.0,0.0,0.0); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, S.L, 0.0, S.L); + } + + void pre_cluster(N_t, N_t, const wolff_system& S, v_t, const ising_t&) { + glClear(GL_COLOR_BUFFER_BIT); + for (v_t i = 0; i < pow(S.L, 2); i++) { + if (S.s[i].x == S.s0.x) { + glColor3f(0.0, 0.0, 0.0); + } else { + glColor3f(1.0, 1.0, 1.0); + } + glRecti(i / S.L, i % S.L, (i / S.L) + 1, (i % S.L) + 1); + } + glFlush(); + C = 0; + } + + void plain_bond_visited(const wolff_system&, v_t, const ising_t&, v_t, double dE) {} + + void ghost_bond_visited(const wolff_system&, v_t, const ising_t& s_old, const ising_t& s_new, double dE) {} + + void plain_site_transformed(const wolff_system& S, v_t i, const ising_t&) { + glColor3f(1.0, 0.0, 0.0); + glRecti(i / S.L, i % S.L, (i / S.L) + 1, (i % S.L) + 1); + C++; + if (C % frame_skip == 0) { + glFlush(); + } + } + + void ghost_site_transformed(const wolff_system&, const ising_t&) {} + + void post_cluster(N_t, N_t, const wolff_system&) {} +}; + +int main(int argc, char *argv[]) { + + // set defaults + N_t N = (N_t)1e4; + D_t D = 2; + L_t L = 128; + double T = 2.26918531421; + double H = 0.0; + unsigned int window_size = 512; + unsigned int frame_skip = 1; + + int opt; + + // take command line arguments + while ((opt = getopt(argc, argv, "N:D:L:T:H:w:f:")) != -1) { + switch (opt) { + case 'N': // number of steps + N = (N_t)atof(optarg); + break; + case 'D': // dimension + D = atoi(optarg); + break; + case 'L': // linear size + L = atoi(optarg); + break; + case 'T': // temperature + T = atof(optarg); + break; + case 'H': // external field + H = atof(optarg); + break; + case 'w': + window_size = atoi(optarg); + break; + case 'f': + frame_skip = atoi(optarg); + break; + default: + exit(EXIT_FAILURE); + } + } + + // define the spin-spin coupling + std::function Z = [] (const ising_t& s1, const ising_t& s2) -> double { + return (double)(s1 * s2); + }; + + // define the spin-field coupling + std::function B = [=] (const ising_t& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system S(D, L, T, Z, B); + + // define function that generates self-inverse rotations + std::function gen_R = [] (std::mt19937&, const ising_t& s) -> ising_t { + return ising_t(true); + }; + + // initailze the measurement object + draw_ising A(S, window_size, frame_skip, argc, argv); + + // initialize the random number generator + auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + std::mt19937 rng{seed}; + + // run wolff N times + wolff(N, S, gen_R, A, rng); + + // exit + return 0; +} + diff --git a/examples/include/colors.h b/examples/include/colors.h deleted file mode 100644 index abf137c..0000000 --- a/examples/include/colors.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include - -double hue_to_R(double theta) { - if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((0 <= theta) && (theta < M_PI / 3)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { - return 1.0; - } else { - return 0.0; - } -} - -double hue_to_G(double theta) { - if (((0 <= theta) && (theta < M_PI / 3)) || ((M_PI <= theta) && (theta < 4 * M_PI / 3))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((M_PI / 3 <= theta) && (theta < 2 * M_PI / 3)) || ((2 * M_PI / 3 <= theta) && (theta < M_PI))) { - return 1.0; - } else { - return 0.0; - } -} - -double hue_to_B(double theta) { - if (((2 * M_PI / 3 <= theta) && (theta < M_PI)) || ((5 * M_PI / 3 <= theta) && (theta <= 2 * M_PI))) { - return 1.0 - fabs(fmod(theta / (2 * M_PI / 6), 2) - 1.0); - } else if (((M_PI <= theta) && (theta < 4 * M_PI / 3)) || ((4 * M_PI / 3 <= theta) && (theta < 5 * M_PI / 3))) { - return 1.0; - } else { - return 0.0; - } -} - diff --git a/examples/include/correlation.hpp b/examples/include/correlation.hpp deleted file mode 100644 index da8ab7f..0000000 --- a/examples/include/correlation.hpp +++ /dev/null @@ -1,23 +0,0 @@ - -#pragma once - -#include -#include - -#include - -template -double correlation_length(const std::vector& ReF, const std::vector& ImF, D_t D) { - double total = 0; - -#ifdef DIMENSION - for (D_t j = 0; j < DIMENSION; j++) { -#else - for (D_t j = 0; j < D; j++) { -#endif - total += norm_squared(ReF[j]) + norm_squared(ImF[j]); - } - - return total / D; -} - diff --git a/examples/include/measure.hpp b/examples/include/measure.hpp deleted file mode 100644 index bf8baab..0000000 --- a/examples/include/measure.hpp +++ /dev/null @@ -1,159 +0,0 @@ - -#pragma once - -#include -#include -#include "correlation.hpp" -#include - -#define POSSIBLE_MEASUREMENTS 4 -const unsigned char measurement_energy = 1 << 0; -const unsigned char measurement_clusterSize = 1 << 1; -const unsigned char measurement_magnetization = 1 << 2; -const unsigned char measurement_fourierZero = 1 << 3; - -char const *measurement_labels[] = {"E", "S", "M", "F"}; - -template -class wolff_research_measurements : public wolff_measurement { - private: - std::vector> precomputed_sin; - std::vector> precomputed_cos; - FILE **files; - D_t D; - unsigned char flags; - std::function &, const wolff_research_measurements&)> other_f; - bool silent; - public: - v_t last_cluster_size; - double E; - typename X_t::M_t M; - std::vector ReF; - std::vector ImF; - - wolff_research_measurements(unsigned char flags, unsigned long timestamp, std::function &, const wolff_research_measurements&)> other_f, state_t& s, bool silent) : flags(flags), D(s.D), other_f(other_f), silent(silent) { - FILE **files = (FILE **)calloc(POSSIBLE_MEASUREMENTS, sizeof(FILE *)); - - for (uint8_t i = 0; i < POSSIBLE_MEASUREMENTS; i++) { - if (flags & (1 << i)) { - char *filename = (char *)malloc(255 * sizeof(char)); - sprintf(filename, "wolff_%lu_%s.dat", timestamp, measurement_labels[i]); - files[i] = fopen(filename, "wb"); - free(filename); - } - } - -#ifdef BOND_DEPENDENCE - E = 0; - for (v_t v = 0; v < s.nv; v++) { - for (const v_t &vn : s.g.v_adj[v]) { - if (v < vn) { - E -= s.J(v, s.spins[v], vn, s.spins[vn]); - } - } - } -#else - E = - (double)s.ne * s.J(s.spins[0], s.spins[0]); -#endif - -#ifndef NOFIELD -#ifdef SITE_DEPENDENCE - for (v_t i = 0; i < s.nv; i++) { - E -= s.H(i, s.spins[i]); - } -#else - E -= (double)s.nv * s.H(s.spins[0]); -#endif -#endif - - M = s.spins[0] * s.nv; - - ReF.resize(s.D); - ImF.resize(s.D); - for (D_t i = 0; i < s.D; i++) { - ReF[i] = s.spins[0] * 0.0; - ImF[i] = s.spins[0] * 0.0; - } - precomputed_cos.resize(s.nv); - precomputed_sin.resize(s.nv); - for (v_t i = 0; i < s.nv; i++) { - precomputed_cos[i].resize(s.D); - precomputed_sin[i].resize(s.D); - for (D_t j = 0; j < s.D; j++) { - precomputed_cos[i][j] = cos(2 * M_PI * s.g.coordinate[i][j] / (double)s.L); - precomputed_sin[i][j] = sin(2 * M_PI * s.g.coordinate[i][j] / (double)s.L); - } - } - - if (!silent) printf("\n"); - - } - - void pre_cluster(const state_t& s, count_t step, count_t N, v_t v0, const R_t& R) { - last_cluster_size = 0; - if (!silent) printf("\033[F\033[JWOLFF: step %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", step, N, E, last_cluster_size); - - } - - void plain_bond_added(v_t vi, const X_t& si_old, const X_t& si_new, v_t vn, const X_t& sn, double dE) { - E += dE; - } - - void ghost_bond_added(v_t v, const X_t& rs_old, const X_t& rs_new, double dE) { - E += dE; - M += rs_new - rs_old; - -#ifdef DIMENSION - for (D_t i = 0; i < DIMENSION; i++) -#else - for (D_t i = 0; i < D; i++) -#endif - { - ReF[i] += (rs_new - rs_old) * precomputed_cos[v][i]; - ImF[i] += (rs_new - rs_old) * precomputed_sin[v][i]; - } - } - - void plain_site_transformed(v_t v, const X_t& s_old, const X_t& s_new) { - last_cluster_size++; - } - - void ghost_site_transformed(const R_t& r_old, const R_t& r_new) { - } - - void post_cluster(const state_t& s, count_t step, count_t N) { - if (flags & measurement_energy) { - float smaller_E = (float)E; - fwrite(&smaller_E, sizeof(float), 1, files[0]); - } - if (flags & measurement_clusterSize) { - fwrite(&(last_cluster_size), sizeof(uint32_t), 1, files[1]); - } - if (flags & measurement_magnetization) { - write_magnetization(M, files[2]); - } - if (flags & measurement_fourierZero) { - float smaller_X = (float)correlation_length(ReF, ImF, D); - fwrite(&smaller_X, sizeof(float), 1, files[3]); - } - - other_f(s, *this); - - } - - ~wolff_research_measurements() { - for (uint8_t i = 0; i < POSSIBLE_MEASUREMENTS; i++) { - if (flags & (1 << i)) { - fclose(files[i]); - } - } - - if (!silent) { - printf("\033[F\033[J"); - } - printf("WOLFF COMPLETE: E = %.2f, S = %" PRIv "\n", E, last_cluster_size); - - free(files); - } -}; - diff --git a/examples/include/randutils b/examples/include/randutils deleted file mode 160000 index 8486a61..0000000 --- a/examples/include/randutils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8486a610a954a8248c12485fb4cfc390a5f5f854 diff --git a/examples/ising.cpp b/examples/ising.cpp new file mode 100644 index 0000000..ffcb7e4 --- /dev/null +++ b/examples/ising.cpp @@ -0,0 +1,82 @@ + +#include +#include +#include + +#include "simple_measurement.hpp" + +#include +#include +#include + +int main(int argc, char *argv[]) { + + // set defaults + N_t N = (N_t)1e4; + D_t D = 2; + L_t L = 128; + double T = 2.26918531421; + double H = 0.0; + + int opt; + + // take command line arguments + while ((opt = getopt(argc, argv, "N:D:L:T:H:")) != -1) { + switch (opt) { + case 'N': // number of steps + N = (N_t)atof(optarg); + break; + case 'D': // dimension + D = atoi(optarg); + break; + case 'L': // linear size + L = atoi(optarg); + break; + case 'T': // temperature + T = atof(optarg); + break; + case 'H': // external field + H = atof(optarg); + break; + default: + exit(EXIT_FAILURE); + } + } + + // define the spin-spin coupling + std::function Z = [] (const ising_t& s1, const ising_t& s2) -> double { + return (double)(s1 * s2); + }; + + // define the spin-field coupling + std::function B = [=] (const ising_t& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system S(D, L, T, Z, B); + + // initialize the random number generator + auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + std::mt19937 rng{seed}; + + // define function that generates self-inverse rotations + std::function gen_R = [] (std::mt19937&, const ising_t& s) -> ising_t { + return ising_t(true); + }; + + // initailze the measurement object + simple_measurement A(S); + + // run wolff N times + wolff(N, S, gen_R, A, rng); + + // print the result of our measurements + std::cout << "Wolff complete!\nThe average energy per site was " << A.avgE() / S.nv + << ".\nThe average magnetization per site was " << A.avgM() / S.nv + << ".\nThe average cluster size per site was " << A.avgC() / S.nv << ".\n"; + + // exit + return 0; +} + diff --git a/examples/simple_ising.cpp b/examples/simple_ising.cpp deleted file mode 100644 index 24e4ae5..0000000 --- a/examples/simple_ising.cpp +++ /dev/null @@ -1,192 +0,0 @@ - -#include -#include - -#include "include/randutils/randutils.hpp" - -#include - -// define your R_t and X_t. here both are the same, ising_t -class ising_t { - public: - bool x; - - // both X_t and R_t need a default constructor (and destructor, if relevant) - ising_t() : x(false) {} - ising_t(bool x) : x(x) {} - - // R_t needs the member functions - // X_t act(const X_t& s) const {} - // R_t act(const R_t& s) const {} - // to define action on both spins and other transformations - ising_t act(const ising_t& s) const { - if (x) { - return ising_t(!(s.x)); - } else { - return ising_t(s.x); - } - } - - // R_t needs the member functions - // X_t act_inverse(const X_t& s) const {} - // R_t act_inverse(const R_t& s) const {} - // to define action of its inverse on both spins and other transformations - ising_t act_inverse(const ising_t& s) const { - return this->act(s); - } -}; - -// define how measurements should be taken by importing the interface wolff_measurement -class ising_measurements : public wolff_measurement { - private: - count_t n; - - double E; - int M; - v_t S; - - double totalE; - double totalM; - double totalS; - - public: - ising_measurements(D_t D, L_t L, double H) { - n = 0; - M = (int)pow(L, D); - E = -D * pow(L, D) - H * pow(L, D); - - totalE = 0; - totalM = 0; - totalS = 0; - } - - void pre_cluster(const state_t& s, count_t step, count_t N, v_t v0, const ising_t& R) { - S = 0; - } - - void plain_bond_added(v_t v, const ising_t& s_old, const ising_t& s_new, v_t vn, const ising_t& sn, double dE) { - E += dE; - } - - void ghost_bond_added(v_t v, const ising_t& s_old, const ising_t& s_new, double dE) { - E += dE; - - if (s_old.x) { - M++; - } else { - M--; - } - - if (s_new.x) { - M--; - } else { - M++; - } - } - - void plain_site_transformed(v_t v, const ising_t& s_old, const ising_t& s_new) { - S++; - } - - void ghost_site_transformed(const ising_t& R_old, const ising_t& R_new) { - } - - void post_cluster(const state_t& s, count_t step, count_t N) { - totalE += E; - totalM += M; - totalS += S; - n++; - } - - double avgE() { - return totalE / n; - } - - double avgM() { - return totalM / n; - } - - double avgS() { - return totalS / n; - } -}; - -int main(int argc, char *argv[]) { - - // set defaults - count_t N = (count_t)1e4; - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double H = 0.0; - - int opt; - - // take command line arguments - while ((opt = getopt(argc, argv, "N:D:L:T:H:")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field - H = atof(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // define the spin-spin coupling - std::function Z = [] (const ising_t& s1, const ising_t& s2) -> double { - if (s1.x == s2.x) { - return 1.0; - } else { - return -1.0; - } - }; - - // define the spin-field coupling - std::function B = [=] (const ising_t& s) -> double { - if (s.x) { - return -H; - } else { - return H; - } - }; - - // initialize the system - state_t s(D, L, T, Z, B); - - // initialize the random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define function that generates self-inverse rotations - std::function gen_R = [] (std::mt19937&, const ising_t& s) -> ising_t { - return ising_t(true); - }; - - // initailze the measurement object - ising_measurements m(D, L, H); - - // run wolff N times - wolff(N, s, gen_R, m, rng); - - // print the result of our measurements - std::cout << "Wolff complete!\nThe average energy per site was " << m.avgE() / s.nv - << ".\nThe average magnetization per site was " << m.avgM() / s.nv - << ".\nThe average cluster size per site was " << m.avgS() / s.nv << ".\n"; - - // exit - return 0; -} - diff --git a/examples/simple_measurement.hpp b/examples/simple_measurement.hpp new file mode 100644 index 0000000..2287c58 --- /dev/null +++ b/examples/simple_measurement.hpp @@ -0,0 +1,66 @@ + +#include + +template +class simple_measurement : public wolff_measurement { + private: + N_t n; + + double E; + typename X_t::M_t M; + v_t C; + + double totalE; + typename X_t::F_t totalM; + double totalC; + + public: + simple_measurement(const wolff_system& S) { + n = 0; + M = S.nv * S.s[0]; + E = - (S.ne * S.Z(S.s[0], S.s[0]) + S.nv * S.B(S.s[0])); + + totalE = 0; + totalM = 0.0 * (S.s[0]); + totalC = 0; + } + + void pre_cluster(N_t, N_t, const wolff_system&, v_t, const R_t&) { + C = 0; + } + + void plain_bond_visited(const wolff_system&, v_t, const X_t&, v_t, double dE) { + E += dE; + } + + void ghost_bond_visited(const wolff_system&, v_t, const X_t& s_old, const X_t& s_new, double dE) { + E += dE; + M += s_new - s_old; + } + + void plain_site_transformed(const wolff_system&, v_t, const X_t&) { + C++; + } + + void ghost_site_transformed(const wolff_system&, const R_t&) {} + + void post_cluster(N_t, N_t, const wolff_system&) { + totalE += E; + totalM += M; + totalC += C; + n++; + } + + double avgE() { + return totalE / n; + } + + typename X_t::F_t avgM() { + return totalM / n; + } + + double avgC() { + return totalC / n; + } +}; + diff --git a/examples/src/CMakeLists.txt b/examples/src/CMakeLists.txt deleted file mode 100644 index 3397426..0000000 --- a/examples/src/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ - -add_subdirectory(models) -add_subdirectory(tools) - diff --git a/examples/src/models/CMakeLists.txt b/examples/src/models/CMakeLists.txt deleted file mode 100644 index 0b0c111..0000000 --- a/examples/src/models/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ - -add_subdirectory(ising) -add_subdirectory(On) -add_subdirectory(potts) -add_subdirectory(roughening) - diff --git a/examples/src/models/On/CMakeLists.txt b/examples/src/models/On/CMakeLists.txt deleted file mode 100644 index 1b2e058..0000000 --- a/examples/src/models/On/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ - -add_executable(wolff_planar wolff_On.cpp) -add_executable(wolff_planar_2d_no-field wolff_On.cpp) -add_executable(wolff_heisenberg wolff_On.cpp) - -set_target_properties(wolff_planar PROPERTIES COMPILE_FLAGS "-DN_COMP=2") -set_target_properties(wolff_planar_2d_no-field PROPERTIES COMPILE_FLAGS "-DN_COMP=2 -DDIMENSION=2 -DNOFIELD") -set_target_properties(wolff_heisenberg PROPERTIES COMPILE_FLAGS "-DN_COMP=3") - -find_library(GL NAMES GL) -find_library(GLU NAMES GLU) -find_library(GLUT NAMES glut) - -if (${GLUT} MATCHES "GLUT-NOTFOUND") - target_link_libraries(wolff_planar wolff wolff_examples) - target_link_libraries(wolff_planar_2d_no-field wolff wolff_examples) - target_link_libraries(wolff_heisenberg wolff wolff_examples) -else() - target_compile_definitions(wolff_planar PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_planar_2d_no-field PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_heisenberg PUBLIC HAVE_GLUT) - - target_link_libraries(wolff_planar wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_planar_2d_no-field wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_heisenberg wolff wolff_examples glut GL GLU) -endif() - -install(TARGETS wolff_planar wolff_planar_2d_no-field wolff_heisenberg DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - diff --git a/examples/src/models/On/orthogonal.hpp b/examples/src/models/On/orthogonal.hpp deleted file mode 100644 index f13357f..0000000 --- a/examples/src/models/On/orthogonal.hpp +++ /dev/null @@ -1,202 +0,0 @@ - -#pragma once - -#include -#include -#include - -#include -#include -#include "vector.hpp" - -template -class orthogonal_t : public std::array, q> { - public : - bool is_reflection; - - orthogonal_t() : is_reflection(false) { - for (q_t i = 0; i < q; i++) { - (*this)[i].fill(0); - (*this)[i][i] = (T)1; - } - } - - vector_t act(const vector_t & v) const { - vector_t v_rot; - v_rot.fill(0); - - if (is_reflection) { - double prod = 0; - for (q_t i = 0; i < q; i++) { - prod += v[i] * (*this)[0][i]; - } - for (q_t i = 0; i < q; i++) { - v_rot[i] = v[i] - 2 * prod * (*this)[0][i]; - } - } else { - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot[i] += (*this)[i][j] * v[j]; - } - } - } - - return v_rot; - } - - orthogonal_t act(const orthogonal_t & m) const { - orthogonal_t m_rot; - - m_rot.is_reflection = false; - - if (is_reflection) { - for (q_t i = 0; i < q; i++) { - double akOki = 0; - - for (q_t k = 0; k < q; k++) { - akOki += (*this)[0][k] * m[k][i]; - } - - for (q_t j = 0; j < q; j++) { - m_rot[j][i] = m[j][i] - 2 * akOki * (*this)[0][j]; - } - } - } else { - for (q_t i = 0; i < q; i++) { - m_rot[i].fill(0); - for (q_t j = 0; j < q; j++) { - for (q_t k = 0; k < q; k++) { - m_rot[i][j] += (*this)[i][j] * m[j][k]; - } - } - } - } - - return m_rot; - } - - vector_t act_inverse(const vector_t & v) const { - if (is_reflection) { - return this->act(v); // reflections are their own inverse - } else { - vector_t v_rot; - v_rot.fill(0); - - for (q_t i = 0; i < q; i++) { - for (q_t j = 0; j < q; j++) { - v_rot[i] += (*this)[j][i] * v[j]; - } - } - - return v_rot; - } - } - - vector_t act_inverse(const orthogonal_t & m) const { - if (is_reflection) { - return this->act(m); // reflections are their own inverse - } else { - orthogonal_t m_rot; - m_rot.is_reflection = false; - - for (q_t i = 0; i < q; i++) { - m_rot[i].fill(0); - for (q_t j = 0; j < q; j++) { - for (q_t k = 0; k < q; k++) { - m_rot[i][j] += (*this)[j][i] * m[j][k]; - } - } - } - - return m_rot; - } - } - -}; - - -template -orthogonal_t generate_rotation_uniform (std::mt19937& r, const vector_t & v) { - std::normal_distribution dist(0.0,1.0); - orthogonal_t ptr; - ptr.is_reflection = true; - - double v2 = 0; - - for (q_t i = 0; i < q; i++) { - ptr[0][i] = dist(r); - v2 += ptr[0][i] * ptr[0][i]; - } - - double mag_v = sqrt(v2); - - for (q_t i = 0; i < q; i++) { - ptr[0][i] /= mag_v; - } - - return ptr; -} - -template -orthogonal_t generate_rotation_perturbation (std::mt19937& r, const vector_t & v0, double epsilon, unsigned int n) { - std::normal_distribution dist(0.0,1.0); - orthogonal_t m; - m.is_reflection = true; - - vector_t v; - - if (n > 1) { - std::uniform_int_distribution udist(0, n); - unsigned int rotation = udist(r); - - double cosr = cos(2 * M_PI * rotation / (double)n / 2.0); - double sinr = sin(2 * M_PI * rotation / (double)n / 2.0); - - v[0] = v0[0] * cosr - v0[1] * sinr; - v[1] = v0[1] * cosr + v0[0] * sinr; - - for (q_t i = 2; i < q; i++) { - v[i] = v0[i]; - } - } else { - v = v0; - } - - double m_dot_v = 0; - - for (q_t i = 0; i < q; i++) { - m[0][i] = dist(r); // create a random vector - m_dot_v += m[0][i] * v[i]; - } - - double v2 = 0; - - for (q_t i = 0; i < q; i++) { - m[0][i] = m[0][i] - m_dot_v * v[i]; // find the component orthogonal to v - v2 += pow(m[0][i], 2); - } - - double mag_v = sqrt(v2); - - for (q_t i = 0; i < q; i++) { - m[0][i] /= mag_v; // normalize - } - - v2 = 0; - - double factor = epsilon * dist(r); - - for (q_t i = 0; i < q; i++) { - m[0][i] += factor * v[i]; // perturb orthogonal vector in original direction - v2 += pow(m[0][i], 2); - } - - mag_v = sqrt(v2); - - for (q_t i = 0; i < q; i++) { - m[0][i] /= mag_v; // normalize - } - - return m; -} - diff --git a/examples/src/models/On/vector.hpp b/examples/src/models/On/vector.hpp deleted file mode 100644 index 1cdb60a..0000000 --- a/examples/src/models/On/vector.hpp +++ /dev/null @@ -1,118 +0,0 @@ - -#pragma once - -#include -#include -#include - -#include - -template -class vector_t : public std::array { - public: - - // M_t needs to hold the sum of nv spins - typedef vector_t M_t; - - // F_t needs to hold the double-weighted sum of spins - typedef vector_t F_t; - - vector_t() { - this->fill((T)0); - (*this)[1] = (T)1; - } - - vector_t(const T *x) { - for (q_t i = 0; i < q; i++) { - (*this)[i] = x[i]; - } - } - - template - inline vector_t& operator+=(const vector_t &v) { - for (q_t i = 0; i < q; i++) { - (*this)[i] += (U)v[i]; - } - return *this; - } - - template - inline vector_t& operator-=(const vector_t &v) { - for (q_t i = 0; i < q; i++) { - (*this)[i] -= (U)v[i]; - } - return *this; - } - - inline vector_t operator*(v_t x) const { - vector_t result; - for (q_t i = 0; i < q; i++) { - result[i] = x * (*this)[i]; - } - - return result; - } - - inline vector_t operator*(double x) const { - vector_t result; - for (q_t i = 0; i < q; i++) { - result[i] = x * (*this)[i]; - } - - return result; - } - - inline vector_t operator-(const vector_t& v) const { - vector_t diff = *this; - diff -= v; - return diff; - } -}; - - -template -double norm_squared(vector_t v) { - double tmp = 0; - for (T &x : v) { - tmp += pow(x, 2); - } - - return tmp; -} - -template -void write_magnetization(vector_t M, FILE *outfile) { - for (q_t i = 0; i < q; i++) { - fwrite(&(M[i]), sizeof(T), q, outfile); - } -} - -// below functions and definitions are unnecessary for wolff.h but useful. - -template // save some space and don't write whole doubles -void write_magnetization(vector_t M, FILE *outfile) { - for (q_t i = 0; i < q; i++) { - float M_tmp = (float)M[i]; - fwrite(&M_tmp, sizeof(float), 1, outfile); - } -} - -template -T dot(const vector_t & v1, const vector_t & v2) { - T prod = 0; - - for (q_t i = 0; i < q; i++) { - prod += v1[i] * v2[i]; - } - - return prod; -} - -template -double H_vector(const vector_t & v1, T *H) { - vector_t H_vec(H); - return (double)(dot (v1, H_vec)); -} - -char const *ON_strings[] = {"TRIVIAL", "ISING", "PLANAR", "HEISENBERG"}; - diff --git a/examples/src/models/On/wolff_On.cpp b/examples/src/models/On/wolff_On.cpp deleted file mode 100644 index 67f28a5..0000000 --- a/examples/src/models/On/wolff_On.cpp +++ /dev/null @@ -1,269 +0,0 @@ - -#include -#include - -#ifdef HAVE_GLUT -#include -#endif - -#include "orthogonal.hpp" -#include "vector.hpp" - -#include -#include -#include -#include - -typedef orthogonal_t orthogonal_R_t; -typedef vector_t vector_R_t; -typedef state_t On_t; - -// angle from the x-axis of a two-vector -double theta(vector_R_t v) { - double x = v[0]; - double y = v[1]; - - double val = atan(y / x); - - if (x < 0.0 && y > 0.0) { - return M_PI + val; - } else if ( x < 0.0 && y < 0.0 ) { - return - M_PI + val; - } else { - return val; - } -} - -double H_modulated(vector_R_t v, int order, double mag) { - return mag * cos(order * theta(v)); -} - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e7; - -#ifdef DIMENSION - D_t D = DIMENSION; -#else - D_t D = 2; -#endif - L_t L = 128; - double T = 2.26918531421; - double *H_vec = (double *)calloc(MAX_Q, sizeof(double)); - - bool silent = false; - bool use_pert = false; - bool N_is_sweeps = false; - bool draw = false; - unsigned int window_size = 512; - - bool modulated_field = false; - unsigned int order = 1; - - int opt; - q_t H_ind = 0; - double epsilon = 1; - -// unsigned char measurement_flags = measurement_energy | measurement_clusterSize; - - unsigned char measurement_flags = 0; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:spe:mo:M:Sdw:")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; -#ifdef DIMENSION - case 'D': // dimension - printf("Dimension was specified at compile time, you can't change it now!\n"); - exit(EXIT_FAILURE); -#else - case 'D': // dimension - D = atoi(optarg); - break; -#endif - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H_vec[H_ind] = atof(optarg); - H_ind++; - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'p': - use_pert = true; - break; - case 'e': - epsilon = atof(optarg); - break; - case 'm': - modulated_field = true; - break; - case 'M': - measurement_flags ^= 1 << atoi(optarg); - break; - case 'o': - order = atoi(optarg); - break; - case 'S': - N_is_sweeps = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - unsigned long timestamp; - - { - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; - } - - const char *pert_type; - - std::function gen_R; - - if (use_pert) { - double Hish; - if (modulated_field) { - Hish = fabs(H_vec[0]); - } else { - double H2 = 0; - for (q_t i = 0; i < N_COMP; i++) { - H2 += pow(H_vec[i], 2); - } - Hish = sqrt(H2); - } - - epsilon = sqrt((N_COMP - 1) * T / (D + Hish / 2)) / 2; - - gen_R = std::bind(generate_rotation_perturbation , std::placeholders::_1, std::placeholders::_2, epsilon, order); - pert_type = "PERTURB5"; - } else { - gen_R = generate_rotation_uniform ; - pert_type = "UNIFORM"; - } - - FILE *outfile_info = fopen("wolff_metadata.txt", "a"); - - fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"%s\", \"q\" -> %d, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"FIELD_TYPE\" -> ", timestamp, ON_strings[N_COMP], N_COMP, D, L, (v_t)pow(L, D), D * (v_t)pow(L, D), T); - if (modulated_field) { - fprintf(outfile_info, "\"MODULATED\", \"ORDER\" -> %d, \"H\" -> %.15f, ", order, H_vec[0]); - } else { - fprintf(outfile_info, "\"VECTOR\", \"H\" -> {"); - for (q_t i = 0; i < N_COMP; i++) { - fprintf(outfile_info, "%.15f", H_vec[i]); - if (i < N_COMP - 1) { - fprintf(outfile_info, ", "); - } - } - fprintf(outfile_info, "}, "); - } - - fprintf(outfile_info, "\"GENERATOR\" -> \"%s\"", pert_type); - - if (use_pert) { - fprintf(outfile_info, ", \"EPS\" -> %g", epsilon); - } - - fprintf(outfile_info, " |>\n"); - - fclose(outfile_info); - - std::function &)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const On_t& s, const wolff_research_measurements& m) { - sum_of_clusterSize += m.last_cluster_size; - }; - } else if (draw) { -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - other_f = [&] (const On_t& s, const wolff_research_measurements& m) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(L, 2); i++) { -#ifdef NOFIELD - vector_R_t v_tmp = s.spins[i]; -#else - vector_R_t v_tmp = s.R.act_inverse(s.spins[i]); -#endif - double thetai = fmod(2 * M_PI + theta(v_tmp), 2 * M_PI); - double saturation = 0.7; - double value = 0.9; - double chroma = saturation * value; - glColor3f(chroma * hue_to_R(thetai) + (value - chroma), chroma * hue_to_G(thetai) + (value - chroma), chroma * hue_to_B(thetai) + (value - chroma)); - glRecti(i / L, i % L, (i / L) + 1, (i % L) + 1); - } - glFlush(); - }; -#endif - } else { - other_f = [] (const On_t& s, const wolff_research_measurements& m) {}; - } - - std::function H; - - if (modulated_field) { - H = std::bind(H_modulated, std::placeholders::_1, order, H_vec[0]); - } else { - H = std::bind(H_vector , std::placeholders::_1, H_vec); - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - -#ifndef NOFIELD - state_t s(D, L, T, dot , H); -#else - state_t s(D, L, T, dot ); -#endif - - wolff_research_measurements m(measurement_flags, timestamp, other_f, s, silent); - - if (N_is_sweeps) { - count_t N_rounds = 0; - printf("\n"); - while (sum_of_clusterSize < N * s.nv) { - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - wolff (N, s, gen_R, m, rng); - N_rounds++; - } - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - } else { - wolff (N, s, gen_R, m, rng); - } - - free(H_vec); - - return 0; -} - diff --git a/examples/src/models/ising/CMakeLists.txt b/examples/src/models/ising/CMakeLists.txt deleted file mode 100644 index 9f4acd4..0000000 --- a/examples/src/models/ising/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ - -add_executable(wolff_ising wolff_ising.cpp) -add_executable(wolff_ising_2d wolff_ising.cpp) -add_executable(wolff_ising_2d_no-field wolff_ising.cpp) -add_executable(wolff_random-field_ising wolff_random-field_ising.cpp) - -set_target_properties(wolff_ising_2d PROPERTIES COMPILE_FLAGS "-DDIMENSION=2") -set_target_properties(wolff_ising_2d_no-field PROPERTIES COMPILE_FLAGS "-DDIMENSION=2 -DNOFIELD") - -find_library(GL NAMES GL) -find_library(GLU NAMES GLU) -find_library(GLUT NAMES glut) - -if (${GLUT} MATCHES "GLUT-NOTFOUND") - target_link_libraries(wolff_ising wolff wolff_examples) - target_link_libraries(wolff_ising_2d wolff wolff_examples) - target_link_libraries(wolff_ising_2d_no-field wolff wolff_examples) - target_link_libraries(wolff_random-field_ising wolff wolff_examples) -else() - target_compile_definitions(wolff_ising PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_ising_2d PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_ising_2d_no-field PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_random-field_ising PUBLIC HAVE_GLUT) - - target_link_libraries(wolff_ising wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_ising_2d wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_ising_2d_no-field wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_random-field_ising wolff wolff_examples glut GL GLU) -endif() - -install(TARGETS wolff_ising wolff_ising_2d wolff_ising_2d_no-field wolff_random-field_ising DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - diff --git a/examples/src/models/ising/ising.hpp b/examples/src/models/ising/ising.hpp deleted file mode 100644 index 73b06ed..0000000 --- a/examples/src/models/ising/ising.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include -#include - -#include - -// all that is required to use wolff.hpp is a default constructor -class ising_t { - public: - bool x; - - ising_t() : x(false) {} - - // optional constructors for syntactic sugar - ising_t(bool x) : x(x) {} - ising_t(int x) : x((bool)x) {} - - /* below this comment is code required only for using measure.hpp in the - * examples folder, which provides an interface for measuring several - * generic features of models. these require - * - * - an M_t, representing the magnetization or sum of all spins - * - an F_t, representing a double-weighted version of the magnetization - * - the overloaded operator *, which takes a v_t (unsigned int) and returns an M_t - * - the overloaded operator *, which takes a double and returns an F_t - * - the overloaded operator -, which takes another X_t and returns an M_t - */ - - typedef int M_t; - typedef double F_t; - - inline int operator*(v_t a) const { - if (x) { - return -(int)a; - } else { - return (int)a; - } - } - - inline double operator*(double a) const { - if (x) { - return -a; - } else { - return a; - } - } - - inline int operator-(const ising_t &s) const { - if (x == s.x) { - return 0; - } else { - if (x) { - return -2; - } else { - return 2; - } - } - } -}; - -/* using measure.hpp additionally requires a norm_squared function which takes - * an F_t to a double, and a write_magnetization function, which takes an M_t - * and a FILE pointer and appropriately records the contents of the former to - * the latter. - */ - -double norm_squared(double s) { - return pow(s, 2); -} - -void write_magnetization(int M, FILE *outfile) { - fwrite(&M, sizeof(int), 1, outfile); -} - -/* these definitions allow wolff/finite_states.hpp to be invoked and provide - * much faster performance for models whose number of possible spin - * configurations is finite. - */ - -#define N_STATES 2 -const ising_t states[2] = {ising_t(0), ising_t(1)}; -q_t state_to_ind(ising_t state) { return (q_t)state.x; } - diff --git a/examples/src/models/ising/wolff_ising.cpp b/examples/src/models/ising/wolff_ising.cpp deleted file mode 100644 index de04f32..0000000 --- a/examples/src/models/ising/wolff_ising.cpp +++ /dev/null @@ -1,197 +0,0 @@ - -#include -#include - -// if you have GLUT installed, you can see graphics! -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "z2.hpp" -#include "ising.hpp" - -// finite_states.h can be included for spin types that have special variables -// defined, and it causes wolff execution to use precomputed bond probabilities -#include - -#include - -// measure.hpp contains useful functions for saving timeseries to files -#include - -// include wolff.hpp -#include - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double H = 0.0; - - bool silent = false; - bool draw = false; - bool N_is_sweeps = false; - unsigned int window_size = 512; - - // don't measure anything by default - unsigned char measurement_flags = 0; - - int opt; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:M:S")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field - H = atof(optarg); - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'S': - N_is_sweeps = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - case 'M': - measurement_flags ^= 1 << atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // get nanosecond timestamp for unique run id - unsigned long timestamp; - - { - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function Z = [] (const ising_t& s1, const ising_t& s2) -> double { - if (s1.x == s2.x) { - return 1.0; - } else { - return -1.0; - } - }; - - // define spin-field coupling - std::function B = [=] (const ising_t& s) -> double { - if (s.x) { - return -H; - } else { - return H; - } - }; - - // initialize state object -#ifndef NOFIELD - state_t s(D, L, T, Z, B); -#else - state_t s(D, L, T, Z); -#endif - - // define function that generates self-inverse rotations - std::function gen_R = [] (std::mt19937&, const ising_t& s) -> z2_t { - return z2_t(true); - }; - - std::function &, const wolff_research_measurements&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const state_t& s, const wolff_research_measurements& meas) { - sum_of_clusterSize += meas.last_cluster_size; - }; - } else if (draw) { -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - other_f = [] (const state_t & s, const wolff_research_measurements& meas) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(s.L, 2); i++) { -#ifdef NOFIELD - if (s.spins[i].x == false) { -#else - if (s.spins[i].x == s.R.x) { -#endif - glColor3f(0.0, 0.0, 0.0); - } else { - glColor3f(1.0, 1.0, 1.0); - } - glRecti(i / s.L, i % s.L, (i / s.L) + 1, (i % s.L) + 1); - } - glFlush(); - }; -#endif - } else { - other_f = [] (const state_t& s, const wolff_research_measurements& meas) {}; - } - - wolff_research_measurements m(measurement_flags, timestamp, other_f, s, silent); - - // add line to metadata file with run info - { - FILE *outfile_info = fopen("wolff_metadata.txt", "a"); - - fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"ISING\", \"q\" -> 2, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> %.15f |>\n", timestamp, s.D, s.L, s.nv, s.ne, T, H); - - fclose(outfile_info); - } - - // run wolff for N cluster flips - if (N_is_sweeps) { - count_t N_rounds = 0; - printf("\n"); - while (sum_of_clusterSize < N * s.nv) { - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - wolff(N, s, gen_R, m, rng); - N_rounds++; - } - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - } else { - wolff(N, s, gen_R, m, rng); - } - - return 0; -} - diff --git a/examples/src/models/ising/wolff_random-field_ising.cpp b/examples/src/models/ising/wolff_random-field_ising.cpp deleted file mode 100644 index ce26b88..0000000 --- a/examples/src/models/ising/wolff_random-field_ising.cpp +++ /dev/null @@ -1,207 +0,0 @@ - -#define SITE_DEPENDENCE - -#include -#include - -// if you have GLUT installed, you can see graphics! -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "z2.hpp" -#include "ising.hpp" - -#include - -// measure.hpp contains useful functions for saving timeseries to files -#include - -// include wolff.hpp -#include - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double H = 0.0; - - bool silent = false; - bool draw = false; - bool N_is_sweeps = false; - unsigned int window_size = 512; - - // don't measure anything by default - unsigned char measurement_flags = 0; - - int opt; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:M:S")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field - H = atof(optarg); - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'S': - N_is_sweeps = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - case 'M': - measurement_flags ^= 1 << atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // get nanosecond timestamp for unique run id - unsigned long timestamp; - - { - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function Z = [] (const ising_t& s1, const ising_t& s2) -> double { - if (s1.x == s2.x) { - return 1.0; - } else { - return -1.0; - } - }; - - // create random field - std::vector random_field_values(pow(L, D)); - std::normal_distribution distribution(0.0, H); - for (v_t i = 0; i < pow(L, D); i++) { - random_field_values[i] = distribution(rng); - } - - // define spin-field coupling - std::function B = [&] (v_t v, const ising_t& s) -> double { - if (s.x) { - return -random_field_values[v]; - } else { - return random_field_values[v]; - } - }; - - // initialize state object -#ifndef NOFIELD - state_t s(D, L, T, Z, B); -#else - state_t s(D, L, T, Z); -#endif - - // define function that generates self-inverse rotations - std::function gen_R = [] (std::mt19937&, const ising_t& s) -> z2_t { - return z2_t(true); - }; - - FILE **outfiles = measure_setup_files(measurement_flags, timestamp); - - std::function &)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const state_t& s) { - sum_of_clusterSize += s.last_cluster_size; - }; - } else if (draw) { -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - other_f = [] (const state_t & s) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(s.L, 2); i++) { -#ifdef NOFIELD - if (s.spins[i].x == false) { -#else - if (s.spins[i].x == s.R.x) { -#endif - glColor3f(0.0, 0.0, 0.0); - } else { - glColor3f(1.0, 1.0, 1.0); - } - glRecti(i / s.L, i % s.L, (i / s.L) + 1, (i % s.L) + 1); - } - glFlush(); - }; -#endif - } else { - other_f = [] (const state_t& s) {}; - } - - std::function &)> measurements = measure_function_write_files(measurement_flags, outfiles, other_f); - - // add line to metadata file with run info - { - FILE *outfile_info = fopen("wolff_metadata.txt", "a"); - - fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"ISING\", \"q\" -> 2, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> %.15f |>\n", timestamp, s.D, s.L, s.nv, s.ne, T, H); - - fclose(outfile_info); - } - - // run wolff for N cluster flips - if (N_is_sweeps) { - count_t N_rounds = 0; - printf("\n"); - while (sum_of_clusterSize < N * s.nv) { - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, s.E, s.last_cluster_size); - wolff(N, s, gen_R, measurements, rng, silent); - N_rounds++; - } - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, s.E, s.last_cluster_size); - } else { - wolff(N, s, gen_R, measurements, rng, silent); - } - - measure_free_files(measurement_flags, outfiles); - - return 0; - -} - diff --git a/examples/src/models/ising/z2.hpp b/examples/src/models/ising/z2.hpp deleted file mode 100644 index 19b6c05..0000000 --- a/examples/src/models/ising/z2.hpp +++ /dev/null @@ -1,53 +0,0 @@ - -#pragma once - -#include -#include "ising.hpp" - -/* The minimum definition for a group type R_t to act on a spin type X_t is - * given by the following. - * - * void init(R_t *p); - * void free_spin(R_t r); - * R_t copy(R_t r); - * X_t act(R_t r, X_t x); - * R_t act(R_t r, R_t r); - * X_t act_inverse(R_t r, X_t x); - * R_t act_inverse(R_t r, R_t r); - * - */ - -class z2_t { - public: - bool x; - - z2_t() : x(false) {} - - z2_t(bool x) : x(x) {} - - ising_t act(const ising_t& s) const { - if (x) { - return ising_t(!s.x); - } else { - return ising_t(s.x); - } - } - - z2_t act(const z2_t& r) const { - if (x) { - return z2_t(!r.x); - } else { - return z2_t(r.x); - } - } - - ising_t act_inverse(const ising_t& s) const { - return this->act(s); - } - - z2_t act_inverse(const z2_t& r) const { - return this->act(r); - } -}; - - diff --git a/examples/src/models/potts/CMakeLists.txt b/examples/src/models/potts/CMakeLists.txt deleted file mode 100644 index e78aa6b..0000000 --- a/examples/src/models/potts/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ - -add_executable(wolff_3potts wolff_potts.cpp) -add_executable(wolff_4potts wolff_potts.cpp) -add_executable(wolff_7potts wolff_potts.cpp) -add_executable(wolff_3clock wolff_clock.cpp) -add_executable(wolff_5clock wolff_clock.cpp) - -set_target_properties(wolff_3potts PROPERTIES COMPILE_FLAGS "-DPOTTSQ=3") -set_target_properties(wolff_4potts PROPERTIES COMPILE_FLAGS "-DPOTTSQ=4") -set_target_properties(wolff_7potts PROPERTIES COMPILE_FLAGS "-DPOTTSQ=7") -set_target_properties(wolff_3clock PROPERTIES COMPILE_FLAGS "-DPOTTSQ=3") -set_target_properties(wolff_5clock PROPERTIES COMPILE_FLAGS "-DPOTTSQ=5") - -find_library(GL NAMES GL) -find_library(GLU NAMES GLU) -find_library(GLUT NAMES glut) - -if (${GLUT} MATCHES "GLUT-NOTFOUND") - target_link_libraries(wolff_3potts wolff wolff_examples) - target_link_libraries(wolff_4potts wolff wolff_examples) - target_link_libraries(wolff_7potts wolff wolff_examples) - target_link_libraries(wolff_3clock wolff wolff_examples) - target_link_libraries(wolff_5clock wolff wolff_examples) -else() - target_compile_definitions(wolff_3potts PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_4potts PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_7potts PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_3clock PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_5clock PUBLIC HAVE_GLUT) - - target_link_libraries(wolff_3potts wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_4potts wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_7potts wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_3clock wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_5clock wolff wolff_examples glut GL GLU) -endif() - -install(TARGETS wolff_3potts wolff_4potts wolff_7potts wolff_3clock wolff_5clock DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - diff --git a/examples/src/models/potts/dihedral.hpp b/examples/src/models/potts/dihedral.hpp deleted file mode 100644 index cbc5687..0000000 --- a/examples/src/models/potts/dihedral.hpp +++ /dev/null @@ -1,48 +0,0 @@ - -#pragma once - -#include -#include "potts.hpp" - -template -class dihedral_t { - public: - bool is_reflection; - q_t x; - - dihedral_t() : is_reflection(false), x(0) {} - dihedral_t(bool x, q_t y) : is_reflection(x), x(y) {} - - potts_t act(const potts_t& s) const { - if (this->is_reflection) { - return potts_t(((q + this->x) - s.x) % q); - } else { - return potts_t((this->x + s.x) % q); - } - } - - dihedral_t act(dihedral_t r) const { - if (this->is_reflection) { - return dihedral_t(!(r.is_reflection), ((q + this->x) - r.x) % q); - } else { - return dihedral_t(r.is_reflection, (this->x + r.x) % q); - } - } - - potts_t act_inverse(potts_t s) const { - if (this->is_reflection) { - return this->act(s); - } else { - return potts_t(((s.x + q) - this->x) % q); - } - } - - dihedral_t act_inverse(dihedral_t r) const { - if (this->is_reflection) { - return this->act(r); - } else { - return dihedral_t(r.is_reflection, ((r.x + q) - this->x) % q); - } - } -}; - diff --git a/examples/src/models/potts/potts.hpp b/examples/src/models/potts/potts.hpp deleted file mode 100644 index f4765e2..0000000 --- a/examples/src/models/potts/potts.hpp +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include -#include - -#include -#include "../On/vector.hpp" - -template -class potts_t { - public: - q_t x; - - typedef vector_t M_t; - typedef vector_t F_t; - - potts_t() : x(0) {} - potts_t(q_t x) : x(x) {} - - inline vector_t operator*(v_t a) const { - vector_t result; - result.fill(0); - result[x] = (int)a; - - return result; - } - - inline vector_t operator*(double a) const { - vector_t result; - result.fill(0.0); - result[x] = a; - - return result; - } - - inline vector_t operator-(const potts_t &s) const { - vector_t result; - result.fill(0); - - result[x]++; - result[s.x]--; - - return result; - } -}; - -// we could inherit norm_squared from vector.h, but convention dictates that -// potts norms be changed by a constant factor -template -double norm_squared(vector_t s) { - double total = 0; - for (double& x : s) { - total += pow(x, 2); - } - - return total * (double)q / ((double)q - 1.0); -} - -// we could inherit write_magnetization from vector.h, but since M.x must sum -// to nv we don't need to write the last element -template -void write_magnetization(vector_t M, FILE *outfile) { - for (int& x : M) { - fwrite(&x, sizeof(int), q - 1, outfile); - } -} - -// knock yourself out -const potts_t states[256] = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}, {37}, {38}, {39}, {40}, {41}, {42}, {43}, {44}, {45}, {46}, {47}, {48}, {49}, {50}, {51}, {52}, {53}, {54}, {55}, {56}, {57}, {58}, {59}, {60}, {61}, {62}, {63}, {64}, {65}, {66}, {67}, {68}, {69}, {70}, {71}, {72}, {73}, {74}, {75}, {76}, {77}, {78}, {79}, {80}, {81}, {82}, {83}, {84}, {85}, {86}, {87}, {88}, {89}, {90}, {91}, {92}, {93}, {94}, {95}, {96}, {97}, {98}, {99}, {100}, {101}, {102}, {103}, {104}, {105}, {106}, {107}, {108}, {109}, {110}, {111}, {112}, {113}, {114}, {115}, {116}, {117}, {118}, {119}, {120}, {121}, {122}, {123}, {124}, {125}, {126}, {127}, {128}, {129}, {130}, {131}, {132}, {133}, {134}, {135}, {136}, {137}, {138}, {139}, {140}, {141}, {142}, {143}, {144}, {145}, {146}, {147}, {148}, {149}, {150}, {151}, {152}, {153}, {154}, {155}, {156}, {157}, {158}, {159}, {160}, {161}, {162}, {163}, {164}, {165}, {166}, {167}, {168}, {169}, {170}, {171}, {172}, {173}, {174}, {175}, {176}, {177}, {178}, {179}, {180}, {181}, {182}, {183}, {184}, {185}, {186}, {187}, {188}, {189}, {190}, {191}, {192}, {193}, {194}, {195}, {196}, {197}, {198}, {199}, {200}, {201}, {202}, {203}, {204}, {205}, {206}, {207}, {208}, {209}, {210}, {211}, {212}, {213}, {214}, {215}, {216}, {217}, {218}, {219}, {220}, {221}, {222}, {223}, {224}, {225}, {226}, {227}, {228}, {229}, {230}, {231}, {232}, {233}, {234}, {235}, {236}, {237}, {238}, {239}, {240}, {241}, {242}, {243}, {244}, {245}, {246}, {247}, {248}, {249}, {250}, {251}, {252}, {253}, {254}, {255}}; -template -q_t state_to_ind(potts_t state) { return (q_t)state.x; } - diff --git a/examples/src/models/potts/symmetric.hpp b/examples/src/models/potts/symmetric.hpp deleted file mode 100644 index bc8673f..0000000 --- a/examples/src/models/potts/symmetric.hpp +++ /dev/null @@ -1,52 +0,0 @@ - -#pragma once - -#include -#include -#include -#include "potts.hpp" - -template -class symmetric_t : public std::array { - public: - - symmetric_t() { - for (q_t i = 0; i < q; i++) { - (*this)[i] = i; - } - } - - potts_t act(const potts_t &s) const { - return potts_t((*this)[s.x]); - } - - symmetric_t act(const symmetric_t& r) const { - symmetric_t r_rot; - for (q_t i = 0; i < q; i++) { - r_rot[i] = (*this)[r[i]]; - } - - return r_rot; - } - - potts_t act_inverse(const potts_t& s) const { - for (q_t i = 0; i < q; i++) { - if ((*this)[i] == s.x) { - return potts_t(i); - } - } - - printf("Your spin wasn't a valid state!", s.x); - exit(EXIT_FAILURE); - } - - symmetric_t act_inverse(const symmetric_t& r) const { - symmetric_t r_rot; - for (q_t i = 0; i < q; i++) { - r_rot[(*this)[i]] = r[i]; - } - - return r_rot; - } -}; - diff --git a/examples/src/models/potts/wolff_clock.cpp b/examples/src/models/potts/wolff_clock.cpp deleted file mode 100644 index 0706cc5..0000000 --- a/examples/src/models/potts/wolff_clock.cpp +++ /dev/null @@ -1,149 +0,0 @@ - -#include - -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "dihedral.hpp" -#include "potts.hpp" -#include -#include - -// hack to speed things up considerably -#define N_STATES POTTSQ -#include - -#include - -// include wolff.hpp -#include - -typedef state_t , potts_t> sim_t; - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double *H_vec = (double *)calloc(MAX_Q, sizeof(double)); - - bool silent = false; - bool draw = false; - unsigned int window_size = 512; - - int opt; - q_t H_ind = 0; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H_vec[H_ind] = atof(optarg); - H_ind++; - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function &, const potts_t&)> Z = [] (const potts_t& s1, const potts_t& s2) -> double { - return cos(2 * M_PI * (double)(s1.x + POTTSQ - s2.x) / (double)POTTSQ); - }; - - // define spin-field coupling - std::function &)> B = [=] (const potts_t& s) -> double { - return H_vec[s.x]; - }; - - // initialize state object - state_t , potts_t> s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function (std::mt19937&, potts_t)> gen_R = [] (std::mt19937& r, potts_t v) -> dihedral_t { - dihedral_t rot; - rot.is_reflection = true; - std::uniform_int_distribution dist(0, POTTSQ - 2); - q_t x = dist(r); - rot.x = (2 * v.x + x + 1) % POTTSQ; - - return rot; - }; - - // define function that updates any number of measurements - std::function , potts_t>&)> measurement; - - if (!draw) { - // a very simple example: measure the average magnetization - measurement = [&] (const sim_t& s, const wolff_research_measurements, potts_t>&) { - }; - } else { - // a more complex example: measure the average magnetization, and draw the spin configuration to the screen - -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - measurement = [&] (const sim_t& s, const wolff_research_measurements, potts_t>&) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(L, 2); i++) { - potts_t tmp_s = s.R.act_inverse(s.spins[i]); - glColor3f(hue_to_R(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_G(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_B(tmp_s.x * 2 * M_PI / POTTSQ)); - glRecti(i / L, i % L, (i / L) + 1, (i % L) + 1); - } - glFlush(); - }; -#endif - } - - wolff_research_measurements, potts_t> m(0, 0, measurement, s, silent); - - // run wolff for N cluster flips - wolff(N, s, gen_R, m, rng); - - // free the random number generator - - return 0; - -} - diff --git a/examples/src/models/potts/wolff_potts.cpp b/examples/src/models/potts/wolff_potts.cpp deleted file mode 100644 index 7b92ac1..0000000 --- a/examples/src/models/potts/wolff_potts.cpp +++ /dev/null @@ -1,210 +0,0 @@ - -#include -#include - -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "symmetric.hpp" -#include "potts.hpp" - -// hack to speed things up considerably -#define N_STATES POTTSQ -#include - -// include wolff.h -#include -#include -#include -#include - -typedef state_t , potts_t> sim_t; - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double *H_vec = (double *)calloc(MAX_Q, sizeof(double)); - - bool silent = false; - bool draw = false; - bool N_is_sweeps = false; - unsigned int window_size = 512; - - // don't measure anything by default - unsigned char measurement_flags = 0; - - int opt; - q_t H_ind = 0; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:M:S")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H_vec[H_ind] = atof(optarg); - H_ind++; - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'S': - N_is_sweeps = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - case 'M': - measurement_flags ^= 1 << atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // get nanosecond timestamp for unique run id - unsigned long timestamp; - - { - struct timespec spec; - clock_gettime(CLOCK_REALTIME, &spec); - timestamp = spec.tv_sec*1000000000LL + spec.tv_nsec; - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function &, const potts_t&)> Z = [] (const potts_t& s1, const potts_t& s2) -> double { - if (s1.x == s2.x) { - return 1.0; - } else { - return 0.0; - } - }; - - // define spin-field coupling - std::function &)> B = [=] (const potts_t& s) -> double { - return H_vec[s.x]; - }; - - // initialize state object - state_t , potts_t> s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function (std::mt19937&, potts_t)> gen_R = [] (std::mt19937& r, potts_t v) -> symmetric_t { - symmetric_t rot; - - std::uniform_int_distribution dist(0, POTTSQ - 2); - q_t j = dist(r); - q_t swap_v; - if (j < v.x) { - swap_v = j; - } else { - swap_v = j + 1; - } - - rot[v.x] = swap_v; - rot[swap_v] = v.x; - - return rot; - }; - - std::function , potts_t>&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const sim_t& s, const wolff_research_measurements, potts_t>& m) { - sum_of_clusterSize += m.last_cluster_size; - }; - } else if (draw) { -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - other_f = [] (const sim_t& s, const wolff_research_measurements, potts_t>& m) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(s.L, 2); i++) { - potts_t tmp_s = s.R.act_inverse(s.spins[i]); - glColor3f(hue_to_R(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_G(tmp_s.x * 2 * M_PI / POTTSQ), hue_to_B(tmp_s.x * 2 * M_PI / POTTSQ)); - glRecti(i / s.L, i % s.L, (i / s.L) + 1, (i % s.L) + 1); - } - glFlush(); - }; -#endif - } else { - other_f = [] (const sim_t& s, const wolff_research_measurements, potts_t>& m) {}; - } - - wolff_research_measurements, potts_t> m(measurement_flags, timestamp, other_f, s, silent); - - // add line to metadata file with run info - { - FILE *outfile_info = fopen("wolff_metadata.txt", "a"); - - fprintf(outfile_info, "<| \"ID\" -> %lu, \"MODEL\" -> \"POTTS\", \"q\" -> %d, \"D\" -> %" PRID ", \"L\" -> %" PRIL ", \"NV\" -> %" PRIv ", \"NE\" -> %" PRIv ", \"T\" -> %.15f, \"H\" -> {", timestamp, POTTSQ, s.D, s.L, s.nv, s.ne, T); - - for (q_t i = 0; i < POTTSQ; i++) { - fprintf(outfile_info, "%.15f", H_vec[i]); - if (i < POTTSQ - 1) { - fprintf(outfile_info, ", "); - } - } - - fprintf(outfile_info, "} |>\n"); - - fclose(outfile_info); - } - - // run wolff for N cluster flips - if (N_is_sweeps) { - count_t N_rounds = 0; - printf("\n"); - while (sum_of_clusterSize < N * s.nv) { - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - wolff(N, s, gen_R, m, rng); - N_rounds++; - } - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n\n", (count_t)((double)sum_of_clusterSize / (double)s.nv), N, m.E, m.last_cluster_size); - } else { - wolff(N, s, gen_R, m, rng); - } - - // free the random number generator - free(H_vec); - - return 0; - -} - diff --git a/examples/src/models/roughening/CMakeLists.txt b/examples/src/models/roughening/CMakeLists.txt deleted file mode 100644 index 163a0b9..0000000 --- a/examples/src/models/roughening/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ - -add_executable(wolff_dgm wolff_dgm.cpp) -add_executable(wolff_cgm wolff_cgm.cpp) - -find_library(GL NAMES GL) -find_library(GLU NAMES GLU) -find_library(GLUT NAMES glut) - -if (${GLUT} MATCHES "GLUT-NOTFOUND") - target_link_libraries(wolff_dgm wolff wolff_examples) - target_link_libraries(wolff_cgm wolff wolff_examples) -else() - target_compile_definitions(wolff_dgm PUBLIC HAVE_GLUT) - target_compile_definitions(wolff_cgm PUBLIC HAVE_GLUT) - - target_link_libraries(wolff_dgm wolff wolff_examples glut GL GLU) - target_link_libraries(wolff_cgm wolff wolff_examples glut GL GLU) -endif() - -install(TARGETS wolff_dgm wolff_cgm DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - diff --git a/examples/src/models/roughening/dihedral_inf.hpp b/examples/src/models/roughening/dihedral_inf.hpp deleted file mode 100644 index 19fa195..0000000 --- a/examples/src/models/roughening/dihedral_inf.hpp +++ /dev/null @@ -1,47 +0,0 @@ - -#include -#include -#include "height.hpp" - -template -class dihedral_inf_t { - public: - bool is_reflection; - T x; - - dihedral_inf_t() : is_reflection(false), x(0) {} - dihedral_inf_t(bool x, T y) : is_reflection(x), x(y) {} - - height_t act(const height_t& h) const { - if (this->is_reflection) { - return height_t(this->x - h.x); - } else { - return height_t(this->x + h.x); - } - } - - dihedral_inf_t act(const dihedral_inf_t& r) const { - if (this->is_reflection) { - return dihedral_inf_t(!r.is_reflection, this->x - r.x); - } else { - return dihedral_inf_t(r.is_reflection, this->x + r.x); - } - } - - height_t act_inverse(const height_t& h) const { - if (this->is_reflection) { - return this->act(h); - } else { - return height_t(h.x - this->x); - } - } - - dihedral_inf_t act_inverse(const dihedral_inf_t& r) const { - if (this->is_reflection) { - return this->act(r); - } else { - return dihedral_inf_t(r.is_reflection, r.x - this->x); - } - } -}; - diff --git a/examples/src/models/roughening/height.hpp b/examples/src/models/roughening/height.hpp deleted file mode 100644 index 4023063..0000000 --- a/examples/src/models/roughening/height.hpp +++ /dev/null @@ -1,75 +0,0 @@ - -#pragma once - -#include -#include - -#include - -/* The following is the minimum definition of a spin class. - * - * The class must contain an M_t and an F_t for holding the sum of an - * integer number of spins and a double-weighted number of spins, - * respectively. - * - * void init(X_t *p); - * void free_spin(X_t p); - * void free_spin(M_t p); - * void free_spin(F_t p); - * X_t copy(X_t x); - * void add(M_t *x1, int factor, X_t x2); - * void add(F_t *x1, double factor, X_t x2); - * M_t scalar_multiple(int factor, X_t x); - * F_t scalar_multiple(double factor, X_t x); - * double norm_squared(F_t x); - * void write_magnetization(M_t M, FILE *outfile); - * - */ - -template -struct height_t { - T x; - - typedef T M_t; - typedef double F_t; - - height_t() : x(0) {} - - height_t(T x) : x(x) {} - - inline T operator*(v_t a) const { - return x * a; - } - - inline double operator*(double a) const { - return x * a; - } - - inline T operator-(const height_t& h) const { - return x - h.x; - } -}; - -template -inline T& operator+=(T& M, const height_t &h) { - M += h.x; - - return M; -} - -template -inline T& operator-=(T& M, const height_t &h) { - M -= h.x; - - return M; -} - -double norm_squared(double h) { - return pow(h, 2); -} - -template -void write_magnetization(T M, FILE *outfile) { - fwrite(&M, sizeof(T), 1, outfile); -} - diff --git a/examples/src/models/roughening/wolff_cgm.cpp b/examples/src/models/roughening/wolff_cgm.cpp deleted file mode 100644 index 65f8d66..0000000 --- a/examples/src/models/roughening/wolff_cgm.cpp +++ /dev/null @@ -1,167 +0,0 @@ - -#include - -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "dihedral_inf.hpp" -#include "height.hpp" - -#include - -// include wolff.h -#include - -typedef state_t , height_t> sim_t; - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double H = 0; - - bool silent = false; - bool draw = false; - unsigned int window_size = 512; - double epsilon = 1; - - int opt; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:e:")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H = atof(optarg); - break; - case 'e': // external field. nth call couples to state n - epsilon = atof(optarg); - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function &, const height_t&)> Z = [] (const height_t& h1, const height_t& h2) -> double { - return -pow(h1.x - h2.x, 2); - }; - - // define spin-field coupling - std::function )> B = [=] (height_t h) -> double { - return -H * pow(h.x, 2);; - }; - - // initialize state object - sim_t s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function (std::mt19937&, height_t)> gen_R = [=] (std::mt19937& r, height_t h) -> dihedral_inf_t { - dihedral_inf_t rot; - rot.is_reflection = true; - std::normal_distribution dist(0.0,1.0); - - double amount = epsilon * dist(r); - - rot.x = 2 * h.x + amount; - - return rot; - }; - - // define function that updates any number of measurements - std::function measurement; - - double average_M = 0; - if (!draw) { - // a very simple example: measure the average magnetization - measurement = [&] (const sim_t& s) { - average_M += (double)s.M / (double)N / (double)s.nv; - }; - } else { - // a more complex example: measure the average magnetization, and draw the spin configuration to the screen - -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - measurement = [&] (const sim_t& s) { - average_M += (double)s.M / (double)N / (double)s.nv; - glClear(GL_COLOR_BUFFER_BIT); - double max_h = INT64_MIN; - double min_h = INT64_MAX; - for (v_t i = 0; i < pow(L, 2); i++) { - double cur_h = (s.R.act_inverse(s.spins[i])).x; - if (cur_h < min_h) { - min_h = cur_h; - } - if (cur_h > max_h) { - max_h = cur_h; - } - } - - for (v_t i = 0; i < pow(L, 2); i++) { - double cur_h = (s.R.act_inverse(s.spins[i])).x; - double mag = ((double)(cur_h - min_h)) / ((double)(max_h - min_h)); - glColor3f(mag, mag, mag); - glRecti(i / L, i % L, (i / L) + 1, (i % L) + 1); - } - glFlush(); - }; -#endif - } - - // run wolff for N cluster flips - wolff(N, s, gen_R, measurement, rng, silent); - - // tell us what we found! - printf("%" PRIcount " DGM runs completed. D = %" PRID ", L = %" PRIL ", T = %g, H = %g, = %g\n", N, D, L, T, H, average_M); - - // free the random number generator - - if (draw) { - } - - return 0; - -} - diff --git a/examples/src/models/roughening/wolff_dgm.cpp b/examples/src/models/roughening/wolff_dgm.cpp deleted file mode 100644 index 8395382..0000000 --- a/examples/src/models/roughening/wolff_dgm.cpp +++ /dev/null @@ -1,164 +0,0 @@ - -#include - -#ifdef HAVE_GLUT -#include -#endif - -// include your group and spin space -#include "dihedral_inf.hpp" -#include "height.hpp" - -#include - -// include wolff.h -#include - -typedef state_t , height_t> sim_t; - -int main(int argc, char *argv[]) { - - count_t N = (count_t)1e4; - - D_t D = 2; - L_t L = 128; - double T = 2.26918531421; - double H = 0; - - bool silent = false; - bool draw = false; - unsigned int window_size = 512; - uint64_t epsilon = 1; - - int opt; - - while ((opt = getopt(argc, argv, "N:D:L:T:H:sdw:e:")) != -1) { - switch (opt) { - case 'N': // number of steps - N = (count_t)atof(optarg); - break; - case 'D': // dimension - D = atoi(optarg); - break; - case 'L': // linear size - L = atoi(optarg); - break; - case 'T': // temperature - T = atof(optarg); - break; - case 'H': // external field. nth call couples to state n - H = atof(optarg); - break; - case 'e': // external field. nth call couples to state n - epsilon = atof(optarg); - break; - case 's': // don't print anything during simulation. speeds up slightly - silent = true; - break; - case 'd': -#ifdef HAVE_GLUT - draw = true; - break; -#else - printf("You didn't compile this with the glut library installed!\n"); - exit(EXIT_FAILURE); -#endif - case 'w': - window_size = atoi(optarg); - break; - default: - exit(EXIT_FAILURE); - } - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - - // define spin-spin coupling - std::function &, const height_t&)> Z = [] (const height_t& h1, const height_t& h2) -> double { - return -pow(h1.x - h2.x, 2); - }; - - // define spin-field coupling - std::function &)> B = [=] (const height_t& h) -> double { - return -H * pow(h.x, 2);; - }; - - // initialize state object - sim_t s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function (std::mt19937&, height_t)> gen_R = [=] (std::mt19937& r, height_t h) -> dihedral_inf_t { - dihedral_inf_t rot; - rot.is_reflection = true; - - std::uniform_int_distribution dist(-epsilon,epsilon); - - rot.x = 2 * h.x + dist(r); - - return rot; - }; - - // define function that updates any number of measurements - std::function measurement; - - double average_M = 0; - if (!draw) { - // a very simple example: measure the average magnetization - measurement = [&] (const sim_t& s) { - average_M += (double)s.M / (double)N / (double)s.nv; - }; - } else { - // a more complex example: measure the average magnetization, and draw the spin configuration to the screen - -#ifdef HAVE_GLUT - // initialize glut - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); - glutInitWindowSize(window_size, window_size); - glutCreateWindow("wolff"); - glClearColor(0.0,0.0,0.0,0.0); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, L, 0.0, L); - - measurement = [&] (const sim_t& s) { - average_M += (double)s.M / (double)N / (double)s.nv; - glClear(GL_COLOR_BUFFER_BIT); - int64_t max_h = INT64_MIN; - int64_t min_h = INT64_MAX; - for (v_t i = 0; i < pow(L, 2); i++) { - int64_t cur_h = (s.R.act_inverse(s.spins[i])).x; - if (cur_h < min_h) { - min_h = cur_h; - } - if (cur_h > max_h) { - max_h = cur_h; - } - } - - for (v_t i = 0; i < pow(L, 2); i++) { - int64_t cur_h = (s.R.act_inverse(s.spins[i])).x; - double mag = ((double)(cur_h - min_h)) / ((double)(max_h - min_h)); - glColor3f(mag, mag, mag); - glRecti(i / L, i % L, (i / L) + 1, (i % L) + 1); - } - glFlush(); - }; -#endif - } - - // run wolff for N cluster flips - wolff(N, s, gen_R, measurement, rng, silent); - - // tell us what we found! - printf("%" PRIcount " DGM runs completed. D = %" PRID ", L = %" PRIL ", T = %g, H = %g, = %g\n", N, D, L, T, H, average_M); - - if (draw) { - } - - return 0; - -} - diff --git a/examples/src/tools/CMakeLists.txt b/examples/src/tools/CMakeLists.txt deleted file mode 100644 index 4a6c1a0..0000000 --- a/examples/src/tools/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ - -find_library(fftw REQUIRED NAMES fftw3) - -add_executable(analyze_correlations analyze_correlations.cpp) - -target_link_libraries(analyze_correlations fftw3 wolff) - -install(TARGETS analyze_correlations DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) - diff --git a/examples/src/tools/analyze_correlations.cpp b/examples/src/tools/analyze_correlations.cpp deleted file mode 100644 index abeaff3..0000000 --- a/examples/src/tools/analyze_correlations.cpp +++ /dev/null @@ -1,486 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include - -template -double mean(int N, T *data) { - double total = 0; - for (int i = 0; i < N; i++) { - total += (double)data[i]; - } - - return total / N; -} - -double squared_mean(int N, double *data) { - double total = 0; - for (int i = 0; i < N; i++) { - total += pow(data[i], 2); - } - - return total / N; -} - -double central_moment(int N, double *data, double mean, int m) { - double total = 0; - for (int i = 0; i < N; i++) { - total += pow(data[i] - mean, m); - } - - return total / N; -} - -void compute_OO(int N, fftw_plan forward_plan, double *forward_data, fftw_plan reverse_plan, double *reverse_data) { - - fftw_execute(forward_plan); - - reverse_data[0] = forward_data[0] * forward_data[0]; - reverse_data[N / 2] = forward_data[N/2] * forward_data[N/2]; - - for (count_t i = 1; i < N / 2; i++) { - reverse_data[i] = pow(forward_data[i], 2) + pow(forward_data[N - i], 2); - reverse_data[N - i] = 0; - } - - fftw_execute(reverse_plan); - -} - -double finite_energy(q_t nb, double *J, q_t q, double *H, v_t nv, v_t ne, uint32_t *bo, uint32_t *so) { - double energy = 0; - - v_t tot = 0; - for (q_t i = 0; i < nb - 1; i++) { - energy -= J[i] * bo[i]; - tot += bo[i]; - } - - energy -= J[nb - 1] * (ne - tot); - - tot = 0; - for (q_t i = 0; i < q - 1; i++) { - energy -= H[i] * so[i]; - tot += so[i]; - } - - energy -= H[q - 1] * (nv - tot); - - return energy; -} - -int main (int argc, char *argv[]) { - count_t drop = (count_t)1e4; - count_t length = (count_t)1e4; - bool speedy_drop = false; - bool from_stdin = false; - bool oldstyle = false; - - int opt; - - while ((opt = getopt(argc, argv, "d:l:spo")) != -1) { - switch (opt) { - case 'd': - drop = (count_t)atof(optarg); - break; - case 'l': - length = (count_t)atof(optarg); - break; - case 's': - speedy_drop = true; - break; - case 'p': - from_stdin = true; - break; - case 'o': - oldstyle = true; - break; - default: - exit(EXIT_FAILURE); - } - } - FILE *metadata; - - fftw_set_timelimit(1); - - if (from_stdin) { - metadata = stdin; - } else { - metadata = fopen("wolff_metadata.txt", "r"); - } - - if (metadata == NULL) { - printf("Metadata file not found. Make sure you are in the correct directory!\n"); - exit(EXIT_FAILURE); - } - - unsigned long id; - char *model = (char *)malloc(32 * sizeof(char)); - - if (model == NULL) { - printf("Malloc failed.\n"); - exit(EXIT_FAILURE); - } - - q_t q; - D_t D; - L_t L; - v_t nv, ne; - - while (EOF != fscanf(metadata, "<| \"ID\" -> %lu, \"MODEL\" -> \"%[^\"]\", \"q\" -> %" SCNq ", \"D\" -> %" SCND ", \"L\" -> %" SCNL ", \"NV\" -> %" SCNv ", \"NE\" -> %" SCNv ", ", &id, model, &q, &D, &L, &nv, &ne)) { - - printf("%lu: Processing...\n", id); - -// bool is_finite = 0 == strcmp(model, "ISING") || 0 == strcmp(model, "POTTS") || 0 == strcmp(model, "CLOCK"); - - if (oldstyle) { - q_t nb; - double T; - fscanf(metadata, "\"NB\" -> %" SCNq ", \"T\" -> %lf, \"J\" -> {", &nb, &T); - double *J = (double *)malloc(nb * sizeof(double)); - double *H = (double *)malloc(q * sizeof(double)); - - if (J == NULL || H == NULL) { - printf("%lu: Malloc failed.\n", id); - break; - } - - for (q_t i = 0; i < nb - 1; i++) { - fscanf(metadata, "%lf, ", &(J[i])); - } - fscanf(metadata, "%lf}, \"H\" -> {", &(J[nb - 1])); - for (q_t i = 0; i < q - 1; i++) { - fscanf(metadata, "%lf, ", &(H[i])); - } - fscanf(metadata, "%lf} |>\n", &(H[q - 1])); - - char *filename_M = (char *)malloc(128 * sizeof(char)); - char *filename_B = (char *)malloc(128 * sizeof(char)); - char *filename_S = (char *)malloc(128 * sizeof(char)); - - if (filename_M == NULL || filename_B == NULL || filename_S == NULL) { - printf("%lu: Malloc failed.\n", id); - break; - } - - sprintf(filename_M, "wolff_%lu_M.dat", id); - sprintf(filename_B, "wolff_%lu_B.dat", id); - sprintf(filename_S, "wolff_%lu_S.dat", id); - - FILE *file_M = fopen(filename_M, "rb"); - FILE *file_B = fopen(filename_B, "rb"); - FILE *file_S = fopen(filename_S, "rb"); - - if (file_M == NULL || file_B == NULL || file_S == NULL) { - printf("%lu: Opening data file failed.\n", id); - break; - } - - fseek(file_S, 0, SEEK_END); - unsigned long N = ftell(file_S) / sizeof(uint32_t); - fseek(file_S, 0, SEEK_SET); - - if (speedy_drop) { - drop = N - pow(2, floor(log(N) / log(2))); - } else { - if (N % 2 == 1 && drop % 2 == 0) { - drop++; // make sure M is even - } - } - - if (N <= drop) { - printf("\033[F%lu: Number of steps %lu is less than %" PRIcount ", nothing done.\n", id, N, drop); - } else { - int M = N - drop; - - double M_f = (double)M; - - if (length > M) { - length = M; - } - - double *forward_data = (double *)fftw_malloc(M * sizeof(double)); - fftw_plan forward_plan = fftw_plan_r2r_1d(M, forward_data, forward_data, FFTW_R2HC, 0); - double *reverse_data = (double *)fftw_malloc(M * sizeof(double)); - fftw_plan reverse_plan = fftw_plan_r2r_1d(M, reverse_data, reverse_data, FFTW_HC2R, 0); - - - uint32_t *data_S = (uint32_t *)malloc(N * sizeof(uint32_t)); - fread(data_S, N, sizeof(uint32_t), file_S); - for (count_t i = 0; i < M; i++) { - forward_data[i] = (double)data_S[drop + i]; - } - free(data_S); - double mean_S = mean(M, forward_data); - double squaredMean_S = squared_mean(M, forward_data); - double moment2_S = central_moment(M, forward_data, mean_S, 2); - double moment4_S = central_moment(M, forward_data, mean_S, 4); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_S, "wolff_%lu_S_OO.dat", id); - - FILE *file_S = fopen(filename_S, "wb"); - fwrite(&M_f, sizeof(double), 1, file_S); - fwrite(&mean_S, sizeof(double), 1, file_S); - fwrite(&squaredMean_S, sizeof(double), 1, file_S); - fwrite(&moment2_S, sizeof(double), 1, file_S); - fwrite(&moment4_S, sizeof(double), 1, file_S); - fwrite(reverse_data, sizeof(double), length, file_S); - fclose(file_S); - - uint32_t *data_B = (uint32_t *)malloc((nb - 1) * N * sizeof(uint32_t)); - uint32_t *data_M = (uint32_t *)malloc((q - 1) * N * sizeof(uint32_t)); - fread(data_B, N * (nb - 1), sizeof(uint32_t), file_B); - fread(data_M, N * (q - 1), sizeof(uint32_t), file_M); - - for (count_t i = 0; i < M; i++) { - forward_data[i] = finite_energy(nb, J, q, H, nv, ne, data_B + (nb - 1) * (drop + i), data_M + (q - 1) * (drop + i)); - } - - double mean_E = mean(M, forward_data); - double squaredMean_E = squared_mean(M, forward_data); - double moment2_E = central_moment(M, forward_data, mean_E, 2); - double moment4_E = central_moment(M, forward_data, mean_E, 4); - - free(data_B); - free(data_M); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_B, "wolff_%lu_E_OO.dat", id); - - FILE *file_E = fopen(filename_B, "wb"); - fwrite(&M_f, sizeof(double), 1, file_E); - fwrite(&mean_E, sizeof(double), 1, file_E); - fwrite(&squaredMean_E, sizeof(double), 1, file_E); - fwrite(&moment2_E, sizeof(double), 1, file_E); - fwrite(&moment4_E, sizeof(double), 1, file_E); - fwrite(reverse_data, sizeof(double), length, file_E); - fclose(file_E); - - printf("\033[F%lu: Correlation functions for %d steps written.\n", id, M); - - fftw_destroy_plan(forward_plan); - fftw_destroy_plan(reverse_plan); - fftw_free(forward_data); - fftw_free(reverse_data); - - } - - fclose(file_M); - fclose(file_B); - fclose(file_S); - - free(J); - free(H); - - free(filename_S); - free(filename_B); - free(filename_M); - - } else { - char *junk = (char *)malloc(1024 * sizeof(char)); - fscanf(metadata, "%[^\n]\n", junk); // throw away the rest of the line, we don't need it - free(junk); - - char *filename_E = (char *)malloc(128 * sizeof(char)); - char *filename_F = (char *)malloc(128 * sizeof(char)); - char *filename_M = (char *)malloc(128 * sizeof(char)); - char *filename_S = (char *)malloc(128 * sizeof(char)); - - sprintf(filename_E, "wolff_%lu_E.dat", id); - sprintf(filename_F, "wolff_%lu_F.dat", id); - sprintf(filename_M, "wolff_%lu_M.dat", id); - sprintf(filename_S, "wolff_%lu_S.dat", id); - - FILE *file_E = fopen(filename_E, "rb"); - FILE *file_F = fopen(filename_F, "rb"); - FILE *file_M = fopen(filename_M, "rb"); - FILE *file_S = fopen(filename_S, "rb"); - - fseek(file_S, 0, SEEK_END); - unsigned long N = ftell(file_S) / sizeof(uint32_t); - fseek(file_S, 0, SEEK_SET); - - if (speedy_drop) { - drop = N - pow(2, floor(log(N) / log(2))); - } else { - if (N % 2 == 1 && drop % 2 == 0) { - drop++; // make sure M is even - } - } - - if (N <= drop) { - printf("\033[F%lu: Number of steps %lu is less than %" PRIcount ", nothing done.\n", id, N, drop); - } else { - int M = N - drop; - double M_f = (double)M; - - if (length > M) { - length = M; - } - - double *forward_data = (double *)fftw_malloc(M * sizeof(double)); - fftw_plan forward_plan = fftw_plan_r2r_1d(M, forward_data, forward_data, FFTW_R2HC, 0); - - double *reverse_data = (double *)fftw_malloc(M * sizeof(double)); - fftw_plan reverse_plan = fftw_plan_r2r_1d(M, reverse_data, reverse_data, FFTW_HC2R, 0); - - if (file_S != NULL) { - uint32_t *data_S = (uint32_t *)malloc(N * sizeof(uint32_t)); - - fread(data_S, sizeof(uint32_t), N, file_S); - fclose(file_S); - - for (int i = 0; i < M; i++) { - forward_data[i] = (double)data_S[drop + i]; - } - free(data_S); - - double mean_S = mean(M, forward_data); - double squaredMean_S = squared_mean(M, forward_data); - double moment2_S = central_moment(M, forward_data, mean_S, 2); - double moment4_S = central_moment(M, forward_data, mean_S, 4); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_S, "wolff_%lu_S_OO.dat", id); - FILE *file_S_new = fopen(filename_S, "wb"); - fwrite(&M_f, sizeof(double), 1, file_S_new); - fwrite(&mean_S, sizeof(double), 1, file_S_new); - fwrite(&squaredMean_S, sizeof(double), 1, file_S_new); - fwrite(&moment2_S, sizeof(double), 1, file_S_new); - fwrite(&moment4_S, sizeof(double), 1, file_S_new); - fwrite(reverse_data, sizeof(double), length, file_S_new); - fclose(file_S_new); - } - if (file_F != NULL) { - float *data_F = (float *)malloc(N * sizeof(float)); - - fread(data_F, sizeof(float), N, file_F); - fclose(file_F); - - for (int i = 0; i < M; i++) { - forward_data[i] = (double)data_F[drop + i]; - } - free(data_F); - - double mean_F = mean(M, forward_data); - double squaredMean_F = squared_mean(M, forward_data); - double moment2_F = central_moment(M, forward_data, mean_F, 2); - double moment4_F = central_moment(M, forward_data, mean_F, 4); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_F, "wolff_%lu_F_OO.dat", id); - FILE *file_F_new = fopen(filename_F, "wb"); - fwrite(&M_f, sizeof(double), 1, file_F_new); - fwrite(&mean_F, sizeof(double), 1, file_F_new); - fwrite(&squaredMean_F, sizeof(double), 1, file_F_new); - fwrite(&moment2_F, sizeof(double), 1, file_F_new); - fwrite(&moment4_F, sizeof(double), 1, file_F_new); - fwrite(reverse_data, sizeof(double), length, file_F_new); - fclose(file_F_new); - } - if (file_E != NULL) { - float *data_E = (float *)malloc(N * sizeof(float)); - - fread(data_E, sizeof(float), N, file_E); - fclose(file_E); - - for (int i = 0; i < M; i++) { - forward_data[i] = (double)data_E[drop + i]; - } - free(data_E); - - double mean_E = mean(M, forward_data); - double squaredMean_E = squared_mean(M, forward_data); - double moment2_E = central_moment(M, forward_data, mean_E, 2); - double moment4_E = central_moment(M, forward_data, mean_E, 4); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_E, "wolff_%lu_E_OO.dat", id); - FILE *file_E_new = fopen(filename_E, "wb"); - fwrite(&M_f, sizeof(double), 1, file_E_new); - fwrite(&mean_E, sizeof(double), 1, file_E_new); - fwrite(&squaredMean_E, sizeof(double), 1, file_E_new); - fwrite(&moment2_E, sizeof(double), 1, file_E_new); - fwrite(&moment4_E, sizeof(double), 1, file_E_new); - fwrite(reverse_data, sizeof(double), length, file_E_new); - fclose(file_E_new); - } - if (file_M != NULL) { - if (0 == strcmp(model, "PLANAR")) { - float *data_M = (float *)malloc(2 * N * sizeof(float)); - fread(data_M, sizeof(float), 2 * N, file_M); - fclose(file_M); - for (int i = 0; i < M; i++) { - forward_data[i] = (double)sqrt(pow(data_M[2 * drop + 2 * i], 2) + pow(data_M[2 * drop + 2 * i + 1], 2)); - } - free(data_M); - } else if (0 == strcmp(model, "HEISENBERG")) { - float *data_M = (float *)malloc(3 * N * sizeof(float)); - fread(data_M, sizeof(float), 3 * N, file_M); - fclose(file_M); - for (int i = 0; i < M; i++) { - forward_data[i] = sqrt(pow(data_M[3 * drop + 3 * i], 2) + pow(data_M[3 * drop + 3 * i + 1], 2) + pow(data_M[3 * drop + 3 * i + 2], 2)); - } - free(data_M); - } else if (0 == strcmp(model, "ISING")) { - int *data_M = (int *)malloc(N * sizeof(float)); - fread(data_M, sizeof(int), N, file_M); - fclose(file_M); - for (int i = 0; i < M; i++) { - forward_data[i] = (double)data_M[i]; - } - free(data_M); - } else { - printf("UNKNOWN MODEL\n"); - exit(EXIT_FAILURE); - } - - double mean_M = mean(M, forward_data); - double squaredMean_M = squared_mean(M, forward_data); - double moment2_M = central_moment(M, forward_data, mean_M, 2); - double moment4_M = central_moment(M, forward_data, mean_M, 4); - - compute_OO(M, forward_plan, forward_data, reverse_plan, reverse_data); - - sprintf(filename_M, "wolff_%lu_M_OO.dat", id); - FILE *file_M_new = fopen(filename_M, "wb"); - fwrite(&M_f, sizeof(double), 1, file_M_new); - fwrite(&mean_M, sizeof(double), 1, file_M_new); - fwrite(&squaredMean_M, sizeof(double), 1, file_M_new); - fwrite(&moment2_M, sizeof(double), 1, file_M_new); - fwrite(&moment4_M, sizeof(double), 1, file_M_new); - fwrite(reverse_data, sizeof(double), length, file_M_new); - fclose(file_M_new); - } - - printf("\033[F%lu: Correlation functions for %d steps written.\n", id, M); - fftw_destroy_plan(forward_plan); - fftw_destroy_plan(reverse_plan); - fftw_free(forward_data); - fftw_free(reverse_data); - - } - free(filename_E); - free(filename_S); - free(filename_F); - free(filename_M); - } - } - - free(model); - fclose(metadata); - fftw_cleanup(); - - return 0; -} - diff --git a/lib/include/wolff.hpp b/lib/include/wolff.hpp index b730c8d..b78cd4b 100644 --- a/lib/include/wolff.hpp +++ b/lib/include/wolff.hpp @@ -1,30 +1,27 @@ +#ifndef WOLFF_H +#define WOLFF_H + #include "wolff/cluster.hpp" -#include "wolff/state.hpp" template -void wolff(count_t N, state_t & s, std::function gen_R, wolff_measurement& m, std::mt19937& r) { - -#ifdef FINITE_STATES -#ifdef NOFIELD - initialize_probs(s.J, s.T); -#else - initialize_probs(s.J, s.H, s.T); -#endif -#endif +void wolff(N_t N, wolff_system& S, + std::function r_gen, + wolff_measurement& A, std::mt19937& rng) { - std::uniform_int_distribution dist(0, s.nv); + std::uniform_int_distribution dist(0, S.nv - 1); - for (count_t steps = 0; steps < N; steps++) { - v_t v0 = dist(r); - R_t step = gen_R(r, s.spins[v0]); + for (N_t n = 0; n < N; n++) { + v_t i0 = dist(rng); + R_t r = r_gen(rng, S.s[i0]); - m.pre_cluster(s, steps, N, v0, step); + A.pre_cluster(n, N, S, i0, r); - flip_cluster(s, v0, step, r, m); + wolff_cluster_flip(S, i0, r, rng, A); - m.post_cluster(s, steps, N); + A.post_cluster(n, N, S); } - } +#endif + 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 #include #include -#include +#include #include "types.h" -#include "state.hpp" +#include "system.hpp" #include "graph.hpp" -#include "meas.h" +#include "measurement.hpp" template -void flip_cluster(state_t& s, v_t v0, const R_t& r, std::mt19937& rand, wolff_measurement& m) { +void wolff_cluster_flip(wolff_system& S, v_t i0, const R_t& r, + std::mt19937& rng, wolff_measurement& A) { std::uniform_real_distribution dist(0.0, 1.0); - std::stack stack; - stack.push(v0); + std::queue queue; + queue.push(i0); - std::vector marks(s.g.nv, false); + std::vector 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 + diff --git a/lib/include/wolff/finite_states.hpp b/lib/include/wolff/finite_states.hpp index 426edad..4cca69e 100644 --- a/lib/include/wolff/finite_states.hpp +++ b/lib/include/wolff/finite_states.hpp @@ -1,40 +1,35 @@ -#pragma once + +#ifndef WOLFF_FINITE_STATES +#define WOLFF_FINITE_STATES #include -#include #include -#define FINITE_STATES - -// must have N_STATES, states[N_STATES], and state_to_ind defined before -// invoking header +#include "system.hpp" -std::array, N_STATES>, N_STATES> J_probs; -#ifndef NOFIELD -std::array, N_STATES> H_probs; +std::array, WOLFF_FINITE_STATES_N>, WOLFF_FINITE_STATES_N> finite_states_Zp; +#ifndef WOLFF_NO_FIELD +std::array, WOLFF_FINITE_STATES_N> finite_states_Bp; #endif -template -#ifndef NOFIELD -void initialize_probs(std::function J, std::function H, double T) { - for (q_t i = 0; i < N_STATES; i++) { - for (q_t j = 0; j < N_STATES; j++) { - H_probs[i][j] = 1.0 - exp(-(H(states[i]) - H(states[j])) / T); +template +void finite_states_init(const wolff_system& S) { +#ifndef WOLFF_NO_FIELD + for (q_t i = 0; i < WOLFF_FINITE_STATES_N; i++) { + for (q_t j = 0; j < WOLFF_FINITE_STATES_N; j++) { + finite_states_Bp[i][j] = 1.0 - exp(-(S.B(finite_states_possible[i]) - S.B(finite_states_possible[j])) / S.T); } } -#else -void initialize_probs(std::function J, double T) { #endif - for (q_t i = 0; i < N_STATES; i++) { - for (q_t j = 0; j < N_STATES; j++) { - for (q_t k = 0; k < N_STATES; k++) { - J_probs[i][j][k] = 1.0 - exp(-(J(states[i], states[k]) - J(states[j], states[k])) / T); + for (q_t i = 0; i < WOLFF_FINITE_STATES_N; i++) { + for (q_t j = 0; j < WOLFF_FINITE_STATES_N; j++) { + for (q_t k = 0; k < WOLFF_FINITE_STATES_N; k++) { + finite_states_Zp[i][j][k] = 1.0 - exp(-(S.Z(finite_states_possible[i], finite_states_possible[k]) - S.Z(finite_states_possible[j], finite_states_possible[k])) / S.T); } } } } - - +#endif diff --git a/lib/include/wolff/graph.hpp b/lib/include/wolff/graph.hpp index 0aeb6af..fcd73fa 100644 --- a/lib/include/wolff/graph.hpp +++ b/lib/include/wolff/graph.hpp @@ -1,5 +1,6 @@ -#pragma once +#ifndef WOLFF_GRAPH_H +#define WOLFF_GRAPH_H #include #include @@ -15,10 +16,12 @@ class graph_t { public: v_t ne; v_t nv; - std::vector> v_adj; + std::vector> adj; std::vector> coordinate; graph_t(D_t D, L_t L, lattice_t lat = SQUARE_LATTICE); void add_ext(); }; +#endif + diff --git a/lib/include/wolff/meas.h b/lib/include/wolff/meas.h deleted file mode 100644 index 4895eac..0000000 --- a/lib/include/wolff/meas.h +++ /dev/null @@ -1,19 +0,0 @@ - -#pragma once - -#include "types.h" - -template -class wolff_measurement { - public: - virtual void pre_cluster(const state_t&, count_t, count_t, v_t, const R_t&) = 0; - - virtual void plain_bond_added(v_t, const X_t&, const X_t&, v_t, const X_t&, double) = 0; - virtual void ghost_bond_added(v_t, const X_t&, const X_t&, double) = 0; - - virtual void plain_site_transformed(v_t, const X_t&, const X_t&) = 0; - virtual void ghost_site_transformed(const R_t&, const R_t&) = 0; - - virtual void post_cluster(const state_t&, count_t, count_t) = 0; -}; - diff --git a/lib/include/wolff/measurement.hpp b/lib/include/wolff/measurement.hpp new file mode 100644 index 0000000..a6a5f79 --- /dev/null +++ b/lib/include/wolff/measurement.hpp @@ -0,0 +1,24 @@ + +#ifndef WOLFF_MEASUREMENTS +#define WOLFF_MEASUREMENTS + +#include "system.hpp" + +template +class wolff_measurement { + public: + virtual void pre_cluster(N_t, N_t, const wolff_system&, v_t, const R_t&) = 0; + + virtual void plain_bond_visited(const wolff_system&, v_t, const X_t&, v_t, double) = 0; + virtual void plain_site_transformed(const wolff_system&, v_t, const X_t&) = 0; + +#ifndef WOLFF_NO_FIELD + virtual void ghost_bond_visited(const wolff_system&, v_t, const X_t&, const X_t&, double) = 0; + virtual void ghost_site_transformed(const wolff_system&, const R_t&) = 0; +#endif + + virtual void post_cluster(N_t, N_t, const wolff_system&) = 0; +}; + +#endif + diff --git a/lib/include/wolff/models/dihedral.hpp b/lib/include/wolff/models/dihedral.hpp new file mode 100644 index 0000000..cbc5687 --- /dev/null +++ b/lib/include/wolff/models/dihedral.hpp @@ -0,0 +1,48 @@ + +#pragma once + +#include +#include "potts.hpp" + +template +class dihedral_t { + public: + bool is_reflection; + q_t x; + + dihedral_t() : is_reflection(false), x(0) {} + dihedral_t(bool x, q_t y) : is_reflection(x), x(y) {} + + potts_t act(const potts_t& s) const { + if (this->is_reflection) { + return potts_t(((q + this->x) - s.x) % q); + } else { + return potts_t((this->x + s.x) % q); + } + } + + dihedral_t act(dihedral_t r) const { + if (this->is_reflection) { + return dihedral_t(!(r.is_reflection), ((q + this->x) - r.x) % q); + } else { + return dihedral_t(r.is_reflection, (this->x + r.x) % q); + } + } + + potts_t act_inverse(potts_t s) const { + if (this->is_reflection) { + return this->act(s); + } else { + return potts_t(((s.x + q) - this->x) % q); + } + } + + dihedral_t act_inverse(dihedral_t r) const { + if (this->is_reflection) { + return this->act(r); + } else { + return dihedral_t(r.is_reflection, ((r.x + q) - this->x) % q); + } + } +}; + diff --git a/lib/include/wolff/models/dihedral_inf.hpp b/lib/include/wolff/models/dihedral_inf.hpp new file mode 100644 index 0000000..bded387 --- /dev/null +++ b/lib/include/wolff/models/dihedral_inf.hpp @@ -0,0 +1,47 @@ + +#include "../types.h" +#include +#include "height.hpp" + +template +class dihedral_inf_t { + public: + bool is_reflection; + T x; + + dihedral_inf_t() : is_reflection(false), x(0) {} + dihedral_inf_t(bool x, T y) : is_reflection(x), x(y) {} + + height_t act(const height_t& h) const { + if (this->is_reflection) { + return height_t(this->x - h.x); + } else { + return height_t(this->x + h.x); + } + } + + dihedral_inf_t act(const dihedral_inf_t& r) const { + if (this->is_reflection) { + return dihedral_inf_t(!r.is_reflection, this->x - r.x); + } else { + return dihedral_inf_t(r.is_reflection, this->x + r.x); + } + } + + height_t act_inverse(const height_t& h) const { + if (this->is_reflection) { + return this->act(h); + } else { + return height_t(h.x - this->x); + } + } + + dihedral_inf_t act_inverse(const dihedral_inf_t& r) const { + if (this->is_reflection) { + return this->act(r); + } else { + return dihedral_inf_t(r.is_reflection, r.x - this->x); + } + } +}; + diff --git a/lib/include/wolff/models/height.hpp b/lib/include/wolff/models/height.hpp new file mode 100644 index 0000000..bd0ceb6 --- /dev/null +++ b/lib/include/wolff/models/height.hpp @@ -0,0 +1,43 @@ + +#pragma once + +#include +#include + +template +struct height_t { + T x; + + height_t() : x(0) {} + height_t(T x) : x(x) {} + + typedef T M_t; + typedef double F_t; + + inline T operator*(v_t a) const { + return x * a; + } + + inline double operator*(double a) const { + return x * a; + } + + inline T operator-(const height_t& h) const { + return x - h.x; + } +}; + +template +inline T& operator+=(T& M, const height_t &h) { + M += h.x; + + return M; +} + +template +inline T& operator-=(T& M, const height_t &h) { + M -= h.x; + + return M; +} + diff --git a/lib/include/wolff/models/ising.hpp b/lib/include/wolff/models/ising.hpp new file mode 100644 index 0000000..c6a3a47 --- /dev/null +++ b/lib/include/wolff/models/ising.hpp @@ -0,0 +1,81 @@ + +#ifndef WOLFF_MODELS_ISING +#define WOLFF_MODELS_ISING + +#include "../types.h" + +class ising_t { + public: + bool x; + + ising_t() : x(false) {} + + ising_t(bool x) : x(x) {} + ising_t(int x) : x((bool)x) {} + + ising_t act(const ising_t& s) const { + if (x) { + return ising_t(!s.x); + } else { + return ising_t(s.x); + } + } + + ising_t act_inverse(const ising_t& s) const { + return this->act(s); + } + + typedef int M_t; + typedef double F_t; + + inline M_t operator*(v_t a) const { + if (x) { + return -(M_t)a; + } else { + return (M_t)a; + } + } + + inline F_t operator*(double a) const { + if (x) { + return -a; + } else { + return a; + } + } + + inline M_t operator-(const ising_t &s) const { + if (x == s.x) { + return 0; + } else { + if (x) { + return -2; + } else { + return 2; + } + } + } + + inline int operator*(const ising_t& s) const { + if (x == s.x) { + return 1; + } else { + return -1; + } + } +}; + +inline ising_t::M_t operator*(v_t a, const ising_t& s) { + return s * a; +} + +inline ising_t::F_t operator*(double a, const ising_t& s) { + return s * a; +} + +#define WOLFF_FINITE_STATES_N 2 +const ising_t finite_states_possible[2] = {ising_t(0), ising_t(1)}; +q_t finite_states_enum(ising_t state) { return (q_t)state.x; } + +#endif + diff --git a/lib/include/wolff/models/orthogonal.hpp b/lib/include/wolff/models/orthogonal.hpp new file mode 100644 index 0000000..9dd5ddd --- /dev/null +++ b/lib/include/wolff/models/orthogonal.hpp @@ -0,0 +1,199 @@ + +#pragma once + +#include +#include + +#include +#include "vector.hpp" + +template +class orthogonal_t : public std::array, q> { + public : + bool is_reflection; + + orthogonal_t() : is_reflection(false) { + for (q_t i = 0; i < q; i++) { + (*this)[i].fill(0); + (*this)[i][i] = (T)1; + } + } + + vector_t act(const vector_t & v) const { + vector_t v_rot; + v_rot.fill(0); + + if (is_reflection) { + double prod = 0; + for (q_t i = 0; i < q; i++) { + prod += v[i] * (*this)[0][i]; + } + for (q_t i = 0; i < q; i++) { + v_rot[i] = v[i] - 2 * prod * (*this)[0][i]; + } + } else { + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot[i] += (*this)[i][j] * v[j]; + } + } + } + + return v_rot; + } + + orthogonal_t act(const orthogonal_t & m) const { + orthogonal_t m_rot; + + m_rot.is_reflection = false; + + if (is_reflection) { + for (q_t i = 0; i < q; i++) { + double akOki = 0; + + for (q_t k = 0; k < q; k++) { + akOki += (*this)[0][k] * m[k][i]; + } + + for (q_t j = 0; j < q; j++) { + m_rot[j][i] = m[j][i] - 2 * akOki * (*this)[0][j]; + } + } + } else { + for (q_t i = 0; i < q; i++) { + m_rot[i].fill(0); + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m_rot[i][j] += (*this)[i][j] * m[j][k]; + } + } + } + } + + return m_rot; + } + + vector_t act_inverse(const vector_t & v) const { + if (is_reflection) { + return this->act(v); // reflections are their own inverse + } else { + vector_t v_rot; + v_rot.fill(0); + + for (q_t i = 0; i < q; i++) { + for (q_t j = 0; j < q; j++) { + v_rot[i] += (*this)[j][i] * v[j]; + } + } + + return v_rot; + } + } + + vector_t act_inverse(const orthogonal_t & m) const { + if (is_reflection) { + return this->act(m); // reflections are their own inverse + } else { + orthogonal_t m_rot; + m_rot.is_reflection = false; + + for (q_t i = 0; i < q; i++) { + m_rot[i].fill(0); + for (q_t j = 0; j < q; j++) { + for (q_t k = 0; k < q; k++) { + m_rot[i][j] += (*this)[j][i] * m[j][k]; + } + } + } + + return m_rot; + } + } + +}; + +template +orthogonal_t generate_rotation_uniform (std::mt19937& r, const vector_t & v) { + std::normal_distribution dist(0.0,1.0); + orthogonal_t ptr; + ptr.is_reflection = true; + + double v2 = 0; + + for (q_t i = 0; i < q; i++) { + ptr[0][i] = dist(r); + v2 += ptr[0][i] * ptr[0][i]; + } + + double mag_v = sqrt(v2); + + for (q_t i = 0; i < q; i++) { + ptr[0][i] /= mag_v; + } + + return ptr; +} + +template +orthogonal_t generate_rotation_perturbation (std::mt19937& r, const vector_t & v0, double epsilon, unsigned int n) { + std::normal_distribution dist(0.0,1.0); + orthogonal_t m; + m.is_reflection = true; + + vector_t v; + + if (n > 1) { + std::uniform_int_distribution udist(0, n); + unsigned int rotation = udist(r); + + double cosr = cos(2 * M_PI * rotation / (double)n / 2.0); + double sinr = sin(2 * M_PI * rotation / (double)n / 2.0); + + v[0] = v0[0] * cosr - v0[1] * sinr; + v[1] = v0[1] * cosr + v0[0] * sinr; + + for (q_t i = 2; i < q; i++) { + v[i] = v0[i]; + } + } else { + v = v0; + } + + double m_dot_v = 0; + + for (q_t i = 0; i < q; i++) { + m[0][i] = dist(r); // create a random vector + m_dot_v += m[0][i] * v[i]; + } + + double v2 = 0; + + for (q_t i = 0; i < q; i++) { + m[0][i] = m[0][i] - m_dot_v * v[i]; // find the component orthogonal to v + v2 += pow(m[0][i], 2); + } + + double mag_v = sqrt(v2); + + for (q_t i = 0; i < q; i++) { + m[0][i] /= mag_v; // normalize + } + + v2 = 0; + + double factor = epsilon * dist(r); + + for (q_t i = 0; i < q; i++) { + m[0][i] += factor * v[i]; // perturb orthogonal vector in original direction + v2 += pow(m[0][i], 2); + } + + mag_v = sqrt(v2); + + for (q_t i = 0; i < q; i++) { + m[0][i] /= mag_v; // normalize + } + + return m; +} + diff --git a/lib/include/wolff/models/potts.hpp b/lib/include/wolff/models/potts.hpp new file mode 100644 index 0000000..903f25f --- /dev/null +++ b/lib/include/wolff/models/potts.hpp @@ -0,0 +1,50 @@ + +#pragma once + +#include + +#include "../types.h" +#include "vector.hpp" + +template +class potts_t { + public: + q_t x; + + potts_t() : x(0) {} + potts_t(q_t x) : x(x) {} + + typedef vector_t M_t; + typedef vector_t F_t; + + inline vector_t operator*(v_t a) const { + vector_t result; + result.fill(0); + result[x] = (int)a; + + return result; + } + + inline vector_t operator*(double a) const { + vector_t result; + result.fill(0.0); + result[x] = a; + + return result; + } + + inline vector_t operator-(const potts_t &s) const { + vector_t result; + result.fill(0); + + result[x]++; + result[s.x]--; + + return result; + } +}; + +const potts_t states[256] = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34}, {35}, {36}, {37}, {38}, {39}, {40}, {41}, {42}, {43}, {44}, {45}, {46}, {47}, {48}, {49}, {50}, {51}, {52}, {53}, {54}, {55}, {56}, {57}, {58}, {59}, {60}, {61}, {62}, {63}, {64}, {65}, {66}, {67}, {68}, {69}, {70}, {71}, {72}, {73}, {74}, {75}, {76}, {77}, {78}, {79}, {80}, {81}, {82}, {83}, {84}, {85}, {86}, {87}, {88}, {89}, {90}, {91}, {92}, {93}, {94}, {95}, {96}, {97}, {98}, {99}, {100}, {101}, {102}, {103}, {104}, {105}, {106}, {107}, {108}, {109}, {110}, {111}, {112}, {113}, {114}, {115}, {116}, {117}, {118}, {119}, {120}, {121}, {122}, {123}, {124}, {125}, {126}, {127}, {128}, {129}, {130}, {131}, {132}, {133}, {134}, {135}, {136}, {137}, {138}, {139}, {140}, {141}, {142}, {143}, {144}, {145}, {146}, {147}, {148}, {149}, {150}, {151}, {152}, {153}, {154}, {155}, {156}, {157}, {158}, {159}, {160}, {161}, {162}, {163}, {164}, {165}, {166}, {167}, {168}, {169}, {170}, {171}, {172}, {173}, {174}, {175}, {176}, {177}, {178}, {179}, {180}, {181}, {182}, {183}, {184}, {185}, {186}, {187}, {188}, {189}, {190}, {191}, {192}, {193}, {194}, {195}, {196}, {197}, {198}, {199}, {200}, {201}, {202}, {203}, {204}, {205}, {206}, {207}, {208}, {209}, {210}, {211}, {212}, {213}, {214}, {215}, {216}, {217}, {218}, {219}, {220}, {221}, {222}, {223}, {224}, {225}, {226}, {227}, {228}, {229}, {230}, {231}, {232}, {233}, {234}, {235}, {236}, {237}, {238}, {239}, {240}, {241}, {242}, {243}, {244}, {245}, {246}, {247}, {248}, {249}, {250}, {251}, {252}, {253}, {254}, {255}}; +template +q_t finite_states_enum(potts_t state) { return (q_t)state.x; } + diff --git a/lib/include/wolff/models/symmetric.hpp b/lib/include/wolff/models/symmetric.hpp new file mode 100644 index 0000000..7bcc9a6 --- /dev/null +++ b/lib/include/wolff/models/symmetric.hpp @@ -0,0 +1,51 @@ + +#pragma once + +#include + +#include "../types.h" +#include "potts.hpp" + +template +class symmetric_t : public std::array { + public: + + symmetric_t() { + for (q_t i = 0; i < q; i++) { + (*this)[i] = i; + } + } + + potts_t act(const potts_t &s) const { + return potts_t((*this)[s.x]); + } + + symmetric_t act(const symmetric_t& r) const { + symmetric_t r_rot; + for (q_t i = 0; i < q; i++) { + r_rot[i] = (*this)[r[i]]; + } + + return r_rot; + } + + potts_t act_inverse(const potts_t& s) const { + for (q_t i = 0; i < q; i++) { + if ((*this)[i] == s.x) { + return potts_t(i); + } + } + + exit(EXIT_FAILURE); + } + + symmetric_t act_inverse(const symmetric_t& r) const { + symmetric_t r_rot; + for (q_t i = 0; i < q; i++) { + r_rot[(*this)[i]] = r[i]; + } + + return r_rot; + } +}; + diff --git a/lib/include/wolff/models/vector.hpp b/lib/include/wolff/models/vector.hpp new file mode 100644 index 0000000..1d635c8 --- /dev/null +++ b/lib/include/wolff/models/vector.hpp @@ -0,0 +1,108 @@ + +#pragma once + +#include +#include +#include + +#include + +template +class vector_t : public std::array { + public: + + vector_t() { + this->fill((T)0); + (*this)[0] = (T)1; + } + + vector_t(const T *x) { + for (q_t i = 0; i < q; i++) { + (*this)[i] = x[i]; + } + } + + typedef vector_t M_t; + typedef vector_t F_t; + + template + inline vector_t& operator+=(const vector_t &v) { + for (q_t i = 0; i < q; i++) { + (*this)[i] += (T)v[i]; + } + return *this; + } + + template + inline vector_t& operator-=(const vector_t &v) { + for (q_t i = 0; i < q; i++) { + (*this)[i] -= (T)v[i]; + } + return *this; + } + + inline vector_t operator*(v_t x) const { + vector_t result; + for (q_t i = 0; i < q; i++) { + result[i] = x * (*this)[i]; + } + + return result; + } + + inline vector_t operator*(double x) const { + vector_t result; + for (q_t i = 0; i < q; i++) { + result[i] = x * (*this)[i]; + } + + return result; + } + + inline vector_t operator-(const vector_t& v) const { + vector_t diff = *this; + diff -= v; + return diff; + } + + inline T operator*(const vector_t& v) const { + double prod = 0; + + for (q_t i = 0; i < q; i++) { + prod += v[i] * (*this)[i]; + } + + return prod; + } + + template + inline vector_t operator/(U a) const { + vector_t result; + for (q_t i = 0; i < q; i++) { + result[i] = (*this)[i] / a; + } + + return result; + } +}; + +template +inline vector_t operator*(v_t a, const vector_t&v) { + return v * a; +} + +template +inline vector_t operator*(double a, const vector_t&v) { + return v * a; +} + +template +std::ostream& operator<<(std::ostream& os, const vector_t&v) { + os << "( "; + for (T vi : v) { + os << vi << " "; + } + os << ")"; + return os; +} + diff --git a/lib/include/wolff/state.hpp b/lib/include/wolff/state.hpp deleted file mode 100644 index 4909881..0000000 --- a/lib/include/wolff/state.hpp +++ /dev/null @@ -1,68 +0,0 @@ - -#pragma once - -#include -#include - -#include "types.h" -#include "graph.hpp" - -template -class state_t { - public: - D_t D; // the dimension of the system - L_t L; // the linear size of the lattice - v_t nv; // the number of vertices in the original lattice - v_t ne; // the number of edges in the original lattice - graph_t g; // the graph defining the lattice with ghost - double T; // the temperature - std::vector spins; // the state of the ordinary spins -#ifndef NOFIELD - R_t R; // the current state of the ghost site -#endif - -#ifdef BOND_DEPENDENCE - std::function J; // coupling between sites -#else - std::function J; // coupling between sites -#endif - -#ifndef NOFIELD -#ifdef SITE_DEPENDENCE - std::function H; // coupling with the external field -#else - std::function H; // coupling with the external field -#endif -#endif - - state_t(D_t D, L_t L, double T, -#ifdef BOND_DEPENDENCE - std::function J -#else - std::function J -#endif -#ifndef NOFIELD -#ifdef SITE_DEPENDENCE - , std::function H -#else - , std::function H -#endif -#endif - , lattice_t lat = SQUARE_LATTICE) : D(D), L(L), g(D, L, lat), T(T), -#ifndef NOFIELD - R(), -#endif - J(J) -#ifndef NOFIELD - , H(H) -#endif - { - nv = g.nv; - ne = g.ne; - spins.resize(nv); -#ifndef NOFIELD - g.add_ext(); -#endif - } -}; - diff --git a/lib/include/wolff/system.hpp b/lib/include/wolff/system.hpp new file mode 100644 index 0000000..ac82f44 --- /dev/null +++ b/lib/include/wolff/system.hpp @@ -0,0 +1,70 @@ + +#ifndef WOLFF_STATE_H +#define WOLFF_STATE_H + +#include +#include + +#include "types.h" +#include "graph.hpp" + +template +class wolff_system { + public: + D_t D; // dimension + L_t L; // linear size + v_t nv; // number of vertices + v_t ne; // number of edges + graph_t G; // the graph defining the lattice with ghost + double T; // the temperature + std::vector s; // the state of the ordinary spins +#ifndef WOLFF_NO_FIELD + R_t s0; // the current state of the ghost site +#endif + +#ifdef WOLFF_BOND_DEPENDENCE + std::function Z; // coupling between sites +#else + std::function Z; // coupling between sites +#endif + +#ifndef WOLFF_NO_FIELD +#ifdef WOLFF_SITE_DEPENDENCE + std::function B; // coupling with the external field +#else + std::function B; // coupling with the external field +#endif +#endif + + wolff_system(D_t D, L_t L, double T, +#ifdef WOLFF_BOND_DEPENDENCE + std::function Z +#else + std::function Z +#endif +#ifndef WOLFF_NO_FIELD +#ifdef WOLFF_SITE_DEPENDENCE + , std::function B +#else + , std::function B +#endif +#endif + , lattice_t lat = SQUARE_LATTICE) : D(D), L(L), G(D, L, lat), T(T), Z(Z) +#ifndef WOLFF_NO_FIELD + , s0(), B(B) +#endif + { + nv = G.nv; + ne = G.ne; + s.resize(nv); +#ifndef WOLFF_NO_FIELD + G.add_ext(); +#endif +#ifdef WOLFF_FINITE_STATES + finite_states_init(*this); +#endif + } +}; + +#endif + diff --git a/lib/include/wolff/types.h b/lib/include/wolff/types.h index ec9efaf..68bd09e 100644 --- a/lib/include/wolff/types.h +++ b/lib/include/wolff/types.h @@ -1,36 +1,27 @@ #include -typedef uint_fast32_t v_t; -typedef uint_fast8_t q_t; -typedef uint_fast16_t R_t; -typedef uint_fast8_t D_t; -typedef uint_fast16_t L_t; -typedef uint_fast64_t count_t; -typedef int_fast64_t h_t; +typedef uint_fast32_t v_t; // vertex and edge indices +typedef uint_fast8_t q_t; // enumerated states +typedef uint_fast8_t D_t; // dimension +typedef uint_fast16_t L_t; // linear size +typedef uint_fast64_t N_t; // cycle iterator #define MAX_v UINT_FAST32_MAX #define MAX_Q UINT_FAST8_MAX -#define MAX_R UINT_FAST16_MAX #define MAX_D UINT_FAST8_MAX #define MAX_L UINT_FAST16_MAX -#define MAX_COUNT UINT_FAST64_MAX -#define MAX_H INT_FAST64_MAX -#define MIN_H INT_FAST64_MIN +#define MAX_N UINT_FAST64_MAX #define PRIv PRIuFAST32 #define PRIq PRIuFAST8 -#define PRIR PRIuFAST16 #define PRID PRIuFAST8 #define PRIL PRIuFAST16 -#define PRIcount PRIuFAST64 -#define PRIh PRIdFAST64 +#define PRIN PRIuFAST64 #define SCNv SCNuFAST32 #define SCNq SCNuFAST8 -#define SCNR SCNuFAST16 #define SCND SCNuFAST8 #define SCNL SCNuFAST16 -#define SCNcount SCNuFAST64 -#define SCNh SCNdFAST64 +#define SCNN SCNuFAST64 diff --git a/lib/src/graph.cpp b/lib/src/graph.cpp index c6f0ba6..b42aa78 100644 --- a/lib/src/graph.cpp +++ b/lib/src/graph.cpp @@ -7,11 +7,11 @@ graph_t::graph_t(D_t D, L_t L, lattice_t lat) { nv = pow(L, D); ne = D * nv; - v_adj.resize(nv); + adj.resize(nv); coordinate.resize(nv); - for (std::vector v_adj_i : v_adj) { - v_adj_i.reserve(2 * D); + for (std::vector adj_i : adj) { + adj_i.reserve(2 * D); } for (v_t i = 0; i < nv; i++) { @@ -19,21 +19,21 @@ graph_t::graph_t(D_t D, L_t L, lattice_t lat) { for (D_t j = 0; j < D; j++) { coordinate[i][j] = (i / (v_t)pow(L, D - j - 1)) % L; - v_adj[i].push_back(pow(L, j + 1) * (i / ((v_t)pow(L, j + 1))) + fmod(i + pow(L, j), pow(L, j + 1))); - v_adj[i].push_back(pow(L, j + 1) * (i / ((v_t)pow(L, j + 1))) + fmod(pow(L, j+1) + i - pow(L, j), pow(L, j + 1))); + adj[i].push_back(pow(L, j + 1) * (i / ((v_t)pow(L, j + 1))) + fmod(i + pow(L, j), pow(L, j + 1))); + adj[i].push_back(pow(L, j + 1) * (i / ((v_t)pow(L, j + 1))) + fmod(pow(L, j+1) + i - pow(L, j), pow(L, j + 1))); } } break; } case DIAGONAL_LATTICE: { nv = D * pow(L, D); - ne = D * nv; + ne = 2 * nv; - v_adj.resize(nv); + adj.resize(nv); coordinate.resize(nv); - for (std::vector v_adj_i : v_adj) { - v_adj_i.reserve(4 * (D - 1)); + for (std::vector adj_i : adj) { + adj_i.reserve(4 * (D - 1)); } for (D_t i = 0; i < D; i++) { @@ -42,10 +42,10 @@ graph_t::graph_t(D_t D, L_t L, lattice_t lat) { for (v_t j = 0; j < pow(L, D); j++) { v_t vc = sb + j; - v_adj[vc].push_back(((i + 1) % D) * pow(L, D) + j); - v_adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * (j / (v_t)pow(L, D - 1)) + (j + 1 - 2 * (i % 2)) % L); - v_adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * ((L + (j/ (v_t)pow(L, D - 1)) - 1 + 2 * (i % 2)) % L) + (j - i) % L); - v_adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * ((L + (j/ (v_t)pow(L, D - 1)) - 1 + 2 * (i % 2)) % L) + (j + 1 - i) % L); + adj[vc].push_back(((i + 1) % D) * pow(L, D) + j); + adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * (j / (v_t)pow(L, D - 1)) + (j + 1 - 2 * (i % 2)) % L); + adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * ((L + (j/ (v_t)pow(L, D - 1)) - 1 + 2 * (i % 2)) % L) + (j - i) % L); + adj[vc].push_back(((i + 1) % D) * pow(L, D) + pow(L, D - 1) * ((L + (j/ (v_t)pow(L, D - 1)) - 1 + 2 * (i % 2)) % L) + (j + 1 - i) % L); } } break; @@ -54,16 +54,16 @@ graph_t::graph_t(D_t D, L_t L, lattice_t lat) { } void graph_t::add_ext() { - for (std::vector& v_adj_i : v_adj) { - v_adj_i.push_back(nv); + for (std::vector& adj_i : adj) { + adj_i.push_back(nv); } - v_adj.resize(nv + 1); + adj.resize(nv + 1); coordinate.resize(nv + 1); - v_adj[nv].reserve(nv); + adj[nv].reserve(nv); for (v_t i = 0; i < nv; i++) { - v_adj[nv].push_back(i); + adj[nv].push_back(i); } coordinate[nv].resize(coordinate[0].size()); -- cgit v1.2.3-54-g00ecf