Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca-kernels.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
49#ifndef CA_KERNELS_H
50#define CA_KERNELS_H
51
52#include <array>
53#include <cstddef>
54#include <initializer_list>
55#include <memory>
56#include <type_traits>
57
58#include <ah-errors.H>
59#include <al-domain.H>
60#include <al-matrix.H>
61
62#include <ca-traits.H>
63
64namespace Aleph {
65namespace CA {
66
81template <typename T, std::size_t Rows, std::size_t Cols>
83{
84 static_assert(std::is_arithmetic_v<T>, "Kernel2D requires arithmetic weights");
85 static_assert(Rows >= 3 and Cols >= 3, "Kernel2D requires at least 3x3 weights");
86 static_assert(Rows % 2 == 1 and Cols % 2 == 1, "Kernel2D dimensions must be odd");
87 static_assert(Rows == Cols, "Kernel2D currently expects square kernels");
88
89public:
91 using value_type = T;
92
94 static constexpr std::size_t rows_v = Rows;
96 static constexpr std::size_t cols_v = Cols;
98 static constexpr std::size_t size_v = Rows * Cols;
100 static constexpr std::size_t neighbour_count_v = size_v - 1;
102 static constexpr std::size_t radius_v = Rows / 2;
103
104private:
105 std::array<T, size_v> weights_{};
106
107 [[nodiscard]] static constexpr std::size_t index(const std::size_t row, const std::size_t col) noexcept
108 {
109 return row * Cols + col;
110 }
111
112public:
117 constexpr Kernel2D() = default;
118
124 constexpr explicit Kernel2D(const std::array<T, size_v> &weights) : weights_(weights) {}
125
132 explicit Kernel2D(std::initializer_list<T> weights)
133 {
135 << "Kernel2D: expected " << size_v << " weights, got " << weights.size();
136 std::size_t i = 0;
137 for (const auto &w : weights)
138 weights_[i++] = w;
139 }
140
147 explicit Kernel2D(std::initializer_list<std::initializer_list<T>> rows)
148 {
149 ah_length_error_if(rows.size() != Rows)
150 << "Kernel2D: expected " << Rows << " rows, got " << rows.size();
151
152 std::size_t r = 0;
153 for (const auto &row : rows)
154 {
155 ah_length_error_if(row.size() != Cols)
156 << "Kernel2D: expected " << Cols << " columns, got " << row.size();
157 std::size_t c = 0;
158 for (const auto &w : row)
159 weights_[index(r, c++)] = w;
160 ++r;
161 }
162 }
163
171 [[nodiscard]] T operator()(const std::size_t row, const std::size_t col) const
172 {
173 ah_out_of_range_error_if(row >= Rows or col >= Cols)
174 << "Kernel2D::operator(): position (" << row << ", " << col << ") outside kernel";
175 return weights_[index(row, col)];
176 }
177
186 {
187 const ca_index_t r = di + static_cast<ca_index_t>(Rows / 2);
188 const ca_index_t c = dj + static_cast<ca_index_t>(Cols / 2);
189 ah_out_of_range_error_if(r < 0 or c < 0 or static_cast<std::size_t>(r) >= Rows
190 or static_cast<std::size_t>(c) >= Cols)
191 << "Kernel2D::weight_at_offset: offset (" << di << ", " << dj << ") outside radius "
192 << radius_v;
193 return weights_[index(static_cast<std::size_t>(r), static_cast<std::size_t>(c))];
194 }
195
205 [[nodiscard]] T neighbour_weight(const std::size_t k) const
206 {
208 << "Kernel2D::neighbour_weight: index " << k << " outside [0, " << neighbour_count_v << ")";
209
210 std::size_t out = 0;
211 for (std::size_t r = 0; r < Rows; ++r)
212 for (std::size_t c = 0; c < Cols; ++c)
213 {
214 if (r == Rows / 2 and c == Cols / 2)
215 continue;
216 if (out == k)
217 return weights_[index(r, c)];
218 ++out;
219 }
220 return T{};
221 }
222
229 {
230 return weights_[index(Rows / 2, Cols / 2)];
231 }
232
238 [[nodiscard]] constexpr const std::array<T, size_v> &weights() const noexcept
239 {
240 return weights_;
241 }
242
248 [[nodiscard]] constexpr T sum() const noexcept
249 {
250 T acc{};
251 for (const auto &w : weights_)
252 acc += w;
253 return acc;
254 }
255
265 template <typename State>
266 [[nodiscard]] T apply(const State &center_value, Neighbor_View<State> neighbours) const
267 {
268 ah_length_error_if(neighbours.size() != neighbour_count_v)
269 << "Kernel2D::apply: expected " << neighbour_count_v << " neighbours, got "
270 << neighbours.size();
271
272 T acc = static_cast<T>(center_value) * center();
273 std::array<T, neighbour_count_v> neighbour_weights{};
274 std::size_t out = 0;
275 for (std::size_t r = 0; r < Rows; ++r)
276 for (std::size_t c = 0; c < Cols; ++c)
277 {
278 if (r == Rows / 2 and c == Cols / 2)
279 continue;
281 }
282 for (std::size_t k = 0; k < neighbour_count_v; ++k)
283 acc += static_cast<T>(neighbours[k]) * neighbour_weights[k];
284 return acc;
285 }
286
297 {
298 auto rd = std::make_shared<IntRange>(static_cast<int>(Rows));
299 auto cd = std::make_shared<IntRange>(static_cast<int>(Cols));
300 Matrix<int, int, T> ret(rd, cd);
301 for (std::size_t r = 0; r < Rows; ++r)
302 for (std::size_t c = 0; c < Cols; ++c)
303 ret.set_entry(static_cast<int>(r), static_cast<int>(c), weights_[index(r, c)]);
304 return ret;
305 }
306};
307
322template <typename T = double>
324{
325 return Kernel2D<T, 3, 3>(std::array<T, 9>{T{0}, T{1}, T{0}, T{1}, T{-4}, T{1}, T{0}, T{1}, T{0}});
326}
327
342template <typename T = double>
344{
345 return Kernel2D<T, 3, 3>(std::array<T, 9>{T{1} / T{6}, T{4} / T{6}, T{1} / T{6}, T{4} / T{6},
346 T{-20} / T{6}, T{4} / T{6}, T{1} / T{6}, T{4} / T{6},
347 T{1} / T{6}});
348}
349
356template <typename T = double>
358{
359 constexpr T w = T{1} / T{9};
360 return Kernel2D<T, 3, 3>(std::array<T, 9>{w, w, w, w, w, w, w, w, w});
361}
362
369template <typename T = double>
371{
372 constexpr T w = T{1} / T{25};
373 return Kernel2D<T, 5, 5>(
374 std::array<T, 25>{w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w, w});
375}
376
383template <typename T = double>
385{
386 return Kernel2D<T, 3, 3>(std::array<T, 9>{T{-1}, T{0}, T{1}, T{-2}, T{0}, T{2}, T{-1}, T{0}, T{1}});
387}
388
395template <typename T = double>
397{
398 return Kernel2D<T, 3, 3>(std::array<T, 9>{T{-1}, T{-2}, T{-1}, T{0}, T{0}, T{0}, T{1}, T{2}, T{1}});
399}
400
407template <typename T = double>
409{
410 return Kernel2D<T, 3, 3>(std::array<T, 9>{T{1} / T{16}, T{2} / T{16}, T{1} / T{16}, T{2} / T{16},
411 T{4} / T{16}, T{2} / T{16}, T{1} / T{16}, T{2} / T{16},
412 T{1} / T{16}});
413}
414
421template <typename T = double>
423{
424 return Kernel2D<T, 5, 5>(std::array<T, 25>{
425 T{1} / T{256}, T{4} / T{256}, T{6} / T{256}, T{4} / T{256}, T{1} / T{256},
426 T{4} / T{256}, T{16} / T{256}, T{24} / T{256}, T{16} / T{256}, T{4} / T{256},
427 T{6} / T{256}, T{24} / T{256}, T{36} / T{256}, T{24} / T{256}, T{6} / T{256},
428 T{4} / T{256}, T{16} / T{256}, T{24} / T{256}, T{16} / T{256}, T{4} / T{256},
429 T{1} / T{256}, T{4} / T{256}, T{6} / T{256}, T{4} / T{256}, T{1} / T{256}});
430}
431
432} // namespace CA
433} // namespace Aleph
434
435#endif // CA_KERNELS_H
Exception handling system with formatted messages for Aleph-w.
#define ah_length_error_if(C)
Throws std::length_error if condition holds.
Definition ah-errors.H:703
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
Integer domain classes for sparse data structures.
Sparse matrix with generic domains.
long double w
Definition btreepic.C:153
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t row
Definition ca-c-api.h:115
size_t * rows
Definition ca-c-api.h:112
size_t size_t col
Definition ca-c-api.h:116
Common typedefs and tag types for the Cellular Automata module.
Dense odd-sized 2-D convolution kernel.
Definition ca-kernels.H:83
static constexpr std::size_t rows_v
Number of rows.
Definition ca-kernels.H:94
T neighbour_weight(const std::size_t k) const
Return a centre-skipping neighbour weight.
Definition ca-kernels.H:205
T weight_at_offset(const ca_index_t di, const ca_index_t dj) const
Return the weight at an offset from the centre.
Definition ca-kernels.H:185
static constexpr std::size_t index(const std::size_t row, const std::size_t col) noexcept
Definition ca-kernels.H:107
Kernel2D(std::initializer_list< std::initializer_list< T > > rows)
Construct a kernel from nested row initializer lists.
Definition ca-kernels.H:147
Matrix< int, int, T > to_matrix() const
Export the kernel weights as an Aleph::Matrix.
Definition ca-kernels.H:296
std::array< T, size_v > weights_
Definition ca-kernels.H:105
static constexpr std::size_t neighbour_count_v
Number of neighbour weights excluding the centre.
Definition ca-kernels.H:100
static constexpr std::size_t cols_v
Number of columns.
Definition ca-kernels.H:96
constexpr Kernel2D(const std::array< T, size_v > &weights)
Construct a kernel from row-major weights.
Definition ca-kernels.H:124
Kernel2D(std::initializer_list< T > weights)
Construct a kernel from a flat initializer list.
Definition ca-kernels.H:132
T apply(const State &center_value, Neighbor_View< State > neighbours) const
Apply the kernel to centre plus neighbour values.
Definition ca-kernels.H:266
static constexpr std::size_t radius_v
Chebyshev radius matched by Moore<2, radius_v>.
Definition ca-kernels.H:102
T operator()(const std::size_t row, const std::size_t col) const
Return a weight by matrix position.
Definition ca-kernels.H:171
constexpr const std::array< T, size_v > & weights() const noexcept
Return the raw row-major weight array.
Definition ca-kernels.H:238
constexpr T sum() const noexcept
Sum every kernel weight.
Definition ca-kernels.H:248
T value_type
Numeric weight type.
Definition ca-kernels.H:91
static constexpr std::size_t size_v
Total number of weights including the centre.
Definition ca-kernels.H:98
constexpr Kernel2D()=default
Construct a zero kernel.
constexpr T center() const noexcept
Return the centre weight.
Definition ca-kernels.H:228
Sparse matrix with generic row and column domains.
Definition al-matrix.H:66
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
constexpr Kernel2D< T, 3, 3 > sobel_y_kernel() noexcept
Return the vertical Sobel gradient kernel.
Definition ca-kernels.H:396
std::span< const T > Neighbor_View
Read-only view over a contiguous range of neighbour values.
Definition ca-traits.H:90
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
constexpr Kernel2D< T, 5, 5 > gaussian_5x5_kernel() noexcept
Return the separable 5x5 Gaussian blur kernel.
Definition ca-kernels.H:422
constexpr Kernel2D< T, 3, 3 > laplacian_5p_kernel() noexcept
Return the 5-point discrete Laplacian kernel.
Definition ca-kernels.H:323
constexpr Kernel2D< T, 5, 5 > mean_5x5_kernel() noexcept
Return a 5x5 mean filter.
Definition ca-kernels.H:370
constexpr Kernel2D< T, 3, 3 > laplacian_9p_kernel() noexcept
Return the isotropic 9-point discrete Laplacian kernel.
Definition ca-kernels.H:343
constexpr Kernel2D< T, 3, 3 > sobel_x_kernel() noexcept
Return the horizontal Sobel gradient kernel.
Definition ca-kernels.H:384
constexpr Kernel2D< T, 3, 3 > mean_3x3_kernel() noexcept
Return a 3x3 mean filter.
Definition ca-kernels.H:357
constexpr Kernel2D< T, 3, 3 > gaussian_3x3_kernel() noexcept
Return the separable 3x3 Gaussian blur kernel.
Definition ca-kernels.H:408
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:105
static int * k
gsl_rng * r