Skip to content
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

A fix proposal for boudaries of a simplex python version #362

Merged

Conversation

VincentRouvreau
Copy link
Contributor

A fix proposal for #29
Maybe overkill because it could be done easily in pure Python, but the interface would not be the same as the other iterators.

import itertools

    def get_boundaries(self, simplex):
        """This function returns a generator with the boundaries of a given N-simplex.

        :param simplex: The N-simplex, represented by a list of vertex.
        :type simplex: list of int.
        :returns:  The (simplices of the) boundaries of a simplex
        :rtype:  generator of simplices
        """
        return itertools.combinations(simplex,len(simplex)-1)

We wouldn't have :rtype: generator with tuples(simplex, filtration) like the other generators.

@mglisse
Copy link
Member

mglisse commented Jul 3, 2020

the interface would not be the same as the other iterators

Generators and lists are both iterable. The whole point of those concepts is that you don't have to use the same type all the time. I haven't looked at the PR yet.


Ignore the above, I misunderstood. The main point is whether we should get a range of simplices, or a range of pairs (simplex, filtration), which is what the others do. Being consistent makes sense here. Maybe we can add a comment pointing out that if the user does not need the filtration values but just the simplices, they can also use itertools.combinations(simplex,len(simplex)-1), but I don't even think that's necessary.

src/python/include/Simplex_tree_interface.h Outdated Show resolved Hide resolved
src/python/gudhi/simplex_tree.pyx Outdated Show resolved Hide resolved
assert st.insert([1, 2, 3, 4], filtration=2.0) == True

assert list(st.get_boundaries([1, 2, 3])) == [([1, 2], 1.0), ([1, 3], 1.0), ([2, 3], 1.0)]
assert list(st.get_boundaries([2, 3, 4])) == [([2, 3], 1.0), ([2, 4], 2.0), ([3, 4], 2.0)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe check also the boundary of a vertex (should be an empty list).
What happens if I do st.get_boundaries([])? (I don't think it is very important, I am just curious)

Copy link
Contributor Author

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 8f9c065
st.get_boundaries([]) seg faults... I have a look on it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok this is because st.boundary_simplex_range(st.null_simplex()) seg faults.

If I fix it in Simplex_tree_iterators.h by saying:

  template<class SimplexHandle>
  Simplex_tree_boundary_simplex_iterator(SimplexTree * st, SimplexHandle sh)
      : //last_(sh->first),
        next_(st->null_vertex()),
        sib_(nullptr),
        sh_(st->null_simplex()),
        st_(st) {
    // Only check once at the beginning instead of for every increment, as this is expensive.
    if (SimplexTree::Options::contiguous_vertices)
      GUDHI_CHECK(st_->contiguous_vertices(), "The set of vertices is not { 0, ..., n } without holes");
    if (sh != st->null_simplex()) {
      last_ = sh->first;
      Siblings * sib = st->self_siblings(sh);
      next_ = sib->parent();
      sib_ = sib->oncles();
    }

(I find template<class SimplexHandle> quite strange here)
It works fine, but now Cech complex compilation fails because of:

Simplex_tree.h:1262:26: error: conversion from ‘boost::container::flat_map<int, Gudhi::Simplex_tree_node_explicit_storage<Gudhi::Simplex_tree<> >, std::less<int>, boost::container::new_allocator<std::pair<int, Gudhi::Simplex_tree_node_explicit_storage<Gudhi::Simplex_tree<> > > > >::reverse_iterator {aka boost::intrusive::reverse_iterator<boost::container::container_detail::vec_iterator<std::pair<int, Gudhi::Simplex_tree_node_explicit_storage<Gudhi::Simplex_tree<> > >*, false> >}’ to non-scalar type ‘Gudhi::Simplex_tree<>::Simplex_handle {aka boost::container::container_detail::vec_iterator<std::pair<int, Gudhi::Simplex_tree_node_explicit_storage<Gudhi::Simplex_tree<> > >*, false>}’ requested
       for(Simplex_handle next = siblings->members().rbegin(); next != simplex; next++) {
                          ^~~~

It cannot convert a boost::intrusive::reverse_iterator<boost::container::container_detail::vec_iterator<...>> to a boost::container::container_detail::vec_iterator<...>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is ok to crash in the C++ code when violating a precondition (sh has to refer to a real simplex). It is just in python that crashing the interpreter is a bit too extreme. assert len(simplex) != 0 would be good enough for me, or something similar in the C++ glue.
Maybe at some point we could introduce something similar to GUDHI_CHECK, for things that we want to check even in release mode (and throw an exception if that fails) but only when used from python. I don't know exactly how much we would use it, but I think it isn't the first time I've thought of that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm ok. Sounds good to me. I think I need to perform something like assert find(simplex) != null_simplex() because something not found would also seg fault.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I hadn't thought of that case...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I used exceptions on 458bc2d and seems better.
I also added some tests to the limits.

@VincentRouvreau VincentRouvreau added the 3.4.0 GUDHI version 3.4.0 label Nov 2, 2020
@VincentRouvreau VincentRouvreau merged commit 5900b2d into GUDHI:master Nov 2, 2020
@VincentRouvreau VincentRouvreau deleted the python_stree_boundaries branch November 2, 2020 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.4.0 GUDHI version 3.4.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants