11 #ifndef HASSE_COMPLEX_H_
12 #define HASSE_COMPLEX_H_
14 #include <gudhi/allocator.h>
16 #include <boost/iterator/counting_iterator.hpp>
25 #include <tbb/parallel_for.h>
31 template <
class HasseCpx >
32 struct Hasse_simplex {
35 template<
class Complex_ds >
36 Hasse_simplex(Complex_ds & cpx
37 ,
typename Complex_ds::Simplex_handle sh)
38 : filtration_(cpx.filtration(sh))
40 boundary_.reserve(cpx.dimension(sh) + 1);
41 for (
auto b_sh : cpx.boundary_simplex_range(sh)) {
42 boundary_.push_back(cpx.key(b_sh));
46 Hasse_simplex(
typename HasseCpx::Simplex_key key
47 ,
typename HasseCpx::Filtration_value fil
48 , std::vector<typename HasseCpx::Simplex_handle>
const& boundary)
51 , boundary_(boundary) { }
53 typename HasseCpx::Simplex_key key_;
54 typename HasseCpx::Filtration_value filtration_;
55 std::vector<typename HasseCpx::Simplex_handle> boundary_;
72 typedef Hasse_simplex<Hasse_complex> Hasse_simp;
75 typedef int Simplex_handle;
77 typedef boost::counting_iterator< Simplex_handle > Filtration_simplex_iterator;
78 typedef boost::iterator_range<Filtration_simplex_iterator> Filtration_simplex_range;
80 typedef typename std::vector< Simplex_handle >::iterator Boundary_simplex_iterator;
81 typedef boost::iterator_range<Boundary_simplex_iterator> Boundary_simplex_range;
83 typedef typename std::vector< Simplex_handle >::iterator Skeleton_simplex_iterator;
84 typedef boost::iterator_range< Skeleton_simplex_iterator > Skeleton_simplex_range;
87 Skeleton_simplex_range skeleton_simplex_range(
int dim = 0) {
89 std::cerr <<
"Dimension must be 0 \n";
91 return Skeleton_simplex_range(vertices_.begin(), vertices_.end());
94 template <
class Complex_ds >
95 Hasse_complex(Complex_ds & cpx)
96 : complex_(cpx.num_simplices())
100 int size = complex_.size();
102 tbb::parallel_for(0, size, [&](
int idx){
new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));});
103 for (
int idx=0; idx < size; ++idx)
104 if (complex_[idx].boundary_.empty())
105 vertices_.push_back(idx);
107 for (
int idx=0; idx < size; ++idx) {
108 new (&complex_[idx]) Hasse_simp(cpx, cpx.simplex(idx));
109 if (complex_[idx].boundary_.empty())
110 vertices_.push_back(idx);
121 size_t num_simplices() {
122 return complex_.size();
125 Filtration_simplex_range filtration_simplex_range() {
126 return Filtration_simplex_range(Filtration_simplex_iterator(0)
127 , Filtration_simplex_iterator(complex_.size()));
130 Simplex_key
key(Simplex_handle sh) {
131 return complex_[sh].key_;
134 Simplex_key null_key() {
138 Simplex_handle
simplex(Simplex_key key) {
139 if (key == null_key())
return null_simplex();
143 Simplex_handle null_simplex() {
148 if (sh == null_simplex()) {
149 return std::numeric_limits<Filtration_value>::infinity();
151 return complex_[sh].filtration_;
155 if (complex_[sh].boundary_.empty())
return 0;
156 return complex_[sh].boundary_.size() - 1;
163 std::pair<Simplex_handle, Simplex_handle> endpoints(Simplex_handle sh) {
164 return std::pair<Simplex_handle, Simplex_handle>(complex_[sh].boundary_[0]
165 , complex_[sh].boundary_[1]);
168 void assign_key(Simplex_handle sh, Simplex_key key) {
169 complex_[sh].key_ = key;
173 return Boundary_simplex_range(complex_[sh].boundary_.begin()
174 , complex_[sh].boundary_.end());
177 void display_simplex(Simplex_handle sh) {
180 std::clog <<
" " <<
filtration(sh) <<
" key=" << key(sh);
183 void initialize_filtration() {
187 for (
auto & h_simp : complex_)
192 std::vector< Hasse_simp, Gudhi::no_init_allocator<Hasse_simp> > complex_;
193 std::vector<Simplex_handle> vertices_;
194 size_t num_vertices_;
198 template<
typename T1,
typename T2,
typename T3 >
199 std::istream& operator>>(std::istream & is
200 , Hasse_complex< T1, T2, T3 > & hcpx) {
201 assert(hcpx.num_simplices() == 0);
205 hcpx.complex_.reserve(num_simp);
207 std::vector< typename Hasse_complex<T1, T2, T3>::Simplex_key > boundary;
208 typename Hasse_complex<T1, T2, T3>::Filtration_value fil;
209 typename Hasse_complex<T1, T2, T3>::Filtration_value max_fil = 0;
215 hcpx.complex_.emplace_back(key, fil, boundary);
217 if (max_dim < hcpx.dimension(key)) {
218 max_dim = hcpx.dimension(key);
220 if (hcpx.dimension(key) == 0) {
221 hcpx.vertices_.push_back(key);
231 hcpx.dim_max_ = max_dim;
238 #endif // HASSE_COMPLEX_H_