/* 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 "Skeleton_blocker/Simplex.h"
#include "gudhi/Skeleton_blocker_complex.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 "Simple_vertex.h"
//#include "Simple_edge.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_handle Simplex_handle;
typedef Complex::Root_simplex_handle Root_simplex_handle;
typedef Simplex_handle::Simplex_vertex_const_iterator Simplex_vertex_const_iterator;
typedef Complex::Edge_handle Edge_handle;
// true iff v \in complex
bool assert_vertex(Complex &complex,Vertex_handle v){
//assert(complex.contains(v));
return complex.contains(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=0;i--)
// for(int j=i-1;j>=0;j--)
// complex.add_edge(Vertex_handle(i),Vertex_handle(j));
for(int i=0;i 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.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(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.simplex_range(Vertex_handle(0))){
simplex.dimension();
DBGVALUE(simplex);
}
for(const auto& simplex : 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(Vertex_handle(0),Vertex_handle(1));
complex.add_edge(Vertex_handle(1),Vertex_handle(2));
complex.add_edge(Vertex_handle(2),Vertex_handle(0));
complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
unsigned num_simplices = 0 ;
for(const auto& simplex : complex.simplex_range(Vertex_handle(0))){
simplex.dimension();
DBGVALUE(simplex);
}
for(const auto& simplex : 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()){
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.simplex_range()){
s.dimension();
}
return true;
}
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_handle alpha;
Simplex_handle 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(Vertex_handle(i),Vertex_handle(j));
}
complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12)));
complex.add_blocker(Simplex_handle(Vertex_handle(2),Vertex_handle(1),Vertex_handle(10)));
complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(9),Vertex_handle(15)));
complex.add_blocker(Simplex_handle(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(Vertex_handle(b),Vertex_handle(c));complex.add_edge(Vertex_handle(c),Vertex_handle(d));
Simplex_handle alpha = Simplex_handle(Vertex_handle(c));
Skeleton_blocker_link_complex L(complex,alpha);
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(Vertex_handle(i),Vertex_handle(j));
}
Simplex_handle 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()==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_handle alpha;
Simplex_handle 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(Vertex_handle(i),Vertex_handle(j));
}
complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(13)));
alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14));
Skeleton_blocker_link_complex L(complex,alpha);
// Complexes built
// Print result
cerr << "complex complex"<< complex.to_string();
cerr < Ocomplex \n";
return test1&&test2&&test3&&test4&&test5&&test6 ;
}
bool test_link3(){
Complex complex;
Simplex_handle alpha;
Simplex_handle 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(Vertex_handle(i),Vertex_handle(j));
}
complex.add_blocker(Simplex_handle(Vertex_handle(10),Vertex_handle(11),Vertex_handle(12)));
alpha = Simplex_handle(Vertex_handle(12),Vertex_handle(14));
Skeleton_blocker_link_complex L(complex,alpha);
// Complexes built
// Print result
cerr << "complex complex"<< complex.to_string();
cerr < 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_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2),Vertex_handle(3)));
Simplex_handle 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 <());
// Build the complexes
build_complete(4,complex);
complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
Simplex_handle 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 <());
// Build the complexes
build_complete(6,complex);
complex.add_vertex();
complex.add_vertex();
for(int i = 3; i<6; ++i){
complex.add_edge(Vertex_handle(i),Vertex_handle(6));
complex.add_edge(Vertex_handle(i),Vertex_handle(7));
}
complex.add_edge(Vertex_handle(6),Vertex_handle(7));
complex.add_blocker(Simplex_handle(Vertex_handle(0),Vertex_handle(1),Vertex_handle(2)));
complex.add_blocker(Simplex_handle(Vertex_handle(3),Vertex_handle(4),Vertex_handle(5)));
Simplex_handle 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 < 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_handle;
typedef typename SimplexHandle::Vertex_handle Vertex_handle;
simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b) ));
simplices.push_back(Simplex_handle(Vertex_handle(b),Vertex_handle(c) ));
simplices.push_back(Simplex_handle(Vertex_handle(c),Vertex_handle(a) ));
}
template
void add_triangle(int a,int b,int c,list& simplices){
typedef SimplexHandle Simplex_handle;
typedef typename SimplexHandle::Vertex_handle Vertex_handle;
simplices.push_back(Simplex_handle(Vertex_handle(a),Vertex_handle(b),Vertex_handle(c)));
}
bool test_constructor(){
list simplices;
simplices.push_back(Simplex_handle(Vertex_handle(0)));
simplices.push_back(Simplex_handle(Vertex_handle(1)));
simplices.push_back(Simplex_handle(Vertex_handle(2)));
simplices.push_back(Simplex_handle(Vertex_handle(3)));
simplices.push_back(Simplex_handle(Vertex_handle(4)));
simplices.push_back(Simplex_handle(Vertex_handle(5)));
simplices.push_back(Simplex_handle(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(2,3,4,simplices);
add_triangle(1,3,4,simplices);
add_triangle(1,2,4,simplices);
Complex complex(simplices);
PRINT(complex.to_string());
return ( complex.num_vertices()==6&&complex.num_edges()==10&& complex.num_blockers()==2);
}
list subfaces(Simplex_handle 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_handle(first_vertex));
res.splice(res.end(),copy);
return res;
}
}
bool test_constructor2(){
Simplex_handle simplex;
for(int i =0 ; i < 5;++i)
simplex.add_vertex(i);
list simplices(subfaces(simplex));
simplices.remove(simplex);
Complex complex(simplices);
PRINT(complex.to_string());
for(auto b : complex.const_blocker_range()){
cout << "b:"<