include/topology/persistence-diagram.h
author Christos Mantoulidis <cmad@stanford.edu>
Tue, 04 Aug 2009 13:23:16 -0700
branchdev
changeset 156 f75fb57d2831
parent 120 3c830b15d694
child 217 64a272a34cb2
permissions -rw-r--r--
Changed implementation of WeightedRips to store simplex values (max distance between simplices' vertices) as an invisible layer on top of each simplex object, so that the data() field of WeightedRips has been freed for use by the users again.

#ifndef __PERSISTENCE_DIAGRAM_H__
#define __PERSISTENCE_DIAGRAM_H__

#include <utilities/types.h>

#include <vector>
#include <iostream>
#include <cmath>

#include <boost/compressed_pair.hpp>
#include <boost/optional.hpp>
#include <boost/serialization/access.hpp>

/**
 * Class: PDPoint
 *
 * Stores birth-death pair plus any additional information provided by `Data` template parameter.
 */
template<class Data_ = Empty<> >
class PDPoint
{
    public:
        typedef                 Data_                                       Data;

                                PDPoint(const PDPoint& other):
                                    point_(other.point_)                    {}
                                PDPoint(RealType x = 0, RealType y = 0, const Data& data = Data());

        RealType                x() const                                   { return point_.first().first; }
        RealType                y() const                                   { return point_.first().second; }
        const Data&             data() const                                { return point_.second(); }
        Data&                   data()                                      { return point_.second(); }

        std::ostream&           operator<<(std::ostream& out) const         { return (out << x() << " " << y()); } // << " " << data()); }
        
        struct Visitor
        {
            template<class Iterator>
            void                point(Iterator i, PDPoint& p) const         {}
        };

    private:
        RealType&               x()                                         { return point_.first().first; }
        RealType&               y()                                         { return point_.first().second; }

    private:
        boost::compressed_pair<std::pair<RealType, RealType>, Data>       point_;
	
    private:
		/* Serialization */
		friend class boost::serialization::access;
		
		template<class Archive>
		void 					serialize(Archive& ar, version_type );
};

template<class Data>
std::ostream&                   operator<<(std::ostream& out, const PDPoint<Data>& point)     
{ return (point.operator<<(out)); }

template<class Point, class Iterator, class Evaluator, class Visitor>
boost::optional<Point>
make_point(Iterator i, const Evaluator& evaluator, const Visitor& visitor);

template<class Point, class Iterator, class Evaluator>
boost::optional<Point>
make_point(Iterator i, const Evaluator& evaluator)
{ return make_point<Point>(i, evaluator, Point::Visitor()); }


/**
 * Class: PersistenceDiagram
 *
 * Stores birth-death pairs, i.e. points in the extended plane. Each point can also store 
 * additional information described by `Data_` template parameter.
 */
template<class Data_ = Empty<> >
class PersistenceDiagram
{
    public:
        typedef                 Data_                                       Data;
        typedef                 PDPoint<Data>                               Point;
        typedef                 std::vector<Point>                          PointVector;
        typedef                 typename PointVector::const_iterator        const_iterator;

                                PersistenceDiagram()                        {}

        template<class OtherData>
                                PersistenceDiagram(const PersistenceDiagram<OtherData>& other);

        template<class Iterator, class Evaluator>
                                PersistenceDiagram(Iterator bg, Iterator end, 
                                                   const Evaluator& eval = Evaluator());

        template<class Iterator, class Evaluator, class Visitor>
                                PersistenceDiagram(Iterator bg, Iterator end, 
                                                   const Evaluator& eval = Evaluator(), 
                                                   const Visitor& visitor = Visitor());

        template<class Iterator, class Evaluator, class Visitor>
        void                    init(Iterator bg, Iterator end, 
                                     const Evaluator& eval = Evaluator(), 
                                     const Visitor& visitor = Visitor());

        const_iterator          begin() const                               { return points_.begin(); }
        const_iterator          end() const                                 { return points_.end(); }
        size_t                  size() const                                { return points_.size(); }

        void                    push_back(const Point& point)               { points_.push_back(point); }
        
        std::ostream&           operator<<(std::ostream& out) const;

    private:
        PointVector             points_;
	
    private:
		/* Serialization */
		friend class boost::serialization::access;
		
		template<class Archive>
		void 					serialize(Archive& ar, version_type );
};

template<class Data>
std::ostream&                   operator<<(std::ostream& out, const PersistenceDiagram<Data>& pd)     
{ return (pd.operator<<(out)); }

// Function: init_diagram_vector()
template<class Diagrams, class Iterator, class Evaluator, class DimensionExtractor>
void                    init_diagrams(Diagrams& diagrams,
                                      Iterator bg, Iterator end, 
                                      const Evaluator& evaluator = Evaluator(), 
                                      const DimensionExtractor& dimension = DimensionExtractor());

template<class Diagrams, class Iterator, class Evaluator, class DimensionExtractor, class Visitor>
void                    init_diagrams(Diagrams& diagrams,
                                      Iterator bg, Iterator end, 
                                      const Evaluator& evaluator = Evaluator(), 
                                      const DimensionExtractor& dimension = DimensionExtractor(),
                                      const Visitor& visitor = Visitor());

// Class: Linfty 
// Functor that computes L infinity norm between two points
template<class Point1, class Point2>
struct Linfty
{
    RealType            operator()(const Point1& p1, const Point2& p2) const        { return std::max(std::abs(p1.x() - p2.x()), 
                                                                                                      std::abs(p1.y() - p2.y())); }
    
    template<class Point>
    RealType            diagonal(const Point& p) const                              { return std::abs(p.y() - p.x())/2; }
};

// Function: bottleneck_distance(dgm1, dgm2)
// Computes bottleneck distance between the two diagrams.
template<class Diagram1, 
         class Diagram2, 
         class Norm>
RealType                bottleneck_distance(const Diagram1& dgm1, const Diagram2& dgm2, const Norm& norm = Norm());

template<class Diagram1, 
         class Diagram2>
RealType                bottleneck_distance(const Diagram1& dgm1, const Diagram2& dgm2)
{ return bottleneck_distance(dgm1, dgm2, Linfty<typename Diagram1::Point, typename Diagram2::Point>()); }


#include "persistence-diagram.hpp"

#endif // __PERSISTENCE_DIAGRAM_H__