include/topology/simplex.h
author Dmitriy Morozov <morozov@cs.duke.edu>
Fri, 14 Mar 2008 18:35:41 -0400
branchfitness
changeset 49 7558e122ba4f
parent 43 0f970f454094
child 76 66622c6bf8cf
permissions -rw-r--r--
Normalized persistence (#cff) + unpaired simplices output pairs with 0

/*
 * Author: Dmitriy Morozov
 * Department of Computer Science, Duke University, 2005 -- 2007
 */

#ifndef __SIMPLEX_H__
#define __SIMPLEX_H__

#include <vector>
#include <algorithm>
#include <list>
#include <iostream>

#include "utilities/types.h"

#include <boost/serialization/access.hpp>


/**
 * SimplexWithVertices is a basic simplex class. It stores vertices of a given type, 
 * and knows how to compute its own boundary. It should probably be used as a base 
 * class for any explicit simplex representation.
 */
template<class V>
class SimplexWithVertices
{
	public:
		typedef		V																Vertex;
		typedef		SimplexWithVertices<Vertex>										Self;
	
		typedef		std::vector<Vertex>												VertexContainer;
		typedef		std::list<Self>													Cycle;
		
		/// \name Constructors 
		/// @{
		SimplexWithVertices()														{}
		SimplexWithVertices(const Self& s):	
			vertices_(s.vertices_)													{}
		template<class Iterator>
		SimplexWithVertices(Iterator bg, Iterator end):
			vertices_(bg, end)														{ std::sort(vertices_.begin(), vertices_.end()); }
		SimplexWithVertices(const VertexContainer& v):	
			vertices_(v)															{ std::sort(vertices_.begin(), vertices_.end()); }
		SimplexWithVertices(Dimension d, Vertex v):	
			vertices_()																{ vertices_.reserve(d+1); add(v); }
		SimplexWithVertices(Dimension d): 
			vertices_(d+1)															{}
		/// @}
		
		/// \name Core 
		/// @{
		Cycle					boundary() const;
		Dimension				dimension() const									{ return vertices_.size()-1; }
		/// @}
		
		/// \name Vertex manipulation
		/// @{
		bool					contains(const Vertex& v) const;
		const VertexContainer&	vertices() const									{ return vertices_; }
		void					add(const Vertex& v);
		/// @}

		/// \name Assignment and comparison
		/// Gives an ordering on simplices (for example, so that simplices can be used as keys for std::map)
		/// @{
		const Self&				operator=(const Self& s)							{ vertices_ = s.vertices_; return *this; }
		bool					operator==(const Self& s) const						{ return vertices_ == s.vertices_; }
		bool 					operator<(const Self& s) const						{ return vertices_ < s.vertices_; }
		/// @}

		std::ostream&			operator<<(std::ostream& out) const;
	
	private:
		VertexContainer			vertices_;

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

/**
 * SimplexWithValue explicitly adds a RealType value to the SimplexWithVertices.
 */
template<class Vert>
class SimplexWithValue: public SimplexWithVertices<Vert>
{
	public:
		typedef		Vert															Vertex;
		typedef		RealType														Value;
		typedef		SimplexWithValue<Vertex>										Self;
		typedef		SimplexWithVertices<Vertex>										Parent;

		typedef		typename Parent::VertexContainer								VertexContainer;
	
		/// \name Constructors
		/// @{
		SimplexWithValue(Value value = 0): val(value)								{}
		SimplexWithValue(const Self& s):
			Parent(s), val(s.val)													{}
		SimplexWithValue(const Parent& s, Value value = 0): 
			Parent(s), val(value)													{}
		template<class Iterator>
		SimplexWithValue(Iterator bg, Iterator end, Value value = 0):
			Parent(bg, end), val(value)												{}
		SimplexWithValue(const VertexContainer& v, Value value = 0):
			Parent(v), val(value)													{}
		/// @}

		/// \name Core
		/// @{
		void 					set_value(Value value)								{ val = value; }
		Value					get_value() const									{ return val; }
		/// @}
		
		const Self&				operator=(const Self& s);
		std::ostream&			operator<<(std::ostream& out) const;

	private:
		Value					val;

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

/**
 * SimplexWithAttachment stores the vertex to which the simplex is attached (meant for lower-star filtrations)
 */
template<typename V>
class SimplexWithAttachment: public SimplexWithVertices<V>
{
	public:
		typedef 	V																VertexIndex;
		typedef		SimplexWithVertices<VertexIndex>								Parent;
	
		/// \name Constructors 
		/// @{
		SimplexWithAttachment():
			attachment(VertexIndex())												{}
		template<class Iterator>
		SimplexWithAttachment(Iterator bg, Iterator end):
			Parent(bg, end)															{}
		SimplexWithAttachment(const Parent& s):
			Parent(s)																{}
		SimplexWithAttachment(Dimension d, VertexIndex vi):
			Parent(d, vi), attachment(vi)											{}
		/// @}

		void 					set_attachment(VertexIndex v)						{ attachment = v; }
		VertexIndex				get_attachment() const								{ return attachment; }
		
	private:
		VertexIndex				attachment;
	
	private:
		// Serialization
		friend class boost::serialization::access;

		template<class Archive>
		void 					serialize(Archive& ar, version_type );
};

template<class Simplex_>
class DimensionValueComparison
{
	public:
		typedef					Simplex_									Simplex;

		bool					operator()(const Simplex& s1, const Simplex& s2) const
		{
			if (s1.dimension() == s2.dimension())
				return s1.get_value() < s2.get_value();
			else
				return s1.dimension() < s2.dimension();
		}
};

#include "simplex.hpp"

#endif // __SIMPLEX_H__