From d18ef465b79fe53b103bb05d75d7f71b37792276 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Tue, 18 Oct 2022 16:50:12 +0200 Subject: added possibility of negative values in persistance diagram --- .../include/gudhi/Persistence_graph.h | 57 ++++++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) (limited to 'src/Bottleneck_distance/include/gudhi/Persistence_graph.h') diff --git a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h index 33f03b9c..9b663cc2 100644 --- a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h +++ b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h @@ -20,6 +20,7 @@ #include #include #include // for numeric_limits +#include namespace Gudhi { @@ -70,27 +71,51 @@ Persistence_graph::Persistence_graph(const Persistence_diagram1 &diag1, : u(), v(), b_alive(0.) { std::vector u_alive; std::vector v_alive; + std::vector u_nalive; + std::vector v_nalive; + int u_inf = 0; + int v_inf = 0; + double inf = std::numeric_limits::infinity(); + double neginf = -1 * inf; + for (auto it = std::begin(diag1); it != std::end(diag1); ++it) { - if (std::get<1>(*it) == std::numeric_limits::infinity()) - u_alive.push_back(std::get<0>(*it)); - else if (std::get<1>(*it) - std::get<0>(*it) > e) - u.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), u.size())); + if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ + if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) + u_inf++; + else if (std::get<0>(*it) == neginf) + u_nalive.push_back(std::get<1>(*it)); + else if (std::get<1>(*it) == inf) + u_alive.push_back(std::get<0>(*it)); + else if (std::get<1>(*it) - std::get<0>(*it) > e) + u.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), u.size())); + } } for (auto it = std::begin(diag2); it != std::end(diag2); ++it) { - if (std::get<1>(*it) == std::numeric_limits::infinity()) - v_alive.push_back(std::get<0>(*it)); - else if (std::get<1>(*it) - std::get<0>(*it) > e) - v.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), v.size())); + if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ + if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) + v_inf++; + else if (std::get<0>(*it) == neginf) + v_nalive.push_back(std::get<1>(*it)); + else if (std::get<1>(*it) == inf) + v_alive.push_back(std::get<0>(*it)); + else if (std::get<1>(*it) - std::get<0>(*it) > e) + v.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), v.size())); + } } if (u.size() < v.size()) swap(u, v); - std::sort(u_alive.begin(), u_alive.end()); - std::sort(v_alive.begin(), v_alive.end()); - if (u_alive.size() != v_alive.size()) { + + if (u_alive.size() != v_alive.size() || u_nalive.size() != v_nalive.size() || u_inf != v_inf) { b_alive = std::numeric_limits::infinity(); } else { + std::sort(u_alive.begin(), u_alive.end()); + std::sort(v_alive.begin(), v_alive.end()); + std::sort(u_nalive.begin(), u_nalive.end()); + std::sort(v_nalive.begin(), v_nalive.end()); for (auto it_u = u_alive.cbegin(), it_v = v_alive.cbegin(); it_u != u_alive.cend(); ++it_u, ++it_v) b_alive = (std::max)(b_alive, std::fabs(*it_u - *it_v)); + for (auto it_u = u_nalive.cbegin(), it_v = v_nalive.cbegin(); it_u != u_nalive.cend(); ++it_u, ++it_v) + b_alive = (std::max)(b_alive, std::fabs(*it_u - *it_v)); } } @@ -114,7 +139,7 @@ inline int Persistence_graph::corresponding_point_in_v(int u_point_index) const inline double Persistence_graph::distance(int u_point_index, int v_point_index) const { if (on_the_u_diagonal(u_point_index) && on_the_v_diagonal(v_point_index)) - return 0.; + return 0.; Internal_point p_u = get_u_point(u_point_index); Internal_point p_v = get_v_point(v_point_index); return (std::max)(std::fabs(p_u.x() - p_v.x()), std::fabs(p_u.y() - p_v.y())); @@ -132,9 +157,9 @@ inline std::vector Persistence_graph::sorted_distances() const { std::vector distances; distances.push_back(0.); // for empty diagrams for (int u_point_index = 0; u_point_index < size(); ++u_point_index) { - distances.push_back(distance(u_point_index, corresponding_point_in_v(u_point_index))); - for (int v_point_index = 0; v_point_index < size(); ++v_point_index) - distances.push_back(distance(u_point_index, v_point_index)); + distances.push_back(distance(u_point_index, corresponding_point_in_v(u_point_index))); + for (int v_point_index = 0; v_point_index < size(); ++v_point_index) + distances.push_back(distance(u_point_index, v_point_index)); } #ifdef GUDHI_USE_TBB tbb::parallel_sort(distances.begin(), distances.end()); @@ -146,7 +171,7 @@ inline std::vector Persistence_graph::sorted_distances() const { inline Internal_point Persistence_graph::get_u_point(int u_point_index) const { if (!on_the_u_diagonal(u_point_index)) - return u.at(u_point_index); + return u.at(u_point_index); Internal_point projector = v.at(corresponding_point_in_v(u_point_index)); double m = (projector.x() + projector.y()) / 2.; return Internal_point(m, m, u_point_index); -- cgit v1.2.3 From ff59ebb1a3417701a9282783adeb254af14b856c Mon Sep 17 00:00:00 2001 From: hschreiber Date: Tue, 18 Oct 2022 17:31:34 +0200 Subject: syntax correction --- src/Bottleneck_distance/include/gudhi/Persistence_graph.h | 2 +- src/Bottleneck_distance/test/bottleneck_unit_test.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/Bottleneck_distance/include/gudhi/Persistence_graph.h') diff --git a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h index 9b663cc2..de989e1b 100644 --- a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h +++ b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h @@ -76,7 +76,7 @@ Persistence_graph::Persistence_graph(const Persistence_diagram1 &diag1, int u_inf = 0; int v_inf = 0; double inf = std::numeric_limits::infinity(); - double neginf = -1 * inf; + double neginf = -inf; for (auto it = std::begin(diag1); it != std::end(diag1); ++it) { if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ diff --git a/src/Bottleneck_distance/test/bottleneck_unit_test.cpp b/src/Bottleneck_distance/test/bottleneck_unit_test.cpp index 79ee9c2c..38ed89a8 100644 --- a/src/Bottleneck_distance/test/bottleneck_unit_test.cpp +++ b/src/Bottleneck_distance/test/bottleneck_unit_test.cpp @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(neg_global) { BOOST_AUTO_TEST_CASE(bottleneck_simple_test) { std::vector< std::pair > v1, v2; double inf = std::numeric_limits::infinity(); - double neginf = -1 * inf; + double neginf = -inf; double b; v1.emplace_back(9.6, 14.); -- cgit v1.2.3 From 475a20c0645b079aaf204fd47398b7bb278fb490 Mon Sep 17 00:00:00 2001 From: hschreiber Date: Wed, 19 Oct 2022 11:52:41 +0200 Subject: correction of indentation --- .../include/gudhi/Persistence_graph.h | 72 +++++++++++----------- .../test/bottleneck_unit_test.cpp | 62 +++++++++---------- 2 files changed, 67 insertions(+), 67 deletions(-) (limited to 'src/Bottleneck_distance/include/gudhi/Persistence_graph.h') diff --git a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h index de989e1b..c1e10f8e 100644 --- a/src/Bottleneck_distance/include/gudhi/Persistence_graph.h +++ b/src/Bottleneck_distance/include/gudhi/Persistence_graph.h @@ -32,7 +32,7 @@ namespace persistence_diagram { * \ingroup bottleneck_distance */ class Persistence_graph { - public: +public: /** \internal \brief Constructor taking 2 PersistenceDiagrams (concept) as parameters. */ template Persistence_graph(const Persistence_diagram1& diag1, const Persistence_diagram2& diag2, double e); @@ -59,7 +59,7 @@ class Persistence_graph { /** \internal \brief Returns the corresponding internal point */ Internal_point get_v_point(int v_point_index) const; - private: +private: std::vector u; std::vector v; double b_alive; @@ -68,7 +68,7 @@ class Persistence_graph { template Persistence_graph::Persistence_graph(const Persistence_diagram1 &diag1, const Persistence_diagram2 &diag2, double e) - : u(), v(), b_alive(0.) { + : u(), v(), b_alive(0.) { std::vector u_alive; std::vector v_alive; std::vector u_nalive; @@ -79,28 +79,28 @@ Persistence_graph::Persistence_graph(const Persistence_diagram1 &diag1, double neginf = -inf; for (auto it = std::begin(diag1); it != std::end(diag1); ++it) { - if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ - if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) - u_inf++; - else if (std::get<0>(*it) == neginf) - u_nalive.push_back(std::get<1>(*it)); - else if (std::get<1>(*it) == inf) - u_alive.push_back(std::get<0>(*it)); - else if (std::get<1>(*it) - std::get<0>(*it) > e) - u.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), u.size())); - } + if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ + if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) + u_inf++; + else if (std::get<0>(*it) == neginf) + u_nalive.push_back(std::get<1>(*it)); + else if (std::get<1>(*it) == inf) + u_alive.push_back(std::get<0>(*it)); + else if (std::get<1>(*it) - std::get<0>(*it) > e) + u.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), u.size())); + } } for (auto it = std::begin(diag2); it != std::end(diag2); ++it) { - if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ - if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) - v_inf++; - else if (std::get<0>(*it) == neginf) - v_nalive.push_back(std::get<1>(*it)); - else if (std::get<1>(*it) == inf) - v_alive.push_back(std::get<0>(*it)); - else if (std::get<1>(*it) - std::get<0>(*it) > e) - v.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), v.size())); - } + if (std::get<0>(*it) != inf && std::get<1>(*it) != neginf){ + if (std::get<0>(*it) == neginf && std::get<1>(*it) == inf) + v_inf++; + else if (std::get<0>(*it) == neginf) + v_nalive.push_back(std::get<1>(*it)); + else if (std::get<1>(*it) == inf) + v_alive.push_back(std::get<0>(*it)); + else if (std::get<1>(*it) - std::get<0>(*it) > e) + v.push_back(Internal_point(std::get<0>(*it), std::get<1>(*it), v.size())); + } } if (u.size() < v.size()) swap(u, v); @@ -108,14 +108,14 @@ Persistence_graph::Persistence_graph(const Persistence_diagram1 &diag1, if (u_alive.size() != v_alive.size() || u_nalive.size() != v_nalive.size() || u_inf != v_inf) { b_alive = std::numeric_limits::infinity(); } else { - std::sort(u_alive.begin(), u_alive.end()); - std::sort(v_alive.begin(), v_alive.end()); - std::sort(u_nalive.begin(), u_nalive.end()); - std::sort(v_nalive.begin(), v_nalive.end()); + std::sort(u_alive.begin(), u_alive.end()); + std::sort(v_alive.begin(), v_alive.end()); + std::sort(u_nalive.begin(), u_nalive.end()); + std::sort(v_nalive.begin(), v_nalive.end()); for (auto it_u = u_alive.cbegin(), it_v = v_alive.cbegin(); it_u != u_alive.cend(); ++it_u, ++it_v) b_alive = (std::max)(b_alive, std::fabs(*it_u - *it_v)); - for (auto it_u = u_nalive.cbegin(), it_v = v_nalive.cbegin(); it_u != u_nalive.cend(); ++it_u, ++it_v) - b_alive = (std::max)(b_alive, std::fabs(*it_u - *it_v)); + for (auto it_u = u_nalive.cbegin(), it_v = v_nalive.cbegin(); it_u != u_nalive.cend(); ++it_u, ++it_v) + b_alive = (std::max)(b_alive, std::fabs(*it_u - *it_v)); } } @@ -129,17 +129,17 @@ inline bool Persistence_graph::on_the_v_diagonal(int v_point_index) const { inline int Persistence_graph::corresponding_point_in_u(int v_point_index) const { return on_the_v_diagonal(v_point_index) ? - v_point_index - static_cast (v.size()) : v_point_index + static_cast (u.size()); + v_point_index - static_cast (v.size()) : v_point_index + static_cast (u.size()); } inline int Persistence_graph::corresponding_point_in_v(int u_point_index) const { return on_the_u_diagonal(u_point_index) ? - u_point_index - static_cast (u.size()) : u_point_index + static_cast (v.size()); + u_point_index - static_cast (u.size()) : u_point_index + static_cast (v.size()); } inline double Persistence_graph::distance(int u_point_index, int v_point_index) const { if (on_the_u_diagonal(u_point_index) && on_the_v_diagonal(v_point_index)) - return 0.; + return 0.; Internal_point p_u = get_u_point(u_point_index); Internal_point p_v = get_v_point(v_point_index); return (std::max)(std::fabs(p_u.x() - p_v.x()), std::fabs(p_u.y() - p_v.y())); @@ -157,9 +157,9 @@ inline std::vector Persistence_graph::sorted_distances() const { std::vector distances; distances.push_back(0.); // for empty diagrams for (int u_point_index = 0; u_point_index < size(); ++u_point_index) { - distances.push_back(distance(u_point_index, corresponding_point_in_v(u_point_index))); - for (int v_point_index = 0; v_point_index < size(); ++v_point_index) - distances.push_back(distance(u_point_index, v_point_index)); + distances.push_back(distance(u_point_index, corresponding_point_in_v(u_point_index))); + for (int v_point_index = 0; v_point_index < size(); ++v_point_index) + distances.push_back(distance(u_point_index, v_point_index)); } #ifdef GUDHI_USE_TBB tbb::parallel_sort(distances.begin(), distances.end()); @@ -171,7 +171,7 @@ inline std::vector Persistence_graph::sorted_distances() const { inline Internal_point Persistence_graph::get_u_point(int u_point_index) const { if (!on_the_u_diagonal(u_point_index)) - return u.at(u_point_index); + return u.at(u_point_index); Internal_point projector = v.at(corresponding_point_in_v(u_point_index)); double m = (projector.x() + projector.y()) / 2.; return Internal_point(m, m, u_point_index); diff --git a/src/Bottleneck_distance/test/bottleneck_unit_test.cpp b/src/Bottleneck_distance/test/bottleneck_unit_test.cpp index 38ed89a8..9872f20c 100644 --- a/src/Bottleneck_distance/test/bottleneck_unit_test.cpp +++ b/src/Bottleneck_distance/test/bottleneck_unit_test.cpp @@ -31,14 +31,14 @@ std::vector< std::pair > v1, v2; BOOST_AUTO_TEST_CASE(persistence_graph) { // Random construction for (int i = 0; i < n1; i++) { - double a = unif(re); - double b = unif(re); - v1.emplace_back(std::min(a, b), std::max(a, b)); + double a = unif(re); + double b = unif(re); + v1.emplace_back(std::min(a, b), std::max(a, b)); } for (int i = 0; i < n2; i++) { - double a = unif(re); - double b = unif(re); - v2.emplace_back(std::min(a, b), std::max(a, b)); + double a = unif(re); + double b = unif(re); + v2.emplace_back(std::min(a, b), std::max(a, b)); } Persistence_graph g(v1, v2, 0.); std::vector d(g.sorted_distances()); @@ -84,14 +84,14 @@ BOOST_AUTO_TEST_CASE(neighbors_finder) { Persistence_graph g(v1, v2, 0.); Neighbors_finder nf(g, 1.); for (int v_point_index = 1; v_point_index < ((n2 + n1)*9 / 10); v_point_index += 2) - nf.add(v_point_index); + nf.add(v_point_index); // int v_point_index_1 = nf.pull_near(n2 / 2); BOOST_CHECK((v_point_index_1 == -1) || (g.distance(n2 / 2, v_point_index_1) <= 1.)); std::vector l = nf.pull_all_near(n2 / 2); bool v = true; for (auto it = l.cbegin(); it != l.cend(); ++it) - v = v && (g.distance(n2 / 2, *it) > 1.); + v = v && (g.distance(n2 / 2, *it) > 1.); BOOST_CHECK(v); int v_point_index_2 = nf.pull_near(n2 / 2); BOOST_CHECK(v_point_index_2 == -1); @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(layered_neighbors_finder) { Persistence_graph g(v1, v2, 0.); Layered_neighbors_finder lnf(g, 1.); for (int v_point_index = 1; v_point_index < ((n2 + n1)*9 / 10); v_point_index += 2) - lnf.add(v_point_index, v_point_index % 7); + lnf.add(v_point_index, v_point_index % 7); // int v_point_index_1 = lnf.pull_near(n2 / 2, 6); BOOST_CHECK((v_point_index_1 == -1) || (g.distance(n2 / 2, v_point_index_1) <= 1.)); @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(graph_matching) { m1.set_r(0.); int e = 0; while (m1.multi_augment()) - ++e; + ++e; BOOST_CHECK(e > 0); BOOST_CHECK(e <= 2 * sqrt(2 * (n1 + n2))); Graph_matching m2 = m1; @@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(graph_matching) { m2.set_r(upper_bound); e = 0; while (m2.multi_augment()) - ++e; + ++e; BOOST_CHECK(e <= 2 * sqrt(2 * (n1 + n2))); BOOST_CHECK(m2.perfect()); BOOST_CHECK(!m1.perfect()); @@ -139,16 +139,16 @@ BOOST_AUTO_TEST_CASE(global) { std::default_random_engine re; std::vector< std::pair > v1, v2; for (int i = 0; i < n1; i++) { - double a = unif1(re); - double b = unif1(re); - double x = unif2(re); - double y = unif2(re); - v1.emplace_back(std::min(a, b), std::max(a, b)); - v2.emplace_back(std::min(a, b) + std::min(x, y), std::max(a, b) + std::max(x, y)); - if (i % 5 == 0) - v1.emplace_back(std::min(a, b), std::min(a, b) + x); - if (i % 3 == 0) - v2.emplace_back(std::max(a, b), std::max(a, b) + y); + double a = unif1(re); + double b = unif1(re); + double x = unif2(re); + double y = unif2(re); + v1.emplace_back(std::min(a, b), std::max(a, b)); + v2.emplace_back(std::min(a, b) + std::min(x, y), std::max(a, b) + std::max(x, y)); + if (i % 5 == 0) + v1.emplace_back(std::min(a, b), std::min(a, b) + x); + if (i % 3 == 0) + v2.emplace_back(std::max(a, b), std::max(a, b) + y); } BOOST_CHECK(bottleneck_distance(v1, v2, 0.) <= upper_bound / 100.); BOOST_CHECK(bottleneck_distance(v1, v2, upper_bound / 10000.) <= upper_bound / 100. + upper_bound / 10000.); @@ -166,16 +166,16 @@ BOOST_AUTO_TEST_CASE(neg_global) { std::default_random_engine re; std::vector< std::pair > v1, v2; for (int i = 0; i < n1; i++) { - double a = std::log(unif1(re)); - double b = std::log(unif1(re)); - double x = std::log(unif2(re)); - double y = std::log(unif2(re)); - v1.emplace_back(std::min(a, b), std::max(a, b)); - v2.emplace_back(std::min(a, b) + std::min(x, y), std::max(a, b) + std::max(x, y)); - if (i % 5 == 0) - v1.emplace_back(std::min(a, b), std::min(a, b) + x); - if (i % 3 == 0) - v2.emplace_back(std::max(a, b), std::max(a, b) + y); + double a = std::log(unif1(re)); + double b = std::log(unif1(re)); + double x = std::log(unif2(re)); + double y = std::log(unif2(re)); + v1.emplace_back(std::min(a, b), std::max(a, b)); + v2.emplace_back(std::min(a, b) + std::min(x, y), std::max(a, b) + std::max(x, y)); + if (i % 5 == 0) + v1.emplace_back(std::min(a, b), std::min(a, b) + x); + if (i % 3 == 0) + v2.emplace_back(std::max(a, b), std::max(a, b) + y); } BOOST_CHECK(bottleneck_distance(v1, v2, 0.) <= upper_bound / 100.); BOOST_CHECK(bottleneck_distance(v1, v2, upper_bound / 10000.) <= upper_bound / 100. + upper_bound / 10000.); -- cgit v1.2.3