summaryrefslogtreecommitdiff
path: root/matching/tests
diff options
context:
space:
mode:
Diffstat (limited to 'matching/tests')
-rw-r--r--matching/tests/prism_1.bif28
-rw-r--r--matching/tests/prism_2.bif29
-rw-r--r--matching/tests/test_bifiltration.cpp36
l---------matching/tests/test_bifiltration_1.txt1
l---------matching/tests/test_bifiltration_full_triangle_rene.txt1
-rw-r--r--matching/tests/test_common.cpp156
-rw-r--r--matching/tests/test_list.txt1
-rw-r--r--matching/tests/test_matching_distance.cpp167
-rw-r--r--matching/tests/tests_main.cpp2
9 files changed, 421 insertions, 0 deletions
diff --git a/matching/tests/prism_1.bif b/matching/tests/prism_1.bif
new file mode 100644
index 0000000..b37e807
--- /dev/null
+++ b/matching/tests/prism_1.bif
@@ -0,0 +1,28 @@
+bifiltration_phat_like
+26
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+1 1 0 1 0
+1 1 0 2 1
+1 0 0 3 1
+1 0 1 5 4
+1 0 0 4 1
+1 0 0 3 0
+1 0 0 5 0
+1 0 0 4 2
+1 0 0 5 2
+1 0 1 4 3
+1 1 0 2 0
+1 0 1 5 3
+2 1 1 13 10 7
+2 1 1 9 14 13
+2 1 1 8 11 6
+2 1 1 15 10 8
+2 1 1 14 12 16
+2 1 1 17 12 11
+2 4 0 7 16 6
+2 0 4 9 17 15
diff --git a/matching/tests/prism_2.bif b/matching/tests/prism_2.bif
new file mode 100644
index 0000000..49885e6
--- /dev/null
+++ b/matching/tests/prism_2.bif
@@ -0,0 +1,29 @@
+bifiltration_phat_like
+27
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+0 0 0
+1 0 0 2 1
+1 0 0 1 0
+1 0 0 5 3
+1 0 0 3 1
+1 0 0 5 4
+1 0 0 2 0
+1 0 0 4 1
+1 0 0 3 2
+1 0 0 5 2
+1 0 0 4 3
+1 0 0 4 2
+1 0 0 3 0
+2 0 0 16 12 6
+2 0 0 10 14 16
+2 0 0 9 17 7
+2 0 0 15 12 9
+2 0 0 13 17 11
+2 0 0 8 14 13
+2 4 0 6 11 7
+2 0 4 10 8 15
+2 3 3 15 16 13
diff --git a/matching/tests/test_bifiltration.cpp b/matching/tests/test_bifiltration.cpp
new file mode 100644
index 0000000..742dab8
--- /dev/null
+++ b/matching/tests/test_bifiltration.cpp
@@ -0,0 +1,36 @@
+#include "catch/catch.hpp"
+
+#include <sstream>
+#include <iostream>
+
+#include "common_util.h"
+#include "box.h"
+#include "bifiltration.h"
+
+using namespace md;
+
+//TEST_CASE("Small check", "[bifiltration][dim2]")
+//{
+// Bifiltration bif("/home/narn/code/matching_distance/code/src/tests/test_bifiltration_full_triangle_phat_like.txt", BifiltrationFormat::phat_like);
+// auto simplices = bif.simplices();
+// bif.sanity_check();
+//
+// REQUIRE( simplices.size() == 7 );
+//
+// REQUIRE( simplices[0].dim() == 0 );
+// REQUIRE( simplices[1].dim() == 0 );
+// REQUIRE( simplices[2].dim() == 0 );
+// REQUIRE( simplices[3].dim() == 1 );
+// REQUIRE( simplices[4].dim() == 1 );
+// REQUIRE( simplices[5].dim() == 1 );
+// REQUIRE( simplices[6].dim() == 2);
+//
+// REQUIRE( simplices[0].position() == Point(0, 0));
+// REQUIRE( simplices[1].position() == Point(0, 0));
+// REQUIRE( simplices[2].position() == Point(0, 0));
+// REQUIRE( simplices[3].position() == Point(3, 1));
+// REQUIRE( simplices[6].position() == Point(30, 40));
+//
+// Line line_1(Line::pi / 2.0, 0.0);
+// auto dgm = bif.slice_diagram(line_1);
+//}
diff --git a/matching/tests/test_bifiltration_1.txt b/matching/tests/test_bifiltration_1.txt
new file mode 120000
index 0000000..ddd23e9
--- /dev/null
+++ b/matching/tests/test_bifiltration_1.txt
@@ -0,0 +1 @@
+../../data/test_bifiltration_1.txt \ No newline at end of file
diff --git a/matching/tests/test_bifiltration_full_triangle_rene.txt b/matching/tests/test_bifiltration_full_triangle_rene.txt
new file mode 120000
index 0000000..47f49fd
--- /dev/null
+++ b/matching/tests/test_bifiltration_full_triangle_rene.txt
@@ -0,0 +1 @@
+../../data/test_bifiltration_full_triangle_rene.txt \ No newline at end of file
diff --git a/matching/tests/test_common.cpp b/matching/tests/test_common.cpp
new file mode 100644
index 0000000..9079a56
--- /dev/null
+++ b/matching/tests/test_common.cpp
@@ -0,0 +1,156 @@
+#include "catch/catch.hpp"
+
+#include <sstream>
+#include <iostream>
+#include <string>
+
+#include "common_util.h"
+#include "simplex.h"
+#include "matching_distance.h"
+
+//using namespace md;
+using Real = double;
+using Point = md::Point<Real>;
+using Bifiltration = md::Bifiltration<Real>;
+using BifiltrationProxy = md::BifiltrationProxy<Real>;
+using CalculationParams = md::CalculationParams<Real>;
+using CellWithValue = md::CellWithValue<Real>;
+using DualPoint = md::DualPoint<Real>;
+using DualBox = md::DualBox<Real>;
+using Simplex = md::Simplex<Real>;
+using AbstractSimplex = md::AbstractSimplex;
+using BoundStrategy = md::BoundStrategy;
+using TraverseStrategy = md::TraverseStrategy;
+using AxisType = md::AxisType;
+using AngleType = md::AngleType;
+using ValuePoint = md::ValuePoint;
+using Column = md::Column;
+
+
+TEST_CASE("AbstractSimplex", "[abstract_simplex]")
+{
+ AbstractSimplex as;
+ REQUIRE(as.dim() == -1);
+
+ as.push_back(1);
+ REQUIRE(as.dim() == 0);
+ REQUIRE(as.facets().size() == 0);
+
+ as.push_back(0);
+ REQUIRE(as.dim() == 1);
+ REQUIRE(as.facets().size() == 2);
+ REQUIRE(as.facets()[0].dim() == 0);
+ REQUIRE(as.facets()[1].dim() == 0);
+
+}
+
+TEST_CASE("Vertical line", "[vertical_line]")
+{
+ // line x = 1
+ DualPoint l_vertical(AxisType::x_type, AngleType::steep, 0, 1);
+
+ REQUIRE(l_vertical.is_vertical());
+ REQUIRE(l_vertical.is_steep());
+
+ Point p_1(0.5, 0.5);
+ Point p_2(1.5, 0.5);
+ Point p_3(1.5, 1.5);
+ Point p_4(0.5, 1.5);
+ Point p_5(1, 10);
+
+ REQUIRE(l_vertical.x_from_y(10) == 1);
+ REQUIRE(l_vertical.x_from_y(-10) == 1);
+ REQUIRE(l_vertical.x_from_y(0) == 1);
+
+ REQUIRE(not l_vertical.contains(p_1));
+ REQUIRE(not l_vertical.contains(p_2));
+ REQUIRE(not l_vertical.contains(p_3));
+ REQUIRE(not l_vertical.contains(p_4));
+ REQUIRE(l_vertical.contains(p_5));
+
+ REQUIRE(l_vertical.goes_below(p_1));
+ REQUIRE(not l_vertical.goes_below(p_2));
+ REQUIRE(not l_vertical.goes_below(p_3));
+ REQUIRE(l_vertical.goes_below(p_4));
+
+ REQUIRE(not l_vertical.goes_above(p_1));
+ REQUIRE(l_vertical.goes_above(p_2));
+ REQUIRE(l_vertical.goes_above(p_3));
+ REQUIRE(not l_vertical.goes_above(p_4));
+
+}
+
+TEST_CASE("Horizontal line", "[horizontal_line]")
+{
+ // line y = 1
+ DualPoint l_horizontal(AxisType::y_type, AngleType::flat, 0, 1);
+
+ REQUIRE(l_horizontal.is_horizontal());
+ REQUIRE(l_horizontal.is_flat());
+ REQUIRE(l_horizontal.y_slope() == 0);
+ REQUIRE(l_horizontal.y_intercept() == 1);
+
+ Point p_1(0.5, 0.5);
+ Point p_2(1.5, 0.5);
+ Point p_3(1.5, 1.5);
+ Point p_4(0.5, 1.5);
+ Point p_5(2, 1);
+
+ REQUIRE((not l_horizontal.contains(p_1) and
+ not l_horizontal.contains(p_2) and
+ not l_horizontal.contains(p_3) and
+ not l_horizontal.contains(p_4) and
+ l_horizontal.contains(p_5)));
+
+ REQUIRE(not l_horizontal.goes_below(p_1));
+ REQUIRE(not l_horizontal.goes_below(p_2));
+ REQUIRE(l_horizontal.goes_below(p_3));
+ REQUIRE(l_horizontal.goes_below(p_4));
+ REQUIRE(l_horizontal.goes_below(p_5));
+
+ REQUIRE(l_horizontal.goes_above(p_1));
+ REQUIRE(l_horizontal.goes_above(p_2));
+ REQUIRE(not l_horizontal.goes_above(p_3));
+ REQUIRE(not l_horizontal.goes_above(p_4));
+ REQUIRE(l_horizontal.goes_above(p_5));
+}
+
+TEST_CASE("Flat Line with positive slope", "[flat_line]")
+{
+ // line y = x / 2 + 1
+ DualPoint l_flat(AxisType::y_type, AngleType::flat, 0.5, 1);
+
+ REQUIRE(not l_flat.is_horizontal());
+ REQUIRE(l_flat.is_flat());
+ REQUIRE(l_flat.y_slope() == 0.5);
+ REQUIRE(l_flat.y_intercept() == 1);
+
+ REQUIRE(l_flat.y_from_x(0) == 1);
+ REQUIRE(l_flat.y_from_x(1) == 1.5);
+ REQUIRE(l_flat.y_from_x(2) == 2);
+
+ Point p_1(3, 2);
+ Point p_2(-2, 0.01);
+ Point p_3(0, 1.25);
+ Point p_4(6, 4.5);
+ Point p_5(2, 2);
+
+ REQUIRE((not l_flat.contains(p_1) and
+ not l_flat.contains(p_2) and
+ not l_flat.contains(p_3) and
+ not l_flat.contains(p_4) and
+ l_flat.contains(p_5)));
+
+ REQUIRE(not l_flat.goes_below(p_1));
+ REQUIRE(l_flat.goes_below(p_2));
+ REQUIRE(l_flat.goes_below(p_3));
+ REQUIRE(l_flat.goes_below(p_4));
+ REQUIRE(l_flat.goes_below(p_5));
+
+ REQUIRE(l_flat.goes_above(p_1));
+ REQUIRE(not l_flat.goes_above(p_2));
+ REQUIRE(not l_flat.goes_above(p_3));
+ REQUIRE(not l_flat.goes_above(p_4));
+ REQUIRE(l_flat.goes_above(p_5));
+
+}
diff --git a/matching/tests/test_list.txt b/matching/tests/test_list.txt
new file mode 100644
index 0000000..1984606
--- /dev/null
+++ b/matching/tests/test_list.txt
@@ -0,0 +1 @@
+prism_lesnick_1.bif prism_lesnick_2.bif 1.0
diff --git a/matching/tests/test_matching_distance.cpp b/matching/tests/test_matching_distance.cpp
new file mode 100644
index 0000000..82da530
--- /dev/null
+++ b/matching/tests/test_matching_distance.cpp
@@ -0,0 +1,167 @@
+#include "catch/catch.hpp"
+
+#include <sstream>
+#include <iostream>
+#include <string>
+
+#include "spdlog/spdlog.h"
+#include "spdlog/fmt/ostr.h"
+
+#include "common_util.h"
+#include "simplex.h"
+#include "matching_distance.h"
+
+using Real = double;
+using Point = md::Point<Real>;
+using Bifiltration = md::Bifiltration<Real>;
+using BifiltrationProxy = md::BifiltrationProxy<Real>;
+using CalculationParams = md::CalculationParams<Real>;
+using CellWithValue = md::CellWithValue<Real>;
+using DualPoint = md::DualPoint<Real>;
+using DualBox = md::DualBox<Real>;
+using Simplex = md::Simplex<Real>;
+using AbstractSimplex = md::AbstractSimplex;
+using BoundStrategy = md::BoundStrategy;
+using TraverseStrategy = md::TraverseStrategy;
+using AxisType = md::AxisType;
+using AngleType = md::AngleType;
+using ValuePoint = md::ValuePoint;
+using Column = md::Column;
+
+using md::k_corner_vps;
+
+namespace spd = spdlog;
+
+TEST_CASE("Different bounds", "[bounds]")
+{
+ std::vector<Simplex> simplices;
+ std::vector<Point> points;
+
+ Real max_x = 10;
+ Real max_y = 20;
+
+ int simplex_id = 0;
+ for(int i = 0; i <= max_x; ++i) {
+ for(int j = 0; j <= max_y; ++j) {
+ Point p(i, j);
+ simplices.emplace_back(simplex_id++, p, 0, Column());
+ points.push_back(p);
+ }
+ }
+
+ Bifiltration bif_a(simplices.begin(), simplices.end());
+ Bifiltration bif_b(simplices.begin(), simplices.end());
+
+ CalculationParams params;
+ params.initialization_depth = 2;
+
+ BifiltrationProxy bifp_a(bif_a, params.dim);
+ BifiltrationProxy bifp_b(bif_b, params.dim);
+
+ md::DistanceCalculator<Real, BifiltrationProxy> calc(bifp_a, bifp_b, params);
+
+// REQUIRE(calc.max_x_ == Approx(max_x));
+// REQUIRE(calc.max_y_ == Approx(max_y));
+
+ std::vector<DualBox> boxes;
+
+ for(CellWithValue c : calc.get_refined_grid(5, false, false)) {
+ boxes.push_back(c.dual_box());
+ }
+
+ // fill in boxes and points
+
+ for(DualBox db : boxes) {
+ Real local_bound = calc.get_local_dual_bound(db);
+ Real local_bound_refined = calc.get_local_refined_bound(db);
+ REQUIRE(local_bound >= local_bound_refined);
+ for(Point p : points) {
+ for(ValuePoint vp_a : k_corner_vps) {
+ CellWithValue dual_cell(db, 1);
+ DualPoint corner_a = dual_cell.value_point(vp_a);
+ Real wp_a = corner_a.weighted_push(p);
+ dual_cell.set_value_at(vp_a, wp_a);
+ Real point_bound = calc.get_max_displacement_single_point(dual_cell, vp_a, p);
+ for(ValuePoint vp_b : k_corner_vps) {
+ if (vp_b <= vp_a)
+ continue;
+ DualPoint corner_b = dual_cell.value_point(vp_b);
+ Real wp_b = corner_b.weighted_push(p);
+ Real diff = fabs(wp_a - wp_b);
+ if (not(point_bound <= Approx(local_bound_refined))) {
+ std::cerr << "ERROR point: " << p << ", box = " << db << ", point bound = " << point_bound
+ << ", refined local = " << local_bound_refined << std::endl;
+ spd::set_level(spd::level::debug);
+ calc.get_max_displacement_single_point(dual_cell, vp_a, p);
+ calc.get_local_refined_bound(db);
+ spd::set_level(spd::level::info);
+ }
+
+ REQUIRE(point_bound <= Approx(local_bound_refined));
+ REQUIRE(diff <= Approx(point_bound));
+ REQUIRE(diff <= Approx(local_bound_refined));
+ }
+
+ for(DualPoint l_random : db.random_points(100)) {
+ Real wp_random = l_random.weighted_push(p);
+ Real diff = fabs(wp_a - wp_random);
+ if (not(diff <= Approx(point_bound))) {
+ if (db.critical_points(p).size() > 4) {
+ std::cerr << "ERROR interesting case" << std::endl;
+ } else {
+ std::cerr << "ERROR boring case" << std::endl;
+ }
+ spd::set_level(spd::level::debug);
+ l_random.weighted_push(p);
+ spd::set_level(spd::level::info);
+ std::cerr << "ERROR point: " << p << ", box = " << db << ", point bound = " << point_bound
+ << ", refined local = " << local_bound_refined;
+ std::cerr << ", random_dual_point = " << l_random << ", wp_random = " << wp_random
+ << ", diff = " << diff << std::endl;
+ }
+ REQUIRE(diff <= Approx(point_bound));
+ }
+ }
+ }
+ }
+}
+
+TEST_CASE("Bifiltrations from file", "[matching_distance][small_example][lesnick]")
+{
+ std::string fname_a, fname_b;
+
+ fname_a = "../src/tests/prism_1.bif";
+ fname_b = "../src/tests/prism_2.bif";
+
+ Bifiltration bif_a(fname_a);
+ Bifiltration bif_b(fname_b);
+
+ CalculationParams params;
+
+ std::vector<BoundStrategy> bound_strategies {BoundStrategy::local_combined,
+ BoundStrategy::local_dual_bound_refined};
+
+ std::vector<TraverseStrategy> traverse_strategies {TraverseStrategy::breadth_first, TraverseStrategy::depth_first};
+
+ std::vector<double> scaling_factors {10, 1.0};
+
+ for(auto bs : bound_strategies) {
+ for(auto ts : traverse_strategies) {
+ for(double lambda : scaling_factors) {
+ Bifiltration bif_a_copy(bif_a);
+ Bifiltration bif_b_copy(bif_b);
+ bif_a_copy.scale(lambda);
+ bif_b_copy.scale(lambda);
+ params.bound_strategy = bs;
+ params.traverse_strategy = ts;
+ params.max_depth = 7;
+ params.delta = 0.1;
+ params.dim = 1;
+ Real answer = matching_distance(bif_a_copy, bif_b_copy, params);
+ Real correct_answer = lambda * 1.0;
+ REQUIRE(fabs(answer - correct_answer) / correct_answer < params.delta);
+ }
+ }
+ }
+}
+
diff --git a/matching/tests/tests_main.cpp b/matching/tests/tests_main.cpp
new file mode 100644
index 0000000..1c77b13
--- /dev/null
+++ b/matching/tests/tests_main.cpp
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN
+#include "catch/catch.hpp"