#pragma once #include #include #include #include template class vector_t : public std::array { public: // M_t needs to hold the sum of nv spins typedef vector_t M_t; // F_t needs to hold the double-weighted sum of spins typedef vector_t F_t; vector_t() { this->fill((T)0); (*this)[1] = (T)1; } vector_t(const T *x) { for (q_t i = 0; i < q; i++) { (*this)[i] = x[i]; } } template inline vector_t& operator+=(const vector_t &v) { for (q_t i = 0; i < q; i++) { (*this)[i] += (U)v[i]; } return *this; } template inline vector_t& operator-=(const vector_t &v) { for (q_t i = 0; i < q; i++) { (*this)[i] -= (U)v[i]; } return *this; } inline vector_t operator*(v_t x) const { vector_t result; for (q_t i = 0; i < q; i++) { result[i] = x * (*this)[i]; } return result; } inline vector_t operator*(double x) const { vector_t result; for (q_t i = 0; i < q; i++) { result[i] = x * (*this)[i]; } return result; } inline vector_t operator-(const vector_t& v) const { vector_t diff = *this; diff -= v; return diff; } }; template double norm_squared(vector_t v) { double tmp = 0; for (T &x : v) { tmp += pow(x, 2); } return tmp; } template void write_magnetization(vector_t M, FILE *outfile) { for (q_t i = 0; i < q; i++) { fwrite(&(M[i]), sizeof(T), q, outfile); } } // below functions and definitions are unnecessary for wolff.h but useful. template // save some space and don't write whole doubles void write_magnetization(vector_t M, FILE *outfile) { for (q_t i = 0; i < q; i++) { float M_tmp = (float)M[i]; fwrite(&M_tmp, sizeof(float), 1, outfile); } } template T dot(const vector_t & v1, const vector_t & v2) { T prod = 0; for (q_t i = 0; i < q; i++) { prod += v1[i] * v2[i]; } return prod; } template double H_vector(const vector_t & v1, T *H) { vector_t H_vec(H); return (double)(dot (v1, H_vec)); } char const *ON_strings[] = {"TRIVIAL", "ISING", "PLANAR", "HEISENBERG"};