summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorROUVREAU Vincent <vincent.rouvreau@inria.fr>2019-06-27 21:51:22 +0200
committerROUVREAU Vincent <vincent.rouvreau@inria.fr>2019-06-27 21:51:22 +0200
commit6a91777aa7229536d177430aadc4d7e37274cdcb (patch)
tree2ee056688826f72bedc36699b869c8dede58b332 /src
parent68fadb4ebfe5b35a2eec99a9babafbee940a1b42 (diff)
parent9f249e001089af45186aaf0d196d6300705eee31 (diff)
Merge branch 'master' of github.com:GUDHI/gudhi-devel
Diffstat (limited to 'src')
-rw-r--r--src/Bottleneck_distance/doc/Intro_bottleneck_distance.h43
-rw-r--r--src/Bottleneck_distance/doc/bottleneck_distance_example.ipe287
-rw-r--r--src/Bottleneck_distance/doc/bottleneck_distance_example.pngbin0 -> 19485 bytes
-rw-r--r--src/Bottleneck_distance/example/bottleneck_basic_example.cpp22
-rw-r--r--src/Bottleneck_distance/include/gudhi/Bottleneck.h7
-rw-r--r--src/Persistent_cohomology/doc/Intro_persistent_cohomology.h69
-rw-r--r--src/Persistent_cohomology/example/plain_homology.cpp27
-rw-r--r--src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h18
-rw-r--r--src/common/doc/main_page.md32
-rw-r--r--src/cython/cython/cubical_complex.pyx8
-rw-r--r--src/cython/cython/periodic_cubical_complex.pyx10
-rw-r--r--src/cython/cython/persistence_graphical_tools.py55
-rw-r--r--src/cython/cython/reader_utils.pyx34
-rw-r--r--src/cython/cython/simplex_tree.pyx8
-rw-r--r--src/cython/doc/bottleneck_distance_sum.inc4
-rw-r--r--src/cython/doc/bottleneck_distance_user.rst37
-rw-r--r--src/cython/setup.py.in8
-rwxr-xr-xsrc/cython/test/test_reader_utils.py19
18 files changed, 520 insertions, 168 deletions
diff --git a/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h b/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h
index 6fd058a8..7cb0752e 100644
--- a/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h
+++ b/src/Bottleneck_distance/doc/Intro_bottleneck_distance.h
@@ -6,6 +6,9 @@
*
* Copyright (C) 2015 Inria
*
+ * Modifications:
+ * - 2019/06 Vincent Rouvreau : Fix #11 - Distance computation shall be better documented.
+ *
* 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
@@ -37,13 +40,51 @@ namespace persistence_diagram {
*
* The bottleneck distance measures the similarity between two persistence diagrams. It is the shortest distance b for
* which there exists a perfect matching between the points of the two diagrams (completed with all the points on the
- * diagonal in order to ignore cardinality mismatchs) such that any couple of matched points are at distance at most b.
+ * diagonal in order to ignore cardinality mismatchs) such that any couple of matched points are at distance at most b,
+ * where the distance between points is the sup norm in \f$\mathbb{R}^2\f$ (not the Euclidean distance).
*
* \image html perturb_pd.png On this picture, the red edges represent the matching. The bottleneck distance is the length of the longest edge.
*
* This implementation is based on ideas from "Geometry Helps in Bottleneck Matching and Related Problems"
* \cite DBLP:journals/algorithmica/EfratIK01. Another relevant publication, although it was not used is
* "Geometry Helps to Compare Persistence Diagrams" \cite Kerber:2017:GHC:3047249.3064175.
+ *
+ * \section bottleneckdistanceprecision Distance computation
+ *
+ * The following example explains how the distance is computed:
+ *
+ * \code{.cpp}
+#include <gudhi/Bottleneck.h>
+
+#include <iostream>
+#include <vector>
+#include <utility> // for pair
+
+int main() {
+ std::vector< std::pair<double, double> > diag1, diag2;
+ diag1.emplace_back(0., 0.);
+ diag2.emplace_back(0., 13.);
+
+ double b = Gudhi::persistence_diagram::bottleneck_distance(diag1, diag2);
+ std::cout << "Bottleneck distance = " << b << std::endl;
+}
+ * \endcode
+ *
+ * \code Bottleneck distance = 6.5
+ * \endcode
+ *
+ * \image html bottleneck_distance_example.png The point (0, 13) is at distance 6.5 from the diagonal and more specifically from the point (6.5, 6.5)
+ *
+ * \section bottleneckbasicexample Basic example
+ *
+ * This other example computes the bottleneck distance from 2 persistence diagrams:
+ * \include Bottleneck_distance/bottleneck_basic_example.cpp
+ *
+ * \code
+ Bottleneck distance = 0.75
+ Approx bottleneck distance = 0.808176
+ * \endcode
+
*/
/** @} */ // end defgroup bottleneck_distance
diff --git a/src/Bottleneck_distance/doc/bottleneck_distance_example.ipe b/src/Bottleneck_distance/doc/bottleneck_distance_example.ipe
new file mode 100644
index 00000000..2033ea56
--- /dev/null
+++ b/src/Bottleneck_distance/doc/bottleneck_distance_example.ipe
@@ -0,0 +1,287 @@
+<?xml version="1.0"?>
+<!DOCTYPE ipe SYSTEM "ipe.dtd">
+<ipe version="70206" creator="Ipe 7.2.7">
+<info created="D:20190606115351" modified="D:20190607172542"/>
+<ipestyle name="basic">
+<symbol name="arrow/arc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/farc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/ptarc(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fptarc(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="mark/circle(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</symbol>
+<symbol name="mark/disk(sx)" transformations="translations">
+<path fill="sym-stroke">
+0.6 0 0 0.6 0 0 e
+</path>
+</symbol>
+<symbol name="mark/fdisk(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+0.5 0 0 0.5 0 0 e
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+0.6 0 0 0.6 0 0 e
+0.4 0 0 0.4 0 0 e
+</path>
+</group>
+</symbol>
+<symbol name="mark/box(sx)" transformations="translations">
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</symbol>
+<symbol name="mark/square(sx)" transformations="translations">
+<path fill="sym-stroke">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+</path>
+</symbol>
+<symbol name="mark/fsquare(sfx)" transformations="translations">
+<group>
+<path fill="sym-fill">
+-0.5 -0.5 m
+0.5 -0.5 l
+0.5 0.5 l
+-0.5 0.5 l
+h
+</path>
+<path fill="sym-stroke" fillrule="eofill">
+-0.6 -0.6 m
+0.6 -0.6 l
+0.6 0.6 l
+-0.6 0.6 l
+h
+-0.4 -0.4 m
+0.4 -0.4 l
+0.4 0.4 l
+-0.4 0.4 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="mark/cross(sx)" transformations="translations">
+<group>
+<path fill="sym-stroke">
+-0.43 -0.57 m
+0.57 0.43 l
+0.43 0.57 l
+-0.57 -0.43 l
+h
+</path>
+<path fill="sym-stroke">
+-0.43 0.57 m
+0.57 -0.43 l
+0.43 -0.57 l
+-0.57 0.43 l
+h
+</path>
+</group>
+</symbol>
+<symbol name="arrow/fnormal(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/pointed(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/fpointed(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-0.8 0 l
+-1 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/linear(spx)">
+<path stroke="sym-stroke" pen="sym-pen">
+-1 0.333 m
+0 0 l
+-1 -0.333 l
+</path>
+</symbol>
+<symbol name="arrow/fdouble(spx)">
+<path stroke="sym-stroke" fill="white" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<symbol name="arrow/double(spx)">
+<path stroke="sym-stroke" fill="sym-stroke" pen="sym-pen">
+0 0 m
+-1 0.333 l
+-1 -0.333 l
+h
+-1 0 m
+-2 0.333 l
+-2 -0.333 l
+h
+</path>
+</symbol>
+<pen name="heavier" value="0.8"/>
+<pen name="fat" value="1.2"/>
+<pen name="ultrafat" value="2"/>
+<symbolsize name="large" value="5"/>
+<symbolsize name="small" value="2"/>
+<symbolsize name="tiny" value="1.1"/>
+<arrowsize name="large" value="10"/>
+<arrowsize name="small" value="5"/>
+<arrowsize name="tiny" value="3"/>
+<color name="red" value="1 0 0"/>
+<color name="green" value="0 1 0"/>
+<color name="blue" value="0 0 1"/>
+<color name="yellow" value="1 1 0"/>
+<color name="orange" value="1 0.647 0"/>
+<color name="gold" value="1 0.843 0"/>
+<color name="purple" value="0.627 0.125 0.941"/>
+<color name="gray" value="0.745"/>
+<color name="brown" value="0.647 0.165 0.165"/>
+<color name="navy" value="0 0 0.502"/>
+<color name="pink" value="1 0.753 0.796"/>
+<color name="seagreen" value="0.18 0.545 0.341"/>
+<color name="turquoise" value="0.251 0.878 0.816"/>
+<color name="violet" value="0.933 0.51 0.933"/>
+<color name="darkblue" value="0 0 0.545"/>
+<color name="darkcyan" value="0 0.545 0.545"/>
+<color name="darkgray" value="0.663"/>
+<color name="darkgreen" value="0 0.392 0"/>
+<color name="darkmagenta" value="0.545 0 0.545"/>
+<color name="darkorange" value="1 0.549 0"/>
+<color name="darkred" value="0.545 0 0"/>
+<color name="lightblue" value="0.678 0.847 0.902"/>
+<color name="lightcyan" value="0.878 1 1"/>
+<color name="lightgray" value="0.827"/>
+<color name="lightgreen" value="0.565 0.933 0.565"/>
+<color name="lightyellow" value="1 1 0.878"/>
+<dashstyle name="dashed" value="[4] 0"/>
+<dashstyle name="dotted" value="[1 3] 0"/>
+<dashstyle name="dash dotted" value="[4 2 1 2] 0"/>
+<dashstyle name="dash dot dotted" value="[4 2 1 2 1 2] 0"/>
+<textsize name="large" value="\large"/>
+<textsize name="small" value="\small"/>
+<textsize name="tiny" value="\tiny"/>
+<textsize name="Large" value="\Large"/>
+<textsize name="LARGE" value="\LARGE"/>
+<textsize name="huge" value="\huge"/>
+<textsize name="Huge" value="\Huge"/>
+<textsize name="footnote" value="\footnotesize"/>
+<textstyle name="center" begin="\begin{center}" end="\end{center}"/>
+<textstyle name="itemize" begin="\begin{itemize}" end="\end{itemize}"/>
+<textstyle name="item" begin="\begin{itemize}\item{}" end="\end{itemize}"/>
+<gridsize name="4 pts" value="4"/>
+<gridsize name="8 pts (~3 mm)" value="8"/>
+<gridsize name="16 pts (~6 mm)" value="16"/>
+<gridsize name="32 pts (~12 mm)" value="32"/>
+<gridsize name="10 pts (~3.5 mm)" value="10"/>
+<gridsize name="20 pts (~7 mm)" value="20"/>
+<gridsize name="14 pts (~5 mm)" value="14"/>
+<gridsize name="28 pts (~10 mm)" value="28"/>
+<gridsize name="56 pts (~20 mm)" value="56"/>
+<anglesize name="90 deg" value="90"/>
+<anglesize name="60 deg" value="60"/>
+<anglesize name="45 deg" value="45"/>
+<anglesize name="30 deg" value="30"/>
+<anglesize name="22.5 deg" value="22.5"/>
+<opacity name="10%" value="0.1"/>
+<opacity name="30%" value="0.3"/>
+<opacity name="50%" value="0.5"/>
+<opacity name="75%" value="0.75"/>
+<tiling name="falling" angle="-60" step="4" width="1"/>
+<tiling name="rising" angle="30" step="4" width="1"/>
+</ipestyle>
+<page>
+<layer name="alpha"/>
+<view layers="alpha" active="alpha"/>
+<path layer="alpha" stroke="black" arrow="normal/normal">
+160 256 m
+288 256 l
+</path>
+<path stroke="black" arrow="normal/normal">
+160 256 m
+160 384 l
+</path>
+<path stroke="navy">
+160 256 m
+264 360 l
+264 360 l
+</path>
+<use name="mark/fdisk(sfx)" pos="160 256" size="normal" stroke="red" fill="red"/>
+<use name="mark/fdisk(sfx)" pos="160 360" size="normal" stroke="navy" fill="navy"/>
+<path stroke="red">
+200 296 m
+224 320 l
+</path>
+<text matrix="1 0 0 1 -32 8" transformations="translations" pos="164 248" stroke="red" type="label" width="23.8" height="7.473" depth="2.49" valign="baseline">(0, 0)</text>
+<text matrix="1 0 0 1 -4 4" transformations="translations" pos="132 356" stroke="navy" type="label" width="28.781" height="7.473" depth="2.49" valign="baseline">(0, 13)</text>
+<text transformations="translations" pos="216 300" stroke="black" type="label" width="39.297" height="7.473" depth="2.49" valign="baseline">(6.5, 6.5)</text>
+<path stroke="black" arrow="normal/normal" rarrow="normal/normal">
+160.433 359.995 m
+213.999 309.986 l
+</path>
+<use name="mark/cross(sx)" pos="214.209 309.567" size="normal" stroke="black"/>
+<text matrix="1 0 0 1 6.00021 -25.5247" transformations="translations" pos="174.375 385.835" stroke="black" type="minipage" width="73.2406" height="11.924" depth="6.95" valign="top">Bottleneck
+distance is 6.5</text>
+</page>
+</ipe>
diff --git a/src/Bottleneck_distance/doc/bottleneck_distance_example.png b/src/Bottleneck_distance/doc/bottleneck_distance_example.png
new file mode 100644
index 00000000..1d3b91aa
--- /dev/null
+++ b/src/Bottleneck_distance/doc/bottleneck_distance_example.png
Binary files differ
diff --git a/src/Bottleneck_distance/example/bottleneck_basic_example.cpp b/src/Bottleneck_distance/example/bottleneck_basic_example.cpp
index 3df7d12d..61778a55 100644
--- a/src/Bottleneck_distance/example/bottleneck_basic_example.cpp
+++ b/src/Bottleneck_distance/example/bottleneck_basic_example.cpp
@@ -1,25 +1,3 @@
-/* This file is part of the Gudhi Library. The Gudhi library
- * (Geometric Understanding in Higher Dimensions) is a generic C++
- * library for computational topology.
- *
- * Authors: Francois Godi, small modifications by Pawel Dlotko
- *
- * Copyright (C) 2015 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/>.
- */
-
#include <gudhi/Bottleneck.h>
#include <iostream>
diff --git a/src/Bottleneck_distance/include/gudhi/Bottleneck.h b/src/Bottleneck_distance/include/gudhi/Bottleneck.h
index 7a553006..4ce6cacc 100644
--- a/src/Bottleneck_distance/include/gudhi/Bottleneck.h
+++ b/src/Bottleneck_distance/include/gudhi/Bottleneck.h
@@ -6,6 +6,9 @@
*
* Copyright (C) 2015 Inria
*
+ * Modifications:
+ * - 2019/06 Vincent Rouvreau : Fix doxygen warning.
+ *
* 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
@@ -92,6 +95,10 @@ inline double bottleneck_distance_exact(Persistence_graph& g) {
*
* \tparam Persistence_diagram1,Persistence_diagram2
* models of the concept `PersistenceDiagram`.
+ *
+ * \param[in] diag1 The first persistence diagram.
+ * \param[in] diag2 The second persistence diagram.
+ *
* \param[in] e
* \parblock
* If `e` is 0, this uses an expensive algorithm to compute the exact distance.
diff --git a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
index 5fb9d4d2..3d28c93a 100644
--- a/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
+++ b/src/Persistent_cohomology/doc/Intro_persistent_cohomology.h
@@ -154,6 +154,8 @@ diagram.
3 1 0.104347 inf
3 2 0.138335 inf \endcode
+More details on the <a href="../../ripscomplex/">Rips complex utilities</a> dedicated page.
+
\li <a href="_persistent_cohomology_2rips_multifield_persistence_8cpp-example.html">
Persistent_cohomology/rips_multifield_persistence.cpp</a> computes the Rips complex of a point cloud and outputs its
persistence diagram with a family of field coefficients.
@@ -166,6 +168,8 @@ The file should contain square or lower triangular distance matrix with semicolo
The code do not check if it is dealing with a distance matrix. It is the user responsibility to provide a valid input.
Please refer to data/distance_matrix/lower_triangular_distance_matrix.csv for an example of a file.
+More details on the <a href="../../ripscomplex/">Rips complex utilities</a> dedicated page.
+
\li <a href="_rips_complex_2rips_correlation_matrix_persistence_8cpp-example.html">
Rips_complex/rips_correlation_matrix_persistence.cpp</a>
computes the Rips complex of a correlation matrix and outputs its persistence diagram.
@@ -175,6 +179,8 @@ It is the user responsibility to ensure that this is the case. The input is to b
triangular matrix.
Please refer to data/correlation_matrix/lower_triangular_correlation_matrix.csv for an example of a file.
+More details on the <a href="../../ripscomplex/">Rips complex utilities</a> dedicated page.
+
\li <a href="_alpha_complex_2alpha_complex_3d_persistence_8cpp-example.html">
Alpha_complex/alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
@@ -185,48 +191,33 @@ Alpha_complex/alpha_complex_3d_persistence.cpp</a> computes the persistent homol
2 1 0.0934117 1.00003
2 2 0.56444 1.03938 \endcode
-\li <a href="_alpha_complex_2exact_alpha_complex_3d_persistence_8cpp-example.html">
-Alpha_complex/exact_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
-\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
-Here, as CGAL computes the exact values, it is slower, but it is necessary when points are on a grid
-for instance.
-\code $> ./exact_alpha_complex_3d_persistence ../../data/points/sphere3D_pts_on_grid.off -p 2 -m 0.1 \endcode
+More details on the <a href="../../alphacomplex/">Alpha complex utilities</a> dedicated page.
+
+CGAL can be forced to compute the exact values, it is slower, but it is necessary when points are on a grid
+for instance (the fast version `--fast` would give incorrect values).
+\code $> ./alpha_complex_3d_persistence ../../data/points/sphere3D_pts_on_grid.off --exact -p 2 -m 0.1 \endcode
\code Simplex_tree dim: 3
2 0 0 inf
2 2 0.0002 0.2028 \endcode
-\li <a href="_alpha_complex_2weighted_alpha_complex_3d_persistence_8cpp-example.html">
-Alpha_complex/weighted_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
+It can also compute the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the weighted alpha complex on points sampling from an OFF file
and a weights file.
-\code $> ./weighted_alpha_complex_3d_persistence ../../data/points/tore3D_300.off
-../../data/points/tore3D_300.weights -p 2 -m 0.45 \endcode
+\code $> ./alpha_complex_3d_persistence ../../data/points/tore3D_300.off
+--weight-file ../../data/points/tore3D_300.weights -p 2 -m 0.45 \endcode
\code Simplex_tree dim: 3
2 0 -1 inf
2 1 -0.931784 0.000103311
2 1 -0.906588 2.60165e-05
2 2 -0.43556 0.0393798 \endcode
-\li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
-Alpha_complex/alpha_complex_persistence.cpp</a> computes the persistent homology with
-\f$\mathbb{Z}/p\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
-\code $> ./alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off \endcode
-\code Alpha complex is of dimension 3 - 9273 simplices - 300 vertices.
-Simplex_tree dim: 3
-2 0 0 inf
-2 1 0.0682162 1.0001
-2 1 0.0934117 1.00003
-2 2 0.56444 1.03938 \endcode
-
-\li <a href="_alpha_complex_2periodic_alpha_complex_3d_persistence_8cpp-example.html">
-Alpha_complex/periodic_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
+One can also compute the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on points sampling from an OFF file.
The second parameter is a \ref FileFormatsIsoCuboid file with coordinates of the periodic cuboid.
Note that the lengths of the sides of the periodic cuboid have to be the same.
-\code $> ./periodic_alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off
-../../data/points/iso_cuboid_3_in_0_1.txt -p 3 -m 1.0 \endcode
-\code Periodic Delaunay computed.
-Simplex_tree dim: 3
+\code $> ./alpha_complex_3d_persistence ../../data/points/grid_10_10_10_in_0_1.off
+--cuboid-file ../../data/points/iso_cuboid_3_in_0_1.txt -p 3 -m 1.0 \endcode
+\code Simplex_tree dim: 3
3 0 0 inf
3 1 0.0025 inf
3 1 0.0025 inf
@@ -236,18 +227,17 @@ Simplex_tree dim: 3
3 2 0.005 inf
3 3 0.0075 inf \endcode
-\li <a href="_persistent_cohomology_2weighted_periodic_alpha_complex_3d_persistence_8cpp-example.html">
-Persistent_cohomology/weighted_periodic_alpha_complex_3d_persistence.cpp</a> computes the persistent homology with
+In order to compute the persistent homology with
\f$\mathbb{Z}/2\mathbb{Z}\f$ coefficients of the periodic alpha complex on weighted points from an OFF file. The
additional parameters of this program are:<br>
(a) The file with the weights of points. The file consist of a sequence of numbers (as many as points).
Note that the weight of each single point have to be bounded by 1/64 times the square of the cuboid edge length.<br>
(b) A \ref FileFormatsIsoCuboid file with coordinates of the periodic cuboid.
Note that the lengths of the sides of the periodic cuboid have to be the same.<br>
-\code $> ./weighted_periodic_alpha_complex_3d_persistence ../../data/points/shifted_sphere.off
-../../data/points/shifted_sphere.weights ../../data/points/iso_cuboid_3_in_0_10.txt 3 1.0 \endcode
-\code Weighted Periodic Delaunay computed.
-Simplex_tree dim: 3
+\code $> ./alpha_complex_3d_persistence ../../data/points/shifted_sphere.off
+--weight-file ../../data/points/shifted_sphere.weights
+--cuboid-file ../../data/points/iso_cuboid_3_in_0_10.txt -p 3 -m 1.0 \endcode
+\code Simplex_tree dim: 3
3 0 -0.0001 inf
3 1 16.0264 inf
3 1 16.0273 inf
@@ -257,6 +247,19 @@ Simplex_tree dim: 3
3 2 36.8838 inf
3 3 58.6783 inf \endcode
+\li <a href="_alpha_complex_2alpha_complex_persistence_8cpp-example.html">
+Alpha_complex/alpha_complex_persistence.cpp</a> computes the persistent homology with
+\f$\mathbb{Z}/p\mathbb{Z}\f$ coefficients of the alpha complex on points sampling from an OFF file.
+\code $> ./alpha_complex_persistence -r 32 -p 2 -m 0.45 ../../data/points/tore3D_300.off \endcode
+\code Alpha complex is of dimension 3 - 9273 simplices - 300 vertices.
+Simplex_tree dim: 3
+2 0 0 inf
+2 1 0.0682162 1.0001
+2 1 0.0934117 1.00003
+2 2 0.56444 1.03938 \endcode
+
+More details on the <a href="../../alphacomplex/">Alpha complex utilities</a> dedicated page.
+
\li <a href="_persistent_cohomology_2plain_homology_8cpp-example.html">
Persistent_cohomology/plain_homology.cpp</a> computes the plain homology of a simple simplicial complex without
filtration values.
diff --git a/src/Persistent_cohomology/example/plain_homology.cpp b/src/Persistent_cohomology/example/plain_homology.cpp
index a2256060..1c70ba5d 100644
--- a/src/Persistent_cohomology/example/plain_homology.cpp
+++ b/src/Persistent_cohomology/example/plain_homology.cpp
@@ -50,26 +50,34 @@ int main() {
ST st;
/* Complex to build. */
- /* 1 3 */
- /* o---o */
- /* /X\ / */
+ /* 1 3 5 */
+ /* o---o---o */
+ /* / \ / */
/* o---o o */
/* 2 0 4 */
- const short triangle012[] = {0, 1, 2};
+ const short edge01[] = {0, 1};
+ const short edge02[] = {0, 2};
+ const short edge12[] = {1, 2};
const short edge03[] = {0, 3};
const short edge13[] = {1, 3};
+ const short edge35[] = {3, 5};
const short vertex4[] = {4};
- st.insert_simplex_and_subfaces(triangle012);
+ st.insert_simplex_and_subfaces(edge01);
+ st.insert_simplex_and_subfaces(edge02);
+ st.insert_simplex_and_subfaces(edge12);
st.insert_simplex_and_subfaces(edge03);
st.insert_simplex(edge13);
+ st.insert_simplex_and_subfaces(edge35);
st.insert_simplex(vertex4);
// Sort the simplices in the order of the filtration
st.initialize_filtration();
// Class for homology computation
- Persistent_cohomology pcoh(st);
+ // By default, since the complex has dimension 1, only 0-dimensional homology would be computed.
+ // Here we also want persistent homology to be computed for the maximal dimension in the complex (persistence_dim_max = true)
+ Persistent_cohomology pcoh(st, true);
// Initialize the coefficient field Z/2Z for homology
pcoh.init_coefficients(2);
@@ -82,13 +90,14 @@ int main() {
// 2 0 0 inf
// 2 0 0 inf
// 2 1 0 inf
- // means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=1.
+ // 2 1 0 inf
+ // means that in Z/2Z-homology, the Betti numbers are b0=2 and b1=2.
pcoh.output_diagram();
- // Print the Betti numbers are b0=2 and b1=1.
+ // Print the Betti numbers are b0=2 and b1=2.
std::cout << std::endl;
std::cout << "The Betti numbers are : ";
- for (int i = 0; i < st.dimension(); i++)
+ for (int i = 0; i < 3; i++)
std::cout << "b" << i << " = " << pcoh.betti_number(i) << " ; ";
std::cout << std::endl;
}
diff --git a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
index c57174cb..689a17c0 100644
--- a/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
+++ b/src/Persistent_cohomology/include/gudhi/Persistent_cohomology.h
@@ -98,9 +98,13 @@ class Persistent_cohomology {
*
* @param[in] cpx Complex for which the persistent homology is computed.
* cpx is a model of FilteredComplex
+ *
+ * @param[in] persistence_dim_max if true, the persistent homology for the maximal dimension in the
+ * complex is computed. If false, it is ignored. Default is false.
+ *
* @exception std::out_of_range In case the number of simplices is more than Simplex_key type numeric limit.
*/
- explicit Persistent_cohomology(FilteredComplex& cpx)
+ explicit Persistent_cohomology(FilteredComplex& cpx, bool persistence_dim_max = false)
: cpx_(&cpx),
dim_max_(cpx.dimension()), // upper bound on the dimension of the simplices
coeff_field_(), // initialize the field coefficient structure.
@@ -126,18 +130,6 @@ class Persistent_cohomology {
++idx_fil;
dsets_.make_set(cpx_->key(sh));
}
- }
-
- /** \brief Initializes the Persistent_cohomology class.
- *
- * @param[in] cpx Complex for which the persistent homology is compiuted.
- * cpx is a model of FilteredComplex
- *
- * @param[in] persistence_dim_max if true, the persistent homology for the maximal dimension in the
- * complex is computed. If false, it is ignored. Default is false.
- */
- Persistent_cohomology(FilteredComplex& cpx, bool persistence_dim_max)
- : Persistent_cohomology(cpx) {
if (persistence_dim_max) {
++dim_max_;
}
diff --git a/src/common/doc/main_page.md b/src/common/doc/main_page.md
index e61eee81..98169f82 100644
--- a/src/common/doc/main_page.md
+++ b/src/common/doc/main_page.md
@@ -24,7 +24,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref cubical_complex - <b>Reference manual:</b> Gudhi::cubical_complex::Bitmap_cubical_complex
+ <b>User manual:</b> \ref cubical_complex
</td>
</tr>
</table>
@@ -57,8 +57,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref alpha_complex - <b>Reference manual:</b> Gudhi::alpha_complex::Alpha_complex and
- Gudhi::alpha_complex::Alpha_complex_3d
+ <b>User manual:</b> \ref alpha_complex
</td>
</tr>
</table>
@@ -82,7 +81,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref cech_complex - <b>Reference manual:</b> Gudhi::cech_complex::Cech_complex
+ <b>User manual:</b> \ref cech_complex
</td>
</tr>
</table>
@@ -108,7 +107,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref rips_complex - <b>Reference manual:</b> Gudhi::rips_complex::Rips_complex
+ <b>User manual:</b> \ref rips_complex
</td>
</tr>
</table>
@@ -133,7 +132,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref witness_complex - <b>Reference manual:</b> Gudhi::witness_complex::SimplicialComplexForWitness
+ <b>User manual:</b> \ref witness_complex
</td>
</tr>
</table>
@@ -149,7 +148,6 @@
topological information about the input data. They can be computed with a cover of the
data, that comes i.e. from the preimage of a family of intervals covering the image
of a scalar-valued function defined on the data. <br>
- <b>User manual:</b> \ref cover_complex - <b>Reference manual:</b> Gudhi::cover_complex::Cover_complex
</td>
<td width="15%">
<b>Author:</b> Mathieu Carri&egrave;re<br>
@@ -160,7 +158,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref cover_complex - <b>Reference manual:</b> Gudhi::cover_complex::Cover_complex
+ <b>User manual:</b> \ref cover_complex
</td>
</tr>
</table>
@@ -188,7 +186,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref simplex_tree - <b>Reference manual:</b> Gudhi::Simplex_tree
+ <b>User manual:</b> \ref simplex_tree
</td>
</tr>
</table>
@@ -216,7 +214,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref skbl - <b>Reference manual:</b> Gudhi::skeleton_blocker::Skeleton_blocker_complex
+ <b>User manual:</b> \ref skbl
</td>
</tr>
</table>
@@ -241,7 +239,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref toplex_map - <b>Reference manual:</b> Gudhi::Toplex_map
+ <b>User manual:</b> \ref toplex_map
</td>
</tr>
</table>
@@ -301,7 +299,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref persistent_cohomology - <b>Reference manual:</b> Gudhi::persistent_cohomology::Persistent_cohomology
+ <b>User manual:</b> \ref persistent_cohomology
</td>
</tr>
</table>
@@ -331,7 +329,7 @@
</tr>
<tr>
<td colspan=2 height="25">
- <b>User manual:</b> \ref tangential_complex - <b>Reference manual:</b> Gudhi::tangential_complex::Tangential_complex
+ <b>User manual:</b> \ref tangential_complex
</td>
</tr>
</table>
@@ -349,7 +347,9 @@
Bottleneck distance measures the similarity between two persistence diagrams.
It's the shortest distance b for which there exists a perfect matching between
the points of the two diagrams (+ all the diagonal points) such that
- any couple of matched points are at distance at most b.
+ any couple of matched points are at distance at most b,
+ where the distance between points is the sup norm in \f$\mathbb{R}^2\f$
+ (not the Euclidean distance).
</td>
<td width="15%">
<b>Author:</b> Fran&ccedil;ois Godi<br>
@@ -374,8 +374,8 @@
</td>
<td width="50%">
It contains implementation of various representations of persistence diagrams; diagrams themselves, persistence
- landscapes (rigorous and grid version), persistence heath maps, vectors and others. It implements basic
- functionalities which are neccessary to use persistence in statistics and machine learning.
+ landscapes (rigorous and grid version), persistence heat maps, vectors and others. It implements basic
+ functionalities which are necessary to use persistence in statistics and machine learning.
</td>
<td width="15%">
<b>Author:</b> Pawel Dlotko<br>
diff --git a/src/cython/cython/cubical_complex.pyx b/src/cython/cython/cubical_complex.pyx
index e94cd539..509af6ca 100644
--- a/src/cython/cython/cubical_complex.pyx
+++ b/src/cython/cython/cubical_complex.pyx
@@ -5,6 +5,8 @@ from libcpp.string cimport string
from libcpp cimport bool
import os
+from numpy import array as np_array
+
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
library for computational topology.
@@ -182,9 +184,9 @@ cdef class CubicalComplex:
specific dimension.
:param dimension: The specific dimension.
- :type from_value: int.
+ :type dimension: int.
:returns: The persistence intervals.
- :rtype: list of pair of float
+ :rtype: numpy array of dimension 2
:note: intervals_in_dim function requires persistence function to be
launched first.
@@ -195,4 +197,4 @@ cdef class CubicalComplex:
else:
print("intervals_in_dim function requires persistence function"
" to be launched first.")
- return intervals_result
+ return np_array(intervals_result)
diff --git a/src/cython/cython/periodic_cubical_complex.pyx b/src/cython/cython/periodic_cubical_complex.pyx
index e626950b..3866f53b 100644
--- a/src/cython/cython/periodic_cubical_complex.pyx
+++ b/src/cython/cython/periodic_cubical_complex.pyx
@@ -5,13 +5,15 @@ from libcpp.string cimport string
from libcpp cimport bool
import os
+from numpy import array as np_array
+
"""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
+ Copyright (C) 2019 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
@@ -184,9 +186,9 @@ cdef class PeriodicCubicalComplex:
specific dimension.
:param dimension: The specific dimension.
- :type from_value: int.
+ :type dimension: int.
:returns: The persistence intervals.
- :rtype: list of pair of float
+ :rtype: numpy array of dimension 2
:note: intervals_in_dim function requires persistence function to be
launched first.
@@ -197,4 +199,4 @@ cdef class PeriodicCubicalComplex:
else:
print("intervals_in_dim function requires persistence function"
" to be launched first.")
- return intervals_result
+ return np_array(intervals_result)
diff --git a/src/cython/cython/persistence_graphical_tools.py b/src/cython/cython/persistence_graphical_tools.py
index d7be936f..7bb69840 100644
--- a/src/cython/cython/persistence_graphical_tools.py
+++ b/src/cython/cython/persistence_graphical_tools.py
@@ -1,10 +1,14 @@
+from os import path
+from math import isfinite
+import numpy as np
+
"""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, Bertrand Michel
- Copyright (C) 2016 Inria
+ Copyright (C) 2019 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
@@ -85,11 +89,9 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
try:
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
- import numpy as np
- import os
if persistence_file is not '':
- if os.path.isfile(persistence_file):
+ if path.isfile(persistence_file):
# Reset persistence
persistence = []
diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
@@ -144,7 +146,7 @@ def plot_persistence_barcode(persistence=[], persistence_file='', alpha=0.6,
return plt
except ImportError:
- print("This function is not available, you may be missing numpy and/or matplotlib.")
+ print("This function is not available, you may be missing matplotlib.")
def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
band=0., max_intervals=1000, max_plots=1000, inf_delta=0.1, legend=False):
@@ -177,11 +179,9 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
try:
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
- import numpy as np
- import os
if persistence_file is not '':
- if os.path.isfile(persistence_file):
+ if path.isfile(persistence_file):
# Reset persistence
persistence = []
diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
@@ -240,7 +240,7 @@ def plot_persistence_diagram(persistence=[], persistence_file='', alpha=0.6,
return plt
except ImportError:
- print("This function is not available, you may be missing numpy and/or matplotlib.")
+ print("This function is not available, you may be missing matplotlib.")
def plot_persistence_density(persistence=[], persistence_file='',
nbins=300, bw_method=None,
@@ -288,38 +288,33 @@ def plot_persistence_density(persistence=[], persistence_file='',
"""
try:
import matplotlib.pyplot as plt
- import numpy as np
from scipy.stats import kde
- import os
- import math
if persistence_file is not '':
- if os.path.isfile(persistence_file):
- # Reset persistence
- persistence = []
- diag = read_persistence_intervals_grouped_by_dimension(persistence_file=persistence_file)
- for key in diag.keys():
- for persistence_interval in diag[key]:
- persistence.append((key, persistence_interval))
+ if dimension is None:
+ # All dimension case
+ dimension = -1
+ if path.isfile(persistence_file):
+ persistence_dim = read_persistence_intervals_in_dimension(persistence_file=persistence_file,
+ only_this_dim=dimension)
+ print(persistence_dim)
else:
print("file " + persistence_file + " not found.")
return None
- persistence_dim = []
- if dimension is not None:
- persistence_dim = [(dim_interval) for dim_interval in persistence if (dim_interval[0] == dimension)]
- else:
- persistence_dim = persistence
+ if len(persistence) > 0:
+ persistence_dim = np.array([(dim_interval[1][0], dim_interval[1][1]) for dim_interval in persistence if (dim_interval[0] == dimension) or (dimension is None)])
+ persistence_dim = persistence_dim[np.isfinite(persistence_dim[:,1])]
if max_intervals > 0 and max_intervals < len(persistence_dim):
# Sort by life time, then takes only the max_intervals elements
- persistence_dim = sorted(persistence_dim,
- key=lambda life_time: life_time[1][1]-life_time[1][0],
- reverse=True)[:max_intervals]
+ persistence_dim = np.array(sorted(persistence_dim,
+ key=lambda life_time: life_time[1]-life_time[0],
+ reverse=True)[:max_intervals])
# Set as numpy array birth and death (remove undefined values - inf and NaN)
- birth = np.asarray([(interval[1][0]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))])
- death = np.asarray([(interval[1][1]) for interval in persistence_dim if (math.isfinite(interval[1][1]) and math.isfinite(interval[1][0]))])
+ birth = persistence_dim[:,0]
+ death = persistence_dim[:,1]
# line display of equation : birth = death
x = np.linspace(death.min(), birth.max(), 1000)
@@ -345,4 +340,4 @@ def plot_persistence_density(persistence=[], persistence_file='',
return plt
except ImportError:
- print("This function is not available, you may be missing numpy, matplotlib and/or scipy.")
+ print("This function is not available, you may be missing matplotlib and/or scipy.")
diff --git a/src/cython/cython/reader_utils.pyx b/src/cython/cython/reader_utils.pyx
index e4572db0..6dde5286 100644
--- a/src/cython/cython/reader_utils.pyx
+++ b/src/cython/cython/reader_utils.pyx
@@ -3,7 +3,9 @@ from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.map cimport map
from libcpp.pair cimport pair
-import os
+
+from os import path
+from numpy import array as np_array
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
@@ -11,7 +13,7 @@ import os
Author(s): Vincent Rouvreau
- Copyright (C) 2017 Inria
+ Copyright (C) 2019 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
@@ -48,7 +50,7 @@ def read_lower_triangular_matrix_from_csv_file(csv_file='', separator=';'):
:rtype: vector[vector[double]]
"""
if csv_file is not '':
- if os.path.isfile(csv_file):
+ if path.isfile(csv_file):
return read_matrix_from_csv_file(str.encode(csv_file), ord(separator[0]))
print("file " + csv_file + " not set or not found.")
return []
@@ -67,29 +69,31 @@ def read_persistence_intervals_grouped_by_dimension(persistence_file=''):
:rtype: map[int, vector[pair[double, double]]]
"""
if persistence_file is not '':
- if os.path.isfile(persistence_file):
+ if path.isfile(persistence_file):
return read_pers_intervals_grouped_by_dimension(str.encode(persistence_file))
print("file " + persistence_file + " not set or not found.")
return []
def read_persistence_intervals_in_dimension(persistence_file='', only_this_dim=-1):
"""Reads a file containing persistence intervals.
- Each line might contain 2, 3 or 4 values: [[field] dimension] birth death
- If `only_this_dim` = -1, dimension is ignored and all lines are returned.
- If `only_this_dim` is >= 0, only the lines where dimension = `only_this_dim`
- (or where dimension is not specified) are returned.
- The return value is an `vector[pair[birth, death]]`
- where `birth` a `double`, and `death` a `double`.
+ Each line of persistence_file might contain 2, 3 or 4 values:
+ [[field] dimension] birth death
Note: the function does not check that birth <= death.
:param persistence_file: A persistence file style name.
:type persistence_file: string
-
- :returns: The persistence pairs grouped by dimension.
- :rtype: map[int, vector[pair[double, double]]]
+ :param only_this_dim: The specific dimension. Default value is -1.
+ If `only_this_dim` = -1, dimension is ignored and all lines are returned.
+ If `only_this_dim` is >= 0, only the lines where dimension =
+ `only_this_dim` (or where dimension is not specified) are returned.
+ :type only_this_dim: int.
+
+ :returns: The persistence intervals.
+ :rtype: numpy array of dimension 2
"""
if persistence_file is not '':
- if os.path.isfile(persistence_file):
- return read_pers_intervals_in_dimension(str.encode(persistence_file), only_this_dim)
+ if path.isfile(persistence_file):
+ return np_array(read_pers_intervals_in_dimension(str.encode(
+ persistence_file), only_this_dim))
print("file " + persistence_file + " not set or not found.")
return []
diff --git a/src/cython/cython/simplex_tree.pyx b/src/cython/cython/simplex_tree.pyx
index ea99c940..43bc11c9 100644
--- a/src/cython/cython/simplex_tree.pyx
+++ b/src/cython/cython/simplex_tree.pyx
@@ -4,13 +4,15 @@ from libcpp.utility cimport pair
from libcpp cimport bool
from libcpp.string cimport string
+from numpy import array as np_array
+
"""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
+ Copyright (C) 2019 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
@@ -499,7 +501,7 @@ cdef class SimplexTree:
:param dimension: The specific dimension.
:type dimension: int.
:returns: The persistence intervals.
- :rtype: list of pair of float
+ :rtype: numpy array of dimension 2
:note: intervals_in_dim function requires
:func:`persistence()<gudhi.SimplexTree.persistence>`
@@ -511,7 +513,7 @@ cdef class SimplexTree:
else:
print("intervals_in_dim function requires persistence function"
" to be launched first.")
- return intervals_result
+ return np_array(intervals_result)
def persistence_pairs(self):
"""This function returns a list of persistence birth and death simplices pairs.
diff --git a/src/cython/doc/bottleneck_distance_sum.inc b/src/cython/doc/bottleneck_distance_sum.inc
index 41b9c5a3..6840e838 100644
--- a/src/cython/doc/bottleneck_distance_sum.inc
+++ b/src/cython/doc/bottleneck_distance_sum.inc
@@ -6,8 +6,8 @@
| ../../doc/Bottleneck_distance/perturb_pd.png | diagrams. It's the shortest distance b for which there exists a | |
| :figclass: align-center | perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 2.0.0 |
| | diagonal points) such that any couple of matched points are at | |
- | Bottleneck distance is the length of | distance at most b. | :Copyright: GPL v3 |
- | the longest edge | | |
+ | Bottleneck distance is the length of | distance at most b, where the distance between points is the sup | :Copyright: GPL v3 |
+ | the longest edge | norm in :math:`\mathbb{R}^2`. | |
| | | :Requires: CGAL :math:`\geq` 4.8.0 |
+-----------------------------------------------------------------+----------------------------------------------------------------------+-----------------------------------------------+
| * :doc:`bottleneck_distance_user` | |
diff --git a/src/cython/doc/bottleneck_distance_user.rst b/src/cython/doc/bottleneck_distance_user.rst
index 605db022..9435c7f1 100644
--- a/src/cython/doc/bottleneck_distance_user.rst
+++ b/src/cython/doc/bottleneck_distance_user.rst
@@ -9,15 +9,42 @@ Definition
.. include:: bottleneck_distance_sum.inc
+This implementation is based on ideas from "Geometry Helps in Bottleneck Matching and Related Problems"
+:cite:`DBLP:journals/algorithmica/EfratIK01`. Another relevant publication, although it was not used is
+"Geometry Helps to Compare Persistence Diagrams" :cite:`Kerber:2017:GHC:3047249.3064175`.
+
Function
--------
.. autofunction:: gudhi.bottleneck_distance
+Distance computation
+--------------------
+
+The following example explains how the distance is computed:
+
+.. testcode::
+
+ import gudhi
+
+ message = "Bottleneck distance = " + '%.1f' % gudhi.bottleneck_distance([[0., 0.]], [[0., 13.]])
+ print(message)
+
+.. testoutput::
+
+ Bottleneck distance = 6.5
+
+.. figure::
+ ../../doc/Bottleneck_distance/bottleneck_distance_example.png
+ :figclass: align-center
+
+ The point (0, 13) is at distance 6.5 from the diagonal and more
+ specifically from the point (6.5, 6.5)
+
Basic example
-------------
-This example computes the bottleneck distance from 2 persistence diagrams:
+This other example computes the bottleneck distance from 2 persistence diagrams:
.. testcode::
@@ -26,15 +53,15 @@ This example computes the bottleneck distance from 2 persistence diagrams:
diag1 = [[2.7, 3.7],[9.6, 14.],[34.2, 34.974], [3.,float('Inf')]]
diag2 = [[2.8, 4.45],[9.5, 14.1],[3.2,float('Inf')]]
- message = "Bottleneck distance approximation=" + '%.2f' % gudhi.bottleneck_distance(diag1, diag2, 0.1)
+ message = "Bottleneck distance approximation = " + '%.2f' % gudhi.bottleneck_distance(diag1, diag2, 0.1)
print(message)
- message = "Bottleneck distance value=" + '%.2f' % gudhi.bottleneck_distance(diag1, diag2)
+ message = "Bottleneck distance value = " + '%.2f' % gudhi.bottleneck_distance(diag1, diag2)
print(message)
The output is:
.. testoutput::
- Bottleneck distance approximation=0.81
- Bottleneck distance value=0.75
+ Bottleneck distance approximation = 0.81
+ Bottleneck distance value = 0.75
diff --git a/src/cython/setup.py.in b/src/cython/setup.py.in
index 4037aab6..c66905ac 100644
--- a/src/cython/setup.py.in
+++ b/src/cython/setup.py.in
@@ -1,5 +1,6 @@
from distutils.core import setup, Extension
from Cython.Build import cythonize
+from numpy import get_include as numpy_get_include
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
@@ -7,7 +8,7 @@ from Cython.Build import cythonize
Author(s): Vincent Rouvreau
- Copyright (C) 2016 Inria
+ Copyright (C) 2019 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
@@ -35,7 +36,7 @@ gudhi = Extension(
extra_link_args=[@GUDHI_CYTHON_EXTRA_LINK_ARGS@],
libraries=[@GUDHI_CYTHON_LIBRARIES@],
library_dirs=[@GUDHI_CYTHON_LIBRARY_DIRS@],
- include_dirs = [@GUDHI_CYTHON_INCLUDE_DIRS@],
+ include_dirs = [numpy_get_include(), @GUDHI_CYTHON_INCLUDE_DIRS@],
runtime_library_dirs=[@GUDHI_CYTHON_RUNTIME_LIBRARY_DIRS@],
)
@@ -46,5 +47,6 @@ setup(
version='@GUDHI_VERSION@',
url='http://gudhi.gforge.inria.fr/',
ext_modules = cythonize(gudhi),
- install_requires = ["cython",],
+ install_requires = ['cython','numpy >= 1.9',],
+ setup_requires = ['numpy >= 1.9',],
)
diff --git a/src/cython/test/test_reader_utils.py b/src/cython/test/test_reader_utils.py
index b240c84f..36e927b0 100755
--- a/src/cython/test/test_reader_utils.py
+++ b/src/cython/test/test_reader_utils.py
@@ -1,4 +1,5 @@
import gudhi
+import numpy as np
"""This file is part of the Gudhi Library. The Gudhi library
(Geometric Understanding in Higher Dimensions) is a generic C++
@@ -53,7 +54,7 @@ def test_non_existing_persistence_file():
persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='pouetpouettralala.toubiloubabdou')
assert persistence == []
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='pouetpouettralala.toubiloubabdou', only_this_dim=1)
- assert persistence == []
+ np.testing.assert_array_equal(persistence, [])
def test_read_persistence_intervals_without_dimension():
# Create test file
@@ -61,11 +62,11 @@ def test_read_persistence_intervals_without_dimension():
test_file.write('# Simple persistence diagram without dimension\n2.7 3.7\n9.6 14.\n34.2 34.974\n3. inf')
test_file.close()
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers')
- assert persistence == [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))]
+ np.testing.assert_array_equal(persistence, [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers', only_this_dim=0)
- assert persistence == []
+ np.testing.assert_array_equal(persistence, [])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_without_dimension.pers', only_this_dim=1)
- assert persistence == []
+ np.testing.assert_array_equal(persistence, [])
persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='persistence_intervals_without_dimension.pers')
assert persistence == {-1: [(2.7, 3.7), (9.6, 14.0), (34.2, 34.974), (3.0, float('Inf'))]}
@@ -75,14 +76,14 @@ def test_read_persistence_intervals_with_dimension():
test_file.write('# Simple persistence diagram with dimension\n0 2.7 3.7\n1 9.6 14.\n3 34.2 34.974\n1 3. inf')
test_file.close()
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers')
- assert persistence == [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))]
+ np.testing.assert_array_equal(persistence, [(2.7, 3.7), (9.6, 14.), (34.2, 34.974), (3., float('Inf'))])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=0)
- assert persistence == [(2.7, 3.7)]
+ np.testing.assert_array_equal(persistence, [(2.7, 3.7)])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=1)
- assert persistence == [(9.6, 14.), (3., float('Inf'))]
+ np.testing.assert_array_equal(persistence, [(9.6, 14.), (3., float('Inf'))])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=2)
- assert persistence == []
+ np.testing.assert_array_equal(persistence, [])
persistence = gudhi.read_persistence_intervals_in_dimension(persistence_file='persistence_intervals_with_dimension.pers', only_this_dim=3)
- assert persistence == [(34.2, 34.974)]
+ np.testing.assert_array_equal(persistence, [(34.2, 34.974)])
persistence = gudhi.read_persistence_intervals_grouped_by_dimension(persistence_file='persistence_intervals_with_dimension.pers')
assert persistence == {0: [(2.7, 3.7)], 1: [(9.6, 14.0), (3.0, float('Inf'))], 3: [(34.2, 34.974)]}