Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca_gray_scott_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
34#include <algorithm>
35#include <cstddef>
36#include <cstdint>
37#include <cstdlib>
38#include <fstream>
39#include <iomanip>
40#include <iostream>
41#include <string>
42
43#include <ah-errors.H>
44
45#include <ca-kernels.H>
46#include <ca-rng.H>
47#include <ca-traits.H>
49#include <tpl_ca_engine.H>
50#include <tpl_ca_lattice.H>
51#include <tpl_ca_neighborhood.H>
52#include <tpl_ca_storage.H>
53
54using namespace Aleph;
55using namespace Aleph::CA;
56
57namespace
58{
59
62
63double seeded_noise(const std::uint64_t master, const Coord_Vec<2> &coord)
64{
65 const std::uint64_t h = cell_seed<2>(master, 0, coord);
66 const double unit = static_cast<double>(h >> 11)
67 * (1.0 / 9007199254740992.0);
68 return unit - 0.5;
69}
70
71std::size_t parse_size_arg(const char *text, const std::size_t fallback)
72{
73 if (text == nullptr)
74 return fallback;
75 char *end = nullptr;
76 const unsigned long value = std::strtoul(text, &end, 10);
77 if (end == text or *end != '\0' or value == 0)
78 return fallback;
79 return static_cast<std::size_t>(value);
80}
81
82void seed_initial_frame(Gray_Lattice &lat, const std::uint64_t master)
83{
84 const ca_size_t rows = lat.size(0);
85 const ca_size_t cols = lat.size(1);
86 const ca_size_t side = std::max<ca_size_t>(8, std::min(rows, cols) / 5);
87 const ca_size_t r0 = rows / 2 - side / 2;
88 const ca_size_t c0 = cols / 2 - side / 2;
89
90 for (ca_size_t i = r0; i < r0 + side; ++i)
91 for (ca_size_t j = c0; j < c0 + side; ++j)
92 {
93 const Coord_Vec<2> c{static_cast<ca_index_t>(i),
94 static_cast<ca_index_t>(j)};
95 const double z = 0.02 * seeded_noise(master, c);
96 lat.set(c, Cell{0.50 + z, 0.25 - z});
97 }
98}
99
100unsigned char to_byte(const double x)
101{
102 const double y = std::clamp(x, 0.0, 1.0);
103 return static_cast<unsigned char>(255.0 * y + 0.5);
104}
105
106void write_ppm(const Gray_Lattice &lat, const std::string &path)
107{
108 std::ofstream out(path, std::ios::binary);
109 ah_runtime_error_if(not out) << "could not open " << path << " for writing";
110
111 out << "P6\n" << lat.size(1) << ' ' << lat.size(0) << "\n255\n";
112 for (ca_size_t i = 0; i < lat.size(0); ++i)
113 for (ca_size_t j = 0; j < lat.size(1); ++j)
114 {
115 const Cell c = lat.at({static_cast<ca_index_t>(i),
116 static_cast<ca_index_t>(j)});
117 const unsigned char r = to_byte(2.2 * c.v);
118 const unsigned char g = to_byte(1.2 * (1.0 - c.u));
119 const unsigned char b = to_byte(1.0 - 1.8 * c.v);
120 out.put(static_cast<char>(r));
121 out.put(static_cast<char>(g));
122 out.put(static_cast<char>(b));
123 }
124}
125
126struct Stats
127{
128 double mean_v = 0.0;
129 double max_v = 0.0;
130 std::size_t peaks = 0;
131};
132
134{
135 Stats stats;
136 double sum = 0.0;
137 for (ca_size_t i = 0; i < lat.size(0); ++i)
138 for (ca_size_t j = 0; j < lat.size(1); ++j)
139 {
140 const Cell c = lat.at({static_cast<ca_index_t>(i),
141 static_cast<ca_index_t>(j)});
142 sum += c.v;
143 if (c.v > stats.max_v)
144 stats.max_v = c.v;
145 if (c.v > 0.10)
146 ++stats.peaks;
147 }
148 stats.mean_v = sum / static_cast<double>(lat.size(0) * lat.size(1));
149 return stats;
150}
151
152} // namespace
153
154int main(int argc, char **argv)
155{
156 const std::string output = argc > 1 ? argv[1] : "gray_scott.ppm";
157 const std::size_t steps = argc > 2 ? parse_size_arg(argv[2], 5000) : 5000;
158 const ca_size_t n = static_cast<ca_size_t>(argc > 3
159 ? parse_size_arg(argv[3], 256)
160 : 256);
161 constexpr std::uint64_t master_seed = 0x5eed1234abcddcbaull;
162
163 std::cout << "Gray-Scott reaction-diffusion example\n";
164 std::cout << " grid : " << n << "x" << n << " Neumann boundary\n";
165 std::cout << " params : F=0.0367 K=0.0649 Du=0.16 Dv=0.08 dt=1\n";
166 std::cout << " seed : 0x" << std::hex << master_seed << std::dec << '\n';
167 std::cout << " steps : " << steps << '\n';
168 std::cout << " output : " << output << "\n\n";
169
170 Gray_Lattice lat({n, n}, Cell{1.0, 0.0});
171 seed_initial_frame(lat, master_seed);
172
173 Gray_Scott_Rule<double> rule(/*F=*/0.0367,
174 /*K=*/0.0649,
175 /*Du=*/0.16,
176 /*Dv=*/0.08);
178 engine(lat, rule);
179
180 const std::size_t report_every = std::max<std::size_t>(1, steps / 10);
181 for (std::size_t step = 0; step < steps; ++step)
182 {
183 engine.step();
184 if ((step + 1) % report_every == 0 or step + 1 == steps)
185 {
186 const Stats stats = stats_for_v(engine.frame());
187 std::cout << " step " << std::setw(5) << (step + 1)
188 << " mean(v)=" << std::fixed << std::setprecision(5)
189 << stats.mean_v
190 << " max(v)=" << stats.max_v
191 << " peaks(v>0.10)=" << stats.peaks << '\n';
192 }
193 }
194
195 write_ppm(engine.frame(), output);
196 std::cout << "\nWrote " << output << '\n';
197 return 0;
198}
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_if(C)
Throws std::runtime_error if condition holds.
Definition ah-errors.H:271
int main()
long double h
Definition btreepic.C:154
size_t steps
Definition ca-c-api.h:126
size_t size_t int32_t value
Definition ca-c-api.h:116
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t * rows
Definition ca-c-api.h:112
size_t cols
Definition ca-c-api.h:105
Fixed 2-D convolution kernels for continuous cellular automata.
Reproducible random-number support for stochastic CA rules (Phase 8).
Common typedefs and tag types for the Cellular Automata module.
Gray-Scott reaction-diffusion rule.
Lattice that adds boundary-aware access on top of a storage.
Moore (Chebyshev) neighborhood of radius R in N dimensions.
Synchronous double-buffered engine.
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
static mpfr_t y
Definition mpfr_mul_d.c:3
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
std::array< ca_index_t, N > Coord_Vec
Default coordinate vector.
Definition ca-traits.H:69
void write_ppm(std::ostream &out, const Lattice &frame, Mapper &&mapper, const NetPBM_Write_Options &opts={})
Write a binary PPM (P6) image.
Definition ca-io.H:1496
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
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.
Zero-gradient (Neumann) boundary.
Definition ca-traits.H:152
Two-field state for reaction-diffusion cellular automata.
Container for comprehensive statistical results.
Definition stat_utils.H:125
static mt19937 engine
gsl_rng * r
Continuous and memory-bearing CA rules (Phase 9).
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).
ofstream output
Definition writeHeap.C:215