Commit 0fad4e77 authored by Baptiste Esteban's avatar Baptiste Esteban
Browse files

Best template parameters for directional hqueue

parent e7e462e7
Pipeline #28035 passed with stages
in 26 minutes and 42 seconds
......@@ -39,15 +39,12 @@ namespace mln::morpho
{
/// \brief Canvas for the edges in the alphatree. Using different data
/// structures related to the type of the edges.
template <typename I, typename N, typename W>
template <typename P, typename N, typename W>
class alphatree_edges;
template <typename I, typename N, typename W>
requires(std::is_integral_v<W>&& std::is_unsigned_v<W> && sizeof(W) <= 2) class alphatree_edges<I, N, W>
template <typename P, typename N, typename W>
requires(std::is_integral_v<W>&& std::is_unsigned_v<W> && sizeof(W) <= 2) class alphatree_edges<P, N, W>
{
static_assert(is_a_v<I, mln::details::Image>);
using P = image_point_t<I>;
public:
alphatree_edges(){};
void push(std::size_t dir, W w, P p) { m_cont.insert(dir, w, p); }
......@@ -57,7 +54,7 @@ namespace mln::morpho
void on_finish_insert() {}
private:
details::directional_hqueue<I, N, W> m_cont;
details::directional_hqueue<P, N, W> m_cont;
};
template <typename P, typename W>
......@@ -68,12 +65,9 @@ namespace mln::morpho
W w;
};
template <typename I, typename N, typename W>
template <typename P, typename N, typename W>
class alphatree_edges
{
static_assert(is_a_v<I, mln::details::Image>);
using P = image_point_t<I>;
public:
alphatree_edges()
: m_current(0)
......@@ -163,8 +157,11 @@ namespace mln::morpho
auto alphatree_compute_edges(I input, N nbh, F distance)
{
static_assert(is_a_v<I, mln::details::Image>);
using V = image_value_t<I>;
auto edges = alphatree_edges<I, N, std::invoke_result_t<F, V, V>>();
using V = image_value_t<I>;
using P = image_point_t<I>;
using W = std::invoke_result_t<F, V, V>;
auto edges = alphatree_edges<P, N, W>();
auto dom = input.domain();
mln_foreach (auto p, dom)
{
......
......@@ -13,13 +13,11 @@ namespace mln::morpho::details
/// \tparam I The image the edges are calculated from
/// \tparam N The neighborhood used to compute the edges
/// \tparam K Value type of the level (Should be unsigned integer of at least a size of 2)
template <typename I, typename N, typename K>
template <typename P, typename N, typename K>
class directional_hqueue
{
static_assert(is_a_v<I, mln::details::Image>, "I should be an image");
static_assert(is_a_v<N, mln::details::Neighborhood>, "N should be a neighborhood");
using Point = image_point_t<I>;
using queue_type = hvectors_unbounded<Point>;
using queue_type = hvectors_unbounded<P>;
public:
/// \brief Constructor
......@@ -29,10 +27,10 @@ namespace mln::morpho::details
/// \param dir The hierarchical queue index (from after_offset() in N)
/// \param w The weight of the edge
/// \param p The point the edge weight is calculated from
void insert(std::size_t dir, int w, Point p) noexcept;
void insert(std::size_t dir, int w, P p) noexcept;
/// \brief Return the tuple (p, q, w) where p and q are the vertex of the edge and w its weight
std::tuple<Point, Point, int> pop() noexcept;
std::tuple<P, P, int> pop() noexcept;
/// \brief Return the lower weight of the queue
int current_level() const noexcept;
......@@ -57,8 +55,8 @@ namespace mln::morpho::details
* Implementation *
******************/
template <typename I, typename N, typename K>
directional_hqueue<I, N, K>::directional_hqueue() noexcept
template <typename P, typename N, typename K>
directional_hqueue<P, N, K>::directional_hqueue() noexcept
: m_current_dir(0)
, m_current_level(0)
, m_size(0)
......@@ -67,8 +65,8 @@ namespace mln::morpho::details
m_queues[i] = std::make_shared<queue_type>(m_nlevels);
}
template <typename I, typename N, typename K>
void directional_hqueue<I, N, K>::insert(std::size_t dir, int w, Point p) noexcept
template <typename P, typename N, typename K>
void directional_hqueue<P, N, K>::insert(std::size_t dir, int w, P p) noexcept
{
// Update the current level and the current dir to keep the queue sorted
if (m_size == 0 || w < m_current_level)
......@@ -80,9 +78,9 @@ namespace mln::morpho::details
m_size++;
}
template <typename I, typename N, typename K>
std::tuple<typename directional_hqueue<I, N, K>::Point, typename directional_hqueue<I, N, K>::Point, int>
directional_hqueue<I, N, K>::pop() noexcept
template <typename P, typename N, typename K>
std::tuple<P, P, int>
directional_hqueue<P, N, K>::pop() noexcept
{
assert(m_size > 0);
const auto p = m_queues[m_current_dir]->pop_front(m_current_level);
......@@ -111,15 +109,15 @@ namespace mln::morpho::details
return {p, q, w};
}
template <typename I, typename N, typename K>
int directional_hqueue<I, N, K>::current_level() const noexcept
template <typename P, typename N, typename K>
int directional_hqueue<P, N, K>::current_level() const noexcept
{
assert(m_size > 0);
return m_current_level;
}
template <typename I, typename N, typename K>
bool directional_hqueue<I, N, K>::empty() const noexcept
template <typename P, typename N, typename K>
bool directional_hqueue<P, N, K>::empty() const noexcept
{
return m_size == 0;
}
......
......@@ -20,11 +20,12 @@ TEST(Morpho, DirectionalHQueueC4)
auto dist = [](std::uint8_t a, std::uint8_t b) -> std::uint8_t { return mln::functional::l2dist_t<>()(a, b); };
using F = decltype(dist);
using V = mln::image_value_t<decltype(ima)>;
using P = mln::image_point_t<decltype(ima)>;
using W = std::invoke_result_t<F, V, V>;
constexpr std::array<W, 12> ref = {1, 2, 4, 5, 5, 8, 8, 12, 12, 17, 21, 24};
auto hqueue = mln::morpho::details::directional_hqueue<decltype(ima), mln::c4_t, W>();
auto hqueue = mln::morpho::details::directional_hqueue<P, mln::c4_t, W>();
mln_foreach (auto p, ima.domain())
{
......@@ -59,11 +60,12 @@ TEST(Morpho, DirectionalHQueueC8)
auto dist = [](std::uint8_t a, std::uint8_t b) -> std::uint8_t { return mln::functional::l2dist_t<>()(a, b); };
using F = decltype(dist);
using V = mln::image_value_t<decltype(ima)>;
using P = mln::image_point_t<decltype(ima)>;
using W = std::invoke_result_t<F, V, V>;
constexpr std::array<W, 20> ref = {1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 8, 9, 12, 12, 16, 16, 17, 20, 21, 24};
auto hqueue = mln::morpho::details::directional_hqueue<decltype(ima), mln::c8_t, W>();
auto hqueue = mln::morpho::details::directional_hqueue<P, mln::c8_t, W>();
mln_foreach (auto p, ima.domain())
{
......@@ -101,12 +103,13 @@ TEST(Morpho, DirectionalHQueueC6)
auto dist = [](std::uint8_t a, std::uint8_t b) -> std::uint8_t { return mln::functional::l2dist_t<>()(a, b); };
using F = decltype(dist);
using V = mln::image_value_t<decltype(ima)>;
using P = mln::image_point_t<decltype(ima)>;
using W = std::invoke_result_t<F, V, V>;
constexpr std::array<W, 33> ref = {0, 1, 1, 2, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 8, 8,
9, 12, 12, 13, 13, 14, 15, 15, 15, 17, 18, 20, 21, 24, 26, 29};
auto hqueue = mln::morpho::details::directional_hqueue<decltype(ima), mln::c6_t, W>();
auto hqueue = mln::morpho::details::directional_hqueue<P, mln::c6_t, W>();
mln_foreach (auto p, ima.domain())
{
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment