include/topology/persistence-diagram.h
author Dmitriy Morozov <dmitriy@mrzv.org>
Thu, 25 Dec 2008 13:09:00 -0800
branchdev
changeset 104 2cc1db3b98c6
parent 103 2ac129839e02
child 105 051af83fba4c
permissions -rw-r--r--
Initial commit of Python bindings

#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/serialization/access.hpp>

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

                                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>
Point   make_point(Iterator i, const Evaluator& evaluator, const Visitor& visitor);

template<class Point, class Iterator, class Evaluator>
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 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()); }
};

// 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__