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.
/*
* Author: Dmitriy Morozov
* Department of Computer Science, Duke University, 2007
*/
#ifndef __AR_VINEYARD_H__
#define __AR_VINEYARD_H__
#include <boost/signals.hpp>
#include <boost/bind.hpp>
#include <list>
#include <vector>
#include "topology/conesimplex.h"
#include "topology/filtration.h"
#include "geometry/kinetic-sort.h"
#include "geometry/simulator.h"
#include "ar-simplex3d.h"
#include "ar-function-kernel.h"
template <class Simulator_>
class ARConeSimplex3D: public ConeSimplex<ARSimplex3D>
{
public:
typedef ConeSimplex<ARSimplex3D> Parent;
typedef ARSimplex3D ARSimplex3D;
/// \name Simulator types
/// @{
typedef Simulator_ Simulator;
typedef typename Simulator::FunctionKernel FunctionKernel;
typedef typename FunctionKernel::Function Function;
/// @}
/// \name ThresholdSort types
/// @{
typedef std::list<Function> ThresholdList;
typedef typename ThresholdList::iterator ThresholdListIterator;
struct ThresholdTrajectoryExtractor
{ Function operator()(ThresholdListIterator i) const { return *i; } };
typedef KineticSort<ThresholdListIterator,
ThresholdTrajectoryExtractor, Simulator> ThresholdSort;
/// @}
typedef boost::signal<void (Simulator*)> NewMaxSignal;
public:
ARConeSimplex3D(const ARSimplex3D& s, bool coned = false);
ARConeSimplex3D(const Parent& p): Parent(p) {} // crucial for boundary() to work correctly
ARConeSimplex3D(const ARConeSimplex3D& other): // need explicit copy-constructor because of the signal
Parent(other, other.coned()),
thresholds_(other.thresholds_) {}
const ThresholdList& thresholds() const { return thresholds_; }
NewMaxSignal& new_max_signal() { return new_max_signal_; }
const Function& max_threshold() const { return thresholds_.back(); }
void schedule_thresholds(Simulator* simulator);
// need explicit operator= because of the signal
ARConeSimplex3D& operator=(const ARConeSimplex3D& other) { Parent::operator=(other); thresholds_ = other.thresholds_; return *this; }
private:
ThresholdList thresholds_;
ThresholdSort thresholds_sort_;
NewMaxSignal new_max_signal_;
void swap_thresholds(ThresholdListIterator i, Simulator* simulator);
};
/**
* Encapsulated filtration, and provides compute_vineyard() functionality.
*/
class ARVineyard
{
public:
typedef ARVineyard Self;
/// \name FunctionKernel and Simulator types
/// @{
typedef ARFunctionKernel FunctionKernel;
typedef FunctionKernel::Function Function;
typedef Simulator<FunctionKernel> SimulatorAR;
/// @}
/// \name Filtration types
/// @{
typedef ARConeSimplex3D<SimulatorAR> ConeSimplex3D;
typedef Filtration<ConeSimplex3D> FiltrationAR;
typedef FiltrationAR::Simplex Simplex;
typedef FiltrationAR::Index Index;
typedef FiltrationAR::Vineyard Vineyard;
typedef Vineyard::Evaluator Evaluator;
/// @}
/// \name SimplexSort types
/// @{
struct SimplexTrajectoryExtractor
{ Function operator()(Index i) const { return i->max_threshold(); } };
typedef KineticSort<Index, SimplexTrajectoryExtractor, SimulatorAR> SimplexSort;
typedef SimplexSort::iterator SimplexSortIterator;
class ThresholdChangeSlot; // used to notify of change in max threshold
/// @}
typedef std::list<Point> PointList;
class StaticEvaluator;
class KineticEvaluator;
public:
ARVineyard(const PointList& points, const Point& z);
~ARVineyard();
void compute_pairing();
void compute_vineyard(double max_radius);
const FiltrationAR* filtration() const { return filtration_; }
const Vineyard* vineyard() const { return vineyard_; }
public:
void swap(Index i, SimulatorAR* simulator); ///< For kinetic sort
private:
void add_simplices();
void change_evaluator(Evaluator* eval);
private:
FiltrationAR* filtration_;
Vineyard* vineyard_;
Evaluator* evaluator_;
Point z_;
Delaunay dt_;
#if 0
private:
// Serialization
friend class boost::serialization::access;
ARVineyard() {}
template<class Archive>
void serialize(Archive& ar, version_type )
{
// FIXME
};
#endif
};
//BOOST_CLASS_EXPORT(ARVineyard)
#ifdef COUNTERS
static Counter* cARVineyardTrajectoryKnee = GetCounter("ar/vineyard/trajectoryknee");
#endif
class ARVineyard::ThresholdChangeSlot
{
public:
ThresholdChangeSlot(SimplexSortIterator iter, SimplexSort* sort,
Vineyard* vineyard, SimulatorAR* sort_simulator):
iter_(iter), sort_(sort), vineyard_(vineyard), sort_simulator_(sort_simulator) { iter_->element->new_max_signal().connect(*this); }
void operator()(SimulatorAR* simulator)
{
Count(cARVineyardTrajectoryKnee);
sort_->update_trajectory(iter_, sort_simulator_);
if (iter_->element->sign())
vineyard_->record_knee(iter_->element);
else
vineyard_->record_knee(iter_->element->pair());
}
private:
SimplexSortIterator iter_;
SimplexSort* sort_; // could make both of these static
Vineyard* vineyard_; // currently inefficient since there is
// only one SimplexSort and one Vineyard,
// but each is stored in every slot
SimulatorAR* sort_simulator_;
};
class ARVineyard::StaticEvaluator: public Evaluator
{
public:
StaticEvaluator() {}
virtual RealType time() const { return 0; }
virtual RealType value(const Simplex& s) const { return s.value(); }
};
class ARVineyard::KineticEvaluator: public Evaluator
{
public:
KineticEvaluator(SimulatorAR* simplex_sort_simulator,
SimulatorAR* trajectory_sort_simulator):
simplex_sort_simulator_(simplex_sort_simulator),
trajectory_sort_simulator_(trajectory_sort_simulator) {}
virtual RealType time() const { return std::max(simplex_sort_simulator_->current_time(), trajectory_sort_simulator_->current_time()); }
virtual RealType value(const Simplex& s) const { return FunctionKernel::value_at(s.max_threshold(), time()); }
private:
SimulatorAR* simplex_sort_simulator_;
SimulatorAR* trajectory_sort_simulator_;
};
#include "ar-vineyard.hpp"
#endif // __AR_VINEYARD_H__