summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaron Kent-Dobias <jaron@kent-dobias.com>2018-07-21 13:21:49 -0400
committerJaron Kent-Dobias <jaron@kent-dobias.com>2018-07-21 13:21:49 -0400
commit0c69763278ed102d0e37aa1fb4feda5827c26c62 (patch)
tree0227d36b272c1243cde6827dcde6f2b3014abb95
parentf14e6eb0e8cb01ee29f98db9797ac37f3e690cb8 (diff)
downloadc++-0c69763278ed102d0e37aa1fb4feda5827c26c62.tar.gz
c++-0c69763278ed102d0e37aa1fb4feda5827c26c62.tar.bz2
c++-0c69763278ed102d0e37aa1fb4feda5827c26c62.zip
simplified the way that measurements work
-rw-r--r--lib/measure.h70
-rw-r--r--lib/wolff.h6
-rw-r--r--src/wolff_On.cpp86
-rw-r--r--src/wolff_ising.cpp11
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;