summaryrefslogtreecommitdiff
path: root/ising_autocorrelation.cpp
blob: 053be015fb7abd2183bb255c177ca204f969e881 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <iostream>
#include <fstream>

#include "ising.hpp"
#include "quantity.hpp"

class Autocorrelation : public measurement<signed, D, TorusGroup<signed, D>, signed> {
public:
  Quantity E;
  Autocorrelation(unsigned lag) : E(lag) {}

  void post_cluster(const isingModel& m) override {
    double E_tmp = 0;

    TorusGroup<signed, D> s0Inv = m.s0.inverse();

    for (const isingSpin* si : m.s) {
      E_tmp -= m.B(s0Inv.act(*si));

      for (const isingSpin* sj : m.dict.neighbors(si->x)) {
        if (si != sj) {
          E_tmp -= m.Z(*si, *sj) / 2;
        }
      }
    }

    E.add(E_tmp);
  }
};

int main(int argc, char* argv[]) {
  unsigned L = 32;
  unsigned N = 1000;
  unsigned mod = 0;
  unsigned multi = 1e4;
  double mag = 0.5;
  double pop = 1.0;
  double T = 2.0 / log(1.0 + sqrt(2.0));
  double H = 1.0;
  double ε = 0.1;
  unsigned lag = 1e2;

  int opt;

  while ((opt = getopt(argc, argv, "N:L:T:H:e:m:M:r:p:l:")) != -1) {
    switch (opt) {
    case 'N':
      N = (unsigned)atof(optarg);
      break;
    case 'L':
      L = atoi(optarg);
      break;
    case 'T':
      T = atof(optarg);
      break;
    case 'H':
      H = atof(optarg);
      break;
    case 'e':
      ε = atof(optarg);
      break;
    case 'm':
      mod = atoi(optarg);
      break;
    case 'M':
      multi = atoi(optarg);
      break;
    case 'r':
      mag = atof(optarg);
      break;
    case 'p':
      pop = atof(optarg);
      break;
    case 'l':
      lag = (unsigned)atof(optarg);
      break;
    default:
      exit(1);
    }
  }

  isingModel ising(L, isingZ(L), isingBMod(L, mod, H));
  isingPopulate(ising, L, pop, mag);

  auto g = isingGen(L);

  measurement<signed, D, TorusGroup<signed, D>, signed> A_empty;

  ising.wolff(T, {g}, A_empty, N);

  Autocorrelation A(lag);

  while (true) {
    ising.wolff(T, {g}, A, N);
    std::array<double, 2> τ = A.E.τ();
    std::cout << A.E.num_added() << " " << A.E.avg() << " " << τ[0] << " " << τ[1] << " " << τ[1] / τ[0] << "\n";
    if (τ[1] / τ[0] < ε && τ[0] * multi < A.E.num_added()) {
      break;
    }
  }

  std::ofstream outfile;
  outfile.open("out.dat", std::ios::app);

  std::array<double, 2> act = A.E.τ();
  std::vector<double> ρ = A.E.ρ();

  outfile << L << " " << T << " " << mod << " " << H << " " << A.E.num_added() << " " <<
  A.E.avg() << " " << A.E.serr() << " " << act[0] << " " << act[1]; for (double ρi : ρ) {
    outfile << " " << ρi;
  }
  outfile << "\n";

  return 0;
}