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

Fixed has_contiguous_segments implementation.

The previous implementation was failing when nodes were numbered in
breadth-first order. Also gave a more descriptive name to the
algorithm.
parent 36e87c02
No related branches found
No related tags found
No related merge requests found
...@@ -121,49 +121,42 @@ bool is_positive(C const& c) ...@@ -121,49 +121,42 @@ bool is_positive(C const& c)
} }
template<typename C> template<typename C>
bool has_contiguous_segments(const C &parent_index) std::vector<typename C::value_type> child_count(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"
); );
if (!is_minimal_degree(parent_index)) { std::vector<typename C::value_type> count(parent_index.size(), 0);
return false; for (auto i = 1u; i < parent_index.size(); ++i) {
} ++count[parent_index[i]];
int n = parent_index.size();
std::vector<bool> is_leaf(n, false);
for(auto i=1; i<n; ++i) {
auto p = parent_index[i];
if(is_leaf[p]) {
return false;
}
if(p != i-1) {
// we have a branch and i-1 is a leaf node
is_leaf[i-1] = true;
}
} }
return true; return count;
} }
template<typename C> template<typename C>
std::vector<typename C::value_type> child_count(const C &parent_index) bool has_contiguous_compartments(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<typename C::value_type> count(parent_index.size(), 0); if (!is_minimal_degree(parent_index)) {
for (std::size_t i = 1; i < parent_index.size(); ++i) { return false;
++count[parent_index[i]];
} }
return count; auto num_child = child_count(parent_index);
for (auto i = 1u; i < parent_index.size(); ++i) {
auto p = parent_index[i];
if (num_child[p] == 1 && p != i-1) {
return false;
}
}
return true;
} }
template<typename C> template<typename C>
...@@ -174,7 +167,7 @@ std::vector<typename C::value_type> branches(const C& parent_index) ...@@ -174,7 +167,7 @@ std::vector<typename C::value_type> branches(const C& parent_index)
"integral type required" "integral type required"
); );
EXPECTS(has_contiguous_segments(parent_index)); EXPECTS(has_contiguous_compartments(parent_index));
std::vector<typename C::value_type> branch_index; std::vector<typename C::value_type> branch_index;
if (parent_index.empty()) { if (parent_index.empty()) {
...@@ -250,7 +243,7 @@ std::vector<typename C::value_type> make_parent_index( ...@@ -250,7 +243,7 @@ std::vector<typename C::value_type> make_parent_index(
} }
EXPECTS(parent_index.size() == branch_index.back()); EXPECTS(parent_index.size() == branch_index.back());
EXPECTS(has_contiguous_segments(parent_index)); EXPECTS(has_contiguous_compartments(parent_index));
EXPECTS(is_strictly_monotonic_increasing(branch_index)); EXPECTS(is_strictly_monotonic_increasing(branch_index));
// expand the branch index // expand the branch index
......
...@@ -261,7 +261,7 @@ swc_record_range_clean::swc_record_range_clean(std::istream& is) ...@@ -261,7 +261,7 @@ swc_record_range_clean::swc_record_range_clean(std::istream& is)
parent_list.push_back(records_[i].parent()); parent_list.push_back(records_[i].parent());
} }
if (!nest::mc::algorithms::has_contiguous_segments(parent_list)) { if (!nest::mc::algorithms::has_contiguous_compartments(parent_list)) {
throw swc_parse_error("branches are not contiguously numbered", 0); throw swc_parse_error("branches are not contiguously numbered", 0);
} }
} }
......
...@@ -172,7 +172,7 @@ TEST(algorithms, is_positive) ...@@ -172,7 +172,7 @@ TEST(algorithms, is_positive)
); );
} }
TEST(algorithms, has_contiguous_segments) TEST(algorithms, has_contiguous_compartments)
{ {
// //
// 0 // 0
...@@ -186,7 +186,7 @@ TEST(algorithms, has_contiguous_segments) ...@@ -186,7 +186,7 @@ TEST(algorithms, has_contiguous_segments)
// 5 6 // 5 6
// //
EXPECT_FALSE( EXPECT_FALSE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2} std::vector<int>{0, 0, 1, 2, 2, 3, 4, 2}
) )
); );
...@@ -203,7 +203,7 @@ TEST(algorithms, has_contiguous_segments) ...@@ -203,7 +203,7 @@ TEST(algorithms, has_contiguous_segments)
// 4 7 // 4 7
// //
EXPECT_FALSE( EXPECT_FALSE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5} std::vector<int>{0, 0, 1, 2, 3, 2, 2, 5}
) )
); );
...@@ -220,7 +220,7 @@ TEST(algorithms, has_contiguous_segments) ...@@ -220,7 +220,7 @@ TEST(algorithms, has_contiguous_segments)
// 4 6 // 4 6
// //
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2} std::vector<int>{0, 0, 1, 2, 3, 2, 5, 2}
) )
); );
...@@ -237,21 +237,34 @@ TEST(algorithms, has_contiguous_segments) ...@@ -237,21 +237,34 @@ TEST(algorithms, has_contiguous_segments)
// 4 6 // 4 6
// //
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1} std::vector<int>{0, 0, 1, 2, 3, 2, 5, 1}
) )
); );
//
// 0
// / \
// 1 2
// / \
// 3 4
//
EXPECT_TRUE(
nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0, 0, 0, 1, 1}
)
);
// Soma-only list // Soma-only list
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{0} std::vector<int>{0}
) )
); );
// Empty list // Empty list
EXPECT_TRUE( EXPECT_TRUE(
nest::mc::algorithms::has_contiguous_segments( nest::mc::algorithms::has_contiguous_compartments(
std::vector<int>{} std::vector<int>{}
) )
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment