/* 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): David Salinas * * Copyright (C) 2014 INRIA Sophia Antipolis-Mediterranee (France) * * 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 . */ #include #include #include #include #include #include "gudhi/Utils.h" #include "gudhi/Test.h" #include "gudhi/Skeleton_blocker.h" //#include "gudhi/Skeleton_blocker_link_complex.h" //#include "gudhi/Skeleton_blocker/Skeleton_blocker_link_superior.h" //#include "gudhi/Skeleton_blocker/Skeleton_blocker_simple_traits.h" //#include "gudhi/Skeleton_blocker/internal/Trie.h" using namespace std; using namespace Gudhi; using namespace skbl; typedef Skeleton_blocker_complex Complex; typedef Complex::Vertex_handle Vertex_handle; typedef Complex::Root_vertex_handle Root_vertex_handle; typedef Complex::Simplex Simplex; typedef Complex::Root_simplex_handle Root_simplex_handle; typedef Simplex::Simplex_vertex_const_iterator Simplex_vertex_const_iterator; typedef Complex::Edge_handle Edge_handle; // true if v in complex bool assert_vertex(Complex &complex, Vertex_handle v) { //assert(complex.contains(v)); return complex.contains(static_cast (v)); } bool assert_simplex(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) { return true; // AddressSimplex simplex((a),(b),(c)); // return complex.contains(&simplex); } // true iff the blocker (a,b,c) is in complex bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c) { return true; //return complex.contains_blocker((a),(b),(c)); } // true iff the blocker (a,b,c,d) is in complex bool assert_blocker(Complex &complex, Root_vertex_handle a, Root_vertex_handle b, Root_vertex_handle c, Root_vertex_handle d) { return true; //Simplex blocker (a,b,c,d); //return complex.contains_blocker(&blocker); } void build_complete(int n, Complex& complex) { complex.clear(); for (int i = 0; i < n; i++) complex.add_vertex(); // for(int i=n-1;i>=0;i--) // for(int j=i-1;j>=0;j--) // complex.add_edge_without_blockers(Vertex_handle(i),Vertex_handle(j)); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } bool test_simplex() { // PRINT("test simplex"); Simplex simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3)); for (auto i = simplex.begin(); i != simplex.end(); ++i) { PRINT(*i); auto j = i; for (++j; j != simplex.end(); ++j) { PRINT(*j); } } return simplex.dimension() == 3; } bool test_num_simplices() { int n = 4; Complex complex; build_complete(n, complex); size_t sum = 0; for (int i = 0; i < n; i++) { PRINT(complex.num_simplices(i)); sum += complex.num_simplices(i); } return complex.num_vertices() == n && complex.num_edges() == 6 && sum == 15 && complex.num_simplices() == 15; } bool test_iterator_vertices1() { int n = 10; Complex complex(10); cerr << "complex.num_vertices():" << complex.num_vertices() << endl; int num_vertex_seen = 0; for (auto vi : complex.vertex_range()) { cerr << "vertex:" << vi << endl; ++num_vertex_seen; } return num_vertex_seen == n; } bool test_iterator_vertices2() { int n = 10; Complex complex; build_complete(10, complex); cerr << "complex.num_vertices():" << complex.num_vertices() << endl; cerr << "complex.num_edges():" << complex.num_edges() << endl; int num_vertex_seen = 0; for (auto vi : complex.vertex_range(Vertex_handle(2))) { cerr << "vertex:" << vi << endl; ++num_vertex_seen; } std::cerr << "num_vertex_seen:" << num_vertex_seen << std::endl; return num_vertex_seen == (n - 1); } bool test_iterator_edge() { const int n = 10; Complex complex(n); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); cerr << "complex.num_edges():" << complex.num_edges() << endl; int num_edges_seen = 0; for (auto edge : complex.edge_range()) { cerr << "edge :" << complex[edge] << endl; ++num_edges_seen; } return num_edges_seen == n * (n - 1) / 2 - 2; } bool test_iterator_edge2() { const int n = 10; Complex complex(n); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); cerr << "complex.num_edges():" << complex.num_edges() << endl; int num_neigbors_seen = 0; for (auto neighbor : complex.vertex_range(Vertex_handle(2))) { cerr << "neighbor" << neighbor << endl; ++num_neigbors_seen; } return num_neigbors_seen == 8; } bool test_iterator_edge3() { const int n = 10; Complex complex(n); for (int i = 0; i < n; i++) for (int j = 0; j < i; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); complex.remove_edge(Vertex_handle(2), Vertex_handle(3)); complex.remove_edge(Vertex_handle(3), Vertex_handle(5)); cerr << "complex.num_edges():" << complex.num_edges() << endl; int num_neigbors_seen = 0; for (auto edge : complex.edge_range(Vertex_handle(2))) { std::cerr << edge << std::endl; ++num_neigbors_seen; } return num_neigbors_seen == 8; } bool test_iterator_triangles() { const int n = 7; Complex complex(n); //create a "ring" around '0' for (int i = 1; i < n; i++) complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(i)); for (int i = 1; i < n - 1; i++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(i + 1)); complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(6)); PRINT(complex.to_string()); int num_triangles_seen = 0; //for (auto t : complex.triangle_range(5)){ TEST("triangles around 5 (should be 2 of them):"); for (auto t : complex.triangle_range(Vertex_handle(5))) { PRINT(t); ++num_triangles_seen; } bool test = (num_triangles_seen == 2); num_triangles_seen = 0; TEST("triangles around 0 (should be 6 of them):"); for (auto t : complex.triangle_range(Vertex_handle(0))) { PRINT(t); ++num_triangles_seen; } test = test && (num_triangles_seen == 6); // we now add another triangle complex.add_vertex(); complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(7)); complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(7)); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(6))); num_triangles_seen = 0; TEST("triangles (should be 6 of them):"); num_triangles_seen = 0; for (auto t : complex.triangle_range()) { PRINT(t); ++num_triangles_seen; } test = test && (num_triangles_seen == 6); PRINT(num_triangles_seen); return test; } //#include "combinatorics/Skeleton_blocker/iterators/Skeleton_blockers_simplices_iterators.h" bool test_iterator_simplices() { Complex complex(6); complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2)); complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0)); complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(3)); complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(3)); complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(5)); complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(5)); complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(4)); complex.add_edge_without_blockers(Vertex_handle(4), Vertex_handle(5)); complex.add_edge_without_blockers(Vertex_handle(3), Vertex_handle(4)); complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(3), Vertex_handle(4), Vertex_handle(5))); bool correct_number_simplices = true; std::map expected_num_simplices; expected_num_simplices[Vertex_handle(0)] = 4; expected_num_simplices[Vertex_handle(1)] = 6; expected_num_simplices[Vertex_handle(2)] = 11; expected_num_simplices[Vertex_handle(3)] = 9; expected_num_simplices[Vertex_handle(4)] = 7; expected_num_simplices[Vertex_handle(5)] = 7; for (auto pair : expected_num_simplices) { unsigned num_simplices_around = 0; for (const auto& simplex : complex.star_simplex_range(pair.first)) { simplex.dimension(); DBGVALUE(simplex); ++num_simplices_around; } correct_number_simplices = correct_number_simplices && (num_simplices_around == pair.second); DBGMSG("current vertex:", pair.first); DBGMSG("expected_num_simplices:", pair.second); DBGMSG("found:", num_simplices_around); } return correct_number_simplices; } bool test_iterator_simplices2() { Complex complex(2); complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); for (const auto& s : complex.triangle_range()) { s.dimension(); return false; // there are no triangles } unsigned num_simplices = 0; DBGVALUE(complex.to_string()); for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) { simplex.dimension(); DBGVALUE(simplex); } for (const auto& simplex : complex.complex_simplex_range()) { DBGVALUE(simplex); simplex.dimension(); ++num_simplices; } bool correct_number_simplices = (num_simplices == 3); return correct_number_simplices; } bool test_iterator_simplices3() { Complex complex(3); complex.add_edge_without_blockers(Vertex_handle(0), Vertex_handle(1)); complex.add_edge_without_blockers(Vertex_handle(1), Vertex_handle(2)); complex.add_edge_without_blockers(Vertex_handle(2), Vertex_handle(0)); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); unsigned num_simplices = 0; for (const auto& simplex : complex.star_simplex_range(Vertex_handle(0))) { simplex.dimension(); DBGVALUE(simplex); } for (const auto& simplex : complex.complex_simplex_range()) { DBGVALUE(simplex); simplex.dimension(); ++num_simplices; } bool correct_number_simplices = (num_simplices == 6); return correct_number_simplices; } bool test_iterator_simplices4() { Complex empty_complex; for (auto v : empty_complex.vertex_range()) { (void) v; } for (auto e : empty_complex.edge_range()) { empty_complex[e]; } for (auto t : empty_complex.triangle_range()) { t.dimension(); } for (auto s : empty_complex.complex_simplex_range()) { s.dimension(); } return true; } bool test_iterator_coboundary() { Complex c; build_complete(4, c); c.remove_edge(Vertex_handle(0), Vertex_handle(2)); PRINT(c.to_string()); Simplex s02(Vertex_handle(0), Vertex_handle(2)); int n = 0; std::set expected; expected.insert(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); expected.insert(Simplex(Vertex_handle(0), Vertex_handle(2), Vertex_handle(3))); for (const auto & s : c.coboundary_range(s02)) { PRINT(s); if (expected.find(s) == expected.end()) return false; ++n; } return n == 2; } template auto blocker_range(Map map) -> decltype(map | boost::adaptors::map_values) { return map | boost::adaptors::map_values; } bool test_iterator_blockers() { Complex complex; Simplex alpha; Simplex vertex_set_expected; // Build the complexes for (int i = 0; i < 20; i++) { complex.add_vertex(); } for (int i = 10; i < 15; i++) { for (int j = i + 1; j < 15; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12))); complex.add_blocker(Simplex(Vertex_handle(2), Vertex_handle(1), Vertex_handle(10))); complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(9), Vertex_handle(15))); complex.add_blocker(Simplex(Vertex_handle(1), Vertex_handle(9), Vertex_handle(8))); // Print result int num_blockers = 0; for (auto blockers : complex.blocker_range(Vertex_handle(10))) { TESTVALUE(*blockers); num_blockers++; } bool test = (num_blockers == 3); num_blockers = 0; for (auto blockers : complex.blocker_range()) { TESTVALUE(*blockers); num_blockers++; } test = test && (num_blockers == 4); return test; } bool test_link0() { enum { a, b, c, d, n }; Complex complex(n); complex.add_edge_without_blockers(Vertex_handle(b), Vertex_handle(c)); complex.add_edge_without_blockers(Vertex_handle(c), Vertex_handle(d)); Simplex alpha = Simplex(Vertex_handle(c)); Skeleton_blocker_link_complex L(complex, alpha); auto L2 = complex.link(alpha); if (L != L2) return false; PRINT(L.num_vertices()); PRINT(L.to_string()); bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(b))); bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(d))); bool test3 = L.num_edges() == 0; bool test4 = L.num_blockers() == 0; return test1 && test2 && test3&&test4; } bool test_link1() { Complex complex; // Build the complexes for (int i = 0; i < 20; i++) { complex.add_vertex(); } for (int i = 10; i < 15; i++) { for (int j = i + 1; j < 15; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } Simplex alpha(Vertex_handle(12), Vertex_handle(14)); Skeleton_blocker_link_complex L(complex, alpha); // Complexes built auto L2 = complex.link(alpha); if (L != L2) return false; // verification bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); bool test4 = L.num_edges() == 3; bool test5 = L.num_blockers() == 0; Root_simplex_handle simplex; simplex.add_vertex(Root_vertex_handle(10)); simplex.add_vertex(Root_vertex_handle(11)); simplex.add_vertex(Root_vertex_handle(13)); bool test6(L.get_simplex_address(simplex)); bool test7 = L.contains(*(L.get_simplex_address(simplex))); cerr << "----> Ocomplex \n"; return test1 && test2 && test3 && test4 && test5 && test6&&test7; } bool test_link2() { Complex complex; Simplex alpha; Simplex vertex_set_expected; // Build the complexes for (int i = 0; i < 20; i++) { complex.add_vertex(); } for (int i = 10; i < 15; i++) { for (int j = i + 1; j < 15; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(13))); alpha = Simplex(Vertex_handle(12), Vertex_handle(14)); Skeleton_blocker_link_complex L(complex, alpha); // Complexes built // Print result cerr << "complex complex" << complex.to_string(); cerr << endl << endl; cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string(); auto L2 = complex.link(alpha); if (L != L2) return false; // verification bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); bool test4 = L.num_edges() == 3; bool test5 = L.num_blockers() == 1; Root_simplex_handle simplex; simplex.add_vertex(Root_vertex_handle(10)); simplex.add_vertex(Root_vertex_handle(11)); simplex.add_vertex(Root_vertex_handle(13)); bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex))); cerr << "----> Ocomplex \n"; return test1 && test2 && test3 && test4 && test5&&test6; } bool test_link3() { Complex complex; Simplex alpha; Simplex vertex_set_expected; // Build the complexes for (int i = 0; i < 20; i++) { complex.add_vertex(); } for (int i = 10; i < 15; i++) { for (int j = i + 1; j < 15; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12))); alpha = Simplex(Vertex_handle(12), Vertex_handle(14)); Skeleton_blocker_link_complex L(complex, alpha); // Complexes built // Print result cerr << "complex complex" << complex.to_string(); cerr << endl << endl; cerr << "L= Link_complex(" << alpha << ") : \n" << L.to_string(); auto L2 = complex.link(alpha); if (L != L2) return false; // verification bool test = assert_vertex(L, *L.get_address(Root_vertex_handle(10))); test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(11))); test = test && assert_vertex(L, *L.get_address(Root_vertex_handle(13))); test = test && L.num_edges() == 2; test = test && L.contains_edge(*L.get_address(Root_vertex_handle(10)), *L.get_address(Root_vertex_handle(13))); test = test && L.contains_edge(*L.get_address(Root_vertex_handle(13)), *L.get_address(Root_vertex_handle(11))); test = test && L.num_blockers() == 0; return test; } bool test_link4() { Complex complex; // Build the complexes for (int i = 0; i < 20; i++) { complex.add_vertex(); } for (int i = 10; i < 15; i++) { for (int j = i + 1; j < 15; j++) complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(j)); } complex.add_blocker(Simplex(Vertex_handle(10), Vertex_handle(11), Vertex_handle(12), Vertex_handle(13))); Simplex alpha(Vertex_handle(12), Vertex_handle(14)); Skeleton_blocker_link_complex L(complex, alpha); // Complexes built // verification bool test1 = L.contains_vertex(*L.get_address(Root_vertex_handle(10))); bool test2 = L.contains_vertex(*L.get_address(Root_vertex_handle(11))); bool test3 = L.contains_vertex(*L.get_address(Root_vertex_handle(13))); bool test4 = L.num_edges() == 3; bool test5 = L.num_blockers() == 1; Root_simplex_handle simplex; simplex.add_vertex(Root_vertex_handle(10)); simplex.add_vertex(Root_vertex_handle(11)); simplex.add_vertex(Root_vertex_handle(13)); bool test6 = L.contains_blocker(*(L.get_simplex_address(simplex))); cerr << "----> Ocomplex \n"; return test1 && test2 && test3 && test4 && test5&&test6; } bool test_link5() { Complex complex(0, new Print_complex_visitor()); // Build the complexes build_complete(4, complex); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2), Vertex_handle(3))); Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)); Skeleton_blocker_link_complex L(complex, alpha); // Complexes built // Print result PRINT(complex.to_string()); cerr << endl << endl; PRINT(L.to_string()); // verification return L.num_vertices() == 0; } bool test_link6() { Complex complex(0, new Print_complex_visitor()); // Build the complexes build_complete(4, complex); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); Simplex alpha(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2)); Skeleton_blocker_link_complex link_blocker_alpha; build_link_of_blocker(complex, alpha, link_blocker_alpha); // Print result PRINT(complex.to_string()); cerr << endl << endl; PRINT(link_blocker_alpha.to_string()); // verification return link_blocker_alpha.num_vertices() == 1; } bool test_link7() { Complex complex(0, new Print_complex_visitor()); // Build the complexes build_complete(6, complex); complex.add_vertex(); complex.add_vertex(); for (int i = 3; i < 6; ++i) { complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(6)); complex.add_edge_without_blockers(Vertex_handle(i), Vertex_handle(7)); } complex.add_edge_without_blockers(Vertex_handle(6), Vertex_handle(7)); complex.add_blocker(Simplex(Vertex_handle(0), Vertex_handle(1), Vertex_handle(2))); complex.add_blocker(Simplex(Vertex_handle(3), Vertex_handle(4), Vertex_handle(5))); Simplex alpha(Vertex_handle(3), Vertex_handle(4), Vertex_handle(5)); Skeleton_blocker_link_complex link_blocker_alpha; build_link_of_blocker(complex, alpha, link_blocker_alpha); //the result should be the edge {6,7} plus the blocker {0,1,2} // Print result PRINT(complex.to_string()); cerr << endl << endl; DBGVALUE(link_blocker_alpha.to_string()); Skeleton_blocker_link_complex link_blocker_alpha_cpy = link_blocker_alpha; DBGVALUE(link_blocker_alpha_cpy.to_string()); bool equal_complexes = (link_blocker_alpha.num_vertices() == link_blocker_alpha_cpy.num_vertices()) &&(link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers()) &&(link_blocker_alpha.num_edges() == link_blocker_alpha_cpy.num_edges()) ; DBGVALUE((link_blocker_alpha.num_blockers() == link_blocker_alpha_cpy.num_blockers())); DBGVALUE((link_blocker_alpha.num_blockers())); DBGVALUE((link_blocker_alpha_cpy.num_blockers())); DBGVALUE(equal_complexes); // verification return link_blocker_alpha.num_vertices() == 5 && link_blocker_alpha.num_edges() == 4 && link_blocker_alpha.num_blockers() == 1 && equal_complexes; } template void add_triangle_edges(int a, int b, int c, list& simplices) { typedef SimplexHandle Simplex; typedef typename SimplexHandle::Vertex_handle Vertex_handle; simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b))); simplices.push_back(Simplex(Vertex_handle(b), Vertex_handle(c))); simplices.push_back(Simplex(Vertex_handle(c), Vertex_handle(a))); } template void add_triangle(int a, int b, int c, list& simplices) { typedef SimplexHandle Simplex; typedef typename SimplexHandle::Vertex_handle Vertex_handle; simplices.push_back(Simplex(Vertex_handle(a), Vertex_handle(b), Vertex_handle(c))); } bool test_constructor() { list simplices; simplices.push_back(Simplex(Vertex_handle(0))); simplices.push_back(Simplex(Vertex_handle(1))); simplices.push_back(Simplex(Vertex_handle(2))); simplices.push_back(Simplex(Vertex_handle(3))); simplices.push_back(Simplex(Vertex_handle(4))); simplices.push_back(Simplex(Vertex_handle(5))); simplices.push_back(Simplex(Vertex_handle(3), Vertex_handle(5))); add_triangle_edges(0, 1, 5, simplices); add_triangle_edges(1, 2, 3, simplices); add_triangle_edges(2, 3, 4, simplices); add_triangle_edges(1, 3, 4, simplices); add_triangle_edges(1, 2, 4, simplices); add_triangle(0, 1, 5, simplices); add_triangle(1, 2, 3, simplices); add_triangle(1, 3, 4, simplices); add_triangle(1, 2, 4, simplices); add_triangle(2, 3, 4, simplices); Complex complex(simplices.begin(), simplices.end()); PRINT(complex.to_string()); return ( complex.num_vertices() == 6 && complex.num_edges() == 10 && complex.num_blockers() == 2); } list subfaces(Simplex top_face) { list res; if (top_face.dimension() == -1) return res; if (top_face.dimension() == 0) { res.push_back(top_face); return res; } else { Vertex_handle first_vertex = top_face.first_vertex(); top_face.remove_vertex(first_vertex); res = subfaces(top_face); list copy = res; for (auto& simplex : copy) { simplex.add_vertex(first_vertex); } res.push_back(Simplex(first_vertex)); res.splice(res.end(), copy); return res; } } bool test_constructor2() { Simplex simplex; for (int i = 0; i < 5; ++i) simplex.add_vertex(static_cast (i)); list simplices(subfaces(simplex)); simplices.remove(simplex); Complex complex(simplices.begin(), simplices.end()); PRINT(complex.to_string()); for (auto b : complex.const_blocker_range()) { cout << "b:" << b << endl; } return ( complex.num_vertices() == 5 && complex.num_edges() == 10 && complex.num_blockers() == 1); } bool test_constructor3() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2)))); subf.pop_back(); //remove max face -> now a blocker 012 simplices.insert(simplices.begin(), subf.begin(), subf.end()); DBGCONT(simplices); Complex complex(simplices.begin(), simplices.end()); DBGVALUE(complex.to_string()); if (complex.num_blockers() != 1) return false; Sh expected_blocker(Vh(0), Vh(1), Vh(2)); for (auto b : complex.const_blocker_range()) if (*b != expected_blocker) return false; return complex.num_vertices() == 3 && complex.num_blockers() == 1; } bool test_constructor4() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3)))); simplices.insert(simplices.begin(), subf.begin(), subf.end()); simplices.push_back(Sh(Vh(4))); simplices.push_back(Sh(Vh(4), Vh(1))); simplices.push_back(Sh(Vh(4), Vh(0))); DBGCONT(simplices); Complex complex(simplices.begin(), simplices.end()); DBGVALUE(complex.to_string()); if (complex.num_blockers() != 1) return false; Sh expected_blocker(Vh(0), Vh(1), Vh(4)); for (auto b : complex.const_blocker_range()) if (*b != expected_blocker) return false; return complex.num_vertices() == 5 && complex.num_blockers() == 1 && complex.num_edges() == 8; } bool test_constructor5() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2)))); simplices.insert(simplices.begin(), subf.begin(), subf.end()); simplices.push_back(Sh(Vh(3))); simplices.push_back(Sh(Vh(3), Vh(1))); simplices.push_back(Sh(Vh(3), Vh(2))); simplices.push_back(Sh(Vh(4))); simplices.push_back(Sh(Vh(4), Vh(1))); simplices.push_back(Sh(Vh(4), Vh(0))); simplices.push_back(Sh(Vh(5))); simplices.push_back(Sh(Vh(5), Vh(2))); simplices.push_back(Sh(Vh(5), Vh(0))); DBGCONT(simplices); Complex complex(simplices.begin(), simplices.end()); DBGVALUE(complex.to_string()); return complex.num_vertices() == 6 && complex.num_blockers() == 3 && complex.num_edges() == 9; } bool test_constructor6() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; auto subf(subfaces(Sh(Vh(0), Vh(1), Vh(2), Vh(3)))); for (auto s : subf) { Sh s1(Vh(0), Vh(1), Vh(2), Vh(3)); Sh s2(Vh(1), Vh(2), Vh(3)); if (s != s1 && s != s2) simplices.push_back(s); } DBGCONT(simplices); Complex complex(simplices.begin(), simplices.end()); DBGVALUE(complex.to_string()); if (complex.num_blockers() != 1) return false; Sh expected_blocker(Vh(1), Vh(2), Vh(3)); for (auto b : complex.const_blocker_range()) if (*b != expected_blocker) return false; return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6; } bool test_constructor7() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; simplices.push_back(Sh(Vh(0), Vh(1), Vh(2))); simplices.push_back(Sh(Vh(1), Vh(2), Vh(3))); simplices.push_back(Sh(Vh(3), Vh(0), Vh(2))); simplices.push_back(Sh(Vh(3), Vh(0), Vh(1))); //get complex from top faces Complex complex(make_complex_from_top_faces(simplices.begin(), simplices.end())); DBGVALUE(complex.to_string()); if (complex.num_blockers() != 1) return false; Sh expected_blocker(Vh(0), Vh(1), Vh(2), Vh(3)); for (auto b : complex.const_blocker_range()) if (*b != expected_blocker) return false; return complex.num_vertices() == 4 && complex.num_blockers() == 1 && complex.num_edges() == 6; } bool test_constructor8() { typedef Vertex_handle Vh; typedef Simplex Sh; std::vector simplices; simplices.push_back(Sh(Vh(0), Vh(1))); simplices.push_back(Sh(Vh(2), Vh(1))); simplices.push_back(Sh(Vh(0), Vh(2))); simplices.push_back(Sh(Vh(3), Vh(1))); simplices.push_back(Sh(Vh(2), Vh(3))); //get complex from top faces Complex complex(make_complex_from_top_faces(simplices.begin(), simplices.end())); DBGVALUE(complex.to_string()); return complex.num_vertices() == 4 && complex.num_blockers() == 2 && complex.num_edges() == 5; } int main(int argc, char *argv[]) { Tests tests_complex; tests_complex.add("test simplex", test_simplex); tests_complex.add("test_num_simplices", test_num_simplices); tests_complex.add("test_link0", test_link0); tests_complex.add("test_link1", test_link1); tests_complex.add("test_link2", test_link2); tests_complex.add("test_link3", test_link3); tests_complex.add("test_link4", test_link4); tests_complex.add("test_link5", test_link5); tests_complex.add("test_link6", test_link6); tests_complex.add("test_link7", test_link7); tests_complex.add("test_constructor_list_simplices", test_constructor); tests_complex.add("test_constructor_list_simplices2", test_constructor2); tests_complex.add("test_constructor_list_simplices3", test_constructor3); tests_complex.add("test_constructor_list_simplices4", test_constructor4); tests_complex.add("test_constructor_list_simplices5", test_constructor5); tests_complex.add("test_constructor_list_simplices6", test_constructor6); tests_complex.add("test_constructor_list_simplices7", test_constructor7); tests_complex.add("test_constructor_list_simplices8", test_constructor8); tests_complex.add("test iterator vertices 1", test_iterator_vertices1); tests_complex.add("test iterator vertices 2", test_iterator_vertices2); tests_complex.add("test iterator edges", test_iterator_edge); tests_complex.add("test iterator edges 2", test_iterator_edge2); tests_complex.add("test iterator edges 3", test_iterator_edge3); tests_complex.add("test iterator blockers", test_iterator_blockers); tests_complex.add("test_iterator_triangles", test_iterator_triangles); tests_complex.add("test iterator simplices", test_iterator_simplices); tests_complex.add("test iterator simplices2", test_iterator_simplices2); tests_complex.add("test iterator simplices3", test_iterator_simplices3); tests_complex.add("test iterator simplices4", test_iterator_simplices4); tests_complex.add("test iterator coboundary", test_iterator_coboundary); if (tests_complex.run()) { return EXIT_SUCCESS; } else { return EXIT_FAILURE; } // test_iterator_simplices(); }