-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Const simplex tree unitary tests and fix operator== and != #1145
base: master
Are you sure you want to change the base?
Const simplex tree unitary tests and fix operator== and != #1145
Conversation
…l into const_simplex_tree
Thanks for the unitary tests! But I think you forgot to include them? |
Oops yes. Should be better now |
Should we update the credit banners with the changes or is it not really necessary? Otherwise, looks good to me. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks ok. There may be things we can clean-up later, but they don't seem like prerequisites.
The change will have to be mentioned in next_release.md (we can now perform many operations on a const ST, but we are now stricter about undocumented direct use of Simplex_handle).
@@ -715,7 +719,7 @@ class Simplex_tree { | |||
static Simplex_data& simplex_data(Simplex_handle sh) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we make it non-static, with const/non-const overloads?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and tested on 99b37a3
@@ -658,6 +658,10 @@ class Simplex_tree { | |||
return sh->second.filtration(); | |||
} | |||
|
|||
static Dictionary_it _to_node_it(Simplex_handle sh){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like making this a non-const member function instead of a static one would be safer, but that's an implementation detail, it is ok as static.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No more static on 85efd97
I also added a comment on that method
@@ -1987,7 +1998,7 @@ class Simplex_tree { | |||
if (!(sh->second.filtration() >= max_filt_border_value)) { | |||
// Store the filtration modification information | |||
modified = true; | |||
sh->second.assign_filtration(max_filt_border_value); | |||
_to_node_it(sh)->second.assign_filtration(max_filt_border_value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ok for now, but in the long run, internally, do we want to use _to_node_it
or do we want to go through the official interface assign_filtration(sh, max_filt_border_value)
? _to_node_it
has the advantage (?) of skipping the assertion, but the code is uglier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, we should prefer the use of assign_filtration(sh, max_filt_border_value)
. I modified it on 0d500bc
@@ -2374,10 +2386,21 @@ class Simplex_tree { | |||
} | |||
return nullptr; | |||
} | |||
List_max_vertex const* nodes_by_label(Vertex_handle v) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you could have the other function call this one and const_cast the result, to avoid duplicating the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did so on f8de11a but I did not find out how to do it without an indirection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::as_const(*this).nodes_by_label(v)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh ? Ok ! I did return const_cast<List_max_vertex*>(std::as_const(*this).nodes_by_label(v));
on 4277a64
} | ||
|
||
/** \brief Returns the extra data stored in a simplex. */ | ||
const Simplex_data simplex_data(Simplex_handle sh) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const Simplex_data simplex_data(Simplex_handle sh) const { | |
const Simplex_data& simplex_data(Simplex_handle sh) const { |
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, done on cbbdc8a
@@ -2374,10 +2386,21 @@ class Simplex_tree { | |||
} | |||
return nullptr; | |||
} | |||
List_max_vertex const* nodes_by_label(Vertex_handle v) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::as_const(*this).nodes_by_label(v)
?
assert(dimension(sh) == 1); | ||
return { find_vertex(sh->first), find_vertex(self_siblings(sh)->parent()) }; | ||
} | ||
|
||
/** Returns the Siblings containing a simplex.*/ | ||
template<class SimplexHandle> | ||
static Siblings* self_siblings(SimplexHandle sh) { | ||
static Siblings const* self_siblings(SimplexHandle sh) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like having const and non-const overloads of self_siblings would avoid a couple const_cast elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did so on 85efd97 and it is true that it removes some const_cast
@@ -1129,7 +1143,7 @@ class Simplex_tree { | |||
* | |||
* Any insertion, deletion or change of filtration value invalidates this cache, | |||
* which can be cleared with clear_filtration(). */ | |||
void initialize_filtration(bool ignore_infinite_values = false) { | |||
void initialize_filtration(bool ignore_infinite_values = false) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should clear_filtration
also be const
, or is it different enough that it shouldn't be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clear_filtration()
constify on 3d21b0c
// all mutable as their content has no impact on the content of the simplex tree itself | ||
// they correspond to some kind of cache or helper attributes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point we should document what functions are safe to use in parallel on a Simplex_tree and what functions are not. Some people have the expectation that const
means thread-safe, which isn't the case in the presence of mutable
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I marked dimension()
, upper_bound_dimension()
, initialize_filtration()
, maybe_initialize_filtration ()
, clear_filtration()
, filtration_simplex_range()
, simplex(Simplex_key idx)
, print_hasse()
as not thread-safe in the doc on 3d21b0c
Remark, that print_hasse()
should not and use complex_simplex_range()
instead of filtration_simplex_range()
.
BOOST_CHECK(STRoot != nullptr); | ||
BOOST_CHECK(STRoot->oncles() == nullptr); | ||
BOOST_CHECK(STRoot->parent() == DEFAULT_VERTEX_VALUE); | ||
BOOST_CHECK(tst.dimension() == -1); | ||
} | ||
|
||
template<class typeST> | ||
void test_iterators_on_empty_simplex_tree(typeST& tst) { | ||
void test_iterators_on_empty_simplex_tree(const typeST& tst) { | ||
std::clog << "Iterator on vertices: " << std::endl; | ||
for (auto vertex : tst.complex_vertex_range()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this is the only place where complex_vertex_range
is tested. Could be nice to test it also for non empty trees?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a test on 38a751f
@@ -671,6 +679,8 @@ class Simplex_tree { | |||
/** \brief Returns the simplex that has index idx in the filtration. | |||
* | |||
* The filtration must be initialized. | |||
* | |||
* @note Not thread safe | |||
*/ | |||
Simplex_handle simplex(Simplex_key idx) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find any place where this method is tested, is it const or non const. I guess, if filtration_simplex_range
works, this method should work too.
Same for contiguous_vertices()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added 2 new tests on 38a751f
@@ -827,7 +849,7 @@ class Simplex_tree { | |||
/** \brief Returns the children of the node in the simplex tree pointed by sh. | |||
* \exception std::invalid_argument In debug mode, if sh has no child. | |||
*/ | |||
Siblings* children(Simplex_handle sh) const { | |||
Siblings const* children(Simplex_handle sh) const { | |||
GUDHI_CHECK(has_children(sh), std::invalid_argument("Simplex_tree::children - argument has no child")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not directly related to this PR, but is there a reason why has_children
(just above at line 840, I can't select it) is public? Or even root
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added some const test about has_children() and root() on 323e119
@@ -1934,7 +1971,7 @@ class Simplex_tree { | |||
* the children of this simplex (a subset of the cofaces). | |||
*/ | |||
template<class Fun> | |||
void for_each_simplex(Fun&& fun) { | |||
void for_each_simplex(Fun&& fun) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also test the method on a non const simplex tree such that fun
modified something in the tree (eg. puts all filtration values to value 2), to ensure that the constness of the method does not block that. I think we already test it indirectly with some use of for_each_simplex
in another place, but I suddenly have a doubt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not tested directly, but this is what is done on assign_MEB_filtration
(cf. test_cech_complex, delaunay_cech_persistence utils)
…static with a const/non const version if necessary
This PR is based on and replaces #1119