Skip to content

Commit 5e7e55e

Browse files
committed
undirected incidence matrix size map getters
1 parent f01d76b commit 5e7e55e

2 files changed

Lines changed: 77 additions & 0 deletions

File tree

include/hgl/impl/incidence_matrix.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ class incidence_matrix<hgl::undirected_t, LayoutTag> final {
6868
return this->_count<impl::element_type::vertex>(vertex_id);
6969
}
7070

71+
[[nodiscard]] std::vector<types::size_type> degree_map(const types::size_type n_vertices
72+
) const noexcept {
73+
return this->_count_map<impl::element_type::vertex>(n_vertices);
74+
}
75+
7176
// --- hyperedge methods ---
7277

7378
gl_attr_force_inline void add_hyperedges(const types::size_type n) noexcept {
@@ -88,6 +93,12 @@ class incidence_matrix<hgl::undirected_t, LayoutTag> final {
8893
return this->_count<impl::element_type::hyperedge>(hyperedge_id);
8994
}
9095

96+
[[nodiscard]] std::vector<types::size_type> hyperedge_size_map(
97+
const types::size_type n_hyperedges
98+
) const noexcept {
99+
return this->_count_map<impl::element_type::hyperedge>(n_hyperedges);
100+
}
101+
91102
// --- binding methods ---
92103

93104
gl_attr_force_inline void bind(
@@ -179,6 +190,26 @@ class incidence_matrix<hgl::undirected_t, LayoutTag> final {
179190
return count;
180191
}
181192

193+
template <impl::element_type Element>
194+
[[nodiscard]] std::vector<types::size_type> _count_map(const types::size_type n_elements
195+
) const noexcept {
196+
std::vector<types::size_type> size_map(this->_matrix.size(), 0uz);
197+
198+
if constexpr (Element == layout_tag::major_element) { // size map major
199+
for (const auto& [i, row] : this->_matrix | std::views::enumerate)
200+
size_map[i] = static_cast<types::size_type>(std::ranges::count(row, true));
201+
}
202+
else { // size map minor
203+
for (const auto& row : this->_matrix)
204+
for (types::size_type j = 0uz; j < this->_matrix_row_size; ++j)
205+
if (row[j])
206+
++size_map[j];
207+
}
208+
209+
size_map.resize(n_elements, 0uz);
210+
return size_map;
211+
}
212+
182213
types::size_type _matrix_row_size = 0uz;
183214
hypergraph_storage_type _matrix;
184215
};

tests/source/hgl/test_incidence_matrix.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,29 @@ TEST_CASE_FIXTURE(
306306
CHECK_FALSE(sut.are_bound(constants::id2, constants::id1));
307307
}
308308

309+
TEST_CASE_FIXTURE(
310+
test_undirected_vertex_major_incidence_matrix,
311+
"element size map getters should return maps of properly calculated element sizes"
312+
) {
313+
constexpr auto n_elements = 5ull;
314+
sut_type sut{n_elements, n_elements};
315+
316+
constexpr auto is_zero = [](const auto& size) { return size == 0ull; };
317+
REQUIRE(std::ranges::all_of(sut.degree_map(n_elements), is_zero));
318+
REQUIRE(std::ranges::all_of(sut.hyperedge_size_map(n_elements), is_zero));
319+
320+
for (std::size_t i = 0uz; i < n_elements; i++)
321+
for (std::size_t j = 0uz; j <= i; j++)
322+
sut.bind(i, j);
323+
324+
const auto deg_map = sut.degree_map(n_elements);
325+
const auto esize_map = sut.hyperedge_size_map(n_elements);
326+
for (std::size_t i = 0uz; i < n_elements; i++) {
327+
CHECK_EQ(deg_map[i], i + 1uz);
328+
CHECK_EQ(esize_map[i], n_elements - i);
329+
}
330+
}
331+
309332
struct test_undirected_hyperedge_major_incidence_matrix : public test_incidence_matrix {
310333
using sut_type = hgl::impl::incidence_matrix<hgl::undirected_t, hgl::impl::hyperedge_major_t>;
311334
};
@@ -583,6 +606,29 @@ TEST_CASE_FIXTURE(
583606
CHECK_FALSE(sut.are_bound(constants::id2, constants::id1));
584607
}
585608

609+
TEST_CASE_FIXTURE(
610+
test_undirected_hyperedge_major_incidence_matrix,
611+
"element size map getters should return maps of properly calculated element sizes"
612+
) {
613+
constexpr auto n_elements = 5ull;
614+
sut_type sut{n_elements, n_elements};
615+
616+
constexpr auto is_zero = [](const auto& size) { return size == 0ull; };
617+
REQUIRE(std::ranges::all_of(sut.degree_map(n_elements), is_zero));
618+
REQUIRE(std::ranges::all_of(sut.hyperedge_size_map(n_elements), is_zero));
619+
620+
for (std::size_t i = 0uz; i < n_elements; i++)
621+
for (std::size_t j = 0uz; j <= i; j++)
622+
sut.bind(i, j);
623+
624+
const auto deg_map = sut.degree_map(n_elements);
625+
const auto esize_map = sut.hyperedge_size_map(n_elements);
626+
for (std::size_t i = 0uz; i < n_elements; i++) {
627+
CHECK_EQ(deg_map[i], i + 1uz);
628+
CHECK_EQ(esize_map[i], n_elements - i);
629+
}
630+
}
631+
586632
struct test_bf_directed_incidence_matrix : public test_incidence_matrix {
587633
template <typename SutType>
588634
auto is_incident_pred() {

0 commit comments

Comments
 (0)