diff options
author | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2018-07-21 13:21:49 -0400 |
---|---|---|
committer | Jaron Kent-Dobias <jaron@kent-dobias.com> | 2018-07-21 13:21:49 -0400 |
commit | 0c69763278ed102d0e37aa1fb4feda5827c26c62 (patch) | |
tree | 0227d36b272c1243cde6827dcde6f2b3014abb95 | |
parent | f14e6eb0e8cb01ee29f98db9797ac37f3e690cb8 (diff) | |
download | c++-0c69763278ed102d0e37aa1fb4feda5827c26c62.tar.gz c++-0c69763278ed102d0e37aa1fb4feda5827c26c62.tar.bz2 c++-0c69763278ed102d0e37aa1fb4feda5827c26c62.zip |
simplified the way that measurements work
-rw-r--r-- | lib/measure.h | 70 | ||||
-rw-r--r-- | lib/wolff.h | 6 | ||||
-rw-r--r-- | src/wolff_On.cpp | 86 | ||||
-rw-r--r-- | src/wolff_ising.cpp | 11 |
4 files changed, 67 insertions, 106 deletions
diff --git a/lib/measure.h b/lib/measure.h index 52e43af..0b86309 100644 --- a/lib/measure.h +++ b/lib/measure.h @@ -3,53 +3,67 @@ #include "measurement.h" -#define POSSIBLE_MEASUREMENTS 5 +#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"}; + #ifdef __cplusplus #include "state.h" #include "correlation.h" #include <functional> -template <class R_t, class X_t> -std::function <void(const state_t <R_t, X_t> *)> measurement_energy_file(FILE *file) { - return [=](const state_t <R_t, X_t> *s) { - float smaller_E = (float)s->E; - fwrite(&smaller_E, sizeof(float), 1, file); - }; -} -template <class R_t, class X_t> -std::function <void(const state_t <R_t, X_t> *)> measurement_cluster_file(FILE *file) { - return [=](const state_t <R_t, X_t> *s) { - fwrite(&(s->last_cluster_size), sizeof(uint32_t), 1, file); - }; -} -template <class R_t, class X_t> -std::function <void(const state_t <R_t, X_t> *)> measurement_magnetization_file(FILE *file) { - return [=](const state_t <R_t, X_t> *s) { - write_magnetization(s->M, file); - }; +FILE **measure_setup_files(unsigned char flags, unsigned long timestamp) { + 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); + } + } + + return files; } template <class R_t, class X_t> -std::function <void(const state_t <R_t, X_t> *)> measurement_fourier_file(FILE *file) { - return [=](const state_t <R_t, X_t> *s) { - float smaller_X = (float)correlation_length(s); - fwrite(&smaller_X, sizeof(float), 1, file); +std::function <void(const state_t <R_t, X_t> *)> measure_function_write_files(unsigned char flags, FILE **files, std::function <void(const state_t <R_t, X_t> *)> other_f) { + return [=] (const state_t <R_t, X_t> *s) { + if (flags & measurement_energy) { + float smaller_E = (float)s->E; + fwrite(&smaller_E, sizeof(float), 1, files[0]); + } + if (flags & measurement_clusterSize) { + fwrite(&(s->last_cluster_size), sizeof(uint32_t), 1, files[1]); + } + if (flags & measurement_magnetization) { + write_magnetization(s->M, files[2]); + } + if (flags & measurement_fourierZero) { + float smaller_X = (float)correlation_length(s); + fwrite(&smaller_X, sizeof(float), 1, files[3]); + } + + other_f(s); }; } -template <class R_t, class X_t> -std::function <void(const state_t <R_t, X_t> *)> measurement_average_cluster(meas_t *x) { - return [=](const state_t <R_t, X_t> *s) { - meas_update(x, s->last_cluster_size); - }; +void measure_free_files(unsigned char flags, FILE **files) { + for (uint8_t i = 0; i < POSSIBLE_MEASUREMENTS; i++) { + if (flags & (1 << i)) { + fclose(files[i]); + } + } + + free(files); } #endif diff --git a/lib/wolff.h b/lib/wolff.h index 21e88d9..4e93d01 100644 --- a/lib/wolff.h +++ b/lib/wolff.h @@ -3,7 +3,7 @@ #include "state.h" template <class R_t, class X_t> -void wolff(count_t N, state_t <R_t, X_t> *s, std::function <R_t(gsl_rng *, const state_t <R_t, X_t> *)> gen_R, unsigned int n_measurements, std::function <void(const state_t <R_t, X_t> *)> *measurements, gsl_rng *r, bool silent) { +void wolff(count_t N, state_t <R_t, X_t> *s, std::function <R_t(gsl_rng *, const state_t <R_t, X_t> *)> gen_R, std::function <void(const state_t <R_t, X_t> *)> measurements, gsl_rng *r, bool silent) { if (!silent) printf("\n"); for (count_t steps = 0; steps < N; steps++) { @@ -14,9 +14,7 @@ void wolff(count_t N, state_t <R_t, X_t> *s, std::function <R_t(gsl_rng *, const flip_cluster <R_t, X_t> (s, v0, step, r); free_spin(step); - for (unsigned int i = 0; i < n_measurements; i++) { - measurements[i](s); - } + measurements(s); } if (!silent) { diff --git a/src/wolff_On.cpp b/src/wolff_On.cpp index 76831ba..491fb27 100644 --- a/src/wolff_On.cpp +++ b/src/wolff_On.cpp @@ -50,7 +50,9 @@ int main(int argc, char *argv[]) { q_t H_ind = 0; double epsilon = 1; - unsigned char measurement_flags = measurement_energy | measurement_clusterSize; +// unsigned char measurement_flags = measurement_energy | measurement_clusterSize; + + unsigned char measurement_flags = 0; while ((opt = getopt(argc, argv, "N:q:D:L:T:J:H:spe:mo:M:S")) != -1) { switch (opt) { @@ -116,7 +118,6 @@ int main(int argc, char *argv[]) { 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); @@ -143,53 +144,21 @@ int main(int argc, char *argv[]) { fclose(outfile_info); - unsigned int n_measurements = 0; - std::function <void(const On_t *)> *measurements = (std::function <void(const On_t *)> *)calloc(POSSIBLE_MEASUREMENTS, sizeof(std::function <void(const On_t *)>)); - FILE *outfile_M, *outfile_E, *outfile_S, *outfile_F; - - if (measurement_flags & measurement_energy) { - char *filename_E = (char *)malloc(255 * sizeof(char)); - sprintf(filename_E, "wolff_%lu_E.dat", timestamp); - outfile_E = fopen(filename_E, "wb"); - free(filename_E); - measurements[n_measurements] = measurement_energy_file<orthogonal_R_t, vector_R_t> (outfile_E); - n_measurements++; - } + FILE **outfiles = measure_setup_files(measurement_flags, timestamp); - if (measurement_flags & measurement_clusterSize) { - char *filename_S = (char *)malloc(255 * sizeof(char)); - sprintf(filename_S, "wolff_%lu_S.dat", timestamp); - outfile_S = fopen(filename_S, "wb"); - free(filename_S); - measurements[n_measurements] = measurement_cluster_file<orthogonal_R_t, vector_R_t> (outfile_S); - n_measurements++; - } + std::function <void(const On_t *)> other_f; + uint64_t sum_of_clusterSize = 0; - if (measurement_flags & measurement_magnetization) { - char *filename_M = (char *)malloc(255 * sizeof(char)); - sprintf(filename_M, "wolff_%lu_M.dat", timestamp); - outfile_M = fopen(filename_M, "wb"); - free(filename_M); - measurements[n_measurements] = measurement_magnetization_file<orthogonal_R_t, vector_R_t> (outfile_M); - n_measurements++; - } - - if (measurement_flags & measurement_fourierZero) { - char *filename_F = (char *)malloc(255 * sizeof(char)); - sprintf(filename_F, "wolff_%lu_F.dat", timestamp); - outfile_F = fopen(filename_F, "wb"); - free(filename_F); - measurements[n_measurements] = measurement_fourier_file<orthogonal_R_t, vector_R_t> (outfile_F); - n_measurements++; - } - - meas_t *meas_sweeps; if (N_is_sweeps) { - meas_sweeps = (meas_t *)calloc(1, sizeof(meas_t)); - measurements[n_measurements] = measurement_average_cluster<orthogonal_R_t, vector_R_t> (meas_sweeps); - n_measurements++; + other_f = [&] (const On_t *s) { + sum_of_clusterSize += s->last_cluster_size; + }; + } else { + other_f = [] (const On_t *s) {}; } + std::function <void(const On_t *)> measurements = measure_function_write_files(measurement_flags, outfiles, other_f); + std::function <double(vector_R_t)> H; if (modulated_field) { @@ -207,35 +176,18 @@ int main(int argc, char *argv[]) { if (N_is_sweeps) { count_t N_rounds = 0; printf("\n"); - while (N_rounds * N * meas_sweeps->x < N * s.nv) { - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n", (count_t)(N_rounds * N * meas_sweeps->x / s.nv), N, s.E, s.last_cluster_size); - wolff <orthogonal_R_t, vector_R_t> (N, &s, gen_R, n_measurements, measurements, r, silent); + 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 <orthogonal_R_t, vector_R_t> (N, &s, gen_R, measurements, r, silent); N_rounds++; } - printf("\033[F\033[J\033[F\033[JWOLFF: sweep %" PRIu64 " / %" PRIu64 ": E = %.2f, S = %" PRIv "\n\n", (count_t)(N_rounds * N * meas_sweeps->x / s.nv), N, s.E, s.last_cluster_size); + 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 <orthogonal_R_t, vector_R_t> (N, &s, gen_R, n_measurements, measurements, r, silent); + wolff <orthogonal_R_t, vector_R_t> (N, &s, gen_R, measurements, r, silent); } - free(measurements); - - if (measurement_flags & measurement_energy) { - fclose(outfile_E); - } - if (measurement_flags & measurement_clusterSize) { - fclose(outfile_S); - } - if (measurement_flags & measurement_magnetization) { - fclose(outfile_M); - } - if (measurement_flags & measurement_fourierZero) { - fclose(outfile_F); - } - - if (N_is_sweeps) { - free(meas_sweeps); - } + measure_free_files(measurement_flags, outfiles); free(H_vec); gsl_rng_free(r); diff --git a/src/wolff_ising.cpp b/src/wolff_ising.cpp index 1812527..fd2f0bb 100644 --- a/src/wolff_ising.cpp +++ b/src/wolff_ising.cpp @@ -30,7 +30,7 @@ int main(int argc, char *argv[]) { case 'T': // temperature T = atof(optarg); break; - case 'H': // external field. nth call couples to state n + case 'H': // external field H = atof(optarg); break; case 's': // don't print anything during simulation. speeds up slightly @@ -49,21 +49,18 @@ int main(int argc, char *argv[]) { std::function <z2_t(gsl_rng *, const state_t <z2_t, ising_t> *)> gen_R = generate_ising_rotation; - unsigned int n_measurements = 1; - double average_M = 0; - std::function <void(const state_t <z2_t, ising_t> *)> *measurements = (std::function <void(const state_t <z2_t, ising_t> *)> *)calloc(1, sizeof(std::function <void(const state_t <z2_t, ising_t> *)>)); + typedef std::function <void(const state_t <z2_t, ising_t> *)> meas_func; - measurements[0] = [&] (const state_t <z2_t, ising_t> *s) { + meas_func measurement = [&] (const state_t <z2_t, ising_t> *s) { average_M += (double)s->M / (double)N / (double)s->nv; }; - wolff(N, &s, gen_R, n_measurements, measurements, r, silent); + wolff(N, &s, gen_R, measurement, r, silent); printf("%" PRIcount " Ising runs completed. D = %" PRID ", L = %" PRIL ", T = %g, H = %g, <M> = %g\n", N, D, L, T, H, average_M); - free(measurements); gsl_rng_free(r); return 0; |