summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/generate_version.sh4
-rw-r--r--src/cython/Makefile8
-rw-r--r--src/cython/Simplex_tree_interface.h133
-rw-r--r--src/cython/cgudhi.pxd30
-rw-r--r--src/cython/gudhi.pyx165
-rwxr-xr-xsrc/cython/main.py65
-rw-r--r--src/cython/setup.py15
7 files changed, 420 insertions, 0 deletions
diff --git a/scripts/generate_version.sh b/scripts/generate_version.sh
index bf30f101..54bb727f 100755
--- a/scripts/generate_version.sh
+++ b/scripts/generate_version.sh
@@ -74,6 +74,10 @@ do
then
# SPECIFIC FOR GUDHI USER INTERFACE
cp -R $ROOT_DIR/src/$package $VERSION_DIR
+ elif [ "$package" == "cython" ]
+ then
+ # SPECIFIC FOR CYTHON INTERFACE
+ cp -R $ROOT_DIR/src/$package $VERSION_DIR
else
# PACKAGE COPY
if [ -d "$ROOT_DIR/src/$package$PACKAGE_INC_DIR" ]
diff --git a/src/cython/Makefile b/src/cython/Makefile
new file mode 100644
index 00000000..b694ab47
--- /dev/null
+++ b/src/cython/Makefile
@@ -0,0 +1,8 @@
+ext:
+ python setup.py build_ext --inplace
+
+test:
+ python main.py
+
+clean:
+ rm -rf build/ *.o *.so *.cpp
diff --git a/src/cython/Simplex_tree_interface.h b/src/cython/Simplex_tree_interface.h
new file mode 100644
index 00000000..df35b335
--- /dev/null
+++ b/src/cython/Simplex_tree_interface.h
@@ -0,0 +1,133 @@
+/* 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) 2016 INRIA Sophia Antipolis-Méditerranée (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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SIMPLEX_TREE_INTERFACE_H
+#define SIMPLEX_TREE_INTERFACE_H
+
+#include <gudhi/graph_simplicial_complex.h>
+#include <gudhi/distance_functions.h>
+#include <gudhi/Simplex_tree.h>
+
+#include <vector>
+#include <utility> // std::pair
+#include <iostream>
+
+namespace Gudhi {
+
+template<typename SimplexTreeOptions = Simplex_tree_options_full_featured>
+class Simplex_tree_interface : public Simplex_tree<SimplexTreeOptions> {
+ typedef typename Simplex_tree<SimplexTreeOptions>::Simplex_handle Simplex_handle;
+ typedef typename std::pair<Simplex_handle, bool> Insertion_result;
+ typedef std::vector<Vertex_handle> Complex;
+ typedef std::pair<Complex, Filtration_value> Filtered_complex;
+ typedef std::vector<Filtered_complex> Complex_tree;
+
+ public:
+
+ bool find_simplex(const Complex& vh) {
+ return (Simplex_tree<SimplexTreeOptions>::find(vh) != Simplex_tree<SimplexTreeOptions>::null_simplex());
+ }
+
+ bool insert_simplex(const Complex& vh, Filtration_value filtration = 0) {
+ Insertion_result result = Simplex_tree<SimplexTreeOptions>::insert_simplex(vh, filtration);
+ return (result.second);
+ }
+
+ bool insert_simplex_and_subfaces(const Complex& complex, Filtration_value filtration = 0) {
+ Insertion_result result = Simplex_tree<SimplexTreeOptions>::insert_simplex_and_subfaces(complex, filtration);
+ return (result.second);
+ }
+
+ Filtration_value simplex_filtration(const Complex& complex) {
+ return Simplex_tree<SimplexTreeOptions>::filtration(Simplex_tree<SimplexTreeOptions>::find(complex));
+ }
+
+ Complex_tree get_filtered_tree() {
+ Complex_tree filtered_tree;
+ for (auto f_simplex : Simplex_tree<SimplexTreeOptions>::filtration_simplex_range()) {
+ Complex simplex;
+ for (auto vertex : Simplex_tree<SimplexTreeOptions>::simplex_vertex_range(f_simplex)) {
+ simplex.insert(simplex.begin(), vertex);
+ }
+ filtered_tree.push_back(std::make_pair(simplex, Simplex_tree<SimplexTreeOptions>::filtration(f_simplex)));
+ }
+ return filtered_tree;
+
+ }
+
+ Complex_tree get_skeleton_tree(int dimension) {
+ Complex_tree skeleton_tree;
+ for (auto f_simplex : Simplex_tree<SimplexTreeOptions>::skeleton_simplex_range(dimension)) {
+ Complex simplex;
+ for (auto vertex : Simplex_tree<SimplexTreeOptions>::simplex_vertex_range(f_simplex)) {
+ simplex.insert(simplex.begin(), vertex);
+ }
+ skeleton_tree.push_back(std::make_pair(simplex, Simplex_tree<SimplexTreeOptions>::filtration(f_simplex)));
+ }
+ return skeleton_tree;
+ }
+
+ Complex_tree get_star_tree(const Complex& complex) {
+ Complex_tree star_tree;
+ for (auto f_simplex : Simplex_tree<SimplexTreeOptions>::star_simplex_range(Simplex_tree<SimplexTreeOptions>::find(complex))) {
+ Complex simplex;
+ for (auto vertex : Simplex_tree<SimplexTreeOptions>::simplex_vertex_range(f_simplex)) {
+ simplex.insert(simplex.begin(), vertex);
+ }
+ star_tree.push_back(std::make_pair(simplex, Simplex_tree<SimplexTreeOptions>::filtration(f_simplex)));
+ }
+ return star_tree;
+ }
+
+ Complex_tree get_coface_tree(const Complex& complex, int dimension) {
+ Complex_tree coface_tree;
+ for (auto f_simplex : Simplex_tree<SimplexTreeOptions>::cofaces_simplex_range(Simplex_tree<SimplexTreeOptions>::find(complex), dimension)) {
+ Complex simplex;
+ for (auto vertex : Simplex_tree<SimplexTreeOptions>::simplex_vertex_range(f_simplex)) {
+ simplex.insert(simplex.begin(), vertex);
+ }
+ coface_tree.push_back(std::make_pair(simplex, Simplex_tree<SimplexTreeOptions>::filtration(f_simplex)));
+ }
+ return coface_tree;
+ }
+
+ void graph_expansion(std::vector<std::vector<double>>&points, int max_dimension, double max_edge_length) {
+ Graph_t prox_graph = compute_proximity_graph(points, max_edge_length, euclidean_distance<std::vector<double>>);
+ Simplex_tree<SimplexTreeOptions>::insert_graph(prox_graph);
+ Simplex_tree<SimplexTreeOptions>::expansion(max_dimension);
+ Simplex_tree<SimplexTreeOptions>::initialize_filtration();
+ }
+
+};
+
+struct Simplex_tree_options_mini : 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;
+};
+
+} // namespace Gudhi
+
+#endif // SIMPLEX_TREE_INTERFACE_H
+
diff --git a/src/cython/cgudhi.pxd b/src/cython/cgudhi.pxd
new file mode 100644
index 00000000..9d055c44
--- /dev/null
+++ b/src/cython/cgudhi.pxd
@@ -0,0 +1,30 @@
+from libcpp.vector cimport vector
+from libcpp.utility cimport pair
+
+cdef extern from "Simplex_tree_interface.h" namespace "Gudhi":
+ cdef cppclass Simplex_tree_options_full_featured:
+ pass
+ cdef cppclass Simplex_tree_options_fast_persistence:
+ pass
+ cdef cppclass Simplex_tree_options_mini:
+ pass
+ cdef cppclass Simplex_tree_interface[T]:
+ Simplex_tree()
+ double filtration()
+ double simplex_filtration(vector[int] simplex)
+ void set_filtration(double filtration)
+ void initialize_filtration()
+ int num_vertices()
+ int num_simplices()
+ void set_dimension(int dimension)
+ int dimension()
+ bint find_simplex(vector[int] simplex)
+ bint insert_simplex(vector[int] simplex, double filtration)
+ bint insert_simplex_and_subfaces(vector[int] simplex, double filtration)
+ vector[pair[vector[int], double]] get_filtered_tree()
+ vector[pair[vector[int], double]] get_skeleton_tree(int dimension)
+ vector[pair[vector[int], double]] get_star_tree(vector[int] simplex)
+ vector[pair[vector[int], double]] get_coface_tree(vector[int] simplex, int dimension)
+ void graph_expansion(vector[vector[double]] points,int max_dimension,double max_edge_length)
+
+
diff --git a/src/cython/gudhi.pyx b/src/cython/gudhi.pyx
new file mode 100644
index 00000000..dd87f4bb
--- /dev/null
+++ b/src/cython/gudhi.pyx
@@ -0,0 +1,165 @@
+from cython cimport numeric
+from libcpp.vector cimport vector
+from libcpp.utility cimport pair
+
+cimport cgudhi
+
+
+# SimplexTree python interface
+cdef class SimplexTree:
+ cdef cgudhi.Simplex_tree_interface[cgudhi.Simplex_tree_options_full_featured] *thisptr
+ def __cinit__(self, points=None, max_dimension=3, max_edge_length=float('inf')):
+ self.thisptr = new cgudhi.Simplex_tree_interface[cgudhi.Simplex_tree_options_full_featured]()
+ # Constructor from graph expansion
+ if points is not None:
+ self.thisptr.graph_expansion(points,max_dimension,max_edge_length)
+ def __dealloc__(self):
+ if self.thisptr != NULL:
+ del self.thisptr
+ def get_filtration(self):
+ return self.thisptr.filtration()
+ def filtration(self, simplex):
+ return self.thisptr.simplex_filtration(simplex)
+ def set_filtration(self, filtration):
+ self.thisptr.set_filtration(<double>filtration)
+ def initialize_filtration(self):
+ self.thisptr.initialize_filtration()
+ def num_vertices(self):
+ return self.thisptr.num_vertices()
+ def num_simplices(self):
+ return self.thisptr.num_simplices()
+ def dimension(self):
+ return self.thisptr.dimension()
+ def set_dimension(self, dim):
+ self.thisptr.set_dimension(<int>dim)
+ def find(self, simplex):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.find_simplex(complex)
+ def insert(self, simplex, filtration = 0.0):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.insert_simplex(complex, <double>filtration)
+ def insert_with_subfaces(self, simplex, filtration = 0.0):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.insert_simplex_and_subfaces(complex, <double>filtration)
+ def get_filtered_tree(self):
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_filtered_tree()
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_skeleton_tree(self, dim):
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_skeleton_tree(<int>dim)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_star_tree(self, simplex):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_star_tree(complex)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_coface_tree(self, simplex, dim):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_coface_tree(complex, <int>dim)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+
+
+cdef class MiniSimplexTree:
+ cdef cgudhi.Simplex_tree_interface[cgudhi.Simplex_tree_options_mini] *thisptr
+ def __cinit__(self):
+ self.thisptr = new cgudhi.Simplex_tree_interface[cgudhi.Simplex_tree_options_mini]()
+ def __dealloc__(self):
+ if self.thisptr != NULL:
+ del self.thisptr
+ def num_vertices(self):
+ return self.thisptr.num_vertices()
+ def num_simplices(self):
+ return self.thisptr.num_simplices()
+ def dimension(self):
+ return self.thisptr.dimension()
+ def set_dimension(self, dim):
+ self.thisptr.set_dimension(<int>dim)
+ def find(self, simplex):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.find_simplex(complex)
+ def insert(self, simplex):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.insert_simplex(complex, 0.0)
+ def insert_with_subfaces(self, simplex, filtration = 0.0):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ return self.thisptr.insert_simplex_and_subfaces(complex, <double>filtration)
+ def get_filtered_tree(self):
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_filtered_tree()
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_skeleton_tree(self, dim):
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_skeleton_tree(<int>dim)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_star_tree(self, simplex):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_star_tree(complex)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
+ def get_coface_tree(self, simplex, dim):
+ cdef vector[int] complex
+ for i in simplex:
+ complex.push_back(i)
+ cdef vector[pair[vector[int], double]] coface_tree = self.thisptr.get_coface_tree(complex, <int>dim)
+ ct = []
+ for filtered_complex in coface_tree:
+ v = []
+ for vertex in filtered_complex.first:
+ v.append(vertex)
+ ct.append((v,filtered_complex.second))
+ return ct
diff --git a/src/cython/main.py b/src/cython/main.py
new file mode 100755
index 00000000..c5f1d03b
--- /dev/null
+++ b/src/cython/main.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+
+import gudhi
+
+st = gudhi.SimplexTree()
+
+print("#######################################################################")
+print("SimplexTree creation from insertion")
+if st.insert([0,1]):
+ print("Inserted !!")
+else:
+ print("Not inserted...")
+
+if st.find([0,1]):
+ print("Found !!")
+else:
+ print("Not found...")
+
+if st.insert_with_subfaces([0,1,2], filtration=4.0):
+ print("Inserted !!")
+else:
+ print("Not inserted...")
+
+# FIXME: Remove this line
+st.set_dimension(3)
+print("dimension=", st.dimension())
+
+st.set_filtration(4.0)
+st.initialize_filtration()
+print("filtration=", st.get_filtration())
+print("filtration[1,2]=", st.filtration([1,2]))
+print("filtration[4,2]=", st.filtration([4,2]))
+
+print("num_simplices=", st.num_simplices())
+print("num_vertices=", st.num_vertices())
+
+print("skeleton_tree[2]=", st.get_skeleton_tree(2))
+print("skeleton_tree[1]=", st.get_skeleton_tree(1))
+print("skeleton_tree[0]=", st.get_skeleton_tree(0))
+
+print("#######################################################################")
+print("SimplexTree creation from graph expansion")
+st_from_graph_expansion = gudhi.SimplexTree(points=[[0,0],[1,0],[0,1],[1,1]],max_dimension=1,max_edge_length=42)
+
+print("filtered_tree=", st_from_graph_expansion.get_filtered_tree())
+print("star([0])=", st_from_graph_expansion.get_star_tree([0]))
+print("coface([0],1)=", st_from_graph_expansion.get_coface_tree([0], 1))
+
+
+print("#######################################################################")
+print("MiniSimplexTree creation from insertion")
+triangle012 = [0, 1, 2]
+edge03 = [0, 3]
+mini_st = gudhi.MiniSimplexTree()
+mini_st.insert_with_subfaces(triangle012)
+mini_st.insert_with_subfaces(edge03)
+# FIXME: Remove this line
+mini_st.set_dimension(2);
+
+edge02 = [0, 2]
+if mini_st.find(edge02):
+ # Only coface is 012
+ print("coface(edge02,1)=", mini_st.get_coface_tree(edge02, 1))
+print("filtered_tree=", mini_st.get_filtered_tree())
+
diff --git a/src/cython/setup.py b/src/cython/setup.py
new file mode 100644
index 00000000..5942560d
--- /dev/null
+++ b/src/cython/setup.py
@@ -0,0 +1,15 @@
+from distutils.core import setup, Extension
+from Cython.Build import cythonize
+
+gudhi = Extension(
+ "gudhi",
+ sources = ['gudhi.pyx',],
+ language = 'c++',
+ extra_compile_args=['-std=c++11'],
+ include_dirs = ['../include','.'],
+)
+
+setup(
+ name = 'gudhi',
+ ext_modules = cythonize(gudhi),
+)