1 #ifndef simplicialfunction_h_thee5Oonae6eig5k
2 #define simplicialfunction_h_thee5Oonae6eig5k
8 #include "simplicialcomplex.h"
13 /** A simplicial function assigns to each simplex in a
14 * simplicial_complex<MAXDIM, IT> a function value of type VT. A natural way to
15 * obtain a simplex_order is to sort the simplicies of a complex according to
16 * their function values while preserving the filtration property. */
17 template<int MAXDIM
, class IT
, class VT
>
18 class simplicial_function
{
21 /** The type of the underlying simplicial complex. */
22 typedef simplicial_complex
<MAXDIM
, IT
> simplcompltype
;
23 /** Type of indices of simplices. */
24 typedef IT index_type
;
25 /** Type of the simplices of the underlying simplicial complex */
26 typedef typename
simplcompltype::simplex simplex
;
27 /** Type of the order on the underlying simplicial complex */
28 typedef typename
simplcompltype::simplex_order simplex_order
;
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
;
32 /** The container that holds the values. */
33 typedef std::vector
<value_type
> values_type
;
35 /** This struct adds a function value to a simplex and is designed to
37 struct valuedsimplex
{
41 /** Create a valuedsimplex. */
42 static valuedsimplex
create_valuedsimplex(int dim
, index_type
* faces
, value_type value
) {
44 vs
.simpl
= simplex::create_simplex(dim
, faces
);
51 /**Create a simplicial function on a given simplicial complex c. Only
52 * define for the (-1)-dim dummy vertex a value, namely
53 * get_minusonedim_value().*/
54 simplicial_function(simplcompltype
&c
) :
56 values
.push_back(get_minusonedim_value());
59 /** Get the value of the (-1)-dimensional dummy simplex. */
60 static value_type
get_minusonedim_value() {
61 return std::numeric_limits
<value_type
>::has_infinity
62 ? -std::numeric_limits
<value_type
>::infinity()
63 : std::numeric_limits
<value_type
>::min();
66 /** Return number of function values. */
71 /** Returns true if we have a function value for exactly every
73 bool is_complete() const {
74 return (size() == c
.size());
77 /** Make the simplicial function complete, i.e. s.t. is_complete()
78 * returns true, by truncating or filling up the list of function
79 * values by the given value. */
80 void make_complete(value_type fill
= value_type()) {
81 // We never would like to get rid of the dummy vertex's value
82 assert(c
.size() >= 1);
83 values
.resize(c
.size(), fill
);
86 /** Return the underlying complex. */
87 const simplcompltype
& get_complex() const {
91 /** Get value of idx-th simplex */
92 const value_type
& get_value(index_type idx
) const {
93 assert(0 <= idx
&& idx
< size());
94 return values
.at(idx
);
97 /** Set value of idx-th simplex */
98 void set_value(index_type idx
, const value_type
& value
) {
99 assert(0 <= idx
&& idx
< size());
100 values
.at(idx
) = value
;
103 /** Get all the values. */
104 const values_type
& get_values() const {
108 /** Set all the values at once. Requires that is_complete() returns
109 * true afterwards. */
110 void set_values(const values_type
& values
) {
111 this->values
= values
;
112 assert(is_complete());
115 /** Add a simplex to the complex and the function. Requires
116 * that is_complete() returns true.
118 * See also simplicial_complex::add_simplex(). */
119 index_type
add_simplex(int dim
, index_type
* faces
, value_type value
) {
120 assert(is_complete());
122 return add_simplex(valuedsimplex::create_valuedsimplex(dim
, faces
, value
));
125 /** Add a simplex of at least dimension 1 to the complex and the
126 * function. The value of the simplex is set to the maximum value of
127 * its faces. Returns the index of the added simplex. Requires that
128 * is_complete() returns true.
130 * See also simplicial_complex::add_simplex(). */
131 index_type
add_simplex(int dim
, index_type
* faces
) {
133 assert(is_complete());
135 // Get max value of its faces
136 VT value
= get_value(faces
[0]);
137 for (size_t i
=1; i
< simplex::face_count_bydim(dim
); ++i
)
138 value
= std::max(value
, get_value(faces
[i
]));
140 return add_simplex(dim
, faces
, value
);
143 /** Add a valued simplex. Requires that is_complete() returns true.
145 * See also simplicial_comple::add_simplex(). */
146 index_type
add_simplex(const valuedsimplex
&s
) {
147 assert(is_complete());
149 values
.push_back(s
.value
);
150 return c
.add_simplex(s
.simpl
);
153 /** Add an array of valued simplices. Requires that is_complete()
155 void add_simplices(valuedsimplex
* sarray
, size_t count
) {
156 assert(is_complete());
158 for (unsigned i
=0; i
< count
; ++i
)
159 add_simplex(sarray
[i
]);
162 /** Returns true iff simplex's values are monotone w.r.t.
163 * face-inclusion, i.e., for each simplex its value is not smaller than
164 * the values of its faces. Requires that is_complex() gives true. */
165 bool is_monotone() const {
166 assert(size() == c
.size());
167 assert(c
.is_complex());
169 for (unsigned i
=0; i
< size(); ++i
) {
170 const simplex
& s
= c
.get_simplex(i
);
171 for (unsigned f
=0; f
< s
.face_count(); ++f
)
172 if (get_value(s
.faces
[f
]) > get_value(i
))
179 /** Check if the given simplex order is a filtration and monotone
180 * w.r.t. to this simplicial function. Note is_monotone() &&
181 * o.is_filtration() can be true, but is_order_monotonefiltration(o)
182 * may still be false. */
183 bool is_order_monotonefiltration(const simplex_order
&o
) const {
184 assert(size() == c
.size());
186 for (unsigned i
=1; i
< size(); ++i
)
187 if (values
.at(o
.order_to_complex(i
-1)) > values
.at(o
.order_to_complex(i
)))
190 return o
.is_filtration();
193 /** Make simplex order a monotone filtration of the underlying complex. */
194 void make_order_monotonefiltration(simplex_order
&so
) const {
195 typename
simplex_order::order_type order
= so
.get_order();
196 std::sort(order
.begin(), order
.end(), cmp_monotone_filtration(*this));
201 /** Compares (operator<) two valued simplices (i.e. indices) in a
202 * simplicial complex w.r.t. lexicographical order on (value,
205 struct cmp_monotone_filtration
{
206 const simplicial_function
&f
;
208 cmp_monotone_filtration(const simplicial_function
&f
) :
210 assert(f
.is_complete());
213 bool operator()(index_type i
, index_type j
) const {
214 assert(f
.is_complete());
216 if (f
.get_value(i
) != f
.get_value(j
))
217 return (f
.get_value(i
) < f
.get_value(j
));
219 return f
.get_complex().get_simplex(i
).dim
< f
.get_complex().get_simplex(j
).dim
;
223 /** Simplex c[i] get assigned values[i]. */
226 /** The complex on which we consider a function. */