Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_ca_lattice.H
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 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
57#ifndef TPL_CA_LATTICE_H
58#define TPL_CA_LATTICE_H
59
60#include <cstddef>
61#include <limits>
62#include <type_traits>
63#include <utility>
64
65#include <ah-errors.H>
66
67#include <ca-traits.H>
68#include <tpl_ca_concepts.H>
69
70namespace Aleph {
71namespace CA {
72
73namespace ca_lattice_detail {
74
75inline ca_size_t magnitude(const ca_index_t c) noexcept
76{
77 if (c >= 0)
78 return static_cast<ca_size_t>(c);
79 return static_cast<ca_size_t>(-(c + 1)) + 1;
80}
81
83inline ca_size_t wrap_into_range(ca_index_t c, const ca_size_t n) noexcept
84{
85 if (n == 0)
86 return 0;
87
88 const ca_size_t mag = magnitude(c);
89 if (c >= 0)
90 return mag % n;
91
92 const ca_size_t r = mag % n;
93 return r == 0 ? 0 : n - r;
94}
95
98inline ca_size_t reflect_into_range(const ca_index_t c, const ca_size_t n) noexcept
99{
100 if (n <= 1)
101 return 0;
102
103 const ca_size_t mag = magnitude(c);
104 if (n > (std::numeric_limits<ca_size_t>::max() >> 1))
105 return c >= 0 ? mag : mag - 1;
106
107 const ca_size_t period = 2 * n;
108 ca_size_t r = 0;
109 if (c >= 0)
110 r = mag % period;
111 else
112 {
113 const ca_size_t mod = mag % period;
114 r = mod == 0 ? 0 : period - mod;
115 }
116
117 if (r >= n)
118 r = period - 1 - r;
119 return r;
120}
121
123template <typename B>
124struct is_constant_boundary : std::false_type
125{
126};
127
128template <typename T, T V>
129struct is_constant_boundary<ConstantBoundary<T, V>> : std::true_type
130{
131};
132
133template <typename B>
135} // namespace ca_lattice_detail
136
147template <typename Storage, typename Boundary = OpenBoundary>
149{
150public:
152 using boundary_type = Boundary;
153 using state_type = typename Storage::state_type;
154 using coord_type = typename Storage::coord_type;
155 using extents_type = typename Storage::extents_type;
156
157 static constexpr std::size_t rank = Storage::rank;
158
159private:
161
163 {
164 if constexpr (ca_lattice_detail::is_constant_boundary_v<Boundary>)
165 return static_cast<state_type>(Boundary::value);
166 else
167 return state_type{};
168 }
169
174 [[nodiscard]] bool fold_coord(coord_type &c) const
175 {
176 using namespace ca_lattice_detail;
177 for (std::size_t d = 0; d < rank; ++d)
178 {
179 const ca_size_t n = store_.size(d);
180 if (n == 0)
181 return false;
182
183 if constexpr (std::is_same_v<Boundary, ToroidalBoundary>)
184 {
185 c[d] = static_cast<ca_index_t>(wrap_into_range(c[d], n));
186 }
187 else if constexpr (std::is_same_v<Boundary, ReflectiveBoundary>)
188 {
189 c[d] = static_cast<ca_index_t>(reflect_into_range(c[d], n));
190 }
191 else if constexpr (std::is_same_v<Boundary, NeumannBoundary>)
192 {
193 // Zero-gradient: clamp to the nearest in-range coordinate.
194 if (c[d] < 0)
195 c[d] = 0;
196 else if (static_cast<ca_size_t>(c[d]) >= n)
197 c[d] = static_cast<ca_index_t>(n - 1);
198 }
199 else
200 {
201 // OpenBoundary or ConstantBoundary<...>
202 if (c[d] < 0 or static_cast<ca_size_t>(c[d]) >= n)
203 return false;
204 }
205 }
206 return true;
207 }
208
209public:
211 Lattice() = default;
212
219 {}
220
222 explicit Lattice(Storage &&s) noexcept(std::is_nothrow_move_constructible_v<Storage>)
223 : store_(std::move(s))
224 {}
225
226 [[nodiscard]] static constexpr std::size_t dimension() noexcept
227 {
228 return rank;
229 }
230
232 {
233 return store_.size();
234 }
235 [[nodiscard]] ca_size_t size(std::size_t d) const
236 {
237 return store_.size(d);
238 }
239
241 {
242 return store_.extents();
243 }
244
246 [[nodiscard]] state_type at(const coord_type &c) const
247 {
248 return store_.at(c);
249 }
250
252 void set(const coord_type &c, const state_type &v)
253 {
254 store_.set(c, v);
255 }
256
271 {
272 if (fold_coord(c))
273 return store_.at(c);
274 return out_of_range_value();
275 }
276
279 {
280 return store_;
281 }
282
285 {
286 return store_;
287 }
288
290 void fill(const state_type &value)
291 {
292 store_.fill(value);
293 }
294
296 void swap(Lattice &other) noexcept(noexcept(store_.swap(other.store_)))
297 {
298 store_.swap(other.store_);
299 }
300};
301
308template <typename Storage, typename Boundary>
310 Lattice<Storage, Boundary> &b) noexcept(noexcept(a.swap(b)))
311{
312 a.swap(b);
313}
314
315} // namespace CA
316} // namespace Aleph
317
318#endif // TPL_CA_LATTICE_H
Exception handling system with formatted messages for Aleph-w.
size_t size_t int32_t value
Definition ca-c-api.h:116
Common typedefs and tag types for the Cellular Automata module.
Lattice that adds boundary-aware access on top of a storage.
state_type at_safe(coord_type c) const
Boundary-aware read.
void set(const coord_type &c, const state_type &v)
Strict write: throws if c is out of range.
typename Storage::state_type state_type
Lattice(const extents_type &extents, const state_type &init=state_type{})
Construct a lattice with the given extents and initial value.
typename Storage::extents_type extents_type
const extents_type & extents() const noexcept
void swap(Lattice &other) noexcept(noexcept(store_.swap(other.store_)))
O(1) swap.
typename Storage::coord_type coord_type
Storage & storage() noexcept
Direct read-write access to the underlying storage.
ca_size_t size(std::size_t d) const
static constexpr std::size_t rank
ca_size_t size() const noexcept
const Storage & storage() const noexcept
Direct read access to the underlying storage (read-only).
bool fold_coord(coord_type &c) const
Try to fold c into a valid in-range coordinate using the boundary policy.
void fill(const state_type &value)
Set every cell to value.
static constexpr std::size_t dimension() noexcept
state_type out_of_range_value() const
Lattice()=default
Construct an empty lattice (no cells allocated).
state_type at(const coord_type &c) const
Strict access: throws if c is out of range.
Lattice(Storage &&s) noexcept(std::is_nothrow_move_constructible_v< Storage >)
Wrap an existing storage by move.
Shape (per-axis sizes) of an mdspan, mixing compile-time and run-time extents.
Definition ah-mdspan.H:303
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
ca_size_t reflect_into_range(const ca_index_t c, const ca_size_t n) noexcept
Reflect a signed coordinate into [0, n) (no-repeat triangle wave).
ca_size_t magnitude(const ca_index_t c) noexcept
ca_size_t wrap_into_range(ca_index_t c, const ca_size_t n) noexcept
Wrap a signed coordinate into [0, n) with positive modulo.
constexpr bool is_constant_boundary_v
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
void swap(Bit_Cell_Storage< N > &a, Bit_Cell_Storage< N > &b) noexcept
Free-function swap so the storage plays nicely with std::swap.
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
static std::atomic< bool > init
Definition hash-fct.C:54
STL namespace.
Constant-value boundary.
Definition ca-traits.H:138
True iff B is a ConstantBoundary<T, V>.
size_t V
gsl_rng * r
C++20 concepts for the Cellular Automata module.