summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-02-16 14:58:11 +0000
committervrouvrea <vrouvrea@636b058d-ea47-450e-bf9e-a15bfbe3eedb>2017-02-16 14:58:11 +0000
commit518acce63202c7b89fa3f76467e50eee7630cf62 (patch)
treed9877e63720c6a6fa2cef113182fe1178c049cb1 /src
parentdf173dbefd275c54d8f5e33794d51709b887d2d3 (diff)
Remove pandas examples and use of OFF files interfaces to be more consistent (pandas interface is not that hard to be done)
Add of distance matrix in Rips git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/ST_cythonize@2081 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3a3b24f0824eed2710edb5bf17d120039973bf62
Diffstat (limited to 'src')
-rw-r--r--src/cython/CMakeLists.txt1
-rw-r--r--src/cython/cython/rips_complex.pyx40
-rw-r--r--src/cython/doc/installation.rst6
-rw-r--r--src/cython/doc/persistent_cohomology_user.rst3
-rw-r--r--src/cython/doc/rips_complex_user.rst126
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py71
-rwxr-xr-xsrc/cython/example/rips_complex_diagram_persistence_from_off_file_example.py (renamed from src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py)64
-rw-r--r--src/cython/include/Rips_complex_interface.h32
-rwxr-xr-xsrc/cython/test/test_rips_complex.py47
9 files changed, 329 insertions, 61 deletions
diff --git a/src/cython/CMakeLists.txt b/src/cython/CMakeLists.txt
index 8723d731..6f7d5de7 100644
--- a/src/cython/CMakeLists.txt
+++ b/src/cython/CMakeLists.txt
@@ -132,6 +132,7 @@ if(PYTHON_PATH AND CYTHON_PATH)
file(GLOB GUDHI_CUBICAL_PERSEUS_FILES "${CMAKE_SOURCE_DIR}/data/bitmap/*cubicalcomplexdoc.txt")
file(COPY ${GUDHI_CUBICAL_PERSEUS_FILES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
+ file(COPY "${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
# Persistence graphical tools examples
file(COPY "${CMAKE_SOURCE_DIR}/data/bitmap/3d_torus.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
file(COPY "${CMAKE_SOURCE_DIR}/data/points/tore3D_300.off" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc/")
diff --git a/src/cython/cython/rips_complex.pyx b/src/cython/cython/rips_complex.pyx
index 7e04ca4b..6bfb4482 100644
--- a/src/cython/cython/rips_complex.pyx
+++ b/src/cython/cython/rips_complex.pyx
@@ -33,9 +33,9 @@ __license__ = "GPL v3"
cdef extern from "Rips_complex_interface.h" namespace "Gudhi":
cdef cppclass Rips_complex_interface "Gudhi::rips_complex::Rips_complex_interface":
- Rips_complex_interface(vector[vector[double]] points, double threshold)
+ Rips_complex_interface(vector[vector[double]] values, double threshold, bool euclidean)
# bool from_file is a workaround for cython to find the correct signature
- Rips_complex_interface(string off_file, double threshold, bool from_file)
+ Rips_complex_interface(string file_name, double threshold, bool euclidean, bool from_file)
void create_simplex_tree(Simplex_tree_interface_full_featured* simplex_tree, int dim_max)
# RipsComplex python interface
@@ -49,9 +49,12 @@ cdef class RipsComplex:
cdef Rips_complex_interface * thisptr
# Fake constructor that does nothing but documenting the constructor
- def __init__(self, points=[], off_file='', max_edge_length=float('inf')):
+ def __init__(self, points=None, off_file='', distance_matrix=None, csv_file='', max_edge_length=float('inf')):
"""RipsComplex constructor.
+ :param max_edge_length: Rips value.
+ :type max_edge_length: int
+
:param points: A list of points in d-Dimension.
:type points: list of list of double
@@ -60,21 +63,44 @@ cdef class RipsComplex:
:param off_file: An OFF file style name.
:type off_file: string
- :param max_edge_length: Rips value.
- :type max_edge_length: int
+ Or
+
+ :param distance_matrix: A distance matrix (full square or lower
+ triangular).
+ :type points: list of list of double
+
+ Or
+
+ :param csv_file: A csv file style name containing a full square or a
+ lower triangular distance matrix.
+ :type csv_file: string
"""
# The real cython constructor
- def __cinit__(self, points=[], off_file='', max_edge_length=float('inf')):
+ def __cinit__(self, points=None, off_file='', distance_matrix=None, csv_file='', max_edge_length=float('inf')):
if off_file is not '':
if os.path.isfile(off_file):
self.thisptr = new Rips_complex_interface(off_file,
max_edge_length,
+ True,
True)
else:
print("file " + off_file + " not found.")
+ elif csv_file is not '':
+ if os.path.isfile(csv_file):
+ self.thisptr = new Rips_complex_interface(csv_file,
+ max_edge_length,
+ False,
+ True)
+ else:
+ print("file " + csv_file + " not found.")
+ elif distance_matrix is not None:
+ self.thisptr = new Rips_complex_interface(distance_matrix, max_edge_length, False)
else:
- self.thisptr = new Rips_complex_interface(points, max_edge_length)
+ if points is None:
+ # Empty Rips construction
+ points=[]
+ self.thisptr = new Rips_complex_interface(points, max_edge_length, True)
def __dealloc__(self):
diff --git a/src/cython/doc/installation.rst b/src/cython/doc/installation.rst
index 12d35821..20d97b3c 100644
--- a/src/cython/doc/installation.rst
+++ b/src/cython/doc/installation.rst
@@ -112,8 +112,9 @@ The following examples require the `Matplotlib <http://matplotlib.org>`_:
* :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>`
* :download:`gudhi_graphical_tools_example.py <../example/gudhi_graphical_tools_example.py>`
* :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>`
- * :download:`rips_complex_diagram_persistence_with_pandas_interface_example.py <../example/rips_complex_diagram_persistence_with_pandas_interface_example.py>`
+ * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>`
* :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>`
+ * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>`
* :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>`
Numpy
@@ -130,6 +131,7 @@ The following examples require the `NumPy <http://numpy.org>`_:
* :download:`alpha_complex_diagram_persistence_from_off_file_example.py <../example/alpha_complex_diagram_persistence_from_off_file_example.py>`
* :download:`gudhi_graphical_tools_example.py <../example/gudhi_graphical_tools_example.py>`
* :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>`
- * :download:`rips_complex_diagram_persistence_with_pandas_interface_example.py <../example/rips_complex_diagram_persistence_with_pandas_interface_example.py>`
+ * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>`
* :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>`
+ * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>`
* :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>`
diff --git a/src/cython/doc/persistent_cohomology_user.rst b/src/cython/doc/persistent_cohomology_user.rst
index 4ca4805d..d264a011 100644
--- a/src/cython/doc/persistent_cohomology_user.rst
+++ b/src/cython/doc/persistent_cohomology_user.rst
@@ -101,8 +101,9 @@ We provide several example files: run these examples with -h for details on thei
* :download:`alpha_complex_from_points_example.py <../example/alpha_complex_from_points_example.py>`
* :download:`periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py <../example/periodic_cubical_complex_barcode_persistence_from_perseus_file_example.py>`
- * :download:`rips_complex_diagram_persistence_with_pandas_interface_example.py <../example/rips_complex_diagram_persistence_with_pandas_interface_example.py>`
+ * :download:`rips_complex_diagram_persistence_from_off_file_example.py <../example/rips_complex_diagram_persistence_from_off_file_example.py>`
* :download:`rips_persistence_diagram.py <../example/rips_persistence_diagram.py>`
+ * :download:`rips_complex_diagram_persistence_from_distance_matrix_file_example.py <../example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py>`
* :download:`random_cubical_complex_persistence_example.py <../example/random_cubical_complex_persistence_example.py>`
* :download:`tangential_complex_plain_homology_from_off_file_example.py <../example/tangential_complex_plain_homology_from_off_file_example.py>`
diff --git a/src/cython/doc/rips_complex_user.rst b/src/cython/doc/rips_complex_user.rst
index be9481de..a5d17e19 100644
--- a/src/cython/doc/rips_complex_user.rst
+++ b/src/cython/doc/rips_complex_user.rst
@@ -38,16 +38,16 @@ set with :math:`max(filtration(4,5), filtration(4,6), filtration(5,6))`. And so
If the Rips_complex interfaces are not detailed enough for your need, please refer to rips_persistence_step_by_step.cpp
example, where the graph construction over the Simplex_tree is more detailed.
-Point cloud and distance function
----------------------------------
+Point cloud
+-----------
-Example from a point cloud and a distance function
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Example from a point cloud
+^^^^^^^^^^^^^^^^^^^^^^^^^^
-This example builds the one skeleton graph from the given points, threshold value, and distance function. Then it
-creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
+This example builds the one skeleton graph from the given points, and max_edge_length value.
+Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
-Then, it is asked to display information about the simplicial complex.
+Finally, it is asked to display information about the simplicial complex.
.. testcode::
@@ -63,7 +63,8 @@ Then, it is asked to display information about the simplicial complex.
for filtered_value in simplex_tree.get_filtered_tree():
print(filtered_value)
-The output is:
+When launching (Rips maximal distance between 2 points is 12.0, is expanded
+until dimension 1 - one skeleton graph in other words), the output is:
.. testoutput::
@@ -90,10 +91,11 @@ The output is:
Example from OFF file
^^^^^^^^^^^^^^^^^^^^^
-This example builds the :doc:`Rips_complex <rips_complex_ref>` from the given points in an OFF file, threshold value,
-and distance function. Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
+This example builds the :doc:`Rips_complex <rips_complex_ref>` from the given
+points in an OFF file, and max_edge_length value.
+Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
-Then, it is asked to display information about the Rips complex.
+Finally, it is asked to display information about the Rips complex.
.. testcode::
@@ -131,3 +133,105 @@ the program output is:
([0, 3], 9.433981132056603)
([4, 6], 9.486832980505138)
([3, 6], 11.0)
+
+Distance matrix
+---------------
+
+Example from a distance matrix
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This example builds the one skeleton graph from the given distance matrix, and max_edge_length value.
+Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
+
+Finally, it is asked to display information about the simplicial complex.
+
+.. testcode::
+
+ import gudhi
+ rips_complex = gudhi.RipsComplex(distance_matrix=[[],
+ [6.0827625303],
+ [5.8309518948, 6.7082039325],
+ [9.4339811321, 6.3245553203, 5],
+ [13.0384048104, 15.6524758425, 8.94427191, 12.0415945788],
+ [18.0277563773, 19.6468827044, 13.152946438, 14.7648230602, 5.3851648071],
+ [17.88854382, 17.1172427686, 12.0830459736, 11, 9.4868329805, 7.2801098893]],
+ max_edge_length=12.0)
+
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
+ result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \
+ repr(simplex_tree.num_simplices()) + ' simplices - ' + \
+ repr(simplex_tree.num_vertices()) + ' vertices.'
+ print(result_str)
+ for filtered_value in simplex_tree.get_filtered_tree():
+ print(filtered_value)
+
+When launching (Rips maximal distance between 2 points is 12.0, is expanded
+until dimension 1 - one skeleton graph in other words), the output is:
+
+.. testoutput::
+
+ Rips complex is of dimension 1 - 18 simplices - 7 vertices.
+ ([0], 0.0)
+ ([1], 0.0)
+ ([2], 0.0)
+ ([3], 0.0)
+ ([4], 0.0)
+ ([5], 0.0)
+ ([6], 0.0)
+ ([2, 3], 5.0)
+ ([4, 5], 5.3851648071)
+ ([0, 2], 5.8309518948)
+ ([0, 1], 6.0827625303)
+ ([1, 3], 6.3245553203)
+ ([1, 2], 6.7082039325)
+ ([5, 6], 7.2801098893)
+ ([2, 4], 8.94427191)
+ ([0, 3], 9.4339811321)
+ ([4, 6], 9.4868329805)
+ ([3, 6], 11.0)
+
+Example from OFF file
+^^^^^^^^^^^^^^^^^^^^^
+
+This example builds the :doc:`Rips_complex <rips_complex_ref>` from the given
+points in an OFF file, and max_edge_length value.
+Then it creates a :doc:`Simplex_tree <simplex_tree_ref>` with it.
+
+Finally, it is asked to display information about the Rips complex.
+
+
+.. testcode::
+
+ import gudhi
+ rips_complex = gudhi.RipsComplex(csv_file='full_square_distance_matrix.csv', max_edge_length=12.0)
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
+ result_str = 'Rips complex is of dimension ' + repr(simplex_tree.dimension()) + ' - ' + \
+ repr(simplex_tree.num_simplices()) + ' simplices - ' + \
+ repr(simplex_tree.num_vertices()) + ' vertices.'
+ print(result_str)
+ for filtered_value in simplex_tree.get_filtered_tree():
+ print(filtered_value)
+
+the program output is:
+
+.. testoutput::
+
+ Rips complex is of dimension 1 - 18 simplices - 7 vertices.
+ ([0], 0.0)
+ ([1], 0.0)
+ ([2], 0.0)
+ ([3], 0.0)
+ ([4], 0.0)
+ ([5], 0.0)
+ ([6], 0.0)
+ ([2, 3], 5.0)
+ ([4, 5], 5.3851648071)
+ ([0, 2], 5.8309518948)
+ ([0, 1], 6.0827625303)
+ ([1, 3], 6.3245553203)
+ ([1, 2], 6.7082039325)
+ ([5, 6], 7.2801098893)
+ ([2, 4], 8.94427191)
+ ([0, 3], 9.4339811321)
+ ([4, 6], 9.4868329805)
+ ([3, 6], 11.0)
diff --git a/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
new file mode 100755
index 00000000..2b726f90
--- /dev/null
+++ b/src/cython/example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+
+import gudhi
+import argparse
+
+"""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
+
+ 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/>.
+"""
+
+__author__ = "Vincent Rouvreau"
+__copyright__ = "Copyright (C) 2016 INRIA"
+__license__ = "GPL v3"
+
+parser = argparse.ArgumentParser(description='RipsComplex creation from '
+ 'a distance matrix read in a OFF file.',
+ epilog='Example: '
+ 'example/rips_complex_diagram_persistence_from_distance_matrix_file_example.py '
+ '-f ../data/distance_matrix/lower_triangular_distance_matrix.csv -e 12.0 -d 3'
+ '- Constructs a Rips complex with the '
+ 'points from the given OFF file.')
+parser.add_argument("-f", "--file", type=str, required=True)
+parser.add_argument("-e", "--max_edge_length", type=float, default=0.5)
+parser.add_argument("-d", "--max_dimension", type=int, default=1)
+parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
+
+args = parser.parse_args()
+
+with open(args.file, 'r') as f:
+ first_line = f.readline()
+ if (first_line == 'OFF\n') or (first_line == 'nOFF\n'):
+ print("#####################################################################")
+ print("RipsComplex creation from distance matrix read in a csv file")
+
+ message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length)
+ print(message)
+
+ rips_complex = gudhi.RipsComplex(off_file=args.file, max_edge_length=args.max_edge_length)
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
+
+ message = "Number of simplices=" + repr(simplex_tree.num_simplices())
+ print(message)
+
+ diag = simplex_tree.persistence()
+
+ print("betti_numbers()=")
+ print(simplex_tree.betti_numbers())
+
+ if args.no_diagram == False:
+ gudhi.diagram_persistence(diag)
+ else:
+ print(args.file, "is not a valid OFF file")
+
+ f.close()
diff --git a/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
index 8af1b767..eb1c4ed5 100755
--- a/src/cython/example/rips_complex_diagram_persistence_with_pandas_interface_example.py
+++ b/src/cython/example/rips_complex_diagram_persistence_from_off_file_example.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
import gudhi
-import pandas
import argparse
"""This file is part of the Gudhi Library. The Gudhi library
@@ -30,40 +29,43 @@ __author__ = "Vincent Rouvreau"
__copyright__ = "Copyright (C) 2016 INRIA"
__license__ = "GPL v3"
-print("#####################################################################")
-print("RipsComplex creation from points read in a file")
-
parser = argparse.ArgumentParser(description='RipsComplex creation from '
- 'points read in a file.',
+ 'points read in a OFF file.',
epilog='Example: '
- 'example/rips_complex_diagram_persistence_with_pandas_interface_example.py '
- '../data/2000_random_points_on_3D_Torus.csv '
- '- Constructs a rips complex with the '
- 'points from the given file. File format '
- 'is X1, X2, ..., Xn')
+ 'example/rips_complex_diagram_persistence_from_off_file_example.py '
+ '-f ../data/points/tore3D_300.off -a 0.6'
+ '- Constructs a Rips complex with the '
+ 'points from the given OFF file.')
parser.add_argument("-f", "--file", type=str, required=True)
-parser.add_argument("-e", "--max-edge-length", type=float, default=0.5)
+parser.add_argument("-e", "--max_edge_length", type=float, default=0.5)
+parser.add_argument("-d", "--max_dimension", type=int, default=1)
parser.add_argument('--no-diagram', default=False, action='store_true' , help='Flag for not to display the diagrams')
args = parser.parse_args()
-points = pandas.read_csv(args.file, header=None)
-
-message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length)
-print(message)
-
-rips_complex = gudhi.RipsComplex(points=points.values,
- max_edge_length=args.max_edge_length)
-
-simplex_tree = rips_complex.create_simplex_tree(max_dimension=len(points.values[0]))
-
-message = "Number of simplices=" + repr(simplex_tree.num_simplices())
-print(message)
-
-diag = simplex_tree.persistence()
-
-print("betti_numbers()=")
-print(simplex_tree.betti_numbers())
-
-if args.no_diagram == False:
- gudhi.diagram_persistence(diag)
+with open(args.file, 'r') as f:
+ first_line = f.readline()
+ if (first_line == 'OFF\n') or (first_line == 'nOFF\n'):
+ print("#####################################################################")
+ print("RipsComplex creation from points read in a OFF file")
+
+ message = "RipsComplex with max_edge_length=" + repr(args.max_edge_length)
+ print(message)
+
+ rips_complex = gudhi.RipsComplex(off_file=args.file, max_edge_length=args.max_edge_length)
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=args.max_dimension)
+
+ message = "Number of simplices=" + repr(simplex_tree.num_simplices())
+ print(message)
+
+ diag = simplex_tree.persistence()
+
+ print("betti_numbers()=")
+ print(simplex_tree.betti_numbers())
+
+ if args.no_diagram == False:
+ gudhi.diagram_persistence(diag)
+ else:
+ print(args.file, "is not a valid OFF file")
+
+ f.close()
diff --git a/src/cython/include/Rips_complex_interface.h b/src/cython/include/Rips_complex_interface.h
index 7e897b1d..9295906c 100644
--- a/src/cython/include/Rips_complex_interface.h
+++ b/src/cython/include/Rips_complex_interface.h
@@ -27,6 +27,7 @@
#include <gudhi/Rips_complex.h>
#include <gudhi/Points_off_io.h>
#include <gudhi/distance_functions.h>
+#include <gudhi/reader_utils.h>
#include "Simplex_tree_interface.h"
@@ -41,17 +42,34 @@ namespace rips_complex {
class Rips_complex_interface {
using Point_d = std::vector<double>;
+ using Distance_matrix = std::vector<std::vector<Simplex_tree_interface<>::Filtration_value>>;
public:
- Rips_complex_interface(std::vector<std::vector<double>>&points, double threshold) {
- rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(points, threshold,
- Euclidean_distance());
+ Rips_complex_interface(std::vector<std::vector<double>>&values, double threshold, bool euclidean) {
+ if (euclidean) {
+ // Rips construction where values is a vector of points
+ rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(values, threshold,
+ Euclidean_distance());
+ } else {
+ // Rips construction where values is a distance matrix
+ rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(values, threshold);
+
+ }
}
- Rips_complex_interface(std::string off_file_name, double threshold, bool from_file = true) {
- Gudhi::Points_off_reader<Point_d> off_reader(off_file_name);
- rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(off_reader.get_point_cloud(),
- threshold, Euclidean_distance());
+ Rips_complex_interface(std::string file_name, double threshold, bool euclidean, bool from_file = true) {
+ if (euclidean) {
+ // Rips construction where file_name is an OFF file
+ Gudhi::Points_off_reader<Point_d> off_reader(file_name);
+ rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(off_reader.get_point_cloud(),
+ threshold, Euclidean_distance());
+ } else {
+ // Rips construction where values is a distance matrix
+ Distance_matrix distances = read_lower_triangular_matrix_from_csv_file<Simplex_tree_interface<>::Filtration_value>(file_name);
+ rips_complex_ = new Rips_complex<Simplex_tree_interface<>::Filtration_value>(distances, threshold);
+
+ }
+
}
void create_simplex_tree(Simplex_tree_interface<>* simplex_tree, int dim_max) {
diff --git a/src/cython/test/test_rips_complex.py b/src/cython/test/test_rips_complex.py
index 687e8529..464c69e5 100755
--- a/src/cython/test/test_rips_complex.py
+++ b/src/cython/test/test_rips_complex.py
@@ -1,4 +1,5 @@
from gudhi import RipsComplex
+from math import sqrt
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
@@ -31,7 +32,7 @@ def test_empty_rips():
rips_complex = RipsComplex()
assert rips_complex.__is_defined() == True
-def test_rips():
+def test_rips_from_points():
point_list = [[0, 0], [1, 0], [0, 1], [1, 1]]
rips_complex = RipsComplex(points=point_list, max_edge_length=42)
@@ -55,7 +56,7 @@ def test_rips():
[([0, 1], 1.0), ([0, 2], 1.0),
([0, 3], 1.4142135623730951)]
-def test_filtered_rips():
+def test_filtered_rips_from_points():
point_list = [[0, 0], [1, 0], [0, 1], [1, 1]]
filtered_rips = RipsComplex(points=point_list, max_edge_length=1.0)
@@ -66,3 +67,45 @@ def test_filtered_rips():
assert simplex_tree.num_simplices() == 8
assert simplex_tree.num_vertices() == 4
+
+def test_rips_from_distance_matrix():
+ distance_matrix = [[0],
+ [1, 0],
+ [1, sqrt(2), 0],
+ [sqrt(2), 1, 1, 0]]
+ rips_complex = RipsComplex(distance_matrix=distance_matrix, max_edge_length=42)
+
+ simplex_tree = rips_complex.create_simplex_tree(max_dimension=1)
+
+ assert simplex_tree.__is_defined() == True
+ assert simplex_tree.__is_persistence_defined() == False
+
+ assert simplex_tree.num_simplices() == 10
+ assert simplex_tree.num_vertices() == 4
+
+ assert simplex_tree.get_filtered_tree() == \
+ [([0], 0.0), ([1], 0.0), ([2], 0.0), ([3], 0.0),
+ ([0, 1], 1.0), ([0, 2], 1.0), ([1, 3], 1.0),
+ ([2, 3], 1.0), ([1, 2], 1.4142135623730951),
+ ([0, 3], 1.4142135623730951)]
+ assert simplex_tree.get_star_tree([0]) == \
+ [([0], 0.0), ([0, 1], 1.0), ([0, 2], 1.0),
+ ([0, 3], 1.4142135623730951)]
+ assert simplex_tree.get_coface_tree([0], 1) == \
+ [([0, 1], 1.0), ([0, 2], 1.0),
+ ([0, 3], 1.4142135623730951)]
+
+def test_filtered_rips_from_distance_matrix():
+ distance_matrix = [[0],
+ [1, 0],
+ [1, sqrt(2), 0],
+ [sqrt(2), 1, 1, 0]]
+ filtered_rips = RipsComplex(distance_matrix=distance_matrix, max_edge_length=1.0)
+
+ simplex_tree = filtered_rips.create_simplex_tree(max_dimension=1)
+
+ assert simplex_tree.__is_defined() == True
+ assert simplex_tree.__is_persistence_defined() == False
+
+ assert simplex_tree.num_simplices() == 8
+ assert simplex_tree.num_vertices() == 4