Factor out simplicial_function
[libstick.git] / include / libstick / persistence.h
index b9fc080ee589c951f9a16a0e354dcc774888028e..a2e163f6bcf851034fd7c41037d164fea06b1bf1 100644 (file)
@@ -6,7 +6,7 @@
 #include <vector>
 #include <cassert>
 
-#include "simplicialcomplex.h"
+#include "simplicialfunction.h"
 #include "booleanmatrix.h"
 
 
@@ -15,11 +15,11 @@ namespace libstick {
 
 /** Persistence computers various persistent homology information on a
  * simplex_order of a simplicial_complex. */
-template<int MAXDIM, class IT, class VT>
+template<int MAXDIM, class IT>
 class persistence {
 
     public:
-        typedef simplicial_complex<MAXDIM, IT, VT> scomplex;
+        typedef simplicial_complex<MAXDIM, IT> scomplex;
         typedef typename scomplex::simplex_order simplex_order;
         typedef boolean_colmatrix<IT> boundary_matrix;
         typedef boolean_colmatrix<IT> transformation_matrix;
@@ -172,8 +172,11 @@ class persistence {
             return tm;
         }
 
-        /** Print the sequence of births and deaths of cycles (homology classes). */
-        void interpret_reduction(std::ostream &os) const {
+        /** Print the sequence of births and deaths of cycles (homology
+         * classes). If a non-NULL simplicial function is given, also the
+         * values of the simplices are printed.  */
+        template<class VT>
+        void interpret_reduction(std::ostream &os, simplicial_function<MAXDIM, IT, VT> *f) const {
             assert(done_matrices);
 
             for (unsigned c=0; c < bm.width(); ++c) {
@@ -199,21 +202,28 @@ class persistence {
                         os << "simplex";
                         break;
                 }
+                os << std::endl;
 
-                os << " \t\tvalue: " << order.get_simplex(c).value << std::endl;
+                if (f != NULL)
+                    os << "  value: " <<  f->get_value(order.order_to_complex(c)) << std::endl;
                 os << "  boundary: " << bm.get_column(c) << std::endl;
 
                 typename boolean_colmatrix<IT>::column_type col = rbm.get_column(c);
                 if (col.isempty()) {
                     os << "  \033[1;32mbirth\033[0;m of a cycle: " << tm.get_column(c) << std::endl;
                 } else {
-                    os << "  \033[1;31mdeath\033[0;m of a cycle: " << rbm.get_column(c) << std::endl;
-                    os << "  boundary of: " << tm.get_column(c) << std::endl;
+                    os << "  \033[1;31mdeath\033[0;m of a cycle: " << rbm.get_column(c);
+                    os << ", boundary of: " << tm.get_column(c) << std::endl;
                 }
                 os << std::endl;
             }
         }
 
+        /** Print the sequence of births and deaths of cycles (homology classes). */
+        void interpret_reduction(std::ostream &os) const {
+            interpret_reduction<float>(os, NULL);
+        }
+
         /** Get the 'dim'-dimensional peristence diagram. */
         const diagram& get_persistence_diagram(int dim) const{
             assert(-1 <= dim);
@@ -273,8 +283,11 @@ class persistence {
 #endif
         }
 
-        /** Print birth and death information in the persistence diagrams. */
-        void interpret_persistence(std::ostream &os) const {
+        /** Print birth and death information in the persistence diagrams. If a
+         * non-NULL simplicial function is given, also the persistence w.r.t.
+         * this function is printed. */
+        template<class VT>
+        void interpret_persistence(std::ostream &os, simplicial_function<MAXDIM, IT, VT> *f) const {
             assert(done_diagrams);
 
             for (int d=-1; d <= MAXDIM; ++d) {
@@ -287,17 +300,27 @@ class persistence {
 
                     os << "  ";
                     if (death > 0) {
-                        const scomplex& c = get_order().get_complex();
-                        const VT pers = c.simplices[death].value - c.simplices[birth].value;
-                        os << birth << "\033[1;31m -> " << death << "\033[0;m" << " \tpers: " << pers;
+                        os << birth << "\033[1;31m -> " << death << "\033[0;m";
+
+                        if (f != NULL) {
+                            const VT pers = f->get_value(death) -  f->get_value(birth);
+                            os << " \tpers: " << pers;
+                        }
                     } else {
-                        os << "\033[1;32m" << birth << "\033[0;m" << " \t\t[essential]";
+                        os << "\033[1;32m" << birth << "\033[0;m";
+                        if (f != NULL)
+                            os << " \t\t[essential]";
                     }
                     os << std::endl;
                 }
             }
         }
 
+        /** Print birth and death information in the persistence diagrams. */
+        void interpret_persistence(std::ostream &os) const {
+            interpret_persistence<float>(os, NULL);
+        }
+
     private:
 
         diagram& _get_persistence_diagram(int dim) {