1 #ifndef simplicialcomplex_h_nealaezeojeeChuh
2 #define simplicialcomplex_h_nealaezeojeeChuh
12 #include <libstick-0.1/booleanmatrix.h>
17 /** A simplicial complex is a std::vector of simplices such that each face is
18 * also part of the complex. Every simplex has dimension at most MAXDIM. The
19 * indices of simplices resp. their faces are of type IT. To each simplex a
20 * value is assigend, which is of type VT. */
21 template<size_t MAXDIM
, class IT
=uint32_t, class VT
=double>
22 class SimplicialComplex
{
25 /** The type of this class. */
26 typedef SimplicialComplex
<MAXDIM
, IT
, VT
> simplcompltype
;
27 /** Type of indices of simplices. */
28 typedef IT index_type
;
29 /** To every simplex a function value is assigned according to which a
30 * filtration is considered. This is the value type of the function. */
31 typedef VT value_type
;
33 /** A simplex of the complex. */
35 /** Dimension of the simplex. */
37 /** The indices of the faces of the simplex. */
38 index_type faces
[MAXDIM
+1];
39 /** The value of the simplex. */
42 /** Create a new simplex with dimension 'dim', (dim+1)-faces and
44 static Simplex
create(size_t dim
, index_type
* faces
, value_type value
) {
45 assert(dim
<= MAXDIM
);
50 memcpy(s
.faces
, faces
, face_count_bydim(dim
)*sizeof(index_type
));
55 /** Get number of faces. */
56 size_t face_count() const {
57 return face_count_bydim(dim
);
60 /** Get number of faces of a dim-dimensional simplex. */
61 static size_t face_count_bydim(size_t dim
) {
68 /** An order of the simplices of complex c. An order can be interpreted
69 * as a permuation of the complex's std::vector of simplices. */
73 typedef BooleanColRowMatrix
<IT
> BoundaryMatrix
;
75 /** Create a standard order of the complex c, i.e., the identity permutation. */
76 SimplexOrder(const simplcompltype
&c
) :
82 /** Reset order to the identity permutation of the complex's simplices. */
85 for (unsigned i
=0; i
< c
.size(); ++i
)
90 /** Return number of simplices. */
92 assert(order
.size() == revorder
.size());
96 /** Get i-th simplex in the simplex order. */
97 const Simplex
& getSimplex(size_t i
) const {
99 return c
.simplices
[order
.at(i
)];
102 /** Returns true iff the faces of simplex i are before i in this order. */
103 bool isFiltration() const {
104 assert(size() == c
.size());
106 for (unsigned i
=0; i
< size(); ++i
)
107 for (unsigned f
=0; f
< getSimplex(i
).face_count(); ++f
)
108 if (revorder
[getSimplex(i
).faces
[f
]] >= i
)
114 /** Returns true iff isFiltration() gives true and values of simplices
115 * are monotone w.r.t. this order of simplices. */
116 bool isMonotone() const {
117 assert(size() == c
.size());
119 for (unsigned i
=1; i
< size(); ++i
)
120 if (getSimplex(i
-1).value
> getSimplex(i
).value
)
123 return isFiltration();
126 /** Sort simplices such that isMonotone() gives true. This
127 * requires that the complex's isMonotone() gave true
129 void makeMonotoneFiltration() {
130 assert(c
.isMonotone());
132 sort(order
.begin(), order
.end(), cmpMonotoneFiltration(c
));
133 restoreRevorderFromOrder();
135 assert(c
.isMonotone());
136 assert(isFiltration());
137 assert(isMonotone());
140 /** Get the boundary matrix of the complex according to this order. */
141 BoundaryMatrix
getBoundaryMatrix() const {
142 BoundaryMatrix
mat(size());
144 for (unsigned c
=0; c
< size(); ++c
)
145 for(unsigned r
=0; r
< getSimplex(c
).face_count(); ++r
)
146 mat
.set(revorder
[getSimplex(c
).faces
[r
]], c
, true);
152 /** Reconstruct 'revorder' by inverting the permutation given by 'order'. */
153 void restoreRevorderFromOrder() {
154 // Make revorder * order the identity permutation
155 for (unsigned i
=0; i
< size(); ++i
)
156 revorder
[order
[i
]] = i
;
159 /** The complex of which we consider a simplex order. */
160 const simplcompltype
&c
;
162 /** The i-th simplex in order is the order[i]-th simplex of the
163 * complex. 'order' can be seen as a permutation of the
164 * simplices saved in 'c'. */
165 std::vector
<index_type
> order
;
167 /** The i-th simplex in the complex is the revorder[i]-th
168 * simplex in order. 'revorder' can be seen as the inverse
169 * permutation saved in 'order'. */
170 std::vector
<index_type
> revorder
;
174 /** Return number of simplices. */
175 size_t size() const {
176 return simplices
.size();
179 /** Add a simplex to the complex. The dimension of the faces must be
180 * dim-1, and they must already be part of the complex. */
181 void addSimplex(size_t dim
, index_type
* faces
, value_type value
) {
182 addSimplex(Simplex::create(dim
, faces
, value
));
185 /** Add a simplex to the complex. The dimension of the faces must be
186 * dim-1, and they must already be part of the complex. */
187 void addSimplex(Simplex s
) {
188 // Check requirements for faces
189 for (unsigned i
=0; i
< s
.face_count(); ++i
) {
190 // Faces are already in complex.
191 assert(s
.faces
[i
] < size());
192 // Faces have dimension dim-1
193 assert(simplices
[s
.faces
[i
]].dim
== s
.dim
-1);
196 simplices
.push_back(s
);
199 /** Return true iff for each simplex i with dimension dim it holds that
200 * the faces of i are contained in the complex and have dimension dim-1. */
201 bool isComplex() const {
202 typename
std::vector
<Simplex
>::const_iterator it
= ++simplices
.begin();
203 for (unsigned i
=0; i
< size(); ++i
) {
205 const Simplex
&s
= simplices
[i
];
206 for (unsigned f
=0; f
< s
.face_count(); ++f
) {
208 if (s
.faces
[f
] >= size())
211 const Simplex
&face
= simplices
[s
.faces
[f
]];
212 if (face
.dim
!= s
.dim
-1)
219 /** Returns true iff simplex's values are monotone w.r.t.
220 * face-inclusion, i.e., for each simplex its value is not smaller than
221 * the values of its faces. Requires that isComplex() gives true. */
222 bool isMonotone() const {
225 typename
std::vector
<Simplex
>::const_iterator it
= ++simplices
.begin();
226 for (; it
!= simplices
.end(); ++it
)
227 for (unsigned f
=0; f
< it
->face_count(); ++f
)
228 if (simplices
[it
->faces
[f
]].value
> it
->value
)
235 /** Compares (operator<) two simplices (i.e. indices) in a
236 * SimplexOrder w.r.t. lexicographical order on (value,
237 * dimension)-tuples. */
238 struct cmpMonotoneFiltration
{
239 const SimplicialComplex
&c
;
241 cmpMonotoneFiltration(const SimplicialComplex
&c
) :
245 bool operator()(index_type i
, index_type j
) {
246 const Simplex
& si
= c
.simplices
[i
];
247 const Simplex
& sj
= c
.simplices
[j
];
249 if (si
.value
< sj
.value
)
251 else if (si
.value
== sj
.value
)
252 return si
.dim
< sj
.dim
;
259 /** A list of simplices */
260 std::vector
<Simplex
> simplices
;