summaryrefslogtreecommitdiff
path: root/src/Simplex_tree
diff options
context:
space:
mode:
Diffstat (limited to 'src/Simplex_tree')
-rw-r--r--src/Simplex_tree/doc/Intro_simplex_tree.h9
-rw-r--r--src/Simplex_tree/example/CMakeLists.txt7
-rw-r--r--src/Simplex_tree/example/graph_expansion_with_blocker.cpp79
-rw-r--r--src/Simplex_tree/example/mini_simplex_tree.cpp2
-rw-r--r--src/Simplex_tree/example/simple_simplex_tree.cpp35
-rw-r--r--src/Simplex_tree/include/gudhi/Simplex_tree.h181
-rw-r--r--src/Simplex_tree/test/CMakeLists.txt22
-rw-r--r--src/Simplex_tree/test/README2
-rw-r--r--src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp235
-rw-r--r--src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp136
-rw-r--r--src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp427
-rw-r--r--src/Simplex_tree/test/simplex_tree_unit_test.cpp275
12 files changed, 1119 insertions, 291 deletions
diff --git a/src/Simplex_tree/doc/Intro_simplex_tree.h b/src/Simplex_tree/doc/Intro_simplex_tree.h
index f5b72ff6..769491d9 100644
--- a/src/Simplex_tree/doc/Intro_simplex_tree.h
+++ b/src/Simplex_tree/doc/Intro_simplex_tree.h
@@ -67,10 +67,13 @@ Information of the Simplex Tree:
Number of vertices = 10 Number of simplices = 98 \endcode
*
* \li <a href="_simplex_tree_2example_alpha_shapes_3_simplex_tree_from_off_file_8cpp-example.html">
- * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> - Simplex tree is computed and displayed from a 3D alpha
- * complex (Requires CGAL, GMP and GMPXX to be installed)
- *
+ * Simplex_tree/example_alpha_shapes_3_simplex_tree_from_off_file.cpp</a> - Simplex tree is computed and displayed
+ * from a 3D alpha complex (Requires CGAL, GMP and GMPXX to be installed).
*
+ * \li <a href="_simplex_tree_2graph_expansion_with_blocker_8cpp-example.html">
+ * Simplex_tree/graph_expansion_with_blocker.cpp</a> - Simple simplex tree construction from a one-skeleton graph with
+ * a simple blocker expansion method.
+ *
* \subsection filteredcomplexeshassecomplex Hasse complex
* The second one is the Hasse_complex. The Hasse complex is a data structure representing explicitly all co-dimension
* 1 incidence relations in a complex. It is consequently faster when accessing the boundary of a simplex, but is less
diff --git a/src/Simplex_tree/example/CMakeLists.txt b/src/Simplex_tree/example/CMakeLists.txt
index e22cc92c..8bc4ad53 100644
--- a/src/Simplex_tree/example/CMakeLists.txt
+++ b/src/Simplex_tree/example/CMakeLists.txt
@@ -34,5 +34,12 @@ if(GMP_FOUND AND CGAL_FOUND)
"${CMAKE_SOURCE_DIR}/data/points/bunny_5000.off")
install(TARGETS Simplex_tree_example_alpha_shapes_3_from_off DESTINATION bin)
+endif()
+add_executable ( Simplex_tree_example_graph_expansion_with_blocker graph_expansion_with_blocker.cpp )
+if (TBB_FOUND)
+ target_link_libraries(Simplex_tree_example_graph_expansion_with_blocker ${TBB_LIBRARIES})
endif()
+add_test(NAME Simplex_tree_example_graph_expansion_with_blocker COMMAND $<TARGET_FILE:Simplex_tree_example_graph_expansion_with_blocker>)
+
+install(TARGETS Simplex_tree_example_graph_expansion_with_blocker DESTINATION bin)
diff --git a/src/Simplex_tree/example/graph_expansion_with_blocker.cpp b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp
new file mode 100644
index 00000000..86bfb8cb
--- /dev/null
+++ b/src/Simplex_tree/example/graph_expansion_with_blocker.cpp
@@ -0,0 +1,79 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Vincent Rouvreau
+ *
+ * Copyright (C) 2014
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <gudhi/Simplex_tree.h>
+
+#include <iostream>
+
+using Simplex_tree = Gudhi::Simplex_tree<>;
+using Simplex_handle = Simplex_tree::Simplex_handle;
+
+int main(int argc, char * const argv[]) {
+
+ // Construct the Simplex Tree with a 1-skeleton graph example
+ Simplex_tree simplexTree;
+
+ simplexTree.insert_simplex({0, 1}, 0.);
+ simplexTree.insert_simplex({0, 2}, 1.);
+ simplexTree.insert_simplex({0, 3}, 2.);
+ simplexTree.insert_simplex({1, 2}, 3.);
+ simplexTree.insert_simplex({1, 3}, 4.);
+ simplexTree.insert_simplex({2, 3}, 5.);
+ simplexTree.insert_simplex({2, 4}, 6.);
+ simplexTree.insert_simplex({3, 6}, 7.);
+ simplexTree.insert_simplex({4, 5}, 8.);
+ simplexTree.insert_simplex({4, 6}, 9.);
+ simplexTree.insert_simplex({5, 6}, 10.);
+ simplexTree.insert_simplex({6}, 10.);
+
+ simplexTree.expansion_with_blockers(3, [&](Simplex_handle sh){
+ bool result = false;
+ std::cout << "Blocker on [";
+ // User can loop on the vertices from the given simplex_handle i.e.
+ for (auto vertex : simplexTree.simplex_vertex_range(sh)) {
+ // We block the expansion, if the vertex '6' is in the given list of vertices
+ if (vertex == 6)
+ result = true;
+ std::cout << vertex << ", ";
+ }
+ std::cout << "] ( " << simplexTree.filtration(sh);
+ // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries)
+ simplexTree.assign_filtration(sh, simplexTree.filtration(sh) + 1.);
+
+ std::cout << " + 1. ) = " << result << std::endl;
+
+ return result;
+ });
+
+ std::cout << "********************************************************************\n";
+ std::cout << "* The complex contains " << simplexTree.num_simplices() << " simplices";
+ std::cout << " - dimension " << simplexTree.dimension() << "\n";
+ std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplexTree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplexTree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/Simplex_tree/example/mini_simplex_tree.cpp b/src/Simplex_tree/example/mini_simplex_tree.cpp
index ad99df23..19e45361 100644
--- a/src/Simplex_tree/example/mini_simplex_tree.cpp
+++ b/src/Simplex_tree/example/mini_simplex_tree.cpp
@@ -52,8 +52,6 @@ int main() {
auto edge03 = {0, 3};
st.insert_simplex_and_subfaces(triangle012);
st.insert_simplex_and_subfaces(edge03);
- // FIXME: Remove this line
- st.set_dimension(2);
auto edge02 = {0, 2};
ST::Simplex_handle e = st.find(edge02);
diff --git a/src/Simplex_tree/example/simple_simplex_tree.cpp b/src/Simplex_tree/example/simple_simplex_tree.cpp
index d8318f03..b6b65b88 100644
--- a/src/Simplex_tree/example/simple_simplex_tree.cpp
+++ b/src/Simplex_tree/example/simple_simplex_tree.cpp
@@ -185,7 +185,6 @@ int main(int argc, char * const argv[]) {
}
// ++ GENERAL VARIABLE SET
- simplexTree.set_dimension(2); // Max dimension = 2 -> (2,1,0)
std::cout << "********************************************************************\n";
// Display the Simplex_tree - Can not be done in the middle of 2 inserts
@@ -194,9 +193,8 @@ int main(int argc, char * const argv[]) {
std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
for (auto f_simplex : simplexTree.filtration_simplex_range()) {
std::cout << " " << "[" << simplexTree.filtration(f_simplex) << "] ";
- for (auto vertex : simplexTree.simplex_vertex_range(f_simplex)) {
- std::cout << static_cast<int>(vertex) << " ";
- }
+ for (auto vertex : simplexTree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
std::cout << std::endl;
}
// [0.1] 0
@@ -249,5 +247,34 @@ int main(int argc, char * const argv[]) {
std::cout << "***+ YES IT IS!\n";
else
std::cout << "***- NO IT ISN'T\n";
+
+ simplexFound = simplexTree.find({ 0, 1 });
+ std::cout << "**************IS THE SIMPLEX {0,1} IN THE SIMPLEX TREE ?\n";
+ if (simplexFound != simplexTree.null_simplex())
+ std::cout << "***+ YES IT IS!\n";
+ else
+ std::cout << "***- NO IT ISN'T\n";
+
+ std::cout << "**************COFACES OF {0,1} IN CODIMENSION 1 ARE\n";
+ for (auto& simplex : simplexTree.cofaces_simplex_range(simplexTree.find({0,1}), 1)) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ std::cout << "**************STARS OF {0,1} ARE\n";
+ for (auto& simplex : simplexTree.star_simplex_range(simplexTree.find({0,1}))) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ std::cout << "**************BOUNDARIES OF {0,1,2} ARE\n";
+ for (auto& simplex : simplexTree.boundary_simplex_range(simplexTree.find({0,1,2}))) {
+ for (auto vertex : simplexTree.simplex_vertex_range(simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
return 0;
}
diff --git a/src/Simplex_tree/include/gudhi/Simplex_tree.h b/src/Simplex_tree/include/gudhi/Simplex_tree.h
index 37b3ea97..7da767cb 100644
--- a/src/Simplex_tree/include/gudhi/Simplex_tree.h
+++ b/src/Simplex_tree/include/gudhi/Simplex_tree.h
@@ -482,7 +482,17 @@ class Simplex_tree {
}
/** \brief Returns an upper bound on the dimension of the simplicial complex. */
- int dimension() const {
+ int upper_bound_dimension() const {
+ return dimension_;
+ }
+
+ /** \brief Returns the dimension of the simplicial complex.
+ \details This function is not constant time because it can recompute dimension if required (can be triggered by
+ `remove_maximal_simplex()` or `prune_above_filtration()`).
+ */
+ int dimension() {
+ if (dimension_to_be_lowered_)
+ lower_upper_bound_dimension();
return dimension_;
}
@@ -591,7 +601,11 @@ class Simplex_tree {
// if filtration value unchanged
return std::pair<Simplex_handle, bool>(null_simplex(), false);
}
- // otherwise the insertion has succeeded
+ // otherwise the insertion has succeeded - size is a size_type
+ if (static_cast<int>(simplex.size()) - 1 > dimension_) {
+ // Update dimension if needed
+ dimension_ = static_cast<int>(simplex.size()) - 1;
+ }
return res_insert;
}
@@ -1067,6 +1081,118 @@ class Simplex_tree {
}
public:
+ /** \brief Expands a simplex tree containing only a graph. Simplices corresponding to cliques in the graph are added
+ * incrementally, faces before cofaces, unless the simplex has dimension larger than `max_dim` or `block_simplex`
+ * returns true for this simplex.
+ *
+ * @param[in] max_dim Expansion maximal dimension value.
+ * @param[in] block_simplex Blocker oracle. Its concept is <CODE>bool block_simplex(Simplex_handle sh)</CODE>
+ *
+ * The function identifies a candidate simplex whose faces are all already in the complex, inserts
+ * it with a filtration value corresponding to the maximum of the filtration values of the faces, then calls
+ * `block_simplex` on a `Simplex_handle` for this new simplex. If `block_simplex` returns true, the simplex is
+ * removed, otherwise it is kept. Note that the evaluation of `block_simplex` is a good time to update the
+ * filtration value of the simplex if you want a customized value. The algorithm then proceeds with the next
+ * candidate.
+ *
+ * @warning several candidates of the same dimension may be inserted simultaneously before calling `block_simplex`,
+ * so if you examine the complex in `block_simplex`, you may hit a few simplices of the same dimension that have not
+ * been vetted by `block_simplex` yet, or have already been rejected but not yet removed.
+ */
+ template< typename Blocker >
+ void expansion_with_blockers(int max_dim, Blocker block_simplex) {
+ // Loop must be from the end to the beginning, as higher dimension simplex are always on the left part of the tree
+ for (auto& simplex : boost::adaptors::reverse(root_.members())) {
+ if (has_children(&simplex)) {
+ siblings_expansion_with_blockers(simplex.second.children(), max_dim, max_dim - 1, block_simplex);
+ }
+ }
+ }
+
+ private:
+ /** \brief Recursive expansion with blockers of the simplex tree.*/
+ template< typename Blocker >
+ void siblings_expansion_with_blockers(Siblings* siblings, int max_dim, int k, Blocker block_simplex) {
+ if (dimension_ < max_dim - k) {
+ dimension_ = max_dim - k;
+ }
+ if (k == 0)
+ return;
+ // No need to go deeper
+ if (siblings->members().size() < 2)
+ return;
+ // Reverse loop starting before the last one for 'next' to be the last one
+ for (auto simplex = siblings->members().rbegin() + 1; simplex != siblings->members().rend(); simplex++) {
+ std::vector<std::pair<Vertex_handle, Node> > intersection;
+ for(auto next = siblings->members().rbegin(); next != simplex; next++) {
+ bool to_be_inserted = true;
+ Filtration_value filt = simplex->second.filtration();
+ // If all the boundaries are present, 'next' needs to be inserted
+ for (Simplex_handle border : boundary_simplex_range(simplex)) {
+ Simplex_handle border_child = find_child(border, next->first);
+ if (border_child == null_simplex()) {
+ to_be_inserted=false;
+ break;
+ }
+ filt = std::max(filt, filtration(border_child));
+ }
+ if (to_be_inserted) {
+ intersection.emplace_back(next->first, Node(nullptr, filt));
+ }
+ }
+ if (intersection.size() != 0) {
+ // Reverse the order to insert
+ Siblings * new_sib = new Siblings(siblings, // oncles
+ simplex->first, // parent
+ boost::adaptors::reverse(intersection)); // boost::container::ordered_unique_range_t
+ std::vector<Simplex_handle> blocked_new_sib_list;
+ // As all intersections are inserted, we can call the blocker function on all new_sib members
+ for (auto new_sib_member = new_sib->members().begin();
+ new_sib_member != new_sib->members().end();
+ new_sib_member++) {
+ bool blocker_result = block_simplex(new_sib_member);
+ // new_sib member has been blocked by the blocker function
+ // add it to the list to be removed - do not perform it while looping on it
+ if (blocker_result)
+ blocked_new_sib_list.push_back(new_sib_member);
+ }
+ bool removed = false;
+ for (auto& blocked_new_sib_member : blocked_new_sib_list){
+ removed = removed || remove_maximal_simplex(blocked_new_sib_member);
+ }
+ if (removed) {
+ // ensure the children property
+ simplex->second.assign_children(siblings);
+ } else {
+ // ensure recursive call
+ simplex->second.assign_children(new_sib);
+ siblings_expansion_with_blockers(new_sib, max_dim, k - 1, block_simplex);
+ }
+ } else {
+ // ensure the children property
+ simplex->second.assign_children(siblings);
+ }
+ }
+ }
+
+ /* \private Returns the Simplex_handle composed of the vertex list (from the Simplex_handle), plus the given
+ * Vertex_handle if the Vertex_handle is found in the Simplex_handle children list.
+ * Returns null_simplex() if it does not exist
+ */
+ Simplex_handle find_child(Simplex_handle sh, Vertex_handle vh) const {
+ if (!has_children(sh))
+ return null_simplex();
+
+ Simplex_handle child = sh->second.children()->find(vh);
+ // Specific case of boost::flat_map does not find, returns boost::flat_map::end()
+ // in simplex tree we want a null_simplex()
+ if (child == sh->second.children()->members().end())
+ return null_simplex();
+
+ return child;
+ }
+
+ public:
/** \brief Write the hasse diagram of the simplicial complex in os.
*
* Each row in the file correspond to a simplex. A line is written:
@@ -1142,6 +1268,9 @@ class Simplex_tree {
* \post Some simplex tree functions require the filtration to be valid. `prune_above_filtration()`
* function is not launching `initialize_filtration()` but returns the filtration modification information. If the
* complex has changed , please call `initialize_filtration()` to recompute it.
+ * \post Note that the dimension of the simplicial complex may be lower after calling `prune_above_filtration()`
+ * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper
+ * bound. If you care, you can call `dimension()` to recompute the exact dimension.
*/
bool prune_above_filtration(Filtration_value filtration) {
return rec_prune_above_filtration(root(), filtration);
@@ -1153,6 +1282,8 @@ class Simplex_tree {
auto last = std::remove_if(list.begin(), list.end(), [=](Dit_value_t& simplex) {
if (simplex.second.filtration() <= filt) return false;
if (has_children(&simplex)) rec_delete(simplex.second.children());
+ // dimension may need to be lowered
+ dimension_to_be_lowered_ = true;
return true;
});
@@ -1161,6 +1292,8 @@ class Simplex_tree {
// Removing the whole siblings, parent becomes a leaf.
sib->oncles()->members()[sib->parent()].assign_children(sib->oncles());
delete sib;
+ // dimension may need to be lowered
+ dimension_to_be_lowered_ = true;
return true;
} else {
// Keeping some elements of siblings. Remove the others, and recurse in the remaining ones.
@@ -1172,14 +1305,49 @@ class Simplex_tree {
return modified;
}
+ private:
+ /** \brief Deep search simplex tree dimension recompute.
+ * @return True if the dimension was modified, false otherwise.
+ * \pre Be sure the simplex tree has not a too low dimension value as the deep search stops when the former dimension
+ * has been reached (cf. `upper_bound_dimension()` and `set_dimension()` methods).
+ */
+ bool lower_upper_bound_dimension() {
+ // reset automatic detection to recompute
+ dimension_to_be_lowered_ = false;
+ int new_dimension = -1;
+ // Browse the tree from the left to the right as higher dimension cells are more likely on the left part of the tree
+ for (Simplex_handle sh : complex_simplex_range()) {
+#ifdef DEBUG_TRACES
+ for (auto vertex : simplex_vertex_range(sh)) {
+ std::cout << " " << vertex;
+ }
+ std::cout << std::endl;
+#endif // DEBUG_TRACES
+
+ int sh_dimension = dimension(sh);
+ if (sh_dimension >= dimension_)
+ // Stop browsing as soon as the dimension is reached, no need to go furter
+ return false;
+ new_dimension = std::max(new_dimension, sh_dimension);
+ }
+ dimension_ = new_dimension;
+ return true;
+ }
+
+
public:
/** \brief Remove a maximal simplex.
* @param[in] sh Simplex handle on the maximal simplex to remove.
+ * @return a boolean value that is an implementation detail, and that the user is supposed to ignore
* \pre Please check the simplex has no coface before removing it.
* \exception std::invalid_argument In debug mode, if sh has children.
- * \post Be aware that removing is shifting data in a flat_map (initialize_filtration to be done).
+ * \post Be aware that removing is shifting data in a flat_map (`initialize_filtration()` to be done).
+ * \post Note that the dimension of the simplicial complex may be lower after calling `remove_maximal_simplex()`
+ * than it was before. However, `upper_bound_dimension()` will return the old value, which remains a valid upper
+ * bound. If you care, you can call `dimension()` to recompute the exact dimension.
+ * \internal @return true if the leaf's branch has no other leaves (branch's children has been re-assigned), false otherwise.
*/
- void remove_maximal_simplex(Simplex_handle sh) {
+ bool remove_maximal_simplex(Simplex_handle sh) {
// Guarantee the simplex has no children
GUDHI_CHECK(!has_children(sh),
std::invalid_argument("Simplex_tree::remove_maximal_simplex - argument has children"));
@@ -1195,7 +1363,11 @@ class Simplex_tree {
// Sibling is emptied : must be deleted, and its parent must point on his own Sibling
child->oncles()->members().at(child->parent()).assign_children(child->oncles());
delete child;
+ // dimension may need to be lowered
+ dimension_to_be_lowered_ = true;
+ return true;
}
+ return false;
}
private:
@@ -1207,6 +1379,7 @@ class Simplex_tree {
std::vector<Simplex_handle> filtration_vect_;
/** \brief Upper bound on the dimension of the simplicial complex.*/
int dimension_;
+ bool dimension_to_be_lowered_ = false;
};
// Print a Simplex_tree in os.
diff --git a/src/Simplex_tree/test/CMakeLists.txt b/src/Simplex_tree/test/CMakeLists.txt
index 81999de6..8684ad2a 100644
--- a/src/Simplex_tree/test/CMakeLists.txt
+++ b/src/Simplex_tree/test/CMakeLists.txt
@@ -3,13 +3,29 @@ project(Simplex_tree_tests)
include(GUDHI_test_coverage)
+# Do not forget to copy test files in current binary dir
+file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
+
add_executable ( Simplex_tree_test_unit simplex_tree_unit_test.cpp )
target_link_libraries(Simplex_tree_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
if (TBB_FOUND)
target_link_libraries(Simplex_tree_test_unit ${TBB_LIBRARIES})
endif()
-# Do not forget to copy test files in current binary dir
-file(COPY "simplex_tree_for_unit_test.txt" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/)
-
gudhi_add_coverage_test(Simplex_tree_test_unit)
+
+add_executable ( Simplex_tree_remove_test_unit simplex_tree_remove_unit_test.cpp )
+target_link_libraries(Simplex_tree_remove_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Simplex_tree_remove_test_unit ${TBB_LIBRARIES})
+endif()
+
+gudhi_add_coverage_test(Simplex_tree_remove_test_unit)
+
+add_executable ( Simplex_tree_iostream_operator_test_unit simplex_tree_iostream_operator_unit_test.cpp )
+target_link_libraries(Simplex_tree_iostream_operator_test_unit ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
+if (TBB_FOUND)
+ target_link_libraries(Simplex_tree_iostream_operator_test_unit ${TBB_LIBRARIES})
+endif()
+
+gudhi_add_coverage_test(Simplex_tree_iostream_operator_test_unit)
diff --git a/src/Simplex_tree/test/README b/src/Simplex_tree/test/README
index 21c3d871..df2ab89a 100644
--- a/src/Simplex_tree/test/README
+++ b/src/Simplex_tree/test/README
@@ -9,6 +9,6 @@ make
To launch with details:
***********************
-./SimplexTreeUT --report_level=detailed --log_level=all
+./Simplex_tree_test_unit --report_level=detailed --log_level=all
==> echo $? returns 0 in case of success (non-zero otherwise)
diff --git a/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp
new file mode 100644
index 00000000..19ce3321
--- /dev/null
+++ b/src/Simplex_tree/test/simplex_tree_graph_expansion_unit_test.cpp
@@ -0,0 +1,235 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <algorithm>
+#include <utility> // std::pair, std::make_pair
+#include <cmath> // float comparison
+#include <limits>
+#include <functional> // greater
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "simplex_tree"
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+// ^
+// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined.
+#include "gudhi/Simplex_tree.h"
+
+using namespace Gudhi;
+
+typedef boost::mpl::list<Simplex_tree<>, Simplex_tree<Simplex_tree_options_fast_persistence>> list_of_tested_variants;
+
+
+bool AreAlmostTheSame(float a, float b) {
+ return std::fabs(a - b) < std::numeric_limits<float>::epsilon();
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_3, typeST, list_of_tested_variants) {
+ using Simplex_handle = typename typeST::Simplex_handle;
+ // Construct the Simplex Tree with a 1-skeleton graph example
+ typeST simplex_tree;
+
+ simplex_tree.insert_simplex({0, 1}, 0.);
+ simplex_tree.insert_simplex({0, 2}, 1.);
+ simplex_tree.insert_simplex({0, 3}, 2.);
+ simplex_tree.insert_simplex({1, 2}, 3.);
+ simplex_tree.insert_simplex({1, 3}, 4.);
+ simplex_tree.insert_simplex({2, 3}, 5.);
+ simplex_tree.insert_simplex({2, 4}, 6.);
+ simplex_tree.insert_simplex({3, 6}, 7.);
+ simplex_tree.insert_simplex({4, 5}, 8.);
+ simplex_tree.insert_simplex({4, 6}, 9.);
+ simplex_tree.insert_simplex({5, 6}, 10.);
+ simplex_tree.insert_simplex({6}, 10.);
+
+ simplex_tree.expansion_with_blockers(3, [&](Simplex_handle sh){
+ bool result = false;
+ std::cout << "Blocker on [";
+ // User can loop on the vertices from the given simplex_handle i.e.
+ for (auto vertex : simplex_tree.simplex_vertex_range(sh)) {
+ // We block the expansion, if the vertex '6' is in the given list of vertices
+ if (vertex == 6)
+ result = true;
+ std::cout << vertex << ", ";
+ }
+ std::cout << "] ( " << simplex_tree.filtration(sh);
+ // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries)
+ simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.);
+
+ std::cout << " + 1. ) = " << result << std::endl;
+
+ return result;
+ });
+
+ std::cout << "********************************************************************\n";
+ std::cout << "simplex_tree_expansion_with_blockers_3\n";
+ std::cout << "********************************************************************\n";
+ std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices";
+ std::cout << " - dimension " << simplex_tree.dimension() << "\n";
+ std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(simplex_tree.num_simplices() == 23);
+ BOOST_CHECK(simplex_tree.dimension() == 3);
+ // {4, 5, 6} shall be blocked
+ BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex());
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 7.));
+
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_with_blockers_2, typeST, list_of_tested_variants) {
+ using Simplex_handle = typename typeST::Simplex_handle;
+ // Construct the Simplex Tree with a 1-skeleton graph example
+ typeST simplex_tree;
+
+ simplex_tree.insert_simplex({0, 1}, 0.);
+ simplex_tree.insert_simplex({0, 2}, 1.);
+ simplex_tree.insert_simplex({0, 3}, 2.);
+ simplex_tree.insert_simplex({1, 2}, 3.);
+ simplex_tree.insert_simplex({1, 3}, 4.);
+ simplex_tree.insert_simplex({2, 3}, 5.);
+ simplex_tree.insert_simplex({2, 4}, 6.);
+ simplex_tree.insert_simplex({3, 6}, 7.);
+ simplex_tree.insert_simplex({4, 5}, 8.);
+ simplex_tree.insert_simplex({4, 6}, 9.);
+ simplex_tree.insert_simplex({5, 6}, 10.);
+ simplex_tree.insert_simplex({6}, 10.);
+
+ simplex_tree.expansion_with_blockers(2, [&](Simplex_handle sh){
+ bool result = false;
+ std::cout << "Blocker on [";
+ // User can loop on the vertices from the given simplex_handle i.e.
+ for (auto vertex : simplex_tree.simplex_vertex_range(sh)) {
+ // We block the expansion, if the vertex '6' is in the given list of vertices
+ if (vertex == 6)
+ result = true;
+ std::cout << vertex << ", ";
+ }
+ std::cout << "] ( " << simplex_tree.filtration(sh);
+ // User can re-assign a new filtration value directly in the blocker (default is the maximal value of boudaries)
+ simplex_tree.assign_filtration(sh, simplex_tree.filtration(sh) + 1.);
+
+ std::cout << " + 1. ) = " << result << std::endl;
+
+ return result;
+ });
+
+ std::cout << "********************************************************************\n";
+ std::cout << "simplex_tree_expansion_with_blockers_2\n";
+ std::cout << "********************************************************************\n";
+ std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices";
+ std::cout << " - dimension " << simplex_tree.dimension() << "\n";
+ std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(simplex_tree.num_simplices() == 22);
+ BOOST_CHECK(simplex_tree.dimension() == 2);
+ // {4, 5, 6} shall be blocked
+ BOOST_CHECK(simplex_tree.find({4, 5, 6}) == simplex_tree.null_simplex());
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 4.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 5.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 6.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 6.));
+ BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex());
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion, typeST, list_of_tested_variants) {
+ // Construct the Simplex Tree with a 1-skeleton graph example
+ typeST simplex_tree;
+
+ simplex_tree.insert_simplex({0, 1}, 0.);
+ simplex_tree.insert_simplex({0, 2}, 1.);
+ simplex_tree.insert_simplex({0, 3}, 2.);
+ simplex_tree.insert_simplex({1, 2}, 3.);
+ simplex_tree.insert_simplex({1, 3}, 4.);
+ simplex_tree.insert_simplex({2, 3}, 5.);
+ simplex_tree.insert_simplex({2, 4}, 6.);
+ simplex_tree.insert_simplex({3, 6}, 7.);
+ simplex_tree.insert_simplex({4, 5}, 8.);
+ simplex_tree.insert_simplex({4, 6}, 9.);
+ simplex_tree.insert_simplex({5, 6}, 10.);
+ simplex_tree.insert_simplex({6}, 10.);
+
+ simplex_tree.expansion(3);
+ std::cout << "********************************************************************\n";
+ std::cout << "simplex_tree_expansion_3\n";
+ std::cout << "********************************************************************\n";
+ std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices";
+ std::cout << " - dimension " << simplex_tree.dimension() << "\n";
+ std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(simplex_tree.num_simplices() == 24);
+ BOOST_CHECK(simplex_tree.dimension() == 3);
+
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2,3})), 5.));
+
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_expansion_2, typeST, list_of_tested_variants) {
+ // Construct the Simplex Tree with a 1-skeleton graph example
+ typeST simplex_tree;
+
+ simplex_tree.insert_simplex({0, 1}, 0.);
+ simplex_tree.insert_simplex({0, 2}, 1.);
+ simplex_tree.insert_simplex({0, 3}, 2.);
+ simplex_tree.insert_simplex({1, 2}, 3.);
+ simplex_tree.insert_simplex({1, 3}, 4.);
+ simplex_tree.insert_simplex({2, 3}, 5.);
+ simplex_tree.insert_simplex({2, 4}, 6.);
+ simplex_tree.insert_simplex({3, 6}, 7.);
+ simplex_tree.insert_simplex({4, 5}, 8.);
+ simplex_tree.insert_simplex({4, 6}, 9.);
+ simplex_tree.insert_simplex({5, 6}, 10.);
+ simplex_tree.insert_simplex({6}, 10.);
+
+ simplex_tree.expansion(2);
+
+ std::cout << "********************************************************************\n";
+ std::cout << "simplex_tree_expansion_2\n";
+ std::cout << "********************************************************************\n";
+ std::cout << "* The complex contains " << simplex_tree.num_simplices() << " simplices";
+ std::cout << " - dimension " << simplex_tree.dimension() << "\n";
+ std::cout << "* Iterator on Simplices in the filtration, with [filtration value]:\n";
+ for (auto f_simplex : simplex_tree.filtration_simplex_range()) {
+ std::cout << " " << "[" << simplex_tree.filtration(f_simplex) << "] ";
+ for (auto vertex : simplex_tree.simplex_vertex_range(f_simplex))
+ std::cout << "(" << vertex << ")";
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(simplex_tree.num_simplices() == 23);
+ BOOST_CHECK(simplex_tree.dimension() == 2);
+
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({4,5,6})), 10.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,2})), 3.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,1,3})), 4.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({0,2,3})), 5.));
+ BOOST_CHECK(AreAlmostTheSame(simplex_tree.filtration(simplex_tree.find({1,2,3})), 5.));
+ BOOST_CHECK(simplex_tree.find({0,1,2,3}) == simplex_tree.null_simplex());
+}
diff --git a/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp
new file mode 100644
index 00000000..ecb9f025
--- /dev/null
+++ b/src/Simplex_tree/test/simplex_tree_iostream_operator_unit_test.cpp
@@ -0,0 +1,136 @@
+#include <iostream>
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "simplex_tree_iostream_operator"
+#include <boost/test/unit_test.hpp>
+#include <boost/mpl/list.hpp>
+
+// ^
+// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined.
+#include "gudhi/Simplex_tree.h"
+
+using namespace Gudhi;
+
+struct MyOptions : Simplex_tree_options_full_featured {
+ // Not doing persistence, so we don't need those
+ static const bool store_key = false;
+ static const bool store_filtration = false;
+ // I have few vertices
+ typedef short Vertex_handle;
+};
+
+typedef boost::mpl::list<Simplex_tree<>,
+ Simplex_tree<Simplex_tree_options_fast_persistence>
+ > list_of_tested_variants;
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(iostream_operator, Stree_type, list_of_tested_variants) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "SIMPLEX TREE IOSTREAM OPERATOR" << std::endl;
+
+ Stree_type st;
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7}, 4.0);
+ st.insert_simplex_and_subfaces({3, 4, 5}, 3.0);
+ st.insert_simplex_and_subfaces({3, 0}, 2.0);
+ st.insert_simplex_and_subfaces({2, 1, 0}, 3.0);
+
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices - dimension = "
+ << st.dimension() << std::endl;
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ // st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt");
+ std::ofstream simplex_tree_ostream(iostream_file.c_str());
+ simplex_tree_ostream << st;
+ simplex_tree_ostream.close();
+
+ Stree_type read_st;
+ std::ifstream simplex_tree_istream(iostream_file.c_str());
+ simplex_tree_istream >> read_st;
+
+ // Display the Simplex_tree
+ std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices - dimension = "
+ << read_st.dimension() << std::endl;
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : read_st.filtration_simplex_range()) {
+ std::cout << " " << "[" << read_st.filtration(f_simplex) << "] ";
+ for (auto vertex : read_st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(st == read_st);
+}
+
+
+BOOST_AUTO_TEST_CASE(mini_iostream_operator) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "MINI SIMPLEX TREE IOSTREAM OPERATOR" << std::endl;
+
+ Simplex_tree<MyOptions> st;
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7});
+ st.insert_simplex_and_subfaces({3, 4, 5});
+ st.insert_simplex_and_subfaces({3, 0});
+ st.insert_simplex_and_subfaces({2, 1, 0});
+
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The ORIGINAL complex contains " << st.num_simplices() << " simplices - dimension = "
+ << st.dimension() << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ // st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ std::string iostream_file("simplex_tree_for_iostream_operator_unit_test.txt");
+ std::ofstream simplex_tree_ostream(iostream_file.c_str());
+ simplex_tree_ostream << st;
+ simplex_tree_ostream.close();
+
+ Simplex_tree<MyOptions> read_st;
+ std::ifstream simplex_tree_istream(iostream_file.c_str());
+ simplex_tree_istream >> read_st;
+
+ // Display the Simplex_tree
+ std::cout << "The READ complex contains " << read_st.num_simplices() << " simplices - dimension = "
+ << read_st.dimension() << std::endl;
+ std::cout << std::endl << std::endl << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : read_st.filtration_simplex_range()) {
+ std::cout << " " << "[" << read_st.filtration(f_simplex) << "] ";
+ for (auto vertex : read_st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ BOOST_CHECK(st == read_st);
+}
diff --git a/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp
new file mode 100644
index 00000000..dc37375c
--- /dev/null
+++ b/src/Simplex_tree/test/simplex_tree_remove_unit_test.cpp
@@ -0,0 +1,427 @@
+#include <iostream>
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MODULE "simplex_tree_remove"
+#include <boost/test/unit_test.hpp>
+
+// ^
+// /!\ Nothing else from Simplex_tree shall be included to test includes are well defined.
+#include "gudhi/Simplex_tree.h"
+
+using namespace Gudhi;
+
+struct MyOptions : Simplex_tree_options_full_featured {
+ // Not doing persistence, so we don't need those
+ static const bool store_key = false;
+ static const bool store_filtration = false;
+ // I have few vertices
+ typedef short Vertex_handle;
+};
+
+using Mini_stree = Simplex_tree<MyOptions>;
+using Stree = Simplex_tree<>;
+
+BOOST_AUTO_TEST_CASE(remove_maximal_simplex) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl;
+
+ Mini_stree st;
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7});
+ st.insert_simplex_and_subfaces({3, 4, 5});
+
+ // Constructs a copy at this state for further test purpose
+ Mini_stree st_pruned = st;
+
+ st.insert_simplex_and_subfaces({3, 0});
+ st.insert_simplex_and_subfaces({2, 1, 0});
+
+ // Constructs a copy at this state for further test purpose
+ Mini_stree st_complete = st;
+ // st_complete and st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ // st_pruned:
+ // 1 6
+ // o---o
+ // \7/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+#ifdef GUDHI_DEBUG
+ std::cout << "Check exception throw in debug mode" << std::endl;
+ // throw excpt because sh has children
+ BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument);
+ BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument);
+ BOOST_CHECK(st == st_complete);
+#endif
+ std::cout << "st.remove_maximal_simplex({0, 2})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 2}));
+ std::cout << "st.remove_maximal_simplex({0, 1, 2})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 1, 2}));
+ std::cout << "st.remove_maximal_simplex({1, 2})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 2}));
+ std::cout << "st.remove_maximal_simplex({2})" << std::endl;
+ st.remove_maximal_simplex(st.find({2}));
+ std::cout << "st.remove_maximal_simplex({3})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 3}));
+
+ BOOST_CHECK(st == st_pruned);
+ // Remove all, but as the simplex tree is not storing filtration, there is no modification
+ st.prune_above_filtration(0.0);
+ BOOST_CHECK(st == st_pruned);
+
+ Mini_stree st_wo_seven;
+
+ st_wo_seven.insert_simplex_and_subfaces({0, 1, 6});
+ st_wo_seven.insert_simplex_and_subfaces({3, 4, 5});
+ // st_wo_seven:
+ // 1 6
+ // o---o
+ // \X/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+ // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not)
+ std::cout << "st.remove_maximal_simplex({0, 1, 6, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 1, 6, 7}));
+ std::cout << "st.remove_maximal_simplex({0, 1, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 1, 7}));
+ std::cout << "st.remove_maximal_simplex({0, 6, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 6, 7}));
+ std::cout << "st.remove_maximal_simplex({0, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 7}));
+ std::cout << "st.remove_maximal_simplex({1, 6, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 6, 7}));
+ std::cout << "st.remove_maximal_simplex({1, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 7}));
+ std::cout << "st.remove_maximal_simplex({6, 7})" << std::endl;
+ st.remove_maximal_simplex(st.find({6, 7}));
+ std::cout << "st.remove_maximal_simplex({7})" << std::endl;
+ st.remove_maximal_simplex(st.find({7}));
+
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+
+ // Check dimension calls lower_upper_bound_dimension to recompute dimension
+ BOOST_CHECK(st.dimension() == 2);
+ BOOST_CHECK(st.upper_bound_dimension() == 2);
+
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension()
+ << " | st_wo_seven.upper_bound_dimension()=" << st_wo_seven.upper_bound_dimension() << std::endl;
+ std::cout << "st.dimension()=" << st.dimension() << " | st_wo_seven.dimension()=" << st_wo_seven.dimension() << std::endl;
+ BOOST_CHECK(st == st_wo_seven);
+}
+
+BOOST_AUTO_TEST_CASE(auto_dimension_set) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "DIMENSION ON REMOVE MAXIMAL SIMPLEX" << std::endl;
+
+ Mini_stree st;
+
+ st.insert_simplex_and_subfaces({0, 1, 2});
+ st.insert_simplex_and_subfaces({0, 1, 3});
+ st.insert_simplex_and_subfaces({1, 2, 3, 4});
+ st.insert_simplex_and_subfaces({1, 2, 3, 5});
+ st.insert_simplex_and_subfaces({6, 7, 8, 9});
+ st.insert_simplex_and_subfaces({6, 7, 8, 10});
+
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.remove_maximal_simplex({6, 7, 8, 10})" << std::endl;
+ st.remove_maximal_simplex(st.find({6, 7, 8, 10}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.remove_maximal_simplex({6, 7, 8, 9})" << std::endl;
+ st.remove_maximal_simplex(st.find({6, 7, 8, 9}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 2, 3, 4}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 2, 3, 5}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 2);
+ std::cout << "st.dimension()=" << st.dimension() << std::endl;
+
+ std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl;
+ st.insert_simplex_and_subfaces({1, 2, 3, 5});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl;
+ st.insert_simplex_and_subfaces({1, 2, 3, 4});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+
+ std::cout << "st.remove_maximal_simplex({1, 2, 3, 5})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 2, 3, 5}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+
+ std::cout << "st.remove_maximal_simplex({1, 2, 3, 4})" << std::endl;
+ st.remove_maximal_simplex(st.find({1, 2, 3, 4}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 2);
+ std::cout << "st.dimension()=" << st.dimension() << std::endl;
+
+ std::cout << "st.insert_simplex_and_subfaces({0, 1, 3, 4})" << std::endl;
+ st.insert_simplex_and_subfaces({0, 1, 3, 4});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.remove_maximal_simplex({0, 1, 3, 4})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 1, 3, 4}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 2);
+ std::cout << "st.dimension()=" << st.dimension() << std::endl;
+
+ std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 5})" << std::endl;
+ st.insert_simplex_and_subfaces({1, 2, 3, 5});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.insert_simplex_and_subfaces({1, 2, 3, 4})" << std::endl;
+ st.insert_simplex_and_subfaces({1, 2, 3, 4});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+
+ // Check you can override the dimension
+ // This is a limit test case - shall not happen
+ st.set_dimension(1);
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 1);
+ // check dimension() and lower_upper_bound_dimension() is not giving the right answer because dimension is too low
+ BOOST_CHECK(st.dimension() == 1);
+
+
+ // Check you can override the dimension
+ // This is a limit test case - shall not happen
+ st.set_dimension(6);
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 6);
+ // check dimension() do not launch lower_upper_bound_dimension()
+ BOOST_CHECK(st.dimension() == 6);
+
+
+ // Reset with the correct value
+ st.set_dimension(3);
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+ BOOST_CHECK(st.dimension() == 3);
+
+ std::cout << "st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6})" << std::endl;
+ st.insert_simplex_and_subfaces({0, 1, 2, 3, 4, 5, 6});
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 6);
+ BOOST_CHECK(st.dimension() == 6);
+
+ std::cout << "st.remove_maximal_simplex({0, 1, 2, 3, 4, 5, 6})" << std::endl;
+ st.remove_maximal_simplex(st.find({0, 1, 2, 3, 4, 5, 6}));
+ std::cout << "st.upper_bound_dimension()=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 6);
+ BOOST_CHECK(st.dimension() == 5);
+
+}
+
+BOOST_AUTO_TEST_CASE(prune_above_filtration) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "PRUNE ABOVE FILTRATION" << std::endl;
+
+ Stree st;
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);
+ st.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
+
+ // Constructs a copy at this state for further test purpose
+ Stree st_pruned = st;
+ st_pruned.initialize_filtration(); // reset
+
+ st.insert_simplex_and_subfaces({3, 0}, 3.0);
+ st.insert_simplex_and_subfaces({2, 1, 0}, 4.0);
+
+ // Constructs a copy at this state for further test purpose
+ Stree st_complete = st;
+ // st_complete and st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+ // st_pruned:
+ // 1 6
+ // o---o
+ // \7/
+ // o o---o
+ // 0 3\X/4
+ // o
+ // 5
+
+ bool simplex_is_changed = false;
+ // Check the no action cases
+ // greater than initial filtration value
+ simplex_is_changed = st.prune_above_filtration(10.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+ // equal to initial filtration value
+ simplex_is_changed = st.prune_above_filtration(6.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+ // lower than initial filtration value, but still greater than the maximum filtration value
+ simplex_is_changed = st.prune_above_filtration(5.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_complete);
+ BOOST_CHECK(!simplex_is_changed);
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+ std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
+ for (auto f_simplex : st.filtration_simplex_range()) {
+ std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
+ for (auto vertex : st.simplex_vertex_range(f_simplex)) {
+ std::cout << (int) vertex << " ";
+ }
+ std::cout << std::endl;
+ }
+
+ // Check the pruned cases
+ simplex_is_changed = st.prune_above_filtration(2.5);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_pruned);
+ BOOST_CHECK(simplex_is_changed);
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+
+ simplex_is_changed = st.prune_above_filtration(2.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+
+ std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices";
+ std::cout << " - dimension " << st.dimension() << std::endl;
+
+ BOOST_CHECK(st == st_pruned);
+ BOOST_CHECK(!simplex_is_changed);
+
+ Stree st_empty;
+ simplex_is_changed = st.prune_above_filtration(0.0);
+ BOOST_CHECK(simplex_is_changed == true);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices";
+ std::cout << " - upper_bound_dimension " << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == 3);
+
+ BOOST_CHECK(st.dimension() == -1);
+ std::cout << "upper_bound_dimension=" << st.upper_bound_dimension() << std::endl;
+ BOOST_CHECK(st.upper_bound_dimension() == -1);
+
+ BOOST_CHECK(st == st_empty);
+ BOOST_CHECK(simplex_is_changed);
+
+ // Test case to the limit
+ simplex_is_changed = st.prune_above_filtration(-1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ BOOST_CHECK(st == st_empty);
+ BOOST_CHECK(!simplex_is_changed);
+}
+
+BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) {
+ std::cout << "********************************************************************" << std::endl;
+ std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl;
+
+ Mini_stree st;
+
+ st.insert_simplex_and_subfaces({0, 1, 6, 7});
+ st.insert_simplex_and_subfaces({3, 4, 5});
+ st.insert_simplex_and_subfaces({3, 0});
+ st.insert_simplex_and_subfaces({2, 1, 0});
+
+ // st:
+ // 1 6
+ // o---o
+ // /X\7/
+ // o---o---o---o
+ // 2 0 3\X/4
+ // o
+ // 5
+
+ st.initialize_filtration();
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ // Test case to the limit - With these options, there is no filtration, which means filtration is 0
+ bool simplex_is_changed = st.prune_above_filtration(1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(!simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ simplex_is_changed = st.prune_above_filtration(0.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(!simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 27);
+
+ // Test case to the limit
+ simplex_is_changed = st.prune_above_filtration(-1.0);
+ if (simplex_is_changed)
+ st.initialize_filtration();
+ // Display the Simplex_tree
+ std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl;
+ BOOST_CHECK(simplex_is_changed);
+ BOOST_CHECK(st.num_simplices() == 0);
+
+ // Display the Simplex_tree
+ std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
+
+}
diff --git a/src/Simplex_tree/test/simplex_tree_unit_test.cpp b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
index 17ddc605..580d610a 100644
--- a/src/Simplex_tree/test/simplex_tree_unit_test.cpp
+++ b/src/Simplex_tree/test/simplex_tree_unit_test.cpp
@@ -297,6 +297,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(simplex_tree_insertion, typeST, list_of_tested_var
// Simplex_handle = boost::container::flat_map< typeST::Vertex_handle, Node >::iterator
typename typeST::Simplex_handle shReturned = returnValue.first;
BOOST_CHECK(shReturned == typename typeST::Simplex_handle(nullptr));
+ std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl;
BOOST_CHECK(st.num_vertices() == (size_t) 4); // Not incremented !!
BOOST_CHECK(st.dimension() == dim_max);
@@ -617,9 +618,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(coface_on_simplex_tree, typeST, list_of_tested_var
/* o */
/* 5 */
- // FIXME
- st.set_dimension(3);
-
std::vector<typename typeST::Vertex_handle> simplex_result;
std::vector<typename typeST::Simplex_handle> result;
std::cout << "First test - Star of (3):" << std::endl;
@@ -716,9 +714,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(copy_move_on_simplex_tree, typeST, list_of_tested_
/* o */
/* 5 */
- // FIXME
- st.set_dimension(3);
-
std::cout << "Printing st - address = " << &st << std::endl;
// Copy constructor
@@ -868,271 +863,3 @@ BOOST_AUTO_TEST_CASE(make_filtration_non_decreasing) {
BOOST_CHECK(st == st_other_copy);
}
-
-struct MyOptions : Simplex_tree_options_full_featured {
- // Not doing persistence, so we don't need those
- static const bool store_key = false;
- static const bool store_filtration = false;
- // I have few vertices
- typedef short Vertex_handle;
-};
-
-BOOST_AUTO_TEST_CASE(remove_maximal_simplex) {
- std::cout << "********************************************************************" << std::endl;
- std::cout << "REMOVE MAXIMAL SIMPLEX" << std::endl;
-
-
- typedef Simplex_tree<MyOptions> miniST;
- miniST st;
-
- // FIXME
- st.set_dimension(3);
-
- st.insert_simplex_and_subfaces({0, 1, 6, 7});
- st.insert_simplex_and_subfaces({3, 4, 5});
-
- // Constructs a copy at this state for further test purpose
- miniST st_pruned = st;
-
- st.insert_simplex_and_subfaces({3, 0});
- st.insert_simplex_and_subfaces({2, 1, 0});
-
- // Constructs a copy at this state for further test purpose
- miniST st_complete = st;
- // st_complete and st:
- // 1 6
- // o---o
- // /X\7/
- // o---o---o---o
- // 2 0 3\X/4
- // o
- // 5
- // st_pruned:
- // 1 6
- // o---o
- // \7/
- // o o---o
- // 0 3\X/4
- // o
- // 5
-
-#ifdef GUDHI_DEBUG
- std::cout << "Check exception throw in debug mode" << std::endl;
- // throw excpt because sh has children
- BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({0, 1, 6})), std::invalid_argument);
- BOOST_CHECK_THROW (st.remove_maximal_simplex(st.find({3})), std::invalid_argument);
- BOOST_CHECK(st == st_complete);
-#endif
-
- st.remove_maximal_simplex(st.find({0, 2}));
- st.remove_maximal_simplex(st.find({0, 1, 2}));
- st.remove_maximal_simplex(st.find({1, 2}));
- st.remove_maximal_simplex(st.find({2}));
- st.remove_maximal_simplex(st.find({0, 3}));
-
- BOOST_CHECK(st == st_pruned);
- // Remove all, but as the simplex tree is not storing filtration, there is no modification
- st.prune_above_filtration(0.0);
- BOOST_CHECK(st == st_pruned);
-
- miniST st_wo_seven;
- // FIXME
- st_wo_seven.set_dimension(3);
-
- st_wo_seven.insert_simplex_and_subfaces({0, 1, 6});
- st_wo_seven.insert_simplex_and_subfaces({3, 4, 5});
- // st_wo_seven:
- // 1 6
- // o---o
- // \X/
- // o o---o
- // 0 3\X/4
- // o
- // 5
-
- // Remove all 7 to test the both remove_maximal_simplex cases (when _members is empty or not)
- st.remove_maximal_simplex(st.find({0, 1, 6, 7}));
- st.remove_maximal_simplex(st.find({0, 1, 7}));
- st.remove_maximal_simplex(st.find({0, 6, 7}));
- st.remove_maximal_simplex(st.find({0, 7}));
- st.remove_maximal_simplex(st.find({1, 6, 7}));
- st.remove_maximal_simplex(st.find({1, 7}));
- st.remove_maximal_simplex(st.find({6, 7}));
- st.remove_maximal_simplex(st.find({7}));
-
- BOOST_CHECK(st == st_wo_seven);
-}
-
-BOOST_AUTO_TEST_CASE(prune_above_filtration) {
- std::cout << "********************************************************************" << std::endl;
- std::cout << "PRUNE ABOVE FILTRATION" << std::endl;
- typedef Simplex_tree<> typeST;
- typeST st;
-
- // FIXME
- st.set_dimension(3);
-
- st.insert_simplex_and_subfaces({0, 1, 6, 7}, 1.0);
- st.insert_simplex_and_subfaces({3, 4, 5}, 2.0);
-
- // Constructs a copy at this state for further test purpose
- typeST st_pruned = st;
- st_pruned.initialize_filtration(); // reset
-
- st.insert_simplex_and_subfaces({3, 0}, 3.0);
- st.insert_simplex_and_subfaces({2, 1, 0}, 4.0);
-
- // Constructs a copy at this state for further test purpose
- typeST st_complete = st;
- // st_complete and st:
- // 1 6
- // o---o
- // /X\7/
- // o---o---o---o
- // 2 0 3\X/4
- // o
- // 5
- // st_pruned:
- // 1 6
- // o---o
- // \7/
- // o o---o
- // 0 3\X/4
- // o
- // 5
-
- bool simplex_is_changed = false;
- // Check the no action cases
- // greater than initial filtration value
- simplex_is_changed = st.prune_above_filtration(10.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- BOOST_CHECK(st == st_complete);
- BOOST_CHECK(!simplex_is_changed);
- // equal to initial filtration value
- simplex_is_changed = st.prune_above_filtration(6.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- BOOST_CHECK(st == st_complete);
- BOOST_CHECK(!simplex_is_changed);
- // lower than initial filtration value, but still greater than the maximum filtration value
- simplex_is_changed = st.prune_above_filtration(5.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- BOOST_CHECK(st == st_complete);
- BOOST_CHECK(!simplex_is_changed);
-
- // Display the Simplex_tree
- std::cout << "The complex contains " << st.num_simplices() << " simplices";
- std::cout << " - dimension " << st.dimension() << std::endl;
- std::cout << "Iterator on Simplices in the filtration, with [filtration value]:" << std::endl;
- for (auto f_simplex : st.filtration_simplex_range()) {
- std::cout << " " << "[" << st.filtration(f_simplex) << "] ";
- for (auto vertex : st.simplex_vertex_range(f_simplex)) {
- std::cout << (int) vertex << " ";
- }
- std::cout << std::endl;
- }
-
- // Check the pruned cases
- simplex_is_changed = st.prune_above_filtration(2.5);
- if (simplex_is_changed)
- st.initialize_filtration();
- BOOST_CHECK(st == st_pruned);
- BOOST_CHECK(simplex_is_changed);
-
- // Display the Simplex_tree
- std::cout << "The complex pruned at 2.5 contains " << st.num_simplices() << " simplices";
- std::cout << " - dimension " << st.dimension() << std::endl;
-
- simplex_is_changed = st.prune_above_filtration(2.0);
- if (simplex_is_changed)
- st.initialize_filtration();
-
- std::cout << "The complex pruned at 2.0 contains " << st.num_simplices() << " simplices";
- std::cout << " - dimension " << st.dimension() << std::endl;
-
- BOOST_CHECK(st == st_pruned);
- BOOST_CHECK(!simplex_is_changed);
-
- typeST st_empty;
- // FIXME
- st_empty.set_dimension(3);
- simplex_is_changed = st.prune_above_filtration(0.0);
- if (simplex_is_changed)
- st.initialize_filtration();
-
- // Display the Simplex_tree
- std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices";
- std::cout << " - dimension " << st.dimension() << std::endl;
-
- BOOST_CHECK(st == st_empty);
- BOOST_CHECK(simplex_is_changed);
-
- // Test case to the limit
- simplex_is_changed = st.prune_above_filtration(-1.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- BOOST_CHECK(st == st_empty);
- BOOST_CHECK(!simplex_is_changed);
-}
-
-BOOST_AUTO_TEST_CASE(mini_prune_above_filtration) {
- std::cout << "********************************************************************" << std::endl;
- std::cout << "MINI PRUNE ABOVE FILTRATION" << std::endl;
- typedef Simplex_tree<MyOptions> typeST;
- typeST st;
-
- // FIXME
- st.set_dimension(3);
-
- st.insert_simplex_and_subfaces({0, 1, 6, 7});
- st.insert_simplex_and_subfaces({3, 4, 5});
- st.insert_simplex_and_subfaces({3, 0});
- st.insert_simplex_and_subfaces({2, 1, 0});
-
- // st:
- // 1 6
- // o---o
- // /X\7/
- // o---o---o---o
- // 2 0 3\X/4
- // o
- // 5
-
- st.initialize_filtration();
-
- // Display the Simplex_tree
- std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
- BOOST_CHECK(st.num_simplices() == 27);
-
- // Test case to the limit - With these options, there is no filtration, which means filtration is 0
- bool simplex_is_changed = st.prune_above_filtration(1.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- // Display the Simplex_tree
- std::cout << "The complex pruned at 1.0 contains " << st.num_simplices() << " simplices" << std::endl;
- BOOST_CHECK(!simplex_is_changed);
- BOOST_CHECK(st.num_simplices() == 27);
-
- simplex_is_changed = st.prune_above_filtration(0.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- // Display the Simplex_tree
- std::cout << "The complex pruned at 0.0 contains " << st.num_simplices() << " simplices" << std::endl;
- BOOST_CHECK(!simplex_is_changed);
- BOOST_CHECK(st.num_simplices() == 27);
-
- // Test case to the limit
- simplex_is_changed = st.prune_above_filtration(-1.0);
- if (simplex_is_changed)
- st.initialize_filtration();
- // Display the Simplex_tree
- std::cout << "The complex pruned at -1.0 contains " << st.num_simplices() << " simplices" << std::endl;
- BOOST_CHECK(simplex_is_changed);
- BOOST_CHECK(st.num_simplices() == 0);
-
- // Display the Simplex_tree
- std::cout << "The complex contains " << st.num_simplices() << " simplices" << std::endl;
-
-}