#pragma once #include "matrix.hpp" #include "spin.hpp" #include "vector.hpp" typedef double Radius; typedef signed IsingSpin; template class Dimer { public: double radius; Vector relativePosition; }; template class Euclidean { public: Vector t; Matrix r; Euclidean(T L) { for (unsigned i = 0; i < D; i++) { t(i) = 0; r(i, i) = 1; for (unsigned j = 1; j < D; j++) { r(i, (i + j) % D) = 0; } } } Euclidean(Vector t0, Matrix r0) { t = t0; r = r0; } Vector act(const Vector& x) const { return t + r * x; } template Vector act(const Vector& x) const { return t.template cast() + r.template cast() * x; } Radius act(Radius r) const { return r; } IsingSpin act(IsingSpin s) const { return s; } Dimer act(const Dimer& d) const { return {.radius = d.radius, .relativePosition = r * d.relativePosition}; } template Spin act(const Spin& s) const { return {.x = act(s.x), .s = act(s.s)}; } Euclidean act(const Euclidean& x) const { return Euclidean(r * x.t + t, r * x.r); } Euclidean inverse() const { return Euclidean(-r.transpose() * t, r.transpose()); } }; template class TorusGroup { private: T L; public: Vector t; Matrix r; /** brief TorusGroup - default constructor, constructs the identity */ TorusGroup(T L) : L(L) { for (unsigned i = 0; i < D; i++) { t(i) = 0; r(i, i) = 1; for (unsigned j = 1; j < D; j++) { r(i, (i + j) % D) = 0; } } } TorusGroup(T L, Vector t0, Matrix r0) : L(L) { t = t0; r = r0; } template Spin act(const Spin& s) const { Spin s_new; s_new.x = t + r * s.x; s_new.s = s.s; for (unsigned i = 0; i < D; i++) { s_new.x(i) = fmod(L + s_new.x(i), L); } return s_new; } Vector act(const Vector& s) const { Vector s_new = t + r * s; for (unsigned i = 0; i < D; i++) { s_new(i) = fmod(L + s_new(i), L); } return s_new; } template Vector act(const Vector& s) const { Vector s_new = t.template cast() + r.template cast() * s; for (unsigned i = 0; i < D; i++) { s_new(i) = fmod(L + s_new(i), L); } return s_new; } TorusGroup act(const TorusGroup& x) const { Vector tnew = r * x.t + t; Matrix rnew = r * x.r; for (unsigned i = 0; i < D; i++) { tnew(i) = fmod(L + tnew(i), L); } TorusGroup pnew(this->L, tnew, rnew); return pnew; } TorusGroup inverse() const { Vector tnew = -r.transpose() * t; Matrix rnew = r.transpose(); TorusGroup pnew(this->L, tnew, rnew); return pnew; } };