summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJaron Kent-Dobias <jaron@kent-dobias.com>2018-07-26 16:18:40 -0400
committerJaron Kent-Dobias <jaron@kent-dobias.com>2018-07-26 16:18:40 -0400
commit1160baa61bad605cf8a1d583e8ae356a54a942df (patch)
treee7c865f38836a9a03349bbd803aae8be9b37a200 /lib
parent870555f569bc63fecdc7c0b16e72e4e002f21c13 (diff)
downloadc++-1160baa61bad605cf8a1d583e8ae356a54a942df.tar.gz
c++-1160baa61bad605cf8a1d583e8ae356a54a942df.tar.bz2
c++-1160baa61bad605cf8a1d583e8ae356a54a942df.zip
many changes, including new spin spaces and groups and cleaning up core library code
Diffstat (limited to 'lib')
-rw-r--r--lib/angle.h48
-rw-r--r--lib/circle_group.h46
-rw-r--r--lib/cluster.h16
-rw-r--r--lib/dihedral.h1
-rw-r--r--lib/state.h6
-rw-r--r--lib/torus.h64
-rw-r--r--lib/vector.h4
7 files changed, 172 insertions, 13 deletions
diff --git a/lib/angle.h b/lib/angle.h
new file mode 100644
index 0000000..c3f128e
--- /dev/null
+++ b/lib/angle.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "types.h"
+
+#include <cmath>
+#include "vector.h"
+
+class angle_t {
+ public:
+ double x;
+
+ typedef vector_t<2, double> M_t;
+ typedef vector_t<2, double> F_t;
+
+ angle_t() : x(0) {}
+ angle_t(double x) : x(x) {}
+
+ inline vector_t<2, double> operator*(v_t a) const {
+ vector_t<2, double>M;
+ M[0] = a * cos(x);
+ M[1] = a * sin(x);
+
+ return M;
+ }
+
+ inline vector_t<2, double> operator*(double a) const {
+ vector_t<2, double>M;
+ M[0] = a * cos(x);
+ M[1] = a * sin(x);
+
+ return M;
+ }
+};
+
+inline vector_t<2,double>& operator+=(vector_t<2,double>& M, const angle_t& theta) {
+ M[0] += cos(theta.x);
+ M[1] += sin(theta.x);
+
+ return M;
+}
+
+inline vector_t<2,double>& operator-=(vector_t<2,double>& M, const angle_t& theta) {
+ M[0] -= cos(theta.x);
+ M[1] -= sin(theta.x);
+
+ return M;
+}
+
diff --git a/lib/circle_group.h b/lib/circle_group.h
new file mode 100644
index 0000000..cb7cadd
--- /dev/null
+++ b/lib/circle_group.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "angle.h"
+
+class circle_group_t {
+ public:
+ bool is_reflection;
+ double x;
+
+ circle_group_t() : is_reflection(false), x(0) {}
+ circle_group_t(bool x, double y) : is_reflection(x), x(y) {}
+
+ angle_t act(const angle_t& theta) const {
+ if (is_reflection) {
+ return angle_t(fmod(2 * M_PI + x - theta.x, 2 * M_PI));
+ } else {
+ return angle_t(fmod(x + theta.x, 2 * M_PI));
+ }
+ }
+
+ circle_group_t act(const circle_group_t& r) const {
+ if (is_reflection) {
+ return circle_group_t(!r.is_reflection, fmod(2 * M_PI + x - r.x, 2 * M_PI));
+ } else {
+ return circle_group_t(r.is_reflection, fmod(x + r.x, 2 * M_PI));
+ }
+ }
+
+ angle_t act_inverse(const angle_t& theta) const {
+ if (is_reflection) {
+ return act(theta);
+ } else {
+ return angle_t(fmod(2 * M_PI + theta.x - x, 2 * M_PI));
+ }
+ }
+
+ circle_group_t act_inverse(const circle_group_t& r) const {
+ if (is_reflection) {
+ return act(r);
+ } else {
+ return circle_group_t(r.is_reflection, fmod(2 * M_PI + r.x - x, 2 * M_PI));
+ }
+ }
+};
+
+
diff --git a/lib/cluster.h b/lib/cluster.h
index c5f2be7..f948586 100644
--- a/lib/cluster.h
+++ b/lib/cluster.h
@@ -31,7 +31,9 @@ void flip_cluster(state_t <R_t, X_t> *state, v_t v0, R_t r, gsl_rng *rand) {
R_old = state->R;
marks[v] = true;
- if (v == state->nv) {
+ bool v_is_ghost = (v == state->nv);
+
+ if (v_is_ghost) {
R_new = r.act(R_old);
} else {
si_old = state->spins[v];
@@ -40,19 +42,18 @@ void flip_cluster(state_t <R_t, X_t> *state, v_t v0, R_t r, gsl_rng *rand) {
for (const v_t &vn : state->g.v_adj[v]) {
X_t sj;
+ bool vn_is_ghost = (vn == state->nv);
- if (vn != state->nv) {
+ if (!vn_is_ghost) {
sj = state->spins[vn];
}
double prob;
- bool is_ext = (v == state->nv || vn == state->nv);
-
- if (is_ext) {
+ if (v_is_ghost || vn_is_ghost) {
X_t rs_old, rs_new;
v_t non_ghost;
- if (vn == state->nv) {
+ if (vn_is_ghost) {
rs_old = R_old.act_inverse(si_old);
rs_new = R_old.act_inverse(si_new);
non_ghost = v;
@@ -61,6 +62,7 @@ void flip_cluster(state_t <R_t, X_t> *state, v_t v0, R_t r, gsl_rng *rand) {
rs_new = R_new.act_inverse(sj);
non_ghost = vn;
}
+
double dE = state->H(rs_old) - state->H(rs_new);
#ifdef FINITE_STATES
prob = H_probs[state_to_ind(rs_old)][state_to_ind(rs_new)];
@@ -97,7 +99,7 @@ void flip_cluster(state_t <R_t, X_t> *state, v_t v0, R_t r, gsl_rng *rand) {
}
}
- if (v == state->nv) {
+ if (v_is_ghost) {
state->R = R_new;
} else {
state->spins[v] = si_new;
diff --git a/lib/dihedral.h b/lib/dihedral.h
index 5588afa..8d0472b 100644
--- a/lib/dihedral.h
+++ b/lib/dihedral.h
@@ -21,7 +21,6 @@ class dihedral_t {
}
}
-
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);
diff --git a/lib/state.h b/lib/state.h
index eefa0cb..5abf65b 100644
--- a/lib/state.h
+++ b/lib/state.h
@@ -27,10 +27,10 @@ class state_t {
std::vector<double> precomputed_cos;
std::vector<double> precomputed_sin;
- std::function <double(X_t, X_t)> J;
- std::function <double(X_t)> H;
+ std::function <double(const X_t&, const X_t&)> J;
+ std::function <double(const X_t&)> H;
- state_t(D_t D, L_t L, double T, std::function <double(X_t, X_t)> J, std::function <double(X_t)> H) : D(D), L(L), g(D, L), T(T), R(), J(J), H(H) {
+ state_t(D_t D, L_t L, double T, std::function <double(const X_t&, const X_t&)> J, std::function <double(const X_t&)> H) : D(D), L(L), g(D, L), T(T), R(), J(J), H(H) {
nv = g.nv;
ne = g.ne;
g.add_ext();
diff --git a/lib/torus.h b/lib/torus.h
new file mode 100644
index 0000000..2aead52
--- /dev/null
+++ b/lib/torus.h
@@ -0,0 +1,64 @@
+
+#pragma once
+
+#include <cmath>
+#include <array>
+#include "types.h"
+
+template <q_t n>
+class torus_t : public std::array<double, n> {
+ public:
+ typedef std::array<double, n> M_t;
+ typedef std::array<double, n> F_t;
+
+ torus_t() {
+ this->fill(0);
+ }
+
+ inline torus_t<n> operator*(v_t a) const {
+ torus_t<n> x;
+ for (q_t i = 0; i < n; i++) {
+ x[i] = a * (*this)[i];
+ }
+
+ return x;
+ }
+
+ inline torus_t<n> operator*(double a) const {
+ torus_t<n> x;
+ for (q_t i = 0; i < n; i++) {
+ x[i] = a * (*this)[i];
+ }
+
+ return x;
+ }
+
+ inline torus_t<n>& operator+=(const torus_t<n>& x) {
+ for (q_t i = 0; i < n; i++) {
+ (*this)[i] += x[i];
+ }
+ }
+
+ inline torus_t<n>& operator-=(const torus_t<n>& x) {
+ for (q_t i = 0; i < n; i++) {
+ (*this)[i] -= x[i];
+ }
+ }
+};
+
+template <q_t n>
+double norm_squared(const torus_t<n>& x) {
+ double tmp = 0;
+ for (const double& xi : x) {
+ tmp += pow(xi, 2);
+ }
+ return tmp;
+}
+
+void write_magnetization(const torus_t<n>& x, FILE *outfile) {
+ for (const double& xi : x) {
+ float tmp_xi = (float)xi;
+ fwrite(&tmp_xi, sizeof(float), 1, outfile);
+ }
+}
+
diff --git a/lib/vector.h b/lib/vector.h
index beee1a7..2f4077a 100644
--- a/lib/vector.h
+++ b/lib/vector.h
@@ -109,7 +109,7 @@ void write_magnetization(vector_t <q, double> M, FILE *outfile) {
}
template <q_t q, class T>
-T dot(vector_t <q, T> v1, vector_t <q, T> v2) {
+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++) {
@@ -120,7 +120,7 @@ T dot(vector_t <q, T> v1, vector_t <q, T> v2) {
}
template <q_t q, class T>
-double H_vector(vector_t <q, T> v1, T *H) {
+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));
}