--- a/CMakeLists.txt Tue Dec 23 11:02:08 2008 -0800
+++ b/CMakeLists.txt Thu Dec 25 14:24:02 2008 -0800
@@ -104,3 +104,4 @@
# Process subdirectories
add_subdirectory (examples)
add_subdirectory (tests)
+add_subdirectory (tools)
--- a/include/topology/filtration.h Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/filtration.h Thu Dec 25 14:24:02 2008 -0800
@@ -10,6 +10,10 @@
// Class: Filtration
//
+// Filtration keeps track of the ordering of the simplices in a complex.
+// The most significant function it provides is <boundary()> which converts
+// the boundary of a simplex at a given index into a list of indices.
+//
// TODO: this is really specialized for an std::vector<> Complex; eventually generalize
// TODO: should we derive from Order?
template<class Complex_,
--- a/include/topology/persistence-diagram.h Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/persistence-diagram.h Thu Dec 25 14:24:02 2008 -0800
@@ -15,12 +15,14 @@
*
* Stores birth-death pair plus any additional information provided by `Data` template parameter.
*/
-template<class Data_>
+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; }
@@ -28,7 +30,7 @@
const Data& data() const { return point_.second(); }
Data& data() { return point_.second(); }
- std::ostream& operator<<(std::ostream& out) const { return (out << x() << " " << y() << " " << data()); }
+ std::ostream& operator<<(std::ostream& out) const { return (out << x() << " " << y()); } // << " " << data()); }
struct Visitor
{
@@ -79,6 +81,9 @@
PersistenceDiagram() {}
+ template<class OtherData>
+ PersistenceDiagram(const PersistenceDiagram<OtherData>& other);
+
template<class Iterator, class Evaluator>
PersistenceDiagram(Iterator bg, Iterator end,
const Evaluator& eval = Evaluator());
--- a/include/topology/persistence-diagram.hpp Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/persistence-diagram.hpp Thu Dec 25 14:24:02 2008 -0800
@@ -12,6 +12,18 @@
point_.second() = data;
}
+
+template<class D>
+template<class OtherData>
+PersistenceDiagram<D>::
+PersistenceDiagram(const PersistenceDiagram<OtherData>& other)
+{
+ points_.reserve(other.size());
+ for (typename PersistenceDiagram<OtherData>::PointVector::const_iterator cur = points_.begin();
+ cur != points_.end(); ++cur)
+ push_back(Point(cur->x(), cur->y()));
+}
+
template<class D>
template<class Iterator, class Evaluator>
PersistenceDiagram<D>::
--- a/include/topology/static-persistence.hpp Tue Dec 23 11:02:08 2008 -0800
+++ b/include/topology/static-persistence.hpp Thu Dec 25 14:24:02 2008 -0800
@@ -23,7 +23,7 @@
ocmp_(ocmp)
{
OrderIndex ocur = begin();
- OffsetMap<size_t, OrderIndex> om(0, ocur); // TODO: this is customized for std::vector Order
+ OffsetMap<typename Filtration::IntermediateIndex, OrderIndex> om(0, ocur); // TODO: this is customized for std::vector Order
for (typename Filtration::Index cur = filtration.begin(); cur != filtration.end(); ++cur, ++ocur)
{
// Convert the Filtration::IndexBoundary into a Cycle, and
--- a/include/utilities/types.h Tue Dec 23 11:02:08 2008 -0800
+++ b/include/utilities/types.h Thu Dec 25 14:24:02 2008 -0800
@@ -17,7 +17,7 @@
typedef const unsigned int& version_type;
struct Empty {};
-std::ostream& operator<<(std::ostream& out, Empty e) { return out; }
+//std::ostream& operator<<(std::ostream& out, Empty e) { return out; }
enum SwitchType
{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/CMakeLists.txt Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,11 @@
+find_package (Qt4 REQUIRED)
+set (QT_USE_QTOPENGL TRUE)
+set (QT_USE_QTXML TRUE)
+include (${QT_USE_FILE})
+
+#find_library (gle_LIBRARY NAMES gle)
+#find_library (QGLViewer_LIBRARY NAMES QGLViewer)
+#find_path (QGLViewer_INCLUDE_DIR QGLViewer/qglviewer.h)
+#include_directories (${QGLViewer_INCLUDE_DIR})
+
+add_subdirectory (diagram-viewer)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/CMakeLists.txt Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,18 @@
+set (diagram-viewerSources
+ diagram.cpp
+ diagram-viewer-main.cpp)
+
+set (diagram-viewerHeaders
+ diagram.h)
+
+qt4_wrap_cpp (diagram-viewerMocSources ${diagram-viewerHeaders})
+
+set (libraries ${libraries}
+ ${Boost_SERIALIZATION_LIBRARY}
+ ${Boost_PROGRAM_OPTIONS_LIBRARY}
+ ${QT_LIBRARIES})
+
+add_executable (diagram-viewer ${diagram-viewerSources}
+ ${diagram-viewerMocSources})
+
+target_link_libraries (diagram-viewer ${libraries})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram-viewer-main.cpp Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,59 @@
+#include <qapplication.h>
+#include <QtGui>
+
+#include "diagram.h"
+
+#include <fstream>
+#include <map>
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/serialization/map.hpp>
+
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+
+
+int main (int argc, char *argv[])
+{
+ std::string diagrams_filename;
+ int dimension;
+
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("diagrams-file", po::value<std::string>(&diagrams_filename), "The collection of persistence diagrams")
+ ("dimension", po::value<int>(&dimension), "Dimension of the diagram to show");
+
+ po::positional_options_description p;
+ p.add("diagrams-file", 1);
+ p.add("dimension", 2);
+
+ po::options_description all; all.add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(all).positional(p).run(), vm);
+ po::notify(vm);
+
+ if (!vm.count("diagrams-file") || !vm.count("dimension"))
+ {
+ std::cout << "Usage: " << argv[0] << " diagrams-file dimension" << std::endl;
+ std::cout << hidden << std::endl;
+ return 1;
+ }
+
+ std::map<Dimension, PDiagram> dgms;
+ std::ifstream ifs(diagrams_filename.c_str());
+ boost::archive::binary_iarchive ia(ifs);
+ ia >> dgms;
+
+
+ QApplication application(argc, argv);
+
+ std::cout << dimension << std::endl;
+ std::cout << dgms[dimension] << std::endl;
+
+ DgmViewer pd(dgms[dimension]);
+ pd.show();
+
+ // Run main loop.
+ return application.exec();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram.cpp Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,95 @@
+#include <iostream>
+
+#include <QtGui>
+#include <QRectF>
+
+#include "diagram.h"
+#include <cmath>
+
+//static const double ellipse_size = 0.035;
+static const double ellipse_size = 3;
+
+/* DgmViewer Implementation */
+DgmViewer::DgmViewer(const PDiagram& dgm):
+ min_x(0), min_y(0), max_x(0), max_y(0)
+{
+ points.reserve(dgm.size());
+
+ for (PDiagram::const_iterator cur = dgm.begin(); cur != dgm.end(); ++cur)
+ {
+ min_x = std::min(min_x, cur->x());
+ min_y = std::min(min_y, cur->y());
+ max_x = std::max(max_x, cur->x());
+ max_y = std::max(max_y, cur->y());
+
+ points.push_back(new DgmPoint(*cur, ellipse_size));
+ }
+
+ addDgmPoints();
+ setWindowTitle(QString("Persistence Diagram"));
+}
+DgmViewer::~DgmViewer()
+{
+ for (PointsVector::iterator cur = points.begin(); cur != points.end(); ++cur)
+ delete *cur;
+}
+
+
+void DgmViewer::addDgmPoints()
+{
+ RealType min = std::min(min_x, min_y);
+ RealType max = std::max(max_x, max_y);
+
+ QGraphicsLineItem* diagonal = new QGraphicsLineItem(QLineF(min, -min, max, -max));
+ QGraphicsLineItem* y_axis = new QGraphicsLineItem(QLineF(0, -min_y, 0, -max_y));
+ QGraphicsLineItem* x_axis = new QGraphicsLineItem(QLineF(min_x, 0, max_x, 0));
+
+ scene.addItem(diagonal);
+ scene.addItem(y_axis);
+ scene.addItem(x_axis);
+
+ for (PointsVector::const_iterator cur = points.begin(); cur != points.end(); ++cur)
+ scene.addItem(*cur);
+
+ //scale(100,100);
+ setScene(&scene);
+ setRenderHint(QPainter::Antialiasing);
+ ensureVisible(scene.itemsBoundingRect());
+ //setMinimumSize( (int)(maxX - minX)*100 + 100, (int) (maxY - minY)*100 + 100);
+}
+
+
+DgmPoint::DgmPoint(QGraphicsItem* parent):
+ QGraphicsItem(parent)
+{
+}
+
+DgmPoint::DgmPoint(const Parent& pt, qreal size, QGraphicsItem *parent):
+ Parent(pt), ellipse_size(size), QGraphicsItem(parent)
+{
+ setToolTip(QString("(%1, %2)").arg(getX()).arg(getY()));
+}
+
+DgmPoint::DgmPoint(RealType b, RealType d, qreal size, QGraphicsItem *parent):
+ Parent(b, d), ellipse_size(size), QGraphicsItem(parent)
+{
+ setToolTip(QString("(%1, %2)").arg(getX()).arg(getY()));
+}
+
+void DgmPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
+{
+ Q_UNUSED(option);
+ Q_UNUSED(widget);
+
+ //QBrush solidFill(unselectColor);
+ //QBRush selectSolidFill(selectColor);
+ painter->setBrush(Qt::SolidPattern);
+ //painter->setPen(selectColor);
+ painter->drawEllipse(QRectF(getX() - ellipse_size, -getY() - ellipse_size, 2*ellipse_size, 2*ellipse_size));
+}
+
+
+QRectF DgmPoint::boundingRect() const
+{
+ return QRectF(getX() - ellipse_size, -getY() - ellipse_size, 2*ellipse_size, 2*ellipse_size);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/diagram-viewer/diagram.h Thu Dec 25 14:24:02 2008 -0800
@@ -0,0 +1,60 @@
+#ifndef __DIAGRAM_H__
+#define __DIAGRAM_H__
+
+#include <QtGui>
+#include <QObject>
+#include <QColor>
+
+#include <map>
+
+#include <utilities/types.h>
+#include <topology/persistence-diagram.h>
+
+typedef PersistenceDiagram<> PDiagram;
+typedef std::map<Dimension, PDiagram> Diagrams;
+
+class DgmPoint;
+
+class DgmViewer: public QGraphicsView
+{
+ Q_OBJECT
+
+ public:
+ typedef std::vector<DgmPoint*> PointsVector;
+
+ DgmViewer(const PDiagram& dgm);
+ ~DgmViewer();
+
+ void addDgmPoints();
+
+ private:
+ PointsVector points;
+ QGraphicsScene scene;
+ RealType min_x, min_y, max_x, max_y;
+};
+
+
+class DgmPoint: public PDPoint<>, public QGraphicsItem
+{
+ public:
+ typedef PDPoint<> Parent;
+
+ DgmPoint(QGraphicsItem* parent = 0);
+ DgmPoint(const Parent& pt, qreal size, QGraphicsItem *parent = 0);
+ DgmPoint(RealType b, RealType d, qreal size, QGraphicsItem *parent = 0);
+
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
+ QRectF boundingRect() const;
+
+ qreal getX() const { return Parent::x(); }
+ qreal getY() const { return Parent::y(); }
+
+ int type() const { return QGraphicsItem::UserType + 1; }
+
+ private:
+ // size of rectangle containing ellipses
+ qreal ellipse_size;
+};
+
+
+#endif // __DIAGRAM_H__