diff options
| -rw-r--r-- | glass.cpp | 138 | 
1 files changed, 88 insertions, 50 deletions
| @@ -1,4 +1,5 @@  #include <eigen3/Eigen/Dense> +#include <eigen3/Eigen/src/Core/CwiseNullaryOp.h>  #include <iostream>  #include <list>  #include <vector> @@ -117,6 +118,14 @@ public:    bool isEmpty() const { return this->squaredNorm() == 0; }    void remove() { this->setZero(); } + +  State<D> flip() const { +    State<D> s; +    for (unsigned i = 0; i < D; i++) { +      s(i) = -this->operator()(i); +    } +    return s; +  }  };  template <unsigned D> class Transformation { @@ -125,21 +134,41 @@ template <unsigned D> class Transformation {      Matrix<D> m;      Vector<D> v; +    Transformation(unsigned L) : L(L) { +      m.setIdentity(); +      v.setZero(); +    } +      Transformation(unsigned L, const Matrix<D>& m, const Vector<D>& v) : L(L), m(m), v(v) {}      Transformation(unsigned L, const std::vector<Matrix<D>>& ms, Rng& r) : m(r.pick(ms)), L(L) {        for (unsigned i = 0; i < D; i++) {          v[i] = r.uniform((unsigned)0, L - 1);        } + +      v = v - m * v;      }      Vector<D> apply(const Vector<D>& x) const { -      return mod<D>(v + m * (x - v), L); +      return mod<D>(v + m * x, L); +    } + +    Transformation<D> apply(const Transformation<D>& t) const { +      Transformation<D> tNew(L); + +      tNew.m = m * t.m; +      tNew.v = apply(t.v); + +      return tNew;      }      State<D> apply(const State<D>& x) const {        return State<D>(m * x);      } + +    Transformation<D> inverse() const { +      return Transformation<D>(L, m.transpose(), -m.transpose() * v); +    }  };  template <unsigned D> class HalfEdge; @@ -167,6 +196,7 @@ public:    const unsigned L;    unsigned N;    std::vector<Vertex<D>> vertices; +  Transformation<D> orientation;    unsigned vectorToIndex(const Vector<D>& x) const {      unsigned i = 0; @@ -184,7 +214,7 @@ public:      return x;    } -  System(unsigned L) : L(L), N(0), vertices(iPow(L, D)) { +  System(unsigned L) : L(L), N(0), vertices(iPow(L, D)), orientation(L) {      for (unsigned i = 0; i < iPow(L, D); i++) {        vertices[i].position = indexToVector(i);        vertices[i].adjacentEdges.reserve(2 * D); @@ -248,16 +278,26 @@ public:    bool tryRandomMove(Rng& r) {      Vertex<D>& v = r.pick(vertices);      State<D> oldState = v.state; +      if (!tryDeletion(v)) {        return false;      } -    if (0.2 > r.uniform(0.0, 1.0)) { -      if (insert(v, State<D>(r))) { -        return true; +    if (1.0 / (2.0 * D) > r.uniform(0.0, 1.0)) { +      for (HalfEdge<D>& e : v.adjacentEdges) { +        if (1 == e.Δx.dot(oldState)) { +          if (insert(e.neighbor, oldState.flip())) { +            return true; +          } +          break; +        }        }      } else { -      if (insert(r.pick(v.adjacentEdges).neighbor, State<D>(r))) { +      State<D> newState(r); +      while (newState.dot(oldState) == 1) { +        newState = State<D>(r); +      } +      if (insert(v, newState)) {          return true;        }      } @@ -345,17 +385,16 @@ public:        }        tryRandomMove(r); -      tryRandomSwap(r);      }    } -  void sweepLocal(double z, Rng& r) { +  void sweepLocal(Rng& r) {      for (unsigned i = 0; i < iPow(L, D); i++) {        tryRandomMove(r);      }    } -  void sweepSwap(double z, Rng& r) { +  void sweepSwap(Rng& r) {      for (unsigned i = 0; i < iPow(L, D); i++) {        tryRandomSwap(r);      } @@ -406,17 +445,29 @@ public:    void swendsenWang(const Transformation<D>& R, Rng& r) {      for (Vertex<D>& v : vertices) {        if (!v.marked) { -        unsigned n = flipCluster(R, v, r, 0.5 < r.uniform(0.0, 1.0)); -        std::cerr << n << " "; +        bool dry = 0.5 < r.uniform(0.0, 1.0); +        unsigned n = flipCluster(R, v, r, dry); +        if (n > pow(L, D) / 4 && !dry) { +          orientation = R.apply(orientation); +        }        }      } -    std::cerr << std::endl; -      for (Vertex<D>& v : vertices) {        v.marked = false;      }    } + +  int overlap(const System<D>& s) const { +    int o = 0; + +    for (unsigned i = 0; i < vertices.size(); i++) { +      State<D> s2 = orientation.apply(s.vertices[vectorToIndex(orientation.inverse().apply(indexToVector(i)))].state); +      o += vertices[i].state.dot(s2); +    } + +    return o; +  }  };  void print(const System<2>& s) { @@ -451,7 +502,7 @@ template <unsigned D> Vector<D> randomVector(unsigned L, Rng& r) {  int main() {    const unsigned D = 3; -  unsigned L = 28; +  unsigned L = 15;    unsigned Nmin = 2e2;    unsigned Nmax = 2e5;    double Tmin = 0.04; @@ -462,53 +513,40 @@ int main() {    Rng r; -  double z = exp(1 / 0.15); +  double z = exp(1 / 0.08); -  s.setGroundState(); -  std::vector<Matrix<D>> ms = generateTorusMatrices<D>(); - -  for (unsigned n = 0; n < 1e3; n++) { +  while (s.density() < 0.818) {      s.sweepGrandCanonical(z, r);    } -  if (s.compatible()) { -    std::cerr << "Still compatible!" << std::endl; -  } - - -  for (unsigned n = 0; n < 10; n++) { -    s.swendsenWang(Transformation<D>(L, ms, r), r); -  } - -  if (s.compatible()) { -    std::cerr << "Still compatible!" << std::endl; -  } +  if (!s.compatible()) { +    std::cerr << "Net compatible!" << std::endl; +    return 1; +  }  -  /* +  std::cerr << "Found state with appropriate density." << std::endl; -  for (unsigned N = Nmin; N <= Nmax; N *= 10) { -    s.setGroundState(); -    for (double T = Tmin; T < Tmax; T *= 1 + δT) { -      double z = exp(1 / T); +  System<D> s0 = s; -      for (unsigned n = 0; n < N; n++) { -        s.sweepGrandCanonical(z, r); -      } +  std::vector<Matrix<D>> ms = generateTorusMatrices<D>(); -      std::cout << L << " " << T << " " << N << " " << δT << " " << 1 / s.density() << std::endl; +  unsigned n = 1; +  for (unsigned i = 0; i < 1e5; i++) { +    if (n < 20 * log(i + 1)) { +      n++; +      std::cout << i << " " << s.overlap(s0) << std::endl;      } - -    for (double T = Tmax; T > Tmin; T /= 1 + δT) { -      double z = exp(1 / T); - -      for (unsigned n = 0; n < N; n++) { -        s.sweepGrandCanonical(z, r); -      } - -      std::cout << L << " " << T << " " << N << " " << δT << " " << 1 / s.density() << std::endl; +    Matrix<D> m = r.pick(ms); +    Vertex<D>& v = r.pick(s.vertices); +    unsigned nC = s.flipCluster(Transformation<D>(L, m, v.position - m * v.position), v, r); +    std::cerr << nC << std::endl; +    for (Vertex<D>& v : s.vertices) { +      v.marked = false;      } +//    s.sweepLocal(r); +//    s.sweepSwap(r); +//    s.swendsenWang(Transformation<D>(L, ms, r), r);    } -  */    return 0;  } | 
