diff options
Diffstat (limited to 'examples')
34 files changed, 370 insertions, 3154 deletions
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 <getopt.h> +#include <iostream> +#include <chrono> + +#include "simple_measurement.hpp" + +#include <wolff/models/vector.hpp> +#include <wolff/models/orthogonal.hpp> +#include <wolff.hpp> + +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<WOLFF_N, double> 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 <double(const vector_t<WOLFF_N, double>&, const vector_t<WOLFF_N, double>&)> Z = [] (const vector_t<WOLFF_N, double>& s1, const vector_t<WOLFF_N, double>& s2) -> double { + return s1 * s2; + }; + + // define the spin-field coupling + std::function <double(const vector_t<WOLFF_N, double>&)> B = [&] (const vector_t<WOLFF_N, double>& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system<orthogonal_t<WOLFF_N, double>, vector_t<WOLFF_N, double>> S(D, L, T, Z, B); + + std::function <orthogonal_t<WOLFF_N, double>(std::mt19937&, const vector_t<WOLFF_N, double>&)> gen_R = generate_rotation_uniform<WOLFF_N>; + + // 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<orthogonal_t<WOLFF_N, double>, vector_t<WOLFF_N, double>>(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 <getopt.h> +#include <iostream> +#include <chrono> + +#include <GL/glut.h> + +#include <wolff/models/ising.hpp> +#include <wolff/finite_states.hpp> +#include <wolff.hpp> + +class draw_ising : public wolff_measurement<ising_t, ising_t> { + private: + unsigned int frame_skip; + v_t C; + public: + draw_ising(const wolff_system<ising_t, ising_t>& 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<ising_t, ising_t>& 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<ising_t, ising_t>&, v_t, const ising_t&, v_t, double dE) {} + + void ghost_bond_visited(const wolff_system<ising_t, ising_t>&, v_t, const ising_t& s_old, const ising_t& s_new, double dE) {} + + void plain_site_transformed(const wolff_system<ising_t, ising_t>& 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<ising_t, ising_t>&, const ising_t&) {} + + void post_cluster(N_t, N_t, const wolff_system<ising_t, ising_t>&) {} +}; + +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 <double(const ising_t&, const ising_t&)> Z = [] (const ising_t& s1, const ising_t& s2) -> double { + return (double)(s1 * s2); + }; + + // define the spin-field coupling + std::function <double(const ising_t&)> B = [=] (const ising_t& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system<ising_t, ising_t> S(D, L, T, Z, B); + + // define function that generates self-inverse rotations + std::function <ising_t(std::mt19937&, const ising_t&)> 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<ising_t, ising_t>(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 <wolff/types.h> - -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 <wolff/types.h> -#include <wolff/state.hpp> - -#include <fftw3.h> - -template <class X_t> -double correlation_length(const std::vector<typename X_t::F_t>& ReF, const std::vector<typename X_t::F_t>& 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 <wolff/state.hpp> -#include <wolff/meas.h> -#include "correlation.hpp" -#include <functional> - -#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 R_t, class X_t> -class wolff_research_measurements : public wolff_measurement<R_t, X_t> { - private: - std::vector<std::vector<double>> precomputed_sin; - std::vector<std::vector<double>> precomputed_cos; - FILE **files; - D_t D; - unsigned char flags; - std::function <void(const state_t <R_t, X_t>&, const wolff_research_measurements<R_t, X_t>&)> other_f; - bool silent; - public: - v_t last_cluster_size; - double E; - typename X_t::M_t M; - std::vector<typename X_t::F_t> ReF; - std::vector<typename X_t::F_t> ImF; - - wolff_research_measurements(unsigned char flags, unsigned long timestamp, std::function <void(const state_t <R_t, X_t>&, const wolff_research_measurements<R_t, X_t>&)> other_f, state_t<R_t, X_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<R_t, X_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<R_t, X_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<X_t>(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 -Subproject 8486a610a954a8248c12485fb4cfc390a5f5f85 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 <getopt.h> +#include <iostream> +#include <chrono> + +#include "simple_measurement.hpp" + +#include <wolff/models/ising.hpp> +#include <wolff/finite_states.hpp> +#include <wolff.hpp> + +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 <double(const ising_t&, const ising_t&)> Z = [] (const ising_t& s1, const ising_t& s2) -> double { + return (double)(s1 * s2); + }; + + // define the spin-field coupling + std::function <double(const ising_t&)> B = [=] (const ising_t& s) -> double { + return H * s; + }; + + // initialize the system + wolff_system<ising_t, ising_t> 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 <ising_t(std::mt19937&, const ising_t&)> 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<ising_t, ising_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/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 <getopt.h> -#include <iostream> - -#include "include/randutils/randutils.hpp" - -#include <wolff.hpp> - -// 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<R_t, X_t> -class ising_measurements : public wolff_measurement<ising_t, ising_t> { - 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<ising_t, ising_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<ising_t, ising_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 <double(const ising_t&, const ising_t&)> 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 <double(const ising_t&)> B = [=] (const ising_t& s) -> double { - if (s.x) { - return -H; - } else { - return H; - } - }; - - // initialize the system - state_t<ising_t, ising_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 <ising_t(std::mt19937&, const ising_t&)> 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<ising_t, ising_t>(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 <wolff/measurement.hpp> + +template <class R_t, class X_t> +class simple_measurement : public wolff_measurement<R_t, X_t> { + 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<R_t, X_t>& 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<R_t, X_t>&, v_t, const R_t&) { + C = 0; + } + + void plain_bond_visited(const wolff_system<R_t, X_t>&, v_t, const X_t&, v_t, double dE) { + E += dE; + } + + void ghost_bond_visited(const wolff_system<R_t, X_t>&, 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<R_t, X_t>&, v_t, const X_t&) { + C++; + } + + void ghost_site_transformed(const wolff_system<R_t, X_t>&, const R_t&) {} + + void post_cluster(N_t, N_t, const wolff_system<R_t, X_t>&) { + 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 <stdlib.h> -#include <random> -#include <cmath> - -#include <wolff/state.hpp> -#include <wolff/types.h> -#include "vector.hpp" - -template <q_t q, class T> -class orthogonal_t : public std::array<std::array<T, q>, 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<q, T> act(const vector_t <q, T>& v) const { - vector_t <q, 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<q, T> act(const orthogonal_t <q, T>& m) const { - orthogonal_t <q, 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 <q, T> act_inverse(const vector_t <q, T>& v) const { - if (is_reflection) { - return this->act(v); // reflections are their own inverse - } else { - vector_t <q, 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 <q, T> act_inverse(const orthogonal_t <q, T>& m) const { - if (is_reflection) { - return this->act(m); // reflections are their own inverse - } else { - orthogonal_t <q, 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 <q_t q> -orthogonal_t <q, double> generate_rotation_uniform (std::mt19937& r, const vector_t <q, double>& v) { - std::normal_distribution<double> dist(0.0,1.0); - orthogonal_t <q, double> 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 <q_t q> -orthogonal_t <q, double> generate_rotation_perturbation (std::mt19937& r, const vector_t <q, double>& v0, double epsilon, unsigned int n) { - std::normal_distribution<double> dist(0.0,1.0); - orthogonal_t <q, double> m; - m.is_reflection = true; - - vector_t <q, double> v; - - if (n > 1) { - std::uniform_int_distribution<unsigned int> 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 <stdlib.h> -#include <cmath> -#include <array> - -#include <wolff/types.h> - -template <q_t q, class T> -class vector_t : public std::array<T, q> { - public: - - // M_t needs to hold the sum of nv spins - typedef vector_t <q, T> M_t; - - // F_t needs to hold the double-weighted sum of spins - typedef vector_t <q, double> 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 <class U> - inline vector_t<q, T>& operator+=(const vector_t<q, U> &v) { - for (q_t i = 0; i < q; i++) { - (*this)[i] += (U)v[i]; - } - return *this; - } - - template <class U> - inline vector_t<q, T>& operator-=(const vector_t<q, U> &v) { - for (q_t i = 0; i < q; i++) { - (*this)[i] -= (U)v[i]; - } - return *this; - } - - inline vector_t<q, T> operator*(v_t x) const { - vector_t<q, T> result; - for (q_t i = 0; i < q; i++) { - result[i] = x * (*this)[i]; - } - - return result; - } - - inline vector_t<q, double> operator*(double x) const { - vector_t<q, double> result; - for (q_t i = 0; i < q; i++) { - result[i] = x * (*this)[i]; - } - - return result; - } - - inline vector_t<q, T> operator-(const vector_t<q, T>& v) const { - vector_t<q, T> diff = *this; - diff -= v; - return diff; - } -}; - - -template<q_t q, class T> -double norm_squared(vector_t<q, T> v) { - double tmp = 0; - for (T &x : v) { - tmp += pow(x, 2); - } - - return tmp; -} - -template <q_t q, class T> -void write_magnetization(vector_t <q, 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 <q_t q> // save some space and don't write whole doubles -void write_magnetization(vector_t <q, double> 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 <q_t q, class T> -T dot(const vector_t <q, T>& v1, const vector_t <q, T>& v2) { - T prod = 0; - - for (q_t i = 0; i < q; i++) { - prod += v1[i] * v2[i]; - } - - return prod; -} - -template <q_t q, class T> -double H_vector(const vector_t <q, T>& v1, T *H) { - vector_t <q, T> H_vec(H); - return (double)(dot <q, T> (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 <getopt.h> -#include <stdio.h> - -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -#include "orthogonal.hpp" -#include "vector.hpp" - -#include <wolff.hpp> -#include <measure.hpp> -#include <colors.h> -#include <randutils/randutils.hpp> - -typedef orthogonal_t <N_COMP, double> orthogonal_R_t; -typedef vector_t <N_COMP, double> vector_R_t; -typedef state_t <orthogonal_R_t, vector_R_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 <orthogonal_R_t(std::mt19937&, vector_R_t)> 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 <N_COMP>, std::placeholders::_1, std::placeholders::_2, epsilon, order); - pert_type = "PERTURB5"; - } else { - gen_R = generate_rotation_uniform <N_COMP>; - 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 <void(const On_t&, const wolff_research_measurements<orthogonal_R_t, vector_R_t>&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const On_t& s, const wolff_research_measurements<orthogonal_R_t, vector_R_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 On_t& s, const wolff_research_measurements<orthogonal_R_t, vector_R_t>& 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<orthogonal_R_t, vector_R_t>& m) {}; - } - - std::function <double(const vector_R_t&)> H; - - if (modulated_field) { - H = std::bind(H_modulated, std::placeholders::_1, order, H_vec[0]); - } else { - H = std::bind(H_vector <N_COMP, double>, std::placeholders::_1, H_vec); - } - - // initialize random number generator - randutils::auto_seed_128 seeds; - std::mt19937 rng{seeds}; - -#ifndef NOFIELD - state_t <orthogonal_R_t, vector_R_t> s(D, L, T, dot <N_COMP, double>, H); -#else - state_t <orthogonal_R_t, vector_R_t> s(D, L, T, dot <N_COMP, double>); -#endif - - wolff_research_measurements<orthogonal_R_t, vector_R_t> 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 <orthogonal_R_t, vector_R_t> (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 <orthogonal_R_t, vector_R_t> (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 <cmath> -#include <stdio.h> - -#include <wolff/types.h> - -// 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 <getopt.h> -#include <stdio.h> - -// if you have GLUT installed, you can see graphics! -#ifdef HAVE_GLUT -#include <GL/glut.h> -#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 <wolff/finite_states.hpp> - -#include <randutils/randutils.hpp> - -// measure.hpp contains useful functions for saving timeseries to files -#include <measure.hpp> - -// include wolff.hpp -#include <wolff.hpp> - -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 <double(const ising_t&, const ising_t&)> 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 <double(const ising_t&)> B = [=] (const ising_t& s) -> double { - if (s.x) { - return -H; - } else { - return H; - } - }; - - // initialize state object -#ifndef NOFIELD - state_t <z2_t, ising_t> s(D, L, T, Z, B); -#else - state_t <z2_t, ising_t> s(D, L, T, Z); -#endif - - // define function that generates self-inverse rotations - std::function <z2_t(std::mt19937&, ising_t)> gen_R = [] (std::mt19937&, const ising_t& s) -> z2_t { - return z2_t(true); - }; - - std::function <void(const state_t<z2_t, ising_t>&, const wolff_research_measurements<z2_t, ising_t>&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const state_t<z2_t, ising_t>& s, const wolff_research_measurements<z2_t, ising_t>& 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 <z2_t, ising_t>& s, const wolff_research_measurements<z2_t, ising_t>& 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<z2_t, ising_t>& s, const wolff_research_measurements<z2_t, ising_t>& meas) {}; - } - - wolff_research_measurements<z2_t, ising_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\" -> \"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 <getopt.h> -#include <stdio.h> - -// if you have GLUT installed, you can see graphics! -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -// include your group and spin space -#include "z2.hpp" -#include "ising.hpp" - -#include <randutils/randutils.hpp> - -// measure.hpp contains useful functions for saving timeseries to files -#include <measure.hpp> - -// include wolff.hpp -#include <wolff.hpp> - -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 <double(const ising_t&, const ising_t&)> 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<double> random_field_values(pow(L, D)); - std::normal_distribution<double> 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 <double(v_t, const ising_t&)> 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 <z2_t, ising_t> s(D, L, T, Z, B); -#else - state_t <z2_t, ising_t> s(D, L, T, Z); -#endif - - // define function that generates self-inverse rotations - std::function <z2_t(std::mt19937&, ising_t)> gen_R = [] (std::mt19937&, const ising_t& s) -> z2_t { - return z2_t(true); - }; - - FILE **outfiles = measure_setup_files(measurement_flags, timestamp); - - std::function <void(const state_t<z2_t, ising_t>&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const state_t<z2_t, ising_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 <z2_t, ising_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<z2_t, ising_t>& s) {}; - } - - std::function <void(const state_t<z2_t, ising_t>&)> 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 <wolff/types.h> -#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 <wolff/types.h> -#include "potts.hpp" - -template <q_t q> -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<q> act(const potts_t<q>& s) const { - if (this->is_reflection) { - return potts_t<q>(((q + this->x) - s.x) % q); - } else { - return potts_t<q>((this->x + s.x) % q); - } - } - - dihedral_t<q> act(dihedral_t<q> r) const { - if (this->is_reflection) { - return dihedral_t<q>(!(r.is_reflection), ((q + this->x) - r.x) % q); - } else { - return dihedral_t<q>(r.is_reflection, (this->x + r.x) % q); - } - } - - potts_t<q> act_inverse(potts_t<q> s) const { - if (this->is_reflection) { - return this->act(s); - } else { - return potts_t<q>(((s.x + q) - this->x) % q); - } - } - - dihedral_t<q> act_inverse(dihedral_t<q> r) const { - if (this->is_reflection) { - return this->act(r); - } else { - return dihedral_t<q>(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 <cmath> -#include <stdio.h> - -#include <wolff/types.h> -#include "../On/vector.hpp" - -template <q_t q> -class potts_t { - public: - q_t x; - - typedef vector_t<q, int> M_t; - typedef vector_t<q, double> F_t; - - potts_t() : x(0) {} - potts_t(q_t x) : x(x) {} - - inline vector_t<q, int> operator*(v_t a) const { - vector_t<q, int> result; - result.fill(0); - result[x] = (int)a; - - return result; - } - - inline vector_t<q, double> operator*(double a) const { - vector_t<q, double> result; - result.fill(0.0); - result[x] = a; - - return result; - } - - inline vector_t<q, int> operator-(const potts_t<q> &s) const { - vector_t<q, int> 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 <q_t q> -double norm_squared(vector_t<q, double> 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 <q_t q> -void write_magnetization(vector_t<q, int> M, FILE *outfile) { - for (int& x : M) { - fwrite(&x, sizeof(int), q - 1, outfile); - } -} - -// knock yourself out -const potts_t<POTTSQ> 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 q> -q_t state_to_ind(potts_t<q> 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 <stdlib.h> -#include <array> -#include <wolff/types.h> -#include "potts.hpp" - -template <q_t q> -class symmetric_t : public std::array<q_t, q> { - public: - - symmetric_t() { - for (q_t i = 0; i < q; i++) { - (*this)[i] = i; - } - } - - potts_t<q> act(const potts_t<q> &s) const { - return potts_t<q>((*this)[s.x]); - } - - symmetric_t<q> act(const symmetric_t<q>& r) const { - symmetric_t<q> r_rot; - for (q_t i = 0; i < q; i++) { - r_rot[i] = (*this)[r[i]]; - } - - return r_rot; - } - - potts_t<q> act_inverse(const potts_t<q>& s) const { - for (q_t i = 0; i < q; i++) { - if ((*this)[i] == s.x) { - return potts_t<q>(i); - } - } - - printf("Your spin wasn't a valid state!", s.x); - exit(EXIT_FAILURE); - } - - symmetric_t<q> act_inverse(const symmetric_t<q>& r) const { - symmetric_t<q> 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 <getopt.h> - -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -// include your group and spin space -#include "dihedral.hpp" -#include "potts.hpp" -#include <colors.h> -#include <measure.hpp> - -// hack to speed things up considerably -#define N_STATES POTTSQ -#include <wolff/finite_states.hpp> - -#include <randutils/randutils.hpp> - -// include wolff.hpp -#include <wolff.hpp> - -typedef state_t <dihedral_t<POTTSQ>, potts_t<POTTSQ>> 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 <double(const potts_t<POTTSQ>&, const potts_t<POTTSQ>&)> Z = [] (const potts_t<POTTSQ>& s1, const potts_t<POTTSQ>& s2) -> double { - return cos(2 * M_PI * (double)(s1.x + POTTSQ - s2.x) / (double)POTTSQ); - }; - - // define spin-field coupling - std::function <double(const potts_t<POTTSQ>&)> B = [=] (const potts_t<POTTSQ>& s) -> double { - return H_vec[s.x]; - }; - - // initialize state object - state_t <dihedral_t<POTTSQ>, potts_t<POTTSQ>> s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function <dihedral_t<POTTSQ>(std::mt19937&, potts_t<POTTSQ>)> gen_R = [] (std::mt19937& r, potts_t<POTTSQ> v) -> dihedral_t<POTTSQ> { - dihedral_t<POTTSQ> rot; - rot.is_reflection = true; - std::uniform_int_distribution<q_t> 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 <void(const sim_t&, const wolff_research_measurements<dihedral_t<POTTSQ>, potts_t<POTTSQ>>&)> measurement; - - if (!draw) { - // a very simple example: measure the average magnetization - measurement = [&] (const sim_t& s, const wolff_research_measurements<dihedral_t<POTTSQ>, potts_t<POTTSQ>>&) { - }; - } 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<dihedral_t<POTTSQ>, potts_t<POTTSQ>>&) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(L, 2); i++) { - potts_t<POTTSQ> 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<dihedral_t<POTTSQ>, potts_t<POTTSQ>> 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 <getopt.h> -#include <stdio.h> - -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -// include your group and spin space -#include "symmetric.hpp" -#include "potts.hpp" - -// hack to speed things up considerably -#define N_STATES POTTSQ -#include <wolff/finite_states.hpp> - -// include wolff.h -#include <measure.hpp> -#include <colors.h> -#include <randutils/randutils.hpp> -#include <wolff.hpp> - -typedef state_t <symmetric_t<POTTSQ>, potts_t<POTTSQ>> 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 <double(const potts_t<POTTSQ>&, const potts_t<POTTSQ>&)> Z = [] (const potts_t<POTTSQ>& s1, const potts_t<POTTSQ>& s2) -> double { - if (s1.x == s2.x) { - return 1.0; - } else { - return 0.0; - } - }; - - // define spin-field coupling - std::function <double(const potts_t<POTTSQ> &)> B = [=] (const potts_t<POTTSQ>& s) -> double { - return H_vec[s.x]; - }; - - // initialize state object - state_t <symmetric_t<POTTSQ>, potts_t<POTTSQ>> s(D, L, T, Z, B); - - // define function that generates self-inverse rotations - std::function <symmetric_t<POTTSQ>(std::mt19937&, potts_t<POTTSQ>)> gen_R = [] (std::mt19937& r, potts_t<POTTSQ> v) -> symmetric_t<POTTSQ> { - symmetric_t<POTTSQ> rot; - - std::uniform_int_distribution<q_t> 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 <void(const sim_t&, const wolff_research_measurements<symmetric_t<POTTSQ>, potts_t<POTTSQ>>&)> other_f; - uint64_t sum_of_clusterSize = 0; - - if (N_is_sweeps) { - other_f = [&] (const sim_t& s, const wolff_research_measurements<symmetric_t<POTTSQ>, potts_t<POTTSQ>>& 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<symmetric_t<POTTSQ>, potts_t<POTTSQ>>& m) { - glClear(GL_COLOR_BUFFER_BIT); - for (v_t i = 0; i < pow(s.L, 2); i++) { - potts_t<POTTSQ> 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<symmetric_t<POTTSQ>, potts_t<POTTSQ>>& m) {}; - } - - wolff_research_measurements<symmetric_t<POTTSQ>, potts_t<POTTSQ>> 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 <wolff/types.h> -#include <cmath> -#include "height.hpp" - -template <class T> -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<T> act(const height_t<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<T> act(const dihedral_inf_t<T>& r) const { - if (this->is_reflection) { - return dihedral_inf_t<T>(!r.is_reflection, this->x - r.x); - } else { - return dihedral_inf_t<T>(r.is_reflection, this->x + r.x); - } - } - - height_t<T> act_inverse(const height_t<T>& h) const { - if (this->is_reflection) { - return this->act(h); - } else { - return height_t(h.x - this->x); - } - } - - dihedral_inf_t<T> act_inverse(const dihedral_inf_t<T>& r) const { - if (this->is_reflection) { - return this->act(r); - } else { - return dihedral_inf_t<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 <cmath> -#include <stdio.h> - -#include <wolff/types.h> - -/* 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 <class T> -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 <class T> -inline T& operator+=(T& M, const height_t<T> &h) { - M += h.x; - - return M; -} - -template <class T> -inline T& operator-=(T& M, const height_t<T> &h) { - M -= h.x; - - return M; -} - -double norm_squared(double h) { - return pow(h, 2); -} - -template <class T> -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 <getopt.h> - -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -// include your group and spin space -#include "dihedral_inf.hpp" -#include "height.hpp" - -#include <randutils/randutils.hpp> - -// include wolff.h -#include <wolff.hpp> - -typedef state_t <dihedral_inf_t<double>, height_t<double>> 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 <double(const height_t<double>&, const height_t<double>&)> Z = [] (const height_t<double>& h1, const height_t<double>& h2) -> double { - return -pow(h1.x - h2.x, 2); - }; - - // define spin-field coupling - std::function <double(height_t<double>)> B = [=] (height_t<double> 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 <dihedral_inf_t<double>(std::mt19937&, height_t<double>)> gen_R = [=] (std::mt19937& r, height_t<double> h) -> dihedral_inf_t<double> { - dihedral_inf_t<double> rot; - rot.is_reflection = true; - std::normal_distribution<double> 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 <void(const sim_t&)> 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, <M> = %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 <getopt.h> - -#ifdef HAVE_GLUT -#include <GL/glut.h> -#endif - -// include your group and spin space -#include "dihedral_inf.hpp" -#include "height.hpp" - -#include <randutils/randutils.hpp> - -// include wolff.h -#include <wolff.hpp> - -typedef state_t <dihedral_inf_t<int64_t>, height_t<int64_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 <double(const height_t<int64_t>&, const height_t<int64_t>&)> Z = [] (const height_t<int64_t>& h1, const height_t<int64_t>& h2) -> double { - return -pow(h1.x - h2.x, 2); - }; - - // define spin-field coupling - std::function <double(const height_t<int64_t> &)> B = [=] (const height_t<int64_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 <dihedral_inf_t<int64_t>(std::mt19937&, height_t<int64_t>)> gen_R = [=] (std::mt19937& r, height_t<int64_t> h) -> dihedral_inf_t<int64_t> { - dihedral_inf_t<int64_t> rot; - rot.is_reflection = true; - - std::uniform_int_distribution<int64_t> dist(-epsilon,epsilon); - - rot.x = 2 * h.x + dist(r); - - return rot; - }; - - // define function that updates any number of measurements - std::function <void(const sim_t&)> 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, <M> = %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 <wolff/types.h> -#include <cmath> -#include <cstring> -#include <stdio.h> -#include <stdlib.h> -#include <getopt.h> -#include <fftw3.h> - -template <class T> -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; -} - |