71#ifndef TPL_CA_NEIGHBORHOOD_H
72#define TPL_CA_NEIGHBORHOOD_H
86namespace ca_neighborhood_detail {
88constexpr std::size_t
static_pow(std::size_t base, std::size_t
exp)
noexcept
91 for (std::size_t i = 0; i <
exp; ++i)
98template <std::
size_t N, std::
size_t R>
108 std::array<std::size_t, N>
cur_buf{};
109 for (std::size_t d = 0; d <
N; ++d)
112 for (std::size_t i = 0; i <
total; ++i)
116 for (std::size_t d = 0; d <
N; ++d)
119 l1 +=
static_cast<std::size_t
>(v < 0 ? -v : v);
125 for (std::size_t d =
N; d-- > 0;)
139template <std::
size_t N, std::
size_t R>
144 std::array<Offset_Vec<N>,
out_n> result{};
147 for (std::size_t d = 0; d <
N; ++d)
151 for (std::size_t i = 0; i <
total; ++i)
154 for (std::size_t d = 0; d <
N; ++d)
166 for (std::size_t d =
N; d-- > 0;)
181template <std::
size_t N, std::
size_t R>
186 std::array<Offset_Vec<N>,
out_n> result{};
189 for (std::size_t d = 0; d <
N; ++d)
193 for (std::size_t i = 0; i <
total; ++i)
196 for (std::size_t d = 0; d <
N; ++d)
197 l1 +=
static_cast<std::size_t
>(
cur[d] < 0 ? -
cur[d] :
cur[d]);
203 for (std::size_t d =
N; d-- > 0;)
227template <std::
size_t N, std::
size_t R = 1>
230 static_assert(
N >= 1,
"Moore requires N >= 1");
231 static_assert(
R >= 1,
"Moore requires R >= 1");
248 = ca_neighborhood_detail::compute_moore_offsets<N, R>();
271 template <
typename F>
275 for (std::size_t i = 0; i <
size_v; ++i)
289template <std::
size_t N, std::
size_t R = 1>
292 static_assert(
N >= 1,
"Von_Neumann requires N >= 1");
293 static_assert(
R >= 1,
"Von_Neumann requires R >= 1");
301 static constexpr std::size_t
size_v = ca_neighborhood_detail::von_neumann_count<N, R>();
310 = ca_neighborhood_detail::compute_von_neumann_offsets<N, R>();
333 template <
typename F>
337 for (std::size_t i = 0; i <
size_v; ++i)
370 static constexpr std::array<Offset_Vec<2>, 6>
offsets
371 = {{{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, -1}, {-1, 1}}};
394 template <
typename F>
450 template <
typename F>
473template <std::
size_t N, std::
size_t K, std::
size_t Radius = 0>
476 static_assert(
N >= 1,
"Custom_Neighborhood requires N >= 1");
477 static_assert(K >= 1,
"Custom_Neighborhood requires K >= 1");
507 for (std::size_t i = 0; i < K; ++i)
515 for (std::size_t
k = 0;
k < K; ++
k)
516 for (std::size_t d = 0; d <
N; ++d)
518 const auto v =
offs_[
k][d];
519 const std::size_t a =
static_cast<std::size_t
>(v < 0 ? -v : v);
543 template <
typename F>
547 for (
const auto &
o :
offs_)
568template <
typename Nbh,
typename L,
typename T>
571 const typename L::coord_type ¢er,
575 <<
out.size() <<
", expected at least " <<
nh.size();
576 using Coord =
typename L::coord_type;
578 nh.for_each_offset(center,
582 for (std::size_t d = 0; d < L::rank; ++d)
584 out[i] =
static_cast<T>(
lat.at_safe(c));
Exception handling system with formatted messages for Aleph-w.
#define ah_length_error_if(C)
Throws std::length_error if condition holds.
size_t size_t int32_t * out
Common typedefs and tag types for the Cellular Automata module.
User-supplied list of offsets for arbitrary connectivity.
constexpr std::size_t radius() const noexcept
constexpr Custom_Neighborhood(std::array< Offset_Vec< N >, K > os)
Build a custom neighborhood from an std::array of offsets.
static constexpr std::size_t radius_v
Compile-time radius (0 if unknown).
static constexpr std::size_t rank_v
Lattice dimension.
constexpr Custom_Neighborhood(const Offset_Vec< N >(&os)[K])
Build a custom neighborhood from a braced offset list.
static constexpr std::size_t size_v
Number of neighbours.
constexpr void for_each_offset(const Coord_Vec< N > ¢er, F &&f) const
Apply a functor to each offset in the neighborhood.
std::array< Offset_Vec< N >, K > offs_
constexpr const std::array< Offset_Vec< N >, K > & offsets() const noexcept
Coord_Vec< N > coord_type
Coordinate type accepted by for_each_offset.
constexpr std::size_t size() const noexcept
Six-neighbour hex pattern in axial coordinates over a 2D lattice.
static constexpr void for_each_offset(const Coord_Vec< 2 > ¢er, F &&f)
Apply a functor to each of the six hex offsets.
Coord_Vec< 2 > coord_type
Coordinate type accepted by for_each_offset.
static constexpr std::size_t radius_v
Chebyshev radius (always 1 for hex grids).
static constexpr std::size_t rank_v
Lattice dimension.
static constexpr std::array< Offset_Vec< 2 >, 6 > offsets
The six axial-coordinate offsets of the hex neighborhood.
static constexpr std::size_t size() noexcept
Return the number of neighbours (always 6).
static constexpr std::size_t radius() noexcept
Return the radius of the neighborhood (always 1).
static constexpr std::size_t size_v
Number of neighbours (always 6).
Moore (Chebyshev) neighborhood of radius R in N dimensions.
constexpr std::size_t size() const noexcept
Return the number of neighbours in the neighborhood.
constexpr void for_each_offset(const Coord_Vec< N > ¢er, F &&f) const
Apply a functor to each offset in the neighborhood.
static constexpr std::size_t radius() noexcept
Return the Chebyshev radius of the neighborhood.
Coord_Vec< N > coord_type
Coordinate type accepted by for_each_offset.
static constexpr std::size_t size_v
Number of neighbours (excluding center).
static constexpr std::size_t radius_v
Chebyshev radius.
static constexpr std::size_t rank_v
Lattice dimension.
static constexpr std::array< Offset_Vec< N >, size_v > offsets
Compile-time, canonical-ordered offsets array.
Three edge-neighbours over a 2D lattice with parity coupling.
static constexpr std::size_t radius() noexcept
Return the radius of the neighborhood (always 1).
Coord_Vec< 2 > coord_type
Coordinate type accepted by for_each_offset.
static constexpr std::size_t radius_v
Chebyshev radius (always 1).
static constexpr std::size_t rank_v
Lattice dimension.
static constexpr std::size_t size_v
Number of neighbours (always 3).
static constexpr std::size_t size() noexcept
Return the number of neighbours (always 3).
static constexpr void for_each_offset(const Coord_Vec< 2 > ¢er, F &&f)
Apply a functor to the three parity-dependent triangle offsets.
Von Neumann (L1) neighborhood of radius R in N dimensions.
static constexpr std::array< Offset_Vec< N >, size_v > offsets
Compile-time, canonical-ordered offsets array.
constexpr void for_each_offset(const Coord_Vec< N > ¢er, F &&f) const
Apply a functor to each offset in the neighborhood.
static constexpr std::size_t rank_v
Lattice dimension.
static constexpr std::size_t size() noexcept
Return the number of neighbours in the neighborhood.
static constexpr std::size_t size_v
Number of neighbours (excluding center).
static constexpr std::size_t radius() noexcept
Return the L1 radius of the neighborhood.
static constexpr std::size_t radius_v
L1 radius.
Coord_Vec< N > coord_type
Coordinate type accepted by for_each_offset.
A coordinate type with N integral components.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_exp_function > > exp(const __gmp_expr< T, U > &expr)
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 std::size_t von_neumann_count() noexcept
Number of integer points in the L1 ball of radius R in N dimensions, excluding the origin.
constexpr std::size_t static_pow(std::size_t base, std::size_t exp) noexcept
Compile-time integer power.
constexpr auto compute_moore_offsets() noexcept
Generate the canonical-ordered list of Moore offsets for N/R.
constexpr auto compute_von_neumann_offsets() noexcept
Generate the canonical-ordered list of Von Neumann offsets for N/R (L1 radius).
@ R
Recovered (and immune).
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
std::array< ca_index_t, N > Coord_Vec
Default coordinate vector.
void gather_neighbors(const Nbh &nh, const L &lat, const typename L::coord_type ¢er, std::span< T > out)
Populate out[0..nh.size()) with neighbour values of center.
Coord_Vec< N > Offset_Vec
Default offset vector (aliases Coord_Vec).
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
C++20 concepts for the Cellular Automata module.