Skip to content
Snippets Groups Projects
Commit e7e99c71 authored by Vasileios Karakasis's avatar Vasileios Karakasis
Browse files

Algorithms for retrieving child counts and branches encoding.

parent 6ef76b41
No related branches found
No related tags found
No related merge requests found
...@@ -112,29 +112,86 @@ namespace algorithms{ ...@@ -112,29 +112,86 @@ namespace algorithms{
} }
template<typename C> template<typename C>
bool is_contiguously_numbered(const C &parent_list) bool has_contiguous_segments(const C &parent_index)
{ {
static_assert( static_assert(
std::is_integral<typename C::value_type>::value, std::is_integral<typename C::value_type>::value,
"integral type required" "integral type required"
); );
std::vector<bool> is_leaf(parent_list.size(), false); if (!is_minimal_degree(parent_index)) {
return false;
}
std::vector<bool> is_leaf(parent_index.size(), false);
auto ret = true; for (std::size_t i = 1; i < parent_index.size(); ++i) {
for (std::size_t i = 1; i < parent_list.size(); ++i) { auto p = parent_index[i];
if (is_leaf[parent_list[i]]) { if (is_leaf[p]) {
ret = false; return false;
break;
} }
if (parent_list[i] != i-1) { if (p != i-1) {
// we have a branch and i-1 is a leaf node // we have a branch and i-1 is a leaf node
is_leaf[i-1] = true; is_leaf[i-1] = true;
} }
} }
return ret; return true;
}
template<typename C>
std::vector<typename C::value_type> child_count(const C &parent_index)
{
static_assert(
std::is_integral<typename C::value_type>::value,
"integral type required"
);
std::vector<typename C::value_type> count(parent_index.size(), 0);
for (std::size_t i = 1; i < parent_index.size(); ++i) {
++count[parent_index[i]];
}
return count;
}
template<typename C, bool CheckStrict = true>
std::vector<typename C::value_type> branches(const C &parent_index)
{
static_assert(
std::is_integral<typename C::value_type>::value,
"integral type required"
);
if (CheckStrict && !has_contiguous_segments(parent_index)) {
throw std::invalid_argument(
"parent_index has not contiguous branch numbering"
);
}
auto num_child = child_count(parent_index);
std::vector<typename C::value_type> branch_index(
parent_index.size(), 0
);
std::size_t num_branches = (num_child[0] == 1) ? 1 : 0;
for (std::size_t i = 1; i < parent_index.size(); ++i) {
auto p = parent_index[i];
if (num_child[p] > 1) {
++num_branches;
}
branch_index[i] = num_branches;
}
return branch_index;
}
template<typename C>
std::vector<typename C::value_type> branches_fast(const C &parent_index)
{
return branches<C, false>(parent_index);
} }
} // namespace algorithms } // namespace algorithms
......
...@@ -170,7 +170,7 @@ TEST(algorithms, is_positive) ...@@ -170,7 +170,7 @@ TEST(algorithms, is_positive)
); );
} }
TEST(algorithms, is_contiguously_numbered) TEST(algorithms, has_contiguous_segments)
{ {
// //
// 0 // 0
...@@ -178,13 +178,13 @@ TEST(algorithms, is_contiguously_numbered) ...@@ -178,13 +178,13 @@ TEST(algorithms, is_contiguously_numbered)
// 1 // 1
// | // |
// 2 // 2
// /|\ // /|\.
// 3 7 4 // 3 7 4
// / \ // / \.
// 5 6 // 5 6
// //
EXPECT_FALSE( EXPECT_FALSE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2} std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2}
) )
); );
...@@ -201,7 +201,7 @@ TEST(algorithms, is_contiguously_numbered) ...@@ -201,7 +201,7 @@ TEST(algorithms, is_contiguously_numbered)
// 4 7 // 4 7
// //
EXPECT_FALSE( EXPECT_FALSE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5} std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5}
) )
); );
...@@ -218,7 +218,7 @@ TEST(algorithms, is_contiguously_numbered) ...@@ -218,7 +218,7 @@ TEST(algorithms, is_contiguously_numbered)
// 4 6 // 4 6
// //
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2} std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2}
) )
); );
...@@ -235,23 +235,130 @@ TEST(algorithms, is_contiguously_numbered) ...@@ -235,23 +235,130 @@ TEST(algorithms, is_contiguously_numbered)
// 4 6 // 4 6
// //
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1} std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1}
) )
); );
// Soma-only list // Soma-only list
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{0} std::vector<int>{0}
) )
); );
// Empty list // Empty list
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::is_contiguously_numbered( nest::mc::algorithms::has_contiguous_segments(
std::vector<int>{} std::vector<int>{}
) )
); );
}
TEST(algorithms, child_count)
{
{
//
// 0
// /|\
// 1 4 6
// / | \
// 2 5 7
// / \
// 3 8
// / \
// 9 11
// / \
// 10 12
// \
// 13
//
std::vector<int> parent_index =
{ 0, 0, 1, 2, 0, 4, 0, 6, 7, 8, 9, 8, 11, 12 };
std::vector<int> expected_child_count =
{ 3, 1, 1, 0, 1, 0, 1, 1, 2, 1, 0, 1, 1, 0 };
// auto count = nest::mc::algorithms::child_count(parent_index);
EXPECT_EQ(expected_child_count,
nest::mc::algorithms::child_count(parent_index));
}
}
TEST(algorithms, branches)
{
using namespace nest::mc;
{
//
// 0
// /|\
// 1 4 6
// / | \
// 2 5 7
// / \
// 3 8
// / \
// 9 11
// / \
// 10 12
// \
// 13
//
std::vector<int> parent_index =
{ 0, 0, 1, 2, 0, 4, 0, 6, 7, 8, 9, 8, 11, 12 };
std::vector<int> expected_branches =
{ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5 };
auto actual_branches = algorithms::branches_fast(parent_index);
EXPECT_EQ(expected_branches, actual_branches);
}
{
//
// 0
// |
// 1
// |
// 2
// |
// 3
//
std::vector<int> parent_index =
{ 0, 0, 1, 2 };
std::vector<int> expected_branches =
{ 0, 1, 1, 1 };
auto actual_branches = algorithms::branches_fast(parent_index);
EXPECT_EQ(expected_branches, actual_branches);
}
{
//
// 0
// |
// 1
// |
// 2
// / \
// 3 4
// \
// 5
//
std::vector<int> parent_index =
{ 0, 0, 1, 2, 2, 4 };
std::vector<int> expected_branches =
{ 0, 1, 1, 2, 3, 3 };
auto actual_branches = algorithms::branches_fast(parent_index);
EXPECT_EQ(expected_branches, actual_branches);
}
{
std::vector<int> parent_index = { 0 };
std::vector<int> expected_branches = { 0 };
auto actual_branches = algorithms::branches_fast(parent_index);
EXPECT_EQ(expected_branches, actual_branches);
}
} }
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