56#include <gtest/gtest.h>
80 std::uniform_real_distribution<double> u(0.0, 1.0);
84 g.set({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)},
91 if (a.size(0) != b.size(0)
or a.size(1) != b.size(1))
95 if (a.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)})
96 != b.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}))
104 for (
ca_size_t i = 0; i < g.size(0); ++i)
105 for (
ca_size_t j = 0; j < g.size(1); ++j)
106 if (g.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}) != 0)
131 for (std::size_t t = 0; t < 30; ++t)
134 <<
"Mismatch at step " << t;
139 <<
"Mismatch after 30 steps";
148 const auto offsets = std::array<Offset_Vec<1>, 2>{{{-1}, {1}}};
162 for (std::size_t t = 0; t < 32; ++t)
166 schemed.frame().at({static_cast<ca_index_t>(i)}))
167 <<
"step " << t <<
", cell " << i;
189 template <
typename State>
192 constexpr State threshold = 4;
194 if (result >= threshold)
196 for (
const auto &n :
nh)
209 for (
int k = 0;
k < 50; ++
k)
211 const auto cur = g.at({6, 6});
212 g.set({6, 6},
cur + 1);
225 for (
ca_size_t i = 0; i < g.size(0); ++i)
226 for (
ca_size_t j = 0; j < g.size(1); ++j)
227 EXPECT_LT(g.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}), 4)
228 <<
"cell (" << i <<
", " << j <<
") still over threshold";
259 <<
"Same master seed must produce identical frames";
274 std::size_t
diff = 0;
277 if (
before.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)})
278 !=
eng.frame().at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}))
281 <<
"5 sub-steps must touch at most 5 cells, got " <<
diff;
325template <
typename Block_Rule>
344 << label <<
": forward(" <<
N <<
") then backward(" <<
N
345 <<
") must restore the initial state bit-by-bit";
375 for (std::size_t t = 0; t < 50; ++t)
384 <<
"non-binary cell after step " << t;
396 for (std::size_t t = 0; t < 100; ++t)
400 <<
"BBM lost particles at step " << t;
410 for (std::size_t t = 0; t < 100; ++t)
414 <<
"TM Gas lost particles at step " << t;
427 int operator()(
int s)
const noexcept {
return s + 1; }
449 std::vector<std::size_t> pre,
post;
450 eng.on_pre_step([&](std::size_t s,
const Grid &) { pre.push_back(s); });
451 eng.on_post_step([&](std::size_t s,
const Grid &) {
post.push_back(s); });
454 EXPECT_EQ(pre, (std::vector<std::size_t>{0, 1, 2}));
size_t size_t int32_t * out
Common typedefs and tag types for the Cellular Automata module.
Update-scheme aware engine.
void step()
Run one engine step using the configured update scheme.
Fredkin–Toffoli Billiard Ball Machine block rule.
Adapt a regular cell rule (with empty neighborhood) to a block rule.
Critters reversible CA block rule.
User-supplied list of offsets for arbitrary connectivity.
Lattice that adds boundary-aware access on top of a storage.
Precomputed transition table for (self, neighbours...).
Moore (Chebyshev) neighborhood of radius R in N dimensions.
Placeholder neighbourhood for engines that drive block rules.
Synchronous double-buffered engine.
Toffoli–Margolus (TM) lattice-gas block rule.
Von Neumann (L1) neighborhood of radius R in N dimensions.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
constexpr Game_Of_Life_Rule make_game_of_life_rule() noexcept
Build the canonical Game of Life rule.
std::span< const T > Neighbor_View
Read-only view over a contiguous range of neighbour values.
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
std::size_t ca_size_t
Unsigned size component used for extents and counts.
std::array< State, 4 > Block_2x2
Fixed-size 2×2 block of cell values used by Margolus rules.
constexpr Lookup_Rule< 2, 2 > make_wolfram_elementary_rule(std::uint8_t rule_no) noexcept
Build the elementary 1D Wolfram rule rule_no (0..255) as a Lookup_Rule<2, 2> over neighbourhood {-1,...
Main namespace for Aleph-w library functions.
size_t size(Node *root) noexcept
and
Check uniqueness with explicit hash + equality functors.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
Synchronous update over rotating sub-blocks.
Margolus 2×2 partition update for reversible CAs.
Pick one cell at random per sub-step, update it in place.
In-place sequential update (no double buffer).
Classical double-buffer synchronous update.
The lattice wraps around on every axis.
Phase 13 update-scheme aware engine.
Block-based local rules for Aleph::CA (Phase 13).
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Rule mechanisms for Aleph::CA.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).
Phase 13 update-scheme strategies for Aleph::CA.