Created pl-vineyard.cpp to compute vineyards given a complex and a sequence of values at each vertex
--- a/examples/grid/CMakeLists.txt Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/CMakeLists.txt Wed Dec 16 15:39:38 2009 -0800
@@ -17,4 +17,8 @@
add_executable (${t} ${t}.cpp)
target_link_libraries (${t} ${libraries} ${CGAL_LIBRARY} ${dsrpdb_LIBRARY})
endforeach (t ${targets})
+
+ # Extra special for program_options
+ add_executable (pl-vineyard pl-vineyard.cpp)
+ target_link_libraries (pl-vineyard ${libraries} ${CGAL_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY})
endif (CGAL_FOUND)
--- a/examples/grid/grid2D.h Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/grid2D.h Wed Dec 16 15:39:38 2009 -0800
@@ -32,7 +32,7 @@
{
public:
typedef RealType ValueType;
- typedef ValueType value_type;
+ typedef ValueType result_type;
typedef unsigned int CoordinateIndex;
typedef boost::counting_iterator<CoordinateIndex> iterator;
--- a/examples/grid/lsvineyard.h Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/lsvineyard.h Wed Dec 16 15:39:38 2009 -0800
@@ -30,7 +30,7 @@
typedef Vertex_ Vertex;
typedef VertexEvaluator_ VertexEvaluator;
- typedef typename VertexEvaluator::value_type VertexValue;
+ typedef typename VertexEvaluator::result_type VertexValue;
typedef Simplex_ Simplex;
typedef Filtration_ LSFiltration;
@@ -171,7 +171,7 @@
{ return out << vi->vertex(); }
template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::KineticVertexComparison
+class LSVineyard<V,VE,S,C>::KineticVertexComparison: public std::binary_function<const KineticVertexType&, const KineticVertexType&, bool>
{
public:
KineticVertexComparison(const VertexComparison& vcmp):
@@ -204,7 +204,7 @@
};
template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::Evaluator
+class LSVineyard<V,VE,S,C>::Evaluator: public std::unary_function<Index, RealType>
{
public:
virtual RealType time() const =0;
@@ -229,7 +229,7 @@
};
template<class V, class VE, class S, class C>
-class LSVineyard<V,VE,S,C>::DimensionFromIterator: std::unary_function<Dimension, iterator>
+class LSVineyard<V,VE,S,C>::DimensionFromIterator: std::unary_function<iterator, Dimension>
{
public:
DimensionFromIterator(const PFMap& pfmap): pfmap_(pfmap) {}
--- a/examples/grid/lsvineyard.hpp Wed Dec 16 15:39:06 2009 -0800
+++ b/examples/grid/lsvineyard.hpp Wed Dec 16 15:39:38 2009 -0800
@@ -32,9 +32,11 @@
rLog(rlLSVineyardDebug, "Simplices paired");
vertices_.sort(KineticVertexComparison(vcmp_)); // sort vertices w.r.t. vcmp_
- std::cout << "Vertex order:" << std::endl;
+#if LOGGING
+ rLog(rlLSVineyardDebug, "Vertex order:");
for (VertexIndex cur = vertices_.begin(); cur != vertices_.end(); ++cur)
- std::cout << " " << cur->vertex() << std::endl;
+ rLog(rlLSVineyardDebug, " %d", cur->vertex());
+#endif
// Initialize simplex_index() and attachment
VertexIndex vi = boost::prior(vertices_.begin());
@@ -85,6 +87,7 @@
{
VertexValue val0 = veval_(cur->vertex());
VertexValue val1 = veval(cur->vertex());
+ rLog(rlLSVineyardDebug, "Vertex %d: %f -> %f", cur->vertex(), val0, val1);
F x = cf(F::NT(val0), F::NT(val1 - val0)); // x = val0 + (val1 - val0)*t = (1-t)*val0 + t*val1
Point p(x);
cur->set_kinetic_key(apt->insert(p));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/grid/pl-vineyard.cpp Wed Dec 16 15:39:38 2009 -0800
@@ -0,0 +1,169 @@
+#include <utilities/log.h>
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "lsvineyard.h"
+
+#include <boost/program_options.hpp>
+#include <boost/iterator/counting_iterator.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+namespace bl = boost::lambda;
+
+
+typedef float VertexValue;
+typedef unsigned Vertex;
+typedef std::vector<VertexValue> VertexVector;
+struct SubscriptFunctor: public std::unary_function<Vertex, VertexValue>
+{
+ SubscriptFunctor(const VertexVector& v): vec(&v) {}
+ float operator()(Vertex i) const { return (*vec)[i]; }
+ SubscriptFunctor& operator=(const SubscriptFunctor& other) { vec = other.vec; return *this; }
+ const VertexVector* vec;
+};
+typedef SubscriptFunctor VertexEvaluator;
+typedef std::vector<VertexVector> VertexVectorVector;
+typedef LSVineyard<Vertex, VertexEvaluator> PLVineyard;
+typedef PLVineyard::Simplex Smplx; // gotta start using namespaces
+
+void program_options(int argc, char* argv[], std::string& complex_fn,
+ std::string& values_fn,
+ std::string& output_prefix,
+ bool& skip_infinite_vines,
+ bool& save_vines,
+ bool& explicit_events);
+void read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices);
+void read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices);
+
+
+int main(int argc, char** argv)
+{
+#ifdef LOGGING
+ rlog::RLogInit(argc, argv);
+#endif
+
+ std::string complex_fn, values_fn, output_prefix;
+ bool skip_infinite_vines = false, explicit_events = false, save_vines = false;
+ program_options(argc, argv, complex_fn, values_fn, output_prefix, skip_infinite_vines, save_vines, explicit_events);
+
+
+ // Read in the complex
+ PLVineyard::LSFiltration simplices;
+ read_simplices(complex_fn, simplices);
+ std::cout << "Complex read, size: " << simplices.size() << std::endl;
+
+ // Read in vertex values
+ VertexVectorVector vertices;
+ read_vertices(values_fn, vertices);
+
+ // Setup the vineyard
+ VertexEvaluator veval(vertices[0]);
+ PLVineyard::VertexComparison vcmp(veval);
+ PLVineyard::SimplexComparison scmp(vcmp);
+ simplices.sort(scmp);
+ PLVineyard v(boost::counting_iterator<Vertex>(0),
+ boost::counting_iterator<Vertex>(vertices[0].size()),
+ simplices, veval);
+ std::cout << "Pairing computed" << std::endl;
+
+ // Compute vineyard
+ for (size_t i = 1; i < vertices.size(); ++i)
+ {
+ veval = VertexEvaluator(vertices[i]);
+ v.compute_vineyard(veval, explicit_events);
+ std::cout << "Processed frame: " << i << std::endl;
+ }
+ std::cout << "Vineyard computed" << std::endl;
+
+ if (save_vines)
+ v.vineyard().save_vines(output_prefix, skip_infinite_vines);
+ else
+ v.vineyard().save_edges(output_prefix, skip_infinite_vines);
+}
+
+
+void read_simplices(const std::string& complex_fn, PLVineyard::LSFiltration& simplices)
+{
+ std::ifstream in(complex_fn.c_str());
+ std::string line;
+ while (std::getline(in, line))
+ {
+ std::istringstream strin(line);
+ simplices.push_back(Smplx(std::istream_iterator<Vertex>(strin), std::istream_iterator<Vertex>()));
+ }
+ std::cout << "Simplices read:" << std::endl;
+ std::copy(simplices.begin(), simplices.end(), std::ostream_iterator<Smplx>(std::cout, "\n"));
+}
+
+void read_vertices(const std::string& vertex_fn, VertexVectorVector& vertices)
+{
+ std::ifstream in(vertex_fn.c_str());
+ std::string line;
+ while (std::getline(in, line))
+ {
+ std::istringstream strin(line);
+ vertices.push_back(VertexVector(std::istream_iterator<VertexValue>(strin), std::istream_iterator<VertexValue>()));
+ }
+ std::cout << "Vertex values read:" << std::endl;
+ for (size_t i = 0; i < vertices.size(); ++i)
+ {
+ std::copy(vertices[i].begin(), vertices[i].end(), std::ostream_iterator<VertexValue>(std::cout, " "));
+ std::cout << std::endl;
+ }
+}
+
+void program_options(int argc, char* argv[], std::string& complex_fn,
+ std::string& values_fn,
+ std::string& output_prefix,
+ bool& skip_infinite_vines,
+ bool& save_vines,
+ bool& explicit_events)
+{
+ namespace po = boost::program_options;
+
+ po::options_description hidden("Hidden options");
+ hidden.add_options()
+ ("complex-file", po::value<std::string>(&complex_fn), "file listing the simplices of the complex")
+ ("values-file", po::value<std::string>(&values_fn), "file listing the values at the vertices")
+ ("output-prefix", po::value<std::string>(&output_prefix), "output prefix");
+
+ po::options_description visible("Allowed options", 100);
+ visible.add_options()
+ ("skip-infinite,s", po::bool_switch(&skip_infinite_vines), "skip infinite vines in the output")
+ ("explicit-events,e", po::bool_switch(&explicit_events), "process kinetic sort events one by one")
+ ("save-vines,v", po::bool_switch(&save_vines), "save vines instead of edges")
+ ("help,h", "produce help message");
+#if LOGGING
+ std::vector<std::string> log_channels;
+ visible.add_options()
+ ("log,l", po::value< std::vector<std::string> >(&log_channels), "log channels to turn on (info, debug, etc)");
+#endif
+
+ po::positional_options_description pos;
+ pos.add("complex-file", 1);
+ pos.add("values-file", 1);
+ pos.add("output-prefix", 1);
+
+ po::options_description all; all.add(visible).add(hidden);
+
+ po::variables_map vm;
+ po::store(po::command_line_parser(argc, argv).
+ options(all).positional(pos).run(), vm);
+ po::notify(vm);
+
+#if LOGGING
+ for (std::vector<std::string>::const_iterator cur = log_channels.begin(); cur != log_channels.end(); ++cur)
+ stderrLog.subscribeTo( RLOG_CHANNEL(cur->c_str()) );
+#endif
+
+ if (vm.count("help") || !vm.count("complex-file") || !vm.count("values-file") || !vm.count("output-prefix"))
+ {
+ std::cout << "Usage: " << argv[0] << " [options] complex-file values-file output-prefix" << std::endl;
+ std::cout << visible << std::endl;
+ std::abort();
+ }
+}
--- a/include/topology/vineyard.h Wed Dec 16 15:39:06 2009 -0800
+++ b/include/topology/vineyard.h Wed Dec 16 15:39:38 2009 -0800
@@ -52,6 +52,7 @@
void set_evaluator(Evaluator* eval) { evaluator = eval; }
void save_edges(const std::string& filename, bool skip_infinite = false) const;
+ void save_vines(const std::string& filename, bool skip_infinite = false) const;
private:
template<class Iter>
--- a/include/topology/vineyard.hpp Wed Dec 16 15:39:06 2009 -0800
+++ b/include/topology/vineyard.hpp Wed Dec 16 15:39:38 2009 -0800
@@ -119,6 +119,33 @@
}
}
+template<class I, class It, class E>
+void
+Vineyard<I,It,E>::
+save_vines(const std::string& filename, bool skip_infinite) const
+{
+ for (unsigned int i = 0; i < vines_vector.size(); ++i)
+ {
+ std::ostringstream os; os << i;
+ std::string fn = filename + os.str() + ".vin";
+ std::ofstream out(fn.c_str());
+ for (typename VineList::const_iterator vi = vines_vector[i]->begin(); vi != vines_vector[i]->end(); ++vi)
+ {
+ for (typename Vine::const_iterator ki = vi->begin(); ki != vi->end(); ki++)
+ {
+ if (skip_infinite && ki->is_infinite())
+ {
+ std::cerr << "Warning: skipping an infinite knee in save_edges() in dimension " << i << std::endl;
+ continue;
+ }
+ out << ki->birth << ' ' << ki->death << ' ' << ki->time << " ";
+ }
+ out << std::endl;
+ }
+ out.close();
+ }
+}
+
/// Records a knee for the given simplex
template<class I, class It, class E>
template<class Iter>