Add tests for matrix reduction of complex examples
[libstick.git] / tests / persistence.h
diff --git a/tests/persistence.h b/tests/persistence.h
new file mode 100644 (file)
index 0000000..55774dd
--- /dev/null
@@ -0,0 +1,217 @@
+#ifndef persistence_h_Fahlaewahgaebaqu
+#define persistence_h_Fahlaewahgaebaqu
+
+#include <cpptest.h>
+#include <cpptest-suite.h>
+
+#include <libstick-0.1/persistence.h>
+
+using namespace libstick;
+
+
+class persistence_TestSuite: public Test::Suite {
+
+    private:
+        typedef simplicial_complex<3, uint32_t, double> scomplex;
+        typedef persistence<3, uint32_t, double> pers;
+        typedef pers::boundary_matrix bm;
+        typedef pers::transformation_matrix tm;
+
+        bool setupcalled;
+        scomplex ball, ring, torus;
+        scomplex::simplex_order oball, oring, otorus;
+
+    public:
+        persistence_TestSuite() :
+            setupcalled(false),
+            oball(ball),
+            oring(ring),
+            otorus(torus)
+            {
+            TEST_ADD(persistence_TestSuite::test_matrix_reduction);
+        }
+
+    protected:
+        virtual void setup() {
+            if (setupcalled)
+                return;
+            setupcalled = true;
+
+            //   7 ------------------------------------- 8
+            //    \                                     /
+            //     \    4 ------------------------- 5  /
+            //      \    \                         /  /
+            //       \    \      1 ------- 2      /  /
+            //        \    \      \       /      /  /
+            //         \    \      \     /      /  /
+            //          \    \      \   /      /  /
+            //           \    \      \ /      /  /
+            //            \    \      3      /  /
+            //             \    \           /  /
+            //              \    \         /  /
+            //               \    \       /  /
+            //                \    \     /  /
+            //                 \    \   /  /
+            //                  \    \ /  /
+            //                   \    6  /
+            //                    \     /
+            //                     \   /
+            //                      \ /
+            //                       9
+
+            scomplex::Simplex ssring[] = {
+                // dimension, faces, value...
+                /*  1 */ {0, {},           1},
+                /*  2 */ {0, {},           2},
+                /*  3 */ {0, {},           3},
+                /*  4 */ {0, {},           4},
+                /*  5 */ {0, {},           5},
+                /*  6 */ {0, {},           6},
+                /*  7 */ {1, {2, 3},       6.01},
+                /*  8 */ {1, {3, 1},       6.02},
+                /*  9 */ {1, {1, 2},       6.03},
+                /* 10 */ {1, {4, 5},       6.04},
+                /* 11 */ {1, {5, 6},       6.05},
+                /* 12 */ {1, {6, 4},       6.06},
+                /* 13 */ {1, {1, 4},       6.07},
+                /* 14 */ {1, {1, 5},       6.08},
+                /* 15 */ {2, {13, 14, 10}, 6.0801},
+                /* 16 */ {1, {3, 6},       6.09},
+                /* 17 */ {1, {2, 5},       6.10},
+                /* 18 */ {1, {2, 6},       6.11},
+                /* 19 */ {2, {9, 14, 17},  6.1101},
+                /* 20 */ {2, {7, 16, 18},  6.1102},
+                /* 21 */ {2, {11, 17, 18}, 6.1103},
+                /* 22 */ {1, {1, 6},       6.12},
+                /* 23 */ {2, {12, 13, 22}, 6.1201},
+                /* 24 */ {2, {8, 16, 22},  6.1202}
+            };
+            const size_t cntssring = sizeof(ssring)/sizeof(scomplex::Simplex);
+            ring.add_simplices(ssring, cntssring);
+            oring.reset();
+
+            scomplex::Simplex sstorus[] = {
+                // dimension, faces, value...
+                /* 25 */ {0, {},           7},
+                /* 26 */ {0, {},           8},
+                /* 27 */ {0, {},           9},
+                /* 28 */ {1, {25, 26},     9.01},
+                /* 29 */ {1, {26, 27},     9.02},
+                /* 30 */ {1, {25, 27},     9.03},
+                /* 31 */ {1, {25, 1},      9.04},
+                /* 32 */ {1, {26, 1},      9.05},
+                /* 33 */ {2, {28, 31, 32}, 9.0501},
+                /* 34 */ {1, {27, 1},      9.06},
+                /* 35 */ {2, {30, 31, 34}, 9.0601},
+                /* 36 */ {1, {27, 3},      9.07},
+                /* 37 */ {2, {36, 34, 8},  9.0701},
+                /* 38 */ {1, {27, 2},      9.08},
+                /* 39 */ {1, {26, 2},      9.09},
+                /* 40 */ {2, {9, 32, 39},  9.0901},
+                /* 41 */ {2, {29, 38, 39}, 9.0902},
+                /* 42 */ {2, {7, 38, 36},  9.0903},
+                /* 43 */ {1, {4, 25},      9.10},
+                /* 44 */ {1, {5, 26},      9.11},
+                /* 45 */ {1, {6, 27},      9.12},
+                /* 46 */ {1, {4, 26},      9.13},
+                /* 47 */ {1, {4, 27},      9.14},
+                /* 48 */ {1, {5, 27},      9.15},
+                /* 49 */ {2, {43, 47, 30}, 9.1501},
+                /* 50 */ {2, {12, 45, 47}, 9.1502},
+                /* 51 */ {2, {29, 44, 48}, 9.1503},
+                /* 52 */ {2, {48, 11, 45}, 9.1504},
+                /* 53 */ {2, {10, 46, 44}, 9.1505},
+                /* 54 */ {2, {43, 46, 28}, 9.1506},
+            };
+            const size_t cntsstorus = sizeof(sstorus)/sizeof(scomplex::Simplex);
+            torus = ring;
+            torus.add_simplices(sstorus, cntsstorus);
+            otorus.reset();
+
+            scomplex::Simplex ssball[] = {
+                // dimension, faces, value...
+                {0, {},                1},
+                {0, {},                2},
+                {0, {},                3},
+                {0, {},                4},
+                {0, {},                5},
+                {1, {1, 2},            6},
+                {1, {2, 3},            7},
+                {1, {3, 4},            8},
+                {1, {4, 1},            9},
+                {1, {1, 5},           10},
+                {1, {2, 5},           11},
+                {1, {3, 5},           12},
+                {1, {4, 5},           13},
+                {2, {6, 10, 11},      14},
+                {2, {7, 11, 12},      15},
+                {2, {8, 12, 13},      16},
+                {2, {9, 13, 10},      17},
+                {1, {1, 3},           18},
+                {2, {18, 6, 7},       19},
+                {2, {18, 8, 9},       20},
+                {2, {18, 10, 12},     21},
+                {3, {21, 14, 15, 19}, 22},
+                {3, {21, 16, 17, 20}, 23},
+            };
+            const size_t cntssball = sizeof(ssball)/sizeof(scomplex::Simplex);
+            ball.add_simplices(ssball, cntssball);
+            oball.reset();
+        }
+
+        virtual void tear_down() {
+        }
+
+        void test_matrix_reduction() {
+            pers ringp(oring);
+            const bm &ringbm = ringp.get_boundary_matrix();
+            const bm &ringrbm = ringp.get_reduced_boundary_matrix();
+            const tm &ringtm = ringp.get_transformation_matrix();
+            TEST_ASSERT(ringrbm == ringbm * ringtm);
+
+            pers torusp(otorus);
+            const bm &torusbm = torusp.get_boundary_matrix();
+            const bm &torusrbm = torusp.get_reduced_boundary_matrix();
+            const tm &torustm = torusp.get_transformation_matrix();
+            TEST_ASSERT(torusrbm == torusbm * torustm);
+
+            uint32_t torusrbme_coords[][2] = {
+                    {0, 1}, {2, 7}, {3, 7}, {1, 8}, {2, 8}, {4, 10}, {5, 10}, {4, 11}, {6, 11}, {1, 13},
+                    {4, 13}, {10, 15}, {13, 15}, {14, 15}, {9, 19}, {10, 19}, {13, 19}, {17, 19}, {7, 20},
+                    {16, 20}, {18, 20}, {7, 21}, {9, 21}, {10, 21}, {11, 21}, {13, 21}, {16, 21}, {12, 23},
+                    {13, 23}, {22, 23}, {7, 24}, {8, 24}, {9, 24}, {10, 24}, {11, 24}, {12, 24}, {25, 28},
+                    {26, 28}, {25, 29}, {27, 29}, {1, 31}, {25, 31}, {28, 33}, {31, 33}, {32, 33}, {30, 35},
+                    {31, 35}, {34, 35}, {8, 37}, {30, 37}, {31, 37}, {36, 37}, {9, 40}, {28, 40}, {31, 40},
+                    {39, 40}, {9, 41}, {28, 41}, {29, 41}, {31, 41}, {38, 41}, {7, 42}, {8, 42}, {9, 42},
+                    {28, 42}, {29, 42}, {30, 42}, {7, 49}, {8, 49}, {9, 49}, {28, 49}, {29, 49}, {43, 49},
+                    {47, 49}, {10, 50}, {11, 50}, {28, 50}, {29, 50}, {43, 50}, {45, 50}, {29, 51}, {44, 51},
+                    {48, 51}, {10, 52}, {28, 52}, {43, 52}, {44, 52}, {28, 53}, {43, 53}, {46, 53 }
+            };
+            bm torusrbme(torusbm.size());
+            torusrbme.set_all(torusrbme_coords, sizeof(torusrbme_coords)/(2*sizeof(uint32_t)), true);
+            TEST_ASSERT(torusrbme == torusrbm);
+
+
+            pers ballp(oball);
+            const bm &ballbm = ballp.get_boundary_matrix();
+            const bm &ballrbm = ballp.get_reduced_boundary_matrix();
+            const tm &balltm = ballp.get_transformation_matrix();
+            TEST_ASSERT(ballrbm == ballbm * balltm);
+
+            uint32_t ballrbme_coords[][2] = {
+                    {0, 1}, {1, 6}, {2, 6}, {1, 7}, {3, 7}, {1, 8}, {4, 8}, {1, 10}, {5, 10}, {6, 14},
+                    {10, 14}, {11, 14}, {6, 15}, {7, 15}, {10, 15}, {12, 15}, {6, 16}, {7, 16}, {8, 16},
+                    {10, 16}, {13, 16}, {6, 17}, {7, 17}, {8, 17}, {9, 17}, {6, 19}, {7, 19}, {18, 19},
+                    {14, 22}, {15, 22}, {19, 22}, {21, 22}, {14, 23}, {15, 23}, {16, 23}, {17, 23}, {19, 23},
+                    {20, 23 }
+            };
+            bm ballrbme(ballrbm.size());
+            ballrbme.set_all(ballrbme_coords, sizeof(ballrbme_coords)/(2*sizeof(uint32_t)), true);
+            TEST_ASSERT(ballrbme == ballrbm);
+
+            //std::cout << std::endl;
+            //ballp.interpret_reduction(std::cout);
+        }
+};
+
+#endif