Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca_ising_magnetisation_example.cc
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11*/
12
38#include <algorithm>
39#include <array>
40#include <cmath>
41#include <cstddef>
42#include <cstdint>
43#include <iomanip>
44#include <iostream>
45#include <random>
46#include <string>
47
48#include <ca-rng.H>
49#include <ca-traits.H>
50#include <tpl_ca_engine.H>
51#include <tpl_ca_lattice.H>
52#include <tpl_ca_neighborhood.H>
53#include <tpl_ca_storage.H>
55
56using namespace Aleph;
57using namespace Aleph::CA;
58
59namespace
60{
61
63
68void seed_disordered(Ising_Lattice &lat, std::uint32_t rng_seed,
69 double up_fraction = 0.60)
70{
71 std::mt19937 rng(rng_seed);
72 std::bernoulli_distribution flip(up_fraction);
73 for (ca_size_t i = 0; i < lat.size(0); ++i)
74 for (ca_size_t j = 0; j < lat.size(1); ++j)
75 lat.set({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)},
76 flip(rng) ? 1 : -1);
77}
78
80{
81 long long s = 0;
82 for (ca_size_t i = 0; i < lat.size(0); ++i)
83 for (ca_size_t j = 0; j < lat.size(1); ++j)
84 s += lat.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)});
85 return static_cast<double>(s)
86 / static_cast<double>(lat.size(0) * lat.size(1));
87}
88
89void render(const Ising_Lattice &lat, std::ostream &os)
90{
91 for (ca_size_t i = 0; i < lat.size(0); ++i)
92 {
93 for (ca_size_t j = 0; j < lat.size(1); ++j)
94 os << (lat.at({static_cast<ca_index_t>(i),
95 static_cast<ca_index_t>(j)}) > 0 ? '+' : '-');
96 os << '\n';
97 }
98}
99
100std::string bar(double absolute, std::size_t width = 40)
101{
102 const std::size_t k
103 = std::min(width, static_cast<std::size_t>(absolute
104 * static_cast<double>(width)));
105 return std::string(k, '|') + std::string(width - k, ' ');
106}
107
108struct Run_Result
109{
110 double avg_abs_m = 0.0;
111 Ising_Lattice final_frame;
112};
113
114Run_Result run_at_temperature(const Ising_Lattice &seed,
115 double T,
116 std::uint64_t master_seed,
117 std::size_t burn_in,
118 std::size_t sample_steps)
119{
120 Ising_Glauber_Rule<> rule(T, /*J=*/1.0, /*H=*/0.0, master_seed);
122 engine(seed, rule);
123
124 // Burn-in: discard transient.
125 engine.run(burn_in);
126
127 // Sample magnetisation over the next `sample_steps` frames.
128 double acc = 0.0;
129 for (std::size_t s = 0; s < sample_steps; ++s)
130 {
131 engine.step();
132 acc += std::abs(mean_magnetisation(engine.frame()));
133 }
134 return {acc / static_cast<double>(sample_steps), engine.frame()};
135}
136
137} // namespace
138
139int main()
140{
141 constexpr ca_size_t rows = 32;
142 constexpr ca_size_t cols = 32;
143 constexpr std::uint64_t master_seed = 0xCAFEBABEull;
144 constexpr std::size_t burn_in = 200;
145 constexpr std::size_t sample_steps = 200;
146
147 std::cout << "Ising / Glauber dynamics on a 32x32 toroidal lattice\n";
148 std::cout << " J = 1.0 H = 0.0 Von-Neumann radius 1 (degree 4)\n";
149 std::cout << " initial bias = 60/40 up/down (breaks Z2 symmetry)\n";
150 std::cout << " exact 2-D critical temperature T_c ~ 2.269\n";
151 std::cout << " master_seed = 0x" << std::hex << master_seed << std::dec
152 << " burn_in = " << burn_in
153 << " sample_steps = " << sample_steps << "\n\n";
154
156 seed_disordered(seed, /*rng_seed=*/0xBEEFu);
157
158 const std::array<double, 5> Ts = {1.0, 2.0, 2.269, 2.5, 4.0};
159
160 std::cout << "Temperature sweep:\n";
161 std::cout << " T |<m>| magnetisation curve\n";
162 std::cout << " ----- ----- ----------------------------------------\n";
163
164 Run_Result cold{}, critical{}, hot{};
165 for (std::size_t k = 0; k < Ts.size(); ++k)
166 {
167 const double T = Ts[k];
168 const Run_Result r
169 = run_at_temperature(seed, T, master_seed, burn_in, sample_steps);
170 std::cout << " " << std::setw(5) << std::fixed << std::setprecision(3) << T
171 << " " << std::setw(5) << std::fixed << std::setprecision(3)
172 << r.avg_abs_m
173 << " [" << bar(r.avg_abs_m) << "]\n";
174 if (k == 0) cold = r;
175 else if (k == 2) critical = r;
176 else if (k == Ts.size() - 1) hot = r;
177 }
178 std::cout << std::defaultfloat;
179
180 std::cout << "\n--- Final spin configurations ---\n";
181 std::cout << "\nT = 1.0 (ordered, |<m>| ~ 1)\n";
182 render(cold.final_frame, std::cout);
183 std::cout << "\nT = 2.269 (~T_c, critical fluctuations)\n";
184 render(critical.final_frame, std::cout);
185 std::cout << "\nT = 4.0 (disordered, |<m>| ~ 0)\n";
186 render(hot.final_frame, std::cout);
187
188 std::cout << "\nNote: the same `master_seed` reproduces every value\n"
189 " bit-for-bit on any thread count via cell_seed().\n";
190 return 0;
191}
size_t * rows
Definition ca-c-api.h:112
size_t cols
Definition ca-c-api.h:105
Reproducible random-number support for stochastic CA rules (Phase 8).
Common typedefs and tag types for the Cellular Automata module.
Ising rule with Glauber single-spin-flip dynamics.
Lattice that adds boundary-aware access on top of a storage.
Synchronous double-buffered engine.
Von Neumann (L1) neighborhood of radius R in N dimensions.
static mt19937 rng
static void bar(int val, int scale=1)
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::size_t ca_size_t
Unsigned size component used for extents and counts.
Definition ca-traits.H:63
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
The lattice wraps around on every axis.
Definition ca-traits.H:124
ValueArg< size_t > seed
Definition testHash.C:53
static int * k
static mt19937 engine
gsl_rng * r
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Reproducible stochastic CA rules (Phase 8).
Dense, contiguous storage for cellular automata cells (1D/2D/3D).