diff options
author | ROUVREAU Vincent <vincent.rouvreau@inria.fr> | 2019-06-27 21:51:22 +0200 |
---|---|---|
committer | ROUVREAU Vincent <vincent.rouvreau@inria.fr> | 2019-06-27 21:51:22 +0200 |
commit | 6a91777aa7229536d177430aadc4d7e37274cdcb (patch) | |
tree | 2ee056688826f72bedc36699b869c8dede58b332 /src | |
parent | 68fadb4ebfe5b35a2eec99a9babafbee940a1b42 (diff) | |
parent | 9f249e001089af45186aaf0d196d6300705eee31 (diff) |
Merge branch 'master' of github.com:GUDHI/gudhi-devel
Diffstat (limited to 'src')
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 Binary files differnew file mode 100644 index 00000000..1d3b91aa --- /dev/null +++ b/src/Bottleneck_distance/doc/bottleneck_distance_example.png 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è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ç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)]} |