Move persistence checking code to unit tests
[libstick.git] / tests / persistence.h
index f48c3867c32efdf55603b960cb5c31e07ab94235..27b01f2f18c73aa0dbfc3ef79e85bc8d583f1419 100644 (file)
@@ -30,6 +30,7 @@ class persistence_TestSuite: public Test::Suite {
             {
             TEST_ADD(persistence_TestSuite::test_matrix_reduction);
             TEST_ADD(persistence_TestSuite::test_betti_numbers);
+            TEST_ADD(persistence_TestSuite::test_lowestones);
         }
 
     protected:
@@ -60,7 +61,7 @@ class persistence_TestSuite: public Test::Suite {
             //                      \ /
             //                       9
 
-            scomplex::Simplex ssring[] = {
+            scomplex::simplex ssring[] = {
                 // dimension, faces, value...
                 /*  1 */ {0, {},           1},
                 /*  2 */ {0, {},           2},
@@ -87,11 +88,11 @@ class persistence_TestSuite: public Test::Suite {
                 /* 23 */ {2, {12, 13, 22}, 6.1201},
                 /* 24 */ {2, {8, 16, 22},  6.1202}
             };
-            const size_t cntssring = sizeof(ssring)/sizeof(scomplex::Simplex);
+            const size_t cntssring = sizeof(ssring)/sizeof(scomplex::simplex);
             ring.add_simplices(ssring, cntssring);
             oring.reset();
 
-            scomplex::Simplex sstorus[] = {
+            scomplex::simplex sstorus[] = {
                 // dimension, faces, value...
                 /* 25 */ {0, {},           7},
                 /* 26 */ {0, {},           8},
@@ -124,12 +125,12 @@ class persistence_TestSuite: public Test::Suite {
                 /* 53 */ {2, {10, 46, 44}, 9.1505},
                 /* 54 */ {2, {43, 46, 28}, 9.1506},
             };
-            const size_t cntsstorus = sizeof(sstorus)/sizeof(scomplex::Simplex);
+            const size_t cntsstorus = sizeof(sstorus)/sizeof(scomplex::simplex);
             torus = ring;
             torus.add_simplices(sstorus, cntsstorus);
             otorus.reset();
 
-            scomplex::Simplex ssball[] = {
+            scomplex::simplex ssball[] = {
                 // dimension, faces, value...
                 {0, {},                1},
                 {0, {},                2},
@@ -155,7 +156,7 @@ class persistence_TestSuite: public Test::Suite {
                 {3, {21, 14, 15, 19}, 22},
                 {3, {21, 16, 17, 20}, 23},
             };
-            const size_t cntssball = sizeof(ssball)/sizeof(scomplex::Simplex);
+            const size_t cntssball = sizeof(ssball)/sizeof(scomplex::simplex);
             ball.add_simplices(ssball, cntssball);
             oball.reset();
         }
@@ -194,7 +195,6 @@ class persistence_TestSuite: public Test::Suite {
             torusrbme.set_all(torusrbme_coords, sizeof(torusrbme_coords)/(2*sizeof(uint32_t)), true);
             TEST_ASSERT(torusrbme == torusrbm);
 
-
             pers ballp(oball);
             ballp.compute_matrices();
             const bm &ballbm = ballp.get_boundary_matrix();
@@ -283,6 +283,36 @@ class persistence_TestSuite: public Test::Suite {
             TEST_ASSERT(ballp.get_persistence_diagram(2).persistent_betti(oball.size()-3, oball.size()-3) == 2);
             TEST_ASSERT(ballp.get_persistence_diagram(3).persistent_betti(oball.size()-3, oball.size()-3) == 0);
         }
+
+        void test_lowestones() {
+            test_lowestones_impl(oring);
+            test_lowestones_impl(otorus);
+            test_lowestones_impl(oball);
+        }
+
+        void test_lowestones_impl(const scomplex::simplex_order& so) {
+            pers p(so);
+            p.compute_matrices();
+            const bm &lowestones = p.get_lowestones_matrix();
+
+            for (unsigned c=0; c < lowestones.size(); ++c)
+                assert(lowestones.get_column(c).size() <= 1);
+            for (unsigned r=0; r < lowestones.size(); ++r)
+                assert(lowestones.get_row(r).size() <= 1);
+            for (unsigned c=0; c < lowestones.size(); ++c) {
+                // If (r,c) is a one then
+                //   (i) a cycle dies with c --> row c is zero
+                //  (ii) a cycle is born with r --> column r is zero
+                //Hence
+                //   (i) the column r is a zero-column
+                //   (i) the row c is a zero-column
+                if (lowestones.get_column(c).size() > 0) {
+                    const uint32_t r = lowestones.get_column(c).back();
+                    assert(lowestones.get_column(r).size() == 0);
+                    assert(lowestones.get_row(c).size() == 0);
+                }
+            }
+        }
 };
 
 #endif