Resurrected vineyard code: dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Wed, 16 Dec 2009 15:39:06 -0800
branchdev
changeset 179 d15c6d144645
parent 148 a99fdaafa31a
child 180 27508309a680
Resurrected vineyard code: * Switched StaticPersistence + (serializable) Filtration to Boost.MultiIndex * Updated DynamicPersistenceTrails to work with the new MultiIndex way * Created LSVineyard class, and fixed the grid examples
examples/CMakeLists.txt
examples/alphashapes/alphashapes2d.cpp
examples/alphashapes/alphashapes2d.h
examples/alphashapes/alphashapes2d.hpp
examples/alphashapes/alphashapes3d.cpp
examples/alphashapes/alphashapes3d.h
examples/alphashapes/alphashapes3d.hpp
examples/cech-complex/cech-complex.cpp
examples/fitness/avida-distance.cpp
examples/fitness/avida-rips-distance.cpp
examples/grid/CMakeLists.txt
examples/grid/combustion-vineyard.cpp
examples/grid/grid2D.h
examples/grid/grid2D.hpp
examples/grid/grid2Dvineyard.h
examples/grid/grid2Dvineyard.hpp
examples/grid/lsvineyard.h
examples/grid/lsvineyard.hpp
examples/grid/pdbdistance-vineyard.cpp
examples/grid/test-grid2D-vineyard.cpp
examples/poincare/poincare.cpp
examples/rips/rips-pairwise.cpp
examples/rips/rips.cpp
examples/triangle/triangle.cpp
include/topology/chain.h
include/topology/chain.hpp
include/topology/complex-traits.h
include/topology/dynamic-persistence.h
include/topology/dynamic-persistence.hpp
include/topology/filtration.h
include/topology/filtration.hpp
include/topology/lowerstarfiltration.h
include/topology/order.h
include/topology/persistence-diagram.hpp
include/topology/simplex.h
include/topology/simplex.hpp
include/topology/static-persistence.h
include/topology/static-persistence.hpp
include/topology/vineyard.h
include/topology/vineyard.hpp
include/utilities/indirect.h
include/utilities/property-maps.h
--- a/examples/CMakeLists.txt	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/CMakeLists.txt	Wed Dec 16 15:39:06 2009 -0800
@@ -4,7 +4,7 @@
 add_subdirectory			(consistency)
 add_subdirectory			(cohomology)
 add_subdirectory			(fitness)
-#add_subdirectory			(grid)
+add_subdirectory			(grid)
 add_subdirectory			(triangle)
 add_subdirectory			(poincare)
 add_subdirectory			(rips)
--- a/examples/alphashapes/alphashapes2d.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes2d.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -9,7 +9,7 @@
 #include <fstream>
 
 
-typedef Filtration<AlphaSimplex2DVector>        AlphaFiltration;
+typedef Filtration<AlphaSimplex2D>              AlphaFiltration;
 typedef StaticPersistence<>                     Persistence;
 typedef PersistenceDiagram<>                    PDgm;
 
@@ -41,12 +41,12 @@
     }
     rInfo("Delaunay triangulation computed");
    
-    AlphaSimplex2DVector complex;
-    fill_complex(Dt, complex);
-    rInfo("Simplices: %i", complex.size());
+    AlphaFiltration af;
+    fill_complex(Dt, af);
+    rInfo("Simplices: %i", af.size());
 
     // Create the alpha-shape filtration
-    AlphaFiltration af(complex.begin(), complex.end(), AlphaSimplex2D::AlphaOrder());
+    af.sort(AlphaSimplex2D::AlphaOrder());
     rInfo("Filtration initialized");
 
     Persistence p(af);
@@ -55,12 +55,11 @@
     p.pair_simplices();
     rInfo("Simplices paired");
 
-    std::map<Dimension, PDgm> dgms;
+    Persistence::SimplexMap<AlphaFiltration>    m       = p.make_simplex_map(af);
+    std::map<Dimension, PDgm>                   dgms;
     init_diagrams(dgms, p.begin(), p.end(), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, AlphaFiltration::Index>(p.begin(), af.begin()), 
-                                       evaluate_through_filtration(af, AlphaSimplex2D::AlphaValueEvaluator())), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, AlphaFiltration::Index>(p.begin(), af.begin()), 
-                                       evaluate_through_filtration(af, AlphaSimplex2D::DimensionExtractor())));
+                  evaluate_through_map(m, AlphaSimplex2D::AlphaValueEvaluator()),
+                  evaluate_through_map(m, AlphaSimplex2D::DimensionExtractor()));
 
 #if 1
     std::cout << 0 << std::endl << dgms[0] << std::endl;
--- a/examples/alphashapes/alphashapes2d.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes2d.h	Wed Dec 16 15:39:06 2009 -0800
@@ -74,7 +74,8 @@
 
 typedef             std::vector<AlphaSimplex2D>                             AlphaSimplex2DVector;
 void                fill_simplex_set(const Delaunay2D& Dt, AlphaSimplex2D::SimplexSet& simplices);
-void                fill_complex(const Delaunay2D& Dt,     AlphaSimplex2DVector& alpha_order);
+template<class Filtration>
+void                fill_complex(const Delaunay2D& Dt,     Filtration& filtration);
 
 std::ostream&       operator<<(std::ostream& out, const AlphaSimplex2D& s)  { return s.operator<<(out); }
 
--- a/examples/alphashapes/alphashapes2d.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes2d.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -1,4 +1,5 @@
 #include <utilities/log.h>
+#include <boost/foreach.hpp>
 
 AlphaSimplex2D::	    
 AlphaSimplex2D(const Delaunay2D::Vertex& v): alpha_(0), attached_(false)
@@ -104,16 +105,14 @@
 	rInfo("Vertices inserted");
 }
 
-void fill_complex(const Delaunay2D& Dt, AlphaSimplex2DVector& alpha_order)
+template<class Filtration>
+void fill_complex(const Delaunay2D& Dt, Filtration& filtration)
 {
 	// Compute all simplices with their alpha values and attachment information
+    // TODO: this can be optimized; the new Filtration can act as a SimplexSet
 	AlphaSimplex2D::SimplexSet simplices;
     fill_simplex_set(Dt, simplices);
-    
-	// Sort simplices by their alpha values
-	alpha_order.resize(simplices.size());
-	std::copy(simplices.begin(), simplices.end(), alpha_order.begin());
-	// std::sort(alpha_order.begin(), alpha_order.end(), AlphaSimplex2D::AlphaOrder());
-	std::sort(alpha_order.begin(), alpha_order.end(), AlphaSimplex2D::VertexComparison());
+    BOOST_FOREACH(const AlphaSimplex2D& s, simplices)
+        filtration.push_back(s);
 }
 
--- a/examples/alphashapes/alphashapes3d.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes3d.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -13,7 +13,7 @@
 #include <boost/program_options.hpp>
 
 
-typedef Filtration<AlphaSimplex3DVector>        AlphaFiltration;
+typedef Filtration<AlphaSimplex3D>              AlphaFiltration;
 typedef StaticPersistence<>                     Persistence;
 typedef PersistenceDiagram<>                    PDgm;
 
@@ -71,12 +71,12 @@
     }
     rInfo("Delaunay triangulation computed");
    
-    AlphaSimplex3DVector complex;
-    fill_complex(Dt, complex);
-    rInfo("Simplices: %d", complex.size());
+    AlphaFiltration  af;
+    fill_complex(Dt, af);
+    rInfo("Simplices: %d", af.size());
 
     // Create the alpha-shape filtration
-    AlphaFiltration af(complex.begin(), complex.end(), AlphaSimplex3D::AlphaOrder());
+    af.sort(AlphaSimplex3D::AlphaOrder());
     rInfo("Filtration initialized");
     
     Persistence p(af);
@@ -85,12 +85,11 @@
     p.pair_simplices();
     rInfo("Simplices paired");
 
+    Persistence::SimplexMap<AlphaFiltration>    m       = p.make_simplex_map(af);
     std::map<Dimension, PDgm> dgms;
     init_diagrams(dgms, p.begin(), p.end(), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, AlphaFiltration::Index>(p.begin(), af.begin()), 
-                                       evaluate_through_filtration(af, AlphaSimplex3D::AlphaValueEvaluator())), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, AlphaFiltration::Index>(p.begin(), af.begin()), 
-                                       evaluate_through_filtration(af, AlphaSimplex3D::DimensionExtractor())));
+                  evaluate_through_map(m, AlphaSimplex3D::AlphaValueEvaluator()), 
+                  evaluate_through_map(m, AlphaSimplex3D::DimensionExtractor()));
 #if 0
     std::cout << 0 << std::endl << dgms[0] << std::endl;
     std::cout << 1 << std::endl << dgms[1] << std::endl;
--- a/examples/alphashapes/alphashapes3d.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes3d.h	Wed Dec 16 15:39:06 2009 -0800
@@ -77,9 +77,9 @@
 		bool 						attached_;
 };
 
-typedef 			std::vector<AlphaSimplex3D>								AlphaSimplex3DVector;
 void 				fill_simplex_set(const Delaunay3D& Dt, AlphaSimplex3D::SimplexSet& simplices);
-void 				fill_complex(const Delaunay3D& Dt,     AlphaSimplex3DVector& alpha_order);
+template<class Filtration>
+void 				fill_complex(const Delaunay3D& Dt,     Filtration& filtration);
 
 std::ostream& 		operator<<(std::ostream& out, const AlphaSimplex3D& s)	{ return s.operator<<(out); }
 
--- a/examples/alphashapes/alphashapes3d.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/alphashapes/alphashapes3d.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -1,4 +1,5 @@
 #include <utilities/log.h>
+#include <boost/foreach.hpp>
 
 AlphaSimplex3D::	    
 AlphaSimplex3D(const Delaunay3D::Vertex& v): alpha_(0), attached_(false)
@@ -159,15 +160,12 @@
 	rInfo("Vertices inserted");
 }
 
-void fill_complex(const Delaunay3D& Dt, AlphaSimplex3DVector& alpha_order)
+template<class Filtration>
+void fill_complex(const Delaunay3D& Dt, Filtration& filtration)
 {
 	AlphaSimplex3D::SimplexSet simplices;
     fill_simplex_set(Dt, simplices);
-    
-	// Sort simplices by their alpha values
-	alpha_order.resize(simplices.size());
-	std::copy(simplices.begin(), simplices.end(), alpha_order.begin());
-	//std::sort(alpha_order.begin(), alpha_order.end(), AlphaSimplex3D::AlphaOrder());
-	std::sort(alpha_order.begin(), alpha_order.end(), AlphaSimplex3D::VertexComparison());
+    BOOST_FOREACH(const AlphaSimplex3D& s, simplices)
+        filtration.push_back(s);
 }
 
--- a/examples/cech-complex/cech-complex.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/cech-complex/cech-complex.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -15,8 +15,7 @@
 typedef         std::vector<Point>                                      PointContainer;
 typedef         unsigned int                                            PointIndex;
 typedef         Simplex<PointIndex, double>                             Smplx;
-typedef         std::vector<Smplx>                                      SimplexVector;
-typedef         Filtration<SimplexVector>                               CechFiltration;
+typedef         Filtration<Smplx>                                       CechFiltration;
 typedef         StaticPersistence<>                                     Persistence;
 //typedef         DynamicPersistenceTrails<>                              Persistence;
 typedef         PersistenceDiagram<>            PDgm;
@@ -30,7 +29,7 @@
     return numerator/denominator;
 }
 
-void add_simplices(SimplexVector& sv, int d, const PointContainer& points)
+void add_simplices(CechFiltration& sv, int d, const PointContainer& points)
 {
     PointIndex indices[d+1];
     for (int i = 0; i < d+1; ++i) 
@@ -97,21 +96,18 @@
     rInfo("Points read: %d", points.size());
    
     // Compute simplices with their Cech values
-    SimplexVector    sv;
     int num_simplices = 0;
     for (int i = 0; i <= homology_d + 1; ++i)
         num_simplices += choose(points.size(), i+1);
-    sv.reserve(num_simplices);
     rInfo("Reserved SimplexVector of size: %d", num_simplices);
 
+    CechFiltration cf;
     for (int i = 0; i <= homology_d + 1; ++i)
-        add_simplices(sv, i, points);
-    rInfo("Size of SimplexVector: %d", sv.size());
-        
-    std::sort(sv.begin(), sv.end(), Smplx::VertexComparison());
+        add_simplices(cf, i, points);
+    rInfo("Size of SimplexVector: %d", cf.size());
 
-    // Set up the filtration
-    CechFiltration cf(sv.begin(), sv.end(), DataDimensionComparison<Smplx>());
+    // Sort the filtration
+    cf.sort(DataDimensionComparison<Smplx>());
     rInfo("Filtration initialized");
 
     // Compute persistence
@@ -120,12 +116,11 @@
     p.pair_simplices();
     rInfo("Simplices paired");
 
+    Persistence::SimplexMap<CechFiltration>     m = p.make_simplex_map(cf);
     std::map<Dimension, PDgm> dgms;
     init_diagrams(dgms, p.begin(), p.end(), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, CechFiltration::Index>(p.begin(), cf.begin()), 
-                                       evaluate_through_filtration(cf, Smplx::DataEvaluator())), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, CechFiltration::Index>(p.begin(), cf.begin()), 
-                                       evaluate_through_filtration(cf, Smplx::DimensionExtractor())));
+                  evaluate_through_map(m, Smplx::DataEvaluator()), 
+                  evaluate_through_map(m,  Smplx::DimensionExtractor()));
 
     for (int i = 0; i <= homology_d; ++i)
     {
--- a/examples/fitness/avida-distance.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/fitness/avida-distance.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -10,7 +10,7 @@
 
 typedef         Simplex<AvidaOrganismDetail::IDType, double>        Smplx;
 typedef         std::vector<Smplx>                                  Complex;
-typedef         Filtration<Complex>                                 Fltr;
+typedef         Filtration<Smplx>                                   Fltr;
 typedef         StaticPersistence<>                                 Persistence;
 
 int main(int argc, char** argv)
@@ -55,7 +55,6 @@
             simplices.back().add(organisms[j].id());
         }
     }
-    std::sort(simplices.begin(), simplices.end(), Smplx::VertexComparison());
     rInfo("Average distance: %f", float(avg_distance)/
                                   ((organisms.size()*organisms.size() - organisms.size())/2));
 
@@ -67,14 +66,14 @@
     typedef std::vector<RealType> DeathVector;
     DeathVector deaths;
     Smplx::DataEvaluator    eval;
-    OffsetMap<Persistence::OrderIndex, Fltr::Index> m(p.begin(), f.begin());
-    for (Persistence::OrderIndex i = p.begin(); i != p.end(); ++i)
+    Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
+    for (Persistence::iterator i = p.begin(); i != p.end(); ++i)
     {
-        if (i == i->pair) continue;
+        if (i->unpaired()) continue;
         if (i->sign())
         {
-            const Smplx& s = f.simplex(m[i]);
-            const Smplx& t = f.simplex(m[i->pair]);
+            const Smplx& s = m[i];
+            const Smplx& t = m[i->pair];
             AssertMsg(s.dimension() == 0, "Expecting only 0-dimensional diagram");
             AssertMsg(eval(s) == 0,       "Expecting only 0 birth values in 0-D diagram ");
             deaths.push_back(eval(t));
--- a/examples/fitness/avida-rips-distance.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/fitness/avida-rips-distance.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -13,9 +13,8 @@
 typedef         ExplicitDistances<AvidaPopulationDetail>            ExplicitDist;
 typedef         Rips<ExplicitDist>                                  RipsGen;
 typedef         RipsGen::Simplex                                    Smplx;
-typedef         std::vector<Smplx>                                  Complex;
 
-typedef         Filtration<Complex, unsigned>                       Fltr;
+typedef         Filtration<Smplx>                                   Fltr;
 typedef         StaticPersistence<>                                 Persistence;
 
 int main(int argc, char** argv)
@@ -51,12 +50,11 @@
    */
 
     rInfo("Starting to generate rips complex");
-    Complex c;
-    rips.generate(1, rips.max_distance()/2, make_push_back_functor(c));
-    std::sort(c.begin(), c.end(), Smplx::VertexComparison());
+    Fltr f;
+    rips.generate(1, rips.max_distance()/2, make_push_back_functor(f));
     
     rInfo("Generated Rips complex, filling filtration");
-    Fltr f(c.begin(), c.end(), RipsGen::Comparison(rips.distances()));
+    f.sort(RipsGen::Comparison(rips.distances()));
 
     Persistence p(f);
     p.pair_simplices();
@@ -64,14 +62,14 @@
     std::cout << "Outputting histogram of death values" << std::endl;
     typedef std::vector<RealType> DeathVector;
     DeathVector deaths;
-    OffsetMap<Persistence::OrderIndex, Fltr::Index> m(p.begin(), f.begin());
-    for (Persistence::OrderIndex i = p.begin(); i != p.end(); ++i)
+    Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
+    for (Persistence::iterator i = p.begin(); i != p.end(); ++i)
     {
-        if (i == i->pair) continue;
+        if (i->unpaired()) continue;
         if (i->sign())
         {
-            const Smplx& s = f.simplex(m[i]);
-            const Smplx& t = f.simplex(m[i->pair]);
+            const Smplx& s = m[i];
+            const Smplx& t = m[i->pair];
             AssertMsg(s.dimension() == 0, "Expecting only 0-dimensional diagram");
             AssertMsg(evaluator(s) == 0, "Expecting only 0 birth values in 0-D diagram ");
             deaths.push_back(evaluator(t));
--- a/examples/grid/CMakeLists.txt	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/grid/CMakeLists.txt	Wed Dec 16 15:39:06 2009 -0800
@@ -1,5 +1,6 @@
 set							(targets						
 							 test-grid2D 
+							 test-grid2D-vineyard
 							 combustion-vineyard)
 
 if                          (use_dsrpdb)
@@ -7,9 +8,13 @@
                             							pdbdistance-vineyard)
 endif                       (use_dsrpdb)
 
-							 
-add_definitions				(${cgal_cxxflags})
-foreach 					(t ${targets})
-	add_executable			(${t} ${t}.cpp)
-	target_link_libraries	(${t} ${libraries} ${cgal_libraries} ${dsrpdb_LIBRARY})
-endforeach 					(t ${targets})
+if                              (CGAL_FOUND)
+    # add_definitions             (${CGAL_CXX_FLAGS_INIT})
+    add_definitions             (-frounding-math)
+    include_directories         (${CGAL_INCLUDE_DIRS})
+
+    foreach 					(t ${targets})
+        add_executable			(${t} ${t}.cpp)
+        target_link_libraries	(${t} ${libraries} ${CGAL_LIBRARY} ${dsrpdb_LIBRARY})
+    endforeach 					(t ${targets})
+endif                           (CGAL_FOUND)
--- a/examples/grid/combustion-vineyard.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/grid/combustion-vineyard.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -10,72 +10,79 @@
 #include <algorithm>
 
 #include "grid2D.h"
-#include "grid2Dvineyard.h"
+#include "lsvineyard.h"
 
 const int xsize = 600;
 const int ysize = 600;
-const int var = 0;			// which variable to use out of nc of them in each record in the file
+const int var = 0;          // which variable to use out of nc of them in each record in the file
 
 template<typename T>
 void read(std::ifstream& ifs, T& var)
 {
-	ifs.read(reinterpret_cast<char*>(&var), sizeof(T));
+    ifs.read(reinterpret_cast<char*>(&var), sizeof(T));
 }
 
 int main(int argc, char** argv)
 {
-	if (argc < 3)
-	{
-		std::cout << "Usage: combustion-vineyard FRAME1 FRAME2" << std::endl;
-		exit(0);
-	}
-	
-	int size0, nc0;
-	int size1, nc1;
+    if (argc < 3)
+    {
+        std::cout << "Usage: combustion-vineyard FRAME1 FRAME2" << std::endl;
+        exit(0);
+    }
+    
+    int size0, nc0;
+    int size1, nc1;
 
-	std::cout << "Reading: " << argv[1] << std::endl;
-	std::ifstream ifs0(argv[1], std::ios::binary);
-	std::cout << "Reading: " << argv[2] << std::endl;
-	std::ifstream ifs1(argv[2], std::ios::binary);
+    std::cout << "Reading: " << argv[1] << std::endl;
+    std::ifstream ifs0(argv[1], std::ios::binary);
+    std::cout << "Reading: " << argv[2] << std::endl;
+    std::ifstream ifs1(argv[2], std::ios::binary);
 
-	if (!ifs0 || !ifs1)
-	{
-		std::cout << "Could not open the frames" << std::endl;
-		exit(0);
-	}
+    if (!ifs0 || !ifs1)
+    {
+        std::cout << "Could not open the frames" << std::endl;
+        exit(0);
+    }
 
-	read(ifs0, size0); read(ifs0, nc0);
-	read(ifs1, size1); read(ifs1, nc1);
+    read(ifs0, size0); read(ifs0, nc0);
+    read(ifs1, size1); read(ifs1, nc1);
 
-	assert(size0 == size1); assert(nc0 == nc1);
-	assert(size0 == xsize*ysize);
-	
-	Grid2D g0(xsize, ysize), g1(xsize, ysize);
-	
-	for (int y = 0; y < ysize; ++y)
-		for (int x = 0; x < xsize; ++x)
-			for (int d = 0; d < nc0; ++d)
-			{
-				float val0, val1;
-				read(ifs0, val0);
-				read(ifs1, val1);
-				if (d == var)
-				{
-					g0(x,y) = val0;
-					g1(x,y) = val1;
-				}
-			}
-	std::cout << "Grids read" << std::endl;
-	
-	// Generate filtration and compute pairing
-	Grid2DVineyard v(&g0);
-	std::cout << "Filtration generated, size: " << v.filtration()->size() << std::endl;
-	v.compute_pairing();
-	std::cout << "Pairing computed" << std::endl;
-	
-	// Compute vineyard
-	v.compute_vineyard(&g1, true);
-	std::cout << "Vineyard computed" << std::endl;
+    assert(size0 == size1); assert(nc0 == nc1);
+    assert(size0 == xsize*ysize);
+    
+    Grid2D g0(xsize, ysize), g1(xsize, ysize);
+    
+    for (int y = 0; y < ysize; ++y)
+        for (int x = 0; x < xsize; ++x)
+            for (int d = 0; d < nc0; ++d)
+            {
+                float val0, val1;
+                read(ifs0, val0);
+                read(ifs1, val1);
+                if (d == var)
+                {
+                    g0(x,y) = val0;
+                    g1(x,y) = val1;
+                }
+            }
+    std::cout << "Grids read" << std::endl;
+    
+    // Generate the complex, initialize the vineyard (which also computes the pairing)
+    typedef                     LSVineyard<Grid2D::CoordinateIndex, Grid2D>             Grid2DVineyard;
 
-	v.vineyard()->save_edges("combustion");
+    Grid2DVineyard::LSFiltration        simplices;    
+    g0.complex_generator(make_push_back_functor(simplices));
+    Grid2DVineyard::VertexComparison    vcmp(g0);
+    Grid2DVineyard::SimplexComparison   scmp(vcmp);
+    simplices.sort(scmp);
+
+    Grid2DVineyard              v(g0.begin(), g0.end(), simplices, g0);
+    std::cout << "Filtration generated, size: " << v.filtration().size() << std::endl;
+    std::cout << "Pairing computed" << std::endl;
+    
+    // Compute vineyard
+    v.compute_vineyard(g1, true);
+    std::cout << "Vineyard computed" << std::endl;
+
+    v.vineyard().save_edges("combustion");
 }
--- a/examples/grid/grid2D.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/grid/grid2D.h	Wed Dec 16 15:39:06 2009 -0800
@@ -18,67 +18,79 @@
 #include <boost/serialization/base_object.hpp>
 #include <boost/serialization/split_member.hpp>
 #include <boost/serialization/nvp.hpp>
+#include <boost/serialization/export.hpp>
+
+#include <boost/iterator/counting_iterator.hpp>
 
 #include "utilities/types.h"
-
-#include <boost/serialization/export.hpp>
+#include "topology/simplex.h"
 
 /** 
  * Grid2D stores a grid
  */
 class Grid2D
 {
-	public:
-		typedef					RealType								ValueType;
-		typedef					unsigned int							CoordinateIndex;
-		
-		typedef					std::vector<ValueType>					ValueVector;
+    public:
+        typedef                 RealType                                        ValueType;
+        typedef                 ValueType                                       value_type;
+        
+        typedef                 unsigned int                                    CoordinateIndex;
+        typedef                 boost::counting_iterator<CoordinateIndex>       iterator;
+
+        typedef                 Simplex<CoordinateIndex>                        Smplx;
+        typedef                 std::vector<ValueType>                          ValueVector;
 
-	public:
-		Grid2D(CoordinateIndex xx = 1, CoordinateIndex yy = 1);
+    public:
+        Grid2D(CoordinateIndex xx = 1, CoordinateIndex yy = 1);
 
-		/// Sets the grid dimensions to (xx,yy)
-		void					change_dimensions(CoordinateIndex xx, CoordinateIndex yy);
+        /// Sets the grid dimensions to (xx,yy)
+        void                    change_dimensions(CoordinateIndex xx, CoordinateIndex yy);
 
-		ValueType&				operator()(CoordinateIndex i, CoordinateIndex j)			{ return data[i*x + j]; }
-		const ValueType&		operator()(CoordinateIndex i, CoordinateIndex j) const		{ return data[i*x + j]; }
-		ValueType&				operator()(CoordinateIndex i)								{ return data[i]; }
-		const ValueType&		operator()(CoordinateIndex i) const							{ return data[i]; }
+        ValueType&              operator()(CoordinateIndex i, CoordinateIndex j)            { return data[i*x + j]; }
+        const ValueType&        operator()(CoordinateIndex i, CoordinateIndex j) const      { return data[i*x + j]; }
+        ValueType&              operator()(CoordinateIndex i)                               { return data[i]; }
+        const ValueType&        operator()(CoordinateIndex i) const                         { return data[i]; }
 
-		CoordinateIndex			xsize() const												{ return x; }
-		CoordinateIndex			ysize() const												{ return y; }
-		CoordinateIndex			size() const												{ return x*y; }
-		
-		/* Given a sequential index of an element return its coordinates */
-		CoordinateIndex			xpos(CoordinateIndex i) const								{ return i / x; }
-		CoordinateIndex			ypos(CoordinateIndex i) const								{ return i % x; }
-		CoordinateIndex			seq(CoordinateIndex i, CoordinateIndex j) const;
+        CoordinateIndex         xsize() const                                               { return x; }
+        CoordinateIndex         ysize() const                                               { return y; }
+        CoordinateIndex         size() const                                                { return x*y; }
 
-		std::ostream&			operator<<(std::ostream& out) const;
-
-		static const CoordinateIndex INVALID_INDEX = -1;
+        iterator                begin() const                                               { return iterator(0); }
+        iterator                end() const                                                 { return iterator(size()); }
+        
+        /* Given a sequential index of an element return its coordinates */
+        CoordinateIndex         xpos(CoordinateIndex i) const                               { return i / x; }
+        CoordinateIndex         ypos(CoordinateIndex i) const                               { return i % x; }
+        CoordinateIndex         seq(CoordinateIndex i, CoordinateIndex j) const;
 
-	private:
-		CoordinateIndex 		x,y;
-		ValueVector				data;
+        template<class Functor>
+        void                    complex_generator(const Functor& f);
+
+        std::ostream&           operator<<(std::ostream& out) const;
+
+        static const CoordinateIndex INVALID_INDEX = -1;
+
+    private:
+        CoordinateIndex         x,y;
+        ValueVector             data;
 
 #if 0
-	private:
-		// Serialization
-		friend class boost::serialization::access;
+    private:
+        // Serialization
+        friend class boost::serialization::access;
 
-		template<class Archive>	void save(Archive& ar, version_type ) const;
-		template<class Archive>	void load(Archive& ar, version_type );
+        template<class Archive> void save(Archive& ar, version_type ) const;
+        template<class Archive> void load(Archive& ar, version_type );
 
-		BOOST_SERIALIZATION_SPLIT_MEMBER()
+        BOOST_SERIALIZATION_SPLIT_MEMBER()
 #endif
 };
 //BOOST_CLASS_EXPORT(Grid2D)
-		
+    
 
-std::ostream& operator<<(std::ostream& out, const Grid2D& grid)								{ return grid.operator<<(out); }
+std::ostream& operator<<(std::ostream& out, const Grid2D& grid)                             { return grid.operator<<(out); }
 
-		
+        
 #include "grid2D.hpp"
 
 #endif // __GRID2D_H__
--- a/examples/grid/grid2D.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/grid/grid2D.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -5,40 +5,40 @@
 
 Grid2D::
 Grid2D(CoordinateIndex xx, CoordinateIndex yy):
-	x(xx), y(yy), data(x*y)
+    x(xx), y(yy), data(x*y)
 {}
 
-void					
+void                    
 Grid2D::
 change_dimensions(CoordinateIndex xx, CoordinateIndex yy)
 {
-	x = xx; y = yy;
-	data.resize(x*y);
+    x = xx; y = yy;
+    data.resize(x*y);
 }
 
 Grid2D::CoordinateIndex
 Grid2D::
 seq(CoordinateIndex i, CoordinateIndex j) const
 { 
-	// Do not forget to check if less than 0, if Index is made signed --- dangerous
-	if (i >= x || j >= y)
-		return INVALID_INDEX;
+    // Do not forget to check if less than 0, if Index is made signed --- dangerous
+    if (i >= x || j >= y)
+        return INVALID_INDEX;
 
-	return i*x + j; 
+    return i*x + j; 
 }
 
-std::ostream&			
+std::ostream&           
 Grid2D::
 operator<<(std::ostream& out) const
 {
-	for (Grid2D::CoordinateIndex i = 0; i < xsize(); ++i)
-	{
-		for (Grid2D::CoordinateIndex j = 0; j < ysize(); ++j)
-			std::cout << operator()(i, j) << ' ';
-		std::cout << std::endl;
-	}
-	return out;	
-}	
+    for (Grid2D::CoordinateIndex i = 0; i < xsize(); ++i)
+    {
+        for (Grid2D::CoordinateIndex j = 0; j < ysize(); ++j)
+            std::cout << operator()(i, j) << ' ';
+        std::cout << std::endl;
+    }
+    return out; 
+}   
 
 #if 0
 using boost::serialization::make_nvp;
@@ -48,18 +48,74 @@
 Grid2D::
 save(Archive& ar, version_type ) const
 {
-	ar << BOOST_SERIALIZATION_NVP(x);
-	ar << BOOST_SERIALIZATION_NVP(y);
-	ar << make_nvp("data", data);
+    ar << BOOST_SERIALIZATION_NVP(x);
+    ar << BOOST_SERIALIZATION_NVP(y);
+    ar << make_nvp("data", data);
 }
 
-template<class Archive>	
+template<class Archive> 
 void 
 Grid2D::
 load(Archive& ar, version_type )
 {
-	ar >> make_nvp("x", x);
-	ar >> make_nvp("y", y);
-	ar >> make_nvp("data", data);
+    ar >> make_nvp("x", x);
+    ar >> make_nvp("y", y);
+    ar >> make_nvp("data", data);
 }
 #endif
+
+template<class Functor>
+void    
+Grid2D::
+complex_generator(const Functor& f)
+{
+    for (CoordinateIndex x = 0; x < xsize() - 1; ++x)
+        for (CoordinateIndex y = 0; y < ysize() - 1; ++y)
+        {
+            CoordinateIndex v(seq(x,y));
+            CoordinateIndex vh(seq(x+1,y));
+            CoordinateIndex vv(seq(x,y+1));
+            CoordinateIndex vd(seq(x+1,y+1));
+
+            Smplx sh; sh.add(v);  
+            f(sh);
+            sh.add(vh); f(sh);              // Horizontal edge
+            sh.add(vd); f(sh);              // "Horizontal" triangle
+            
+            Smplx sv; sv.add(v);
+            sv.add(vv); f(sv);              // Vertical edge
+            sv.add(vd); f(sv);              // "Vertical" triangle
+            
+            Smplx sd; sd.add(v);
+            sd.add(vd); f(sd);              // Diagonal edge
+
+            if (y == ysize() - 2)
+            {
+                Smplx s; s.add(vv);
+                s.add(vd); f(s);            // Top edge
+            }
+            if (x == xsize() - 2)
+            {
+                Smplx s; s.add(vh);
+                s.add(vd); f(s);            // Right edge
+            }
+        }
+    
+    // Last row
+    for (CoordinateIndex x = 0; x < xsize(); ++x)
+    {
+        std::cout << x << " " << ysize() - 1 << " " << seq(x, ysize() - 1) << std::endl;
+        CoordinateIndex v(seq(x, ysize() - 1));
+        Smplx s; s.add(v);
+        f(s);
+    }
+
+    // Last column
+    for (CoordinateIndex y = 0; y < ysize() - 1; ++y)
+    {
+        std::cout << xsize() - 1 << " " << y << " " << seq(xsize() - 1, y) << std::endl;
+        CoordinateIndex v(seq(xsize() - 1, y));
+        Smplx s; s.add(v);
+        f(s);
+    }
+}
--- a/examples/grid/grid2Dvineyard.h	Tue Jul 28 13:27:13 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2008
- */
-
-#ifndef __GRID2DVINEYARD_H__
-#define __GRID2DVINEYARD_H__
-
-#include "grid2D.h"
-#include "topology/lowerstarfiltration.h"
-
-#include <CGAL/Kinetic/Inexact_simulation_traits.h>
-#include <CGAL/Kinetic/Sort.h>
-#include <CGAL/Kinetic/Sort_visitor_base.h>
-
-#include <vector>
-
-
-class Grid2DVineyard
-{
-	public:
-		typedef					Grid2DVineyard										Self;
-			
-		typedef					Grid2D::CoordinateIndex								CoordinateIndex;
-		typedef					Grid2D::ValueType									ValueType;
-
-		class					KineticVertexType;
-		typedef					std::vector<KineticVertexType>						VertexVector;
-		typedef					VertexVector::iterator								VertexIndex;
-		
-		typedef					LowerStarFiltration<VertexIndex>					LSFiltration; 
-		
-		class					StaticEvaluator;
-		class					KineticEvaluator;
-		class 					VertexComparison;
-		
-		typedef					LSFiltration::Index									Index;
-		typedef					LSFiltration::Simplex								Simplex;
-		typedef					LSFiltration::VertexOrderIndex						VertexOrderIndex;
-		typedef					LSFiltration::VertexType<CoordinateIndex>			LSVertexType;
-
-		typedef					LSFiltration::Vineyard								Vineyard;
-		typedef					Vineyard::Evaluator									Evaluator;
-
-		class					SortVisitor;
-		typedef 				CGAL::Kinetic::Inexact_simulation_traits 			Traits;
-		typedef					CGAL::Kinetic::Sort<Traits, SortVisitor>			Sort;
-		typedef 				Traits::Simulator 									Simulator;
-		typedef 				Traits::Active_points_1_table						ActivePointsTable;
-		typedef 				ActivePointsTable::Key								Key;
-		typedef					std::map<Key, VertexOrderIndex>						KeyOrderMap;
-
-		typedef					std::vector<Grid2D*>								GridStackContainer;
-
-	public:
-								Grid2DVineyard(Grid2D* g);
-								~Grid2DVineyard();
-
-		void					compute_pairing();
-		void					compute_vineyard(Grid2D* grid, bool explicit_events = false);
-		
-		Grid2D*					grid() const										{ return grid_stack_.back(); }
-		Grid2D*					grid(int i) const									{ return grid_stack_[i]; }
-		int						num_grids() const									{ return grid_stack_.size(); }
-		const LSFiltration*		filtration() const									{ return filtration_; }
-		const Vineyard*			vineyard() const									{ return vineyard_; }
-
-	public:
-		// For Kinetic Sort
-		void 					swap(Key a, Key b);
-	
-	protected:
-		// Do something cleverer
-		virtual bool			neighbors(VertexIndex v1, VertexIndex v2) const		{ return true; }
-		
-	private:
-		void 					add_simplices();
-		void					change_evaluator(Evaluator* eval);
-
-	private:
-		GridStackContainer		grid_stack_;
-		VertexVector			vertices_;
-		LSFiltration*			filtration_;
-		Vineyard*				vineyard_;
-		Evaluator*				evaluator_;
-
-		KeyOrderMap				kinetic_map_;
-				
-#if 0
-	private:
-		// Serialization
-		friend class boost::serialization::access;
-		
-		Grid2DVineyard() 																	{}
-
-		template<class Archive> 
-		void serialize(Archive& ar, version_type )
-		{ 
-			ar & BOOST_SERIALIZATION_NVP(grid_stack_); 
-			ar & BOOST_SERIALIZATION_NVP(vertices_); 
-			ar & BOOST_SERIALIZATION_NVP(filtration_); 
-		};
-#endif
-};
-
-//BOOST_CLASS_EXPORT(Grid2DVineyard)
-	
-class Grid2DVineyard::KineticVertexType: public LSVertexType
-{
-	public:
-		typedef					LSVertexType												Parent;
-		
-		Key						kinetic_key() const											{ return key_; }
-		void					set_kinetic_key(Key k)										{ key_ = k; }
-		
-	private:
-		Key						key_;
-};
-
-std::ostream& operator<<(std::ostream& out, const Grid2DVineyard::VertexIndex& vi)			{ return out << vi->index(); }
-
-class Grid2DVineyard::VertexComparison
-{
-	public:
-		VertexComparison(const Grid2D* g): grid(g)											{}
-		bool operator()(VertexIndex i, VertexIndex j) const									{ return (*grid)(i->index()) < 
-																									 (*grid)(j->index()); }
-
-	private:
-		const Grid2D*			grid;
-
-#if 0
-	private:
-		// Serialization
-		friend class boost::serialization::access;
-
-								VertexComparison()											{}
-
-		template<class Archive>
-		void 					serialize(Archive& ar, version_type )						{ ar & BOOST_SERIALIZATION_NVP(grid); }
-#endif
-};
-
-class Grid2DVineyard::StaticEvaluator: public Evaluator
-{
-	public:
-								StaticEvaluator(Grid2D* grid, RealType time): 
-									time_(time), grid_(grid)								{}
-
-		virtual RealType		time()														{ return time_; }
-		virtual RealType		value(const Simplex& s)										{ return (*grid_)(s.get_attachment()->index()); }
-								
-	private:
-		RealType				time_;
-		Grid2D*					grid_;
-};
-
-class Grid2DVineyard::KineticEvaluator: public Evaluator
-{
-	public:
-								KineticEvaluator(Simulator::Handle sp, ActivePointsTable::Handle apt, RealType time_offset): 
-									sp_(sp), apt_(apt), time_offset_(time_offset)			{}
-
-		virtual RealType		time()														{ return time_offset_ + CGAL::to_double(get_time()); }
-		virtual RealType		value(const Simplex& s)										{ return CGAL::to_double(apt_->at(s.get_attachment()->kinetic_key()).x()(get_time())); }
-
-	private:
-		Simulator::Time			get_time()													{ return sp_->current_time(); }
-		
-		Simulator::Handle			sp_;
-		ActivePointsTable::Handle 	apt_;
-		RealType					time_offset_;
-};
-
-
-class Grid2DVineyard::SortVisitor: public CGAL::Kinetic::Sort_visitor_base
-{
-	public:
-								SortVisitor(Grid2DVineyard* gv): gv_(gv)					{}
-
-		template<class Vertex_handle>
-		void					before_swap(Vertex_handle a, Vertex_handle b) const			{ gv_->swap(*a,*b); }
-
-	private:
-		Grid2DVineyard*			gv_;
-};
-
-#include "grid2Dvineyard.hpp"
-
-#endif // __GRID2DVINEYARD_H__
--- a/examples/grid/grid2Dvineyard.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-#include <utilities/log.h>
-
-/* Implementation */
-	
-Grid2DVineyard::
-Grid2DVineyard(Grid2D* g): vertices_(g->size())
-{
-	grid_stack_.push_back(g); 
-	for (CoordinateIndex i = 0; i < g->size(); ++i)
-		vertices_[i].set_index(i);
-
-	evaluator_ = new StaticEvaluator(grid(), 0);
-	vineyard_ = new Vineyard(evaluator_);
-
-	filtration_ = new LSFiltration(vertices_.begin(), vertices_.end(), VertexComparison(grid()), vineyard_);
-	add_simplices();
-}
-
-Grid2DVineyard::
-~Grid2DVineyard()
-{
-	delete filtration_;
-	delete vineyard_;
-	delete evaluator_;
-}
-
-void
-Grid2DVineyard::
-compute_pairing()
-{
-	filtration_->fill_simplex_index_map();
-	filtration_->pair_simplices(filtration_->begin(), filtration_->end());
-	vineyard_->start_vines(filtration_->begin(), filtration_->end());
-}
-
-void					
-Grid2DVineyard::
-compute_vineyard(Grid2D* g, bool explicit_events)
-{
-	AssertMsg(filtration_->is_paired(), "Simplices must be paired for a vineyard to be computed");
-	
-	typedef Traits::Kinetic_kernel::Point_1 								Point;
-	typedef Traits::Kinetic_kernel::Function_kernel::Construct_function 	CF; 
-	typedef Traits::Kinetic_kernel::Motion_function 						F; 
-	
-	Traits tr(0,1);
-	Simulator::Handle sp = tr.simulator_handle();
-	ActivePointsTable::Handle apt = tr.active_points_1_table_handle();
-	Sort sort(tr, SortVisitor(this));
-	
-	// Setup the (linear) trajectories
-	std::cout << "Setting up trajectories" << std::endl;
-	CF cf; 
-	kinetic_map_.clear();
-	for (VertexIndex cur = vertices_.begin(); cur != vertices_.end(); ++cur)
-	{
-		ValueType val0 = (*grid())(cur->index());
-		ValueType val1 = (*g)(cur->index());
-		F x = cf(F::NT(val0), F::NT(val1 - val0));			// x = val0 + (val1 - val0)*t
-		Point p(x);
-		cur->set_kinetic_key(apt->insert(p));
-		kinetic_map_[cur->kinetic_key()] = cur->get_order();
-		if (cur->index() % 10000 == 0)
-			std::cout << "Added trajectory: " << cur->index() << " " << val0 << " " << val1 << std::endl;
-	}
-	
-	// Process all the events (compute the vineyard in the process)
-	change_evaluator(new KineticEvaluator(sp, apt, num_grids() - 1));
-	if (explicit_events)
-	{
-		while (sp->next_event_time() < 1)
-		{
-			std::cout << "Next event time: " << sp->next_event_time() << std::endl;
-			sp->set_current_event_number(sp->current_event_number() + 1);
-			std::cout << "Processed event" << std::endl;
-		}
-	} else
-		sp->set_current_time(1.0);
-	std::cout << "Processed " << sp->current_event_number() << " events" << std::endl;
-	
-	// Add the grid to the stack
-	grid_stack_.push_back(g); 
-	change_evaluator(new StaticEvaluator(grid(), num_grids() - 1));
-	vineyard_->record_diagram(filtration_->begin(), filtration_->end());
-}
-		
-void 					
-Grid2DVineyard::
-swap(Key a, Key b)
-{
-	VertexOrderIndex ao = kinetic_map_[a], bo = kinetic_map_[b];
-	AssertMsg(filtration_->get_vertex_cmp()(ao, bo), "In swap(a,b), a must precede b");
-	filtration_->transpose_vertices(ao);
-	AssertMsg(filtration_->get_vertex_cmp()(bo, ao), "In swap(a,b), b must precede a after the transposition");
-}
-
-void 
-Grid2DVineyard::
-add_simplices()
-{
-	// Takes advantage of LowerStarFiltration's smart append (which allows faces
-	// to be inserted after cofaces, since everything is rearranged in the
-	// proper lower star order anyway). Also note that vertices were added by
-	// LowerStarFiltration's constructor
-	for (CoordinateIndex x = 0; x < grid()->xsize() - 1; ++x)
-		for (CoordinateIndex y = 0; y < grid()->ysize() - 1; ++y)
-		{
-			VertexIndex v(&vertices_[grid()->seq(x,y)]);
-			VertexIndex vh(&vertices_[grid()->seq(x+1,y)]);
-			VertexIndex vv(&vertices_[grid()->seq(x,y+1)]);
-			VertexIndex vd(&vertices_[grid()->seq(x+1,y+1)]);
-
-			Simplex sh(2, v);
-			sh.add(vh);	filtration_->append(sh);		// Horizontal edge
-			sh.add(vd);	filtration_->append(sh);		// "Horizontal" triangle
-			
-			Simplex sv(2, v);
-			sv.add(vv);	filtration_->append(sv);		// Vertical edge
-			sv.add(vd);	filtration_->append(sv);		// "Vertical" triangle
-			
-			Simplex sd(2, v);
-			sd.add(vd); filtration_->append(sd);		// Diagonal edge
-
-			if (y == grid()->ysize() - 2)
-			{
-				Simplex s(1, vv); 
-				s.add(vd); filtration_->append(s);		// Top edge
-			}
-			if (x == grid()->xsize() - 2)
-			{
-				Simplex s(1, vh); 
-				s.add(vd); filtration_->append(s);		// Right edge
-			}
-		}
-}
-
-void
-Grid2DVineyard::
-change_evaluator(Evaluator* eval)
-{
-	AssertMsg(evaluator_ != 0, "change_evaluator() assumes that existing evaluator is not null");
-		
-	delete evaluator_;
-	evaluator_ = eval;
-	vineyard_->set_evaluator(evaluator_);
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/grid/lsvineyard.h	Wed Dec 16 15:39:06 2009 -0800
@@ -0,0 +1,245 @@
+/**
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2009
+ */
+
+#ifndef __LSVINEYARD_H__
+#define __LSVINEYARD_H__
+
+#include <iostream>
+
+#include "topology/simplex.h"
+#include "topology/dynamic-persistence.h"
+#include "topology/lowerstarfiltration.h"
+#include "topology/vineyard.h"
+
+#include <utilities/indirect.h>
+
+#include <CGAL/Kinetic/Inexact_simulation_traits.h>
+#include <CGAL/Kinetic/Sort.h>
+#include <CGAL/Kinetic/Sort_visitor_base.h>
+
+#include <list>
+
+
+template<class Vertex_, class VertexEvaluator_, class Simplex_ = Simplex<Vertex_>, class Filtration_ = Filtration<Simplex_> >
+class LSVineyard
+{
+    public:
+        typedef                     LSVineyard                                          Self;
+
+        typedef                     Vertex_                                             Vertex;
+        typedef                     VertexEvaluator_                                    VertexEvaluator;
+        typedef                     typename VertexEvaluator::value_type                VertexValue;
+        
+        typedef                     Simplex_                                            Simplex;
+        typedef                     Filtration_                                         LSFiltration;
+        typedef                     typename LSFiltration::Index                        LSFIndex;
+
+        class                       KineticVertexType;
+        class                       KineticVertexComparison;
+        typedef                     std::list<KineticVertexType>                        VertexContainer;
+        typedef                     typename VertexContainer::iterator                  VertexIndex;
+
+        struct                      AttachmentData: public VineData                     
+        {   
+            void                    set_attachment(VertexIndex v)                       { attachment = v; }
+            VertexIndex             attachment; 
+        };
+        typedef                     DynamicPersistenceTrails<AttachmentData>            Persistence;
+        typedef                     typename Persistence::OrderIndex                    Index;
+        typedef                     typename Persistence::iterator                      iterator;
+
+        typedef                     typename Persistence::template SimplexMap<LSFiltration>      
+                                                                                        PFMap;
+
+        class                       Evaluator;
+        class                       StaticEvaluator;
+        class                       KineticEvaluator;
+        class                       DimensionFromIterator;
+
+        typedef                     ThroughEvaluatorComparison<VertexEvaluator>         VertexComparison;
+        typedef                     MaxVertexComparison<Simplex, VertexComparison>      SimplexComparison;
+
+        class                       TranspositionVisitor;
+        friend class                TranspositionVisitor;
+        
+        typedef                     Vineyard<Index, iterator, Evaluator>                Vnrd;
+
+        class                       SortVisitor;
+        typedef                     CGAL::Kinetic::Inexact_simulation_traits            Traits;
+        typedef                     CGAL::Kinetic::Sort<Traits, SortVisitor>            Sort;
+        typedef                     Traits::Simulator                                   Simulator;
+        typedef                     Traits::Active_points_1_table                       ActivePointsTable;
+        typedef                     ActivePointsTable::Key                              Key;
+        typedef                     std::map<Key, VertexIndex>                          KeyVertexMap;
+
+    public:
+        template<class VertexIterator>
+                                    LSVineyard(VertexIterator begin, VertexIterator end, 
+                                               LSFiltration& filtration,
+                                               const VertexEvaluator& veval = VertexEvaluator());
+                                    ~LSVineyard();
+
+        void                        compute_vineyard(const VertexEvaluator& veval, bool explicit_events = false);
+        bool                        transpose_vertices(VertexIndex vi);
+        
+        const LSFiltration&         filtration() const                                  { return filtration_; }
+        const Vnrd&                 vineyard() const                                    { return vineyard_; }
+        const Persistence&          persistence() const                                 { return persistence_; }
+        const VertexComparison&     vertex_comparison() const                           { return vcmp_; }
+        const VertexEvaluator&      vertex_evaluator() const                            { return veval_; }
+        const SimplexComparison&    simplex_comparison() const                          { return scmp_; }
+
+        VertexValue                 vertex_value(const Vertex& v) const                 { return veval_(v); }
+        VertexValue                 simplex_value(const Simplex& s) const               { return vertex_value(*std::max_element(s.vertices().begin(), s.vertices().end(), vcmp_)); } 
+        const Simplex&              pfmap(iterator i) const                             { return pfmap_[i]; }
+        const Simplex&              pfmap(Index i) const                                { return pfmap_[i]; }
+
+        Index                       index(iterator i) const                             { return persistence_.index(i); }
+
+    public:
+        // For Kinetic Sort
+        void                        swap(Key a, Key b);
+        
+    private:
+        void                        change_evaluator(Evaluator* eval);
+        void                        set_attachment(iterator i, VertexIndex vi)          { persistence_.modifier()(i, boost::bind(&AttachmentData::set_attachment, bl::_1, vi)); }
+        void                        transpose_filtration(iterator i)                    { filtration_.transpose(filtration_.begin() + (i - persistence_.begin())); }
+
+    private:
+        VertexContainer             vertices_;
+        
+        VertexEvaluator             veval_;
+        VertexComparison            vcmp_;
+        SimplexComparison           scmp_;
+
+        LSFiltration&               filtration_;
+        Persistence                 persistence_;
+        PFMap                       pfmap_;
+        
+        Vnrd                        vineyard_;
+        Evaluator*                  evaluator_;
+        unsigned                    time_count_;
+
+        KeyVertexMap                kinetic_map_;
+                
+#if 0
+    private:
+        // Serialization
+        friend class boost::serialization::access;
+        
+        LSVineyard()                                                                    {}
+
+        template<class Archive> 
+        void serialize(Archive& ar, version_type )
+        { 
+            ar & BOOST_SERIALIZATION_NVP(grid_stack_); 
+            ar & BOOST_SERIALIZATION_NVP(vertices_); 
+            ar & BOOST_SERIALIZATION_NVP(filtration_); 
+        };
+#endif
+};
+
+//BOOST_CLASS_EXPORT(LSVineyard)
+        
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::KineticVertexType
+{
+    public:
+                                KineticVertexType(const Vertex& v):
+                                    vertex_(v)                                              {}
+
+        Key                     kinetic_key() const                                         { return key_; }
+        void                    set_kinetic_key(Key k)                                      { key_ = k; }
+
+        Vertex                  vertex() const                                              { return vertex_; }
+        void                    set_vertex(Vertex v)                                        { vertex_ = v; }
+
+        iterator                simplex_index() const                                       { return simplex_index_; }
+        void                    set_simplex_index(iterator i)                               { simplex_index_ = i; }
+        
+    private:
+        Key                     key_;
+        Vertex                  vertex_;
+        iterator                simplex_index_;
+};
+
+template<class V, class VE, class S, class C>
+std::ostream& 
+operator<<(std::ostream& out, const typename LSVineyard<V,VE,S,C>::VertexIndex& vi)    
+{ return out << vi->vertex(); }
+        
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::KineticVertexComparison
+{
+    public:
+                                KineticVertexComparison(const VertexComparison& vcmp):
+                                    vcmp_(vcmp)                                             {}
+
+        bool                    operator()(const KineticVertexType& v1, const KineticVertexType& v2) const
+        { return vcmp_(v1.vertex(), v2.vertex()); }
+
+    private:
+        VertexComparison            vcmp_;
+};
+
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::TranspositionVisitor: public Persistence::TranspositionVisitor
+{
+    public:
+        typedef                 typename Persistence::TranspositionVisitor                  Parent;
+        typedef                 typename LSVineyard<V,VE,S,C>::iterator                     iterator;
+        typedef                 typename LSVineyard<V,VE,S,C>::Index                        Index;
+
+                                TranspositionVisitor(LSVineyard& v): lsvineyard_(v)         {}
+
+        void                    transpose(iterator i)                                       { lsvineyard_.transpose_filtration(i); }
+        void                    switched(iterator i, SwitchType type)                       { lsvineyard_.vineyard_.switched(index(i), index(boost::next(i))); }
+
+    private:
+        Index                   index(iterator i)                                           { return lsvineyard_.index(i); }
+
+        LSVineyard&             lsvineyard_;
+};
+
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::Evaluator
+{
+    public:
+        virtual RealType        time() const                                                =0;
+        virtual RealType        operator()(Index i) const                                   =0;
+        virtual Dimension       dimension(Index i) const                                    =0;
+        virtual RealType        operator()(iterator i) const                                { return operator()(&*i); }
+        virtual Dimension       dimension(iterator i) const                                 { return dimension(&*i); }
+};
+
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::SortVisitor: public CGAL::Kinetic::Sort_visitor_base
+{
+    public:
+                                SortVisitor(LSVineyard& v): 
+                                    vineyard_(v)                                            {}
+
+        template<class Vertex_handle>
+        void                    pre_swap(Vertex_handle a, Vertex_handle b) const            { vineyard_.swap(*a,*b); }
+
+    private:
+        LSVineyard&             vineyard_;
+};
+
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::DimensionFromIterator: std::unary_function<Dimension, iterator>
+{
+    public:
+                                DimensionFromIterator(const PFMap& pfmap): pfmap_(pfmap)    {}
+
+        Dimension               operator()(iterator i) const                                { return pfmap_[i].dimension(); }                                
+
+    private:
+        const PFMap&            pfmap_;
+};
+
+#include "lsvineyard.hpp"
+
+#endif // __LSVINEYARD_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/grid/lsvineyard.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -0,0 +1,251 @@
+#include <utilities/log.h>
+
+#ifdef LOGGING
+static rlog::RLogChannel* rlLSVineyard =            DEF_CHANNEL("lsvineyard/info", rlog::Log_Debug);
+static rlog::RLogChannel* rlLSVineyardDebug =       DEF_CHANNEL("lsvineyard/debug", rlog::Log_Debug);
+#endif // LOGGING
+
+#ifdef COUNTERS
+static Counter*  cVertexTransposition =                     GetCounter("lsfiltration/transposition");       // counts number of vertex transpositions
+static Counter*  cAttachment =                              GetCounter("lsfiltration/attachment");          // counts the number of attachment changes
+#endif
+
+
+template<class V, class VE, class S, class F>
+template<class VertexIterator>
+LSVineyard<V,VE,S,F>::
+LSVineyard(VertexIterator begin, VertexIterator end, 
+           LSFiltration& filtration,
+           const VertexEvaluator& veval):
+    vertices_(begin, end), filtration_(filtration), 
+    persistence_(filtration_),
+    veval_(veval), vcmp_(veval_), scmp_(vcmp_),
+    pfmap_(persistence_.make_simplex_map(filtration_)),
+    time_count_(0)
+{
+    // TODO: LSVineyard really should sort the filtration_ itself
+    // filtration_.sort(scmp_);
+    // persistence_.init(filtration_);
+
+    rLog(rlLSVineyardDebug, "Initializing LSVineyard");
+    persistence_.pair_simplices();
+    rLog(rlLSVineyardDebug, "Simplices paired");
+
+    vertices_.sort(KineticVertexComparison(vcmp_));     // sort vertices w.r.t. vcmp_
+    std::cout << "Vertex order:" << std::endl;
+    for (VertexIndex cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+        std::cout << "  " << cur->vertex() << std::endl;
+
+    // Initialize simplex_index() and attachment
+    VertexIndex vi = boost::prior(vertices_.begin());
+    for (iterator i = persistence_.begin(); i != persistence_.end(); ++i)
+    {
+        const Simplex& s = pfmap_[i];
+        if (s.dimension() == 0)
+        {
+            ++vi;
+            AssertMsg(s.vertices().front() == vi->vertex(), "In constructor, simplices and vertices must match.");
+            vi->set_simplex_index(i);
+        }
+        set_attachment(i, vi);
+        rLog(rlLSVineyardDebug, "%s attached to %d", tostring(pfmap(i)).c_str(), vi->vertex());
+    }
+
+    evaluator_ = new StaticEvaluator(*this, time_count_);
+    vineyard_.set_evaluator(evaluator_);
+    vineyard_.start_vines(persistence_.begin(), persistence_.end());
+}
+
+template<class V, class VE, class S, class F>
+LSVineyard<V,VE,S,F>::
+~LSVineyard()
+{
+    delete evaluator_;
+}
+
+template<class V, class VE, class S, class F_>
+void                    
+LSVineyard<V,VE,S,F_>::
+compute_vineyard(const VertexEvaluator& veval, bool explicit_events)
+{
+    typedef Traits::Kinetic_kernel::Point_1                                 Point;
+    typedef Traits::Kinetic_kernel::Function_kernel::Construct_function     CF; 
+    typedef Traits::Kinetic_kernel::Motion_function                         F; 
+    
+    Traits tr(0,1);
+    Simulator::Handle sp = tr.simulator_handle();
+    ActivePointsTable::Handle apt = tr.active_points_1_table_handle();
+    Sort sort(tr, SortVisitor(*this));
+    
+    // Setup the (linear) trajectories
+    rLog(rlLSVineyard, "Setting up trajectories");
+    CF cf; 
+    kinetic_map_.clear();
+    for (VertexIndex cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+    {
+        VertexValue val0 = veval_(cur->vertex());
+        VertexValue val1 = veval(cur->vertex());
+        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));
+        kinetic_map_[cur->kinetic_key()] = cur;
+        rLog(rlLSVineyardDebug, "Scheduling: %d %s", cur->vertex(), tostring(x).c_str());
+    }
+    
+    // Process all the events (compute the vineyard in the process)
+    change_evaluator(new KineticEvaluator(*this, sp, apt, time_count_));
+    if (explicit_events)
+    {
+        while (sp->next_event_time() < 1)
+        {
+            rLog(rlLSVineyardDebug, "Next event time: %f", sp->next_event_time());
+            sp->set_current_event_number(sp->current_event_number() + 1);
+            rLog(rlLSVineyardDebug, "Processed event");
+        }
+    } else
+        sp->set_current_time(1.0);
+    rLog(rlLSVineyard, "Processed %d events", sp->current_event_number());
+    
+    veval_ = veval;
+    change_evaluator(new StaticEvaluator(*this, ++time_count_));
+    vineyard_.record_diagram(persistence_.begin(), persistence_.end());
+}
+        
+template<class V, class VE, class S, class F>
+void                    
+LSVineyard<V,VE,S,F>::
+swap(Key a, Key b)
+{
+    rLog(rlLSVineyardDebug, "Entered swap");
+    VertexIndex ao = kinetic_map_[a], bo = kinetic_map_[b];
+    AssertMsg(vcmp_(ao->vertex(), bo->vertex()), "In swap(a,b), a must precede b");
+    transpose_vertices(ao);
+    // AssertMsg(vcmp_(bo->vertex(), ao->vertex()), "In swap(a,b), b must precede a after the transposition");
+}
+
+template<class V, class VE, class S, class F>
+void
+LSVineyard<V,VE,S,F>::
+change_evaluator(Evaluator* eval)
+{
+    AssertMsg(evaluator_ != 0, "change_evaluator() assumes that existing evaluator is not null");
+        
+    delete evaluator_;
+    evaluator_ = eval;
+    vineyard_.set_evaluator(evaluator_);
+}
+
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+namespace bl = boost::lambda;
+
+template<class V, class VE, class S, class F>
+bool
+LSVineyard<V,VE,S,F>::
+transpose_vertices(VertexIndex vi)
+{
+    Count(cVertexTransposition);
+    rLog(rlLSVineyard, "Transposing vertices (%d, %d)", vi->vertex(), boost::next(vi)->vertex());
+
+    DimensionFromIterator                       dim(pfmap_);
+    TranspositionVisitor                        visitor(*this);
+
+    iterator i = vi->simplex_index();
+    iterator i_prev = boost::prior(i);
+    iterator i_next = boost::next(vi)->simplex_index();
+    iterator i_next_prev = boost::prior(i_next);           // transpositions are done in terms of the first index in the pair
+    iterator j = boost::next(i_next);
+    
+    VertexIndex     vi_next = boost::next(vi);
+    const Vertex&   v = vi->vertex();
+    
+    bool result = false;        // has a switch in pairing occurred
+    
+    // First, move the vertex --- this can be sped up if we devise special "vertex transpose" operation
+    rLog(rlLSVineyardDebug, "Starting to move the vertex");
+    while (i_next_prev != i_prev)                       
+    { 
+        rLog(rlLSVineyardDebug, "  Transposing %s %s", tostring(pfmap(i_next_prev)).c_str(),
+                                                       tostring(pfmap(boost::next(i_next_prev))).c_str());
+        result |= persistence_.transpose(i_next_prev, dim, visitor);
+        i_next_prev = boost::prior(i_next);
+    }
+    rLog(rlLSVineyardDebug, "Done moving the vertex");
+
+    // Second, move the simplices attached to it
+    rLog(rlLSVineyardDebug, "Moving attached simplices");
+    while (j != persistence_.end() && j->attachment == vi_next)
+    {
+        rLog(rlLSVineyardDebug, "  Considering %s", tostring(pfmap(j)).c_str());
+        if (pfmap(j).contains(v))       // j becomes attached to v and does not move
+        {
+            Count(cAttachment);
+            rLog(rlLSVineyardDebug, "  Attachment changed for ", tostring(pfmap(j)).c_str());
+            set_attachment(j, vi);
+            ++j;
+            continue;
+        }   
+
+        iterator j_prev = j; ++j;
+        while ((--j_prev)->attachment != vi_next)                // i.e., until we have reached vi_next (and the simplices that follow it) again
+        {
+            rLog(rlLSVineyardDebug, "    Moving: %s, %s", 
+                                      tostring(pfmap(j_prev)).c_str(),
+                                      tostring(pfmap(boost::next(j_prev))).c_str());
+            AssertMsg(j_prev->attachment == vi, "Simplex preceding the one being moved must be attached to v");
+            result |= persistence_.transpose(j_prev, dim, visitor);
+            --j_prev;
+        }
+    }
+    rLog(rlLSVineyard, "Done moving attached simplices");
+    vertices_.splice(vi, vertices_, vi_next);       // swap vi and vi_next
+    
+    return result;
+}
+
+
+/* Evaluators */
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::StaticEvaluator: public Evaluator
+{
+    public:
+                                StaticEvaluator(const LSVineyard& v, RealType time): 
+                                    time_(time), vineyard_(v)                               {}
+
+        virtual RealType        time() const                                                { return time_; }
+        virtual RealType        operator()(Index i) const                                   { return vineyard_.simplex_value(vineyard_.pfmap(i)); }
+        virtual Dimension       dimension(Index i) const                                    { return vineyard_.pfmap(i).dimension(); }
+                                
+    private:
+        RealType                time_;
+        const LSVineyard&       vineyard_;
+};
+
+template<class V, class VE, class S, class C>
+class LSVineyard<V,VE,S,C>::KineticEvaluator: public Evaluator
+{
+    public:
+                                KineticEvaluator(const LSVineyard& v, Simulator::Handle sp, ActivePointsTable::Handle apt, RealType time_offset): 
+                                    vineyard_(v), sp_(sp), apt_(apt), time_offset_(time_offset)           {}
+
+        virtual RealType        time() const                                                { return time_offset_ + CGAL::to_double(get_time()); }
+        virtual RealType        operator()(Index i) const                                   
+        {
+            rLog(rlLSVineyard, "%s (attached to %d): %s(%f) = %f", tostring(vineyard_.pfmap(i)).c_str(),
+                                                                   i->attachment->vertex(),
+                                                                   tostring(apt_->at(i->attachment->kinetic_key()).x()).c_str(),
+                                                                   get_time(),
+                                                                   CGAL::to_double(apt_->at(i->attachment->kinetic_key()).x()(get_time())));
+            return CGAL::to_double(apt_->at(i->attachment->kinetic_key()).x()(get_time())); 
+        }
+        virtual Dimension       dimension(Index i) const                                    { return vineyard_.pfmap(i).dimension(); }
+
+    private:
+        Simulator::Time         get_time() const                                            { return sp_->current_time(); }
+        
+        const LSVineyard&           vineyard_;
+        Simulator::Handle           sp_;
+        ActivePointsTable::Handle   apt_;
+        RealType                    time_offset_;
+};
--- a/examples/grid/pdbdistance-vineyard.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/grid/pdbdistance-vineyard.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -2,7 +2,7 @@
 #include "utilities/log.h"
 
 #include "pdbdistance.h"
-#include "grid2Dvineyard.h"
+#include "lsvineyard.h"
 
 #include <fstream>
 #include <string>
@@ -51,10 +51,20 @@
 	// Compute initial filtration
 	int f = 0; int sf = 0;
 	std::ifstream in(frame_filename(infilename, f, sf++).c_str());
-	Grid2DVineyard v(new PDBDistanceGrid(in, cas_only));
+    PDBDistanceGrid ginit(in, cas_only);
 	in.close();
-	std::cout << "Filtration generated, size: " << v.filtration()->size() << std::endl;
-	v.compute_pairing();
+
+    typedef                     LSVineyard<Grid2D::CoordinateIndex, Grid2D>             Grid2DVineyard;
+    
+    Grid2DVineyard::LSFiltration        simplices;    
+    ginit.complex_generator(make_push_back_functor(simplices));
+    Grid2DVineyard::VertexComparison    vcmp(ginit);
+    Grid2DVineyard::SimplexComparison   scmp(vcmp);
+    simplices.sort(scmp);
+    std::cout << "Complex generated, size: " << simplices.size() << std::endl;
+
+    Grid2DVineyard              v(ginit.begin(), ginit.end(), simplices, ginit);
+	std::cout << "Filtration generated, size: " << v.filtration().size() << std::endl;
 	std::cout << "Pairing computed" << std::endl;
 
 	// Process frames computing the vineyard
@@ -63,13 +73,13 @@
 		std::string fn = frame_filename(infilename, f, sf++);
 		std::cout << "Processing " << fn << std::endl;
 		in.open(fn.c_str());
-		v.compute_vineyard(new PDBDistanceGrid(in, cas_only));
+		v.compute_vineyard(PDBDistanceGrid(in, cas_only));
 		in.close();
 		if (sf == lastsubframe) { sf = 0; ++f; }
 	}
 	std::cout << "Vineyard computed" << std::endl;
 
-	v.vineyard()->save_edges(outfilename);
+	v.vineyard().save_edges(outfilename);
 
 #if 0
 	std::ofstream ofs(outfilename.c_str(), std::ios::binary);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/grid/test-grid2D-vineyard.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -0,0 +1,54 @@
+#include <utilities/log.h>
+
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+
+#include "grid2D.h"
+#include "lsvineyard.h"
+
+int main(int argc, char** argv)
+{
+#ifdef LOGGING
+    rlog::RLogInit(argc, argv);
+    // stdoutLog.subscribeTo(RLOG_CHANNEL("topology"));
+    // stdoutLog.subscribeTo(RLOG_CHANNEL("topology/persistence/transpositions"));
+    // stdoutLog.subscribeTo(RLOG_CHANNEL("topology/vineyard"));
+    stdoutLog.subscribeTo(RLOG_CHANNEL("lsvineyard"));
+#endif     
+
+    Grid2D g0(2, 2), g1(2, 2);
+    g0(0,0) = 1; g0(0,1) = 2; g0(1,0) = 3; g0(1,1) = 0;
+    g1(0,0) = 4; g1(0,1) = 2; g1(1,0) = 3; g1(1,1) = 5;
+    
+    // Generate the complex, initialize the vineyard (which also computes the pairing)
+    typedef                     LSVineyard<Grid2D::CoordinateIndex, Grid2D>             Grid2DVineyard;
+    
+    Grid2DVineyard::LSFiltration        simplices;    
+    g0.complex_generator(make_push_back_functor(simplices));
+    Grid2DVineyard::VertexComparison    vcmp(g0);
+    Grid2DVineyard::SimplexComparison   scmp(vcmp);
+    simplices.sort(scmp);
+    std::cout << "Complex generated, size: " << simplices.size() << std::endl;
+    std::copy(simplices.begin(), simplices.end(), std::ostream_iterator<Grid2D::Smplx>(std::cout, "\n"));
+
+    Grid2DVineyard              v(g0.begin(), g0.end(), simplices, g0);
+    std::cout << "Filtration generated, size: " << v.filtration().size() << std::endl;
+    std::cout << "Pairing computed" << std::endl;
+ 
+    // Simplex order before
+    std::cout << "Simplex order:" << std::endl;
+    for (Grid2DVineyard::LSFiltration::Index cur = v.filtration().begin(); cur != v.filtration().end(); ++cur)
+        std::cout << "  " << v.filtration().simplex(cur) << std::endl;
+
+    // Compute vineyard
+    v.compute_vineyard(g1, true);
+    std::cout << "Vineyard computed" << std::endl;
+    
+    // Simplex order after
+    std::cout << "Simplex order:" << std::endl;
+    for (Grid2DVineyard::LSFiltration::Index cur = v.filtration().begin(); cur != v.filtration().end(); ++cur)
+        std::cout << "  " << v.filtration().simplex(cur) << std::endl;
+
+    v.vineyard().save_edges("test-vineyard");
+}
--- a/examples/poincare/poincare.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/poincare/poincare.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -10,8 +10,7 @@
 #include <boost/program_options.hpp>
 
 typedef         Simplex<unsigned, unsigned>     Smplx;
-typedef         std::vector<Smplx>              Complex;
-typedef         Filtration<Complex>             Fltr;
+typedef         Filtration<Smplx>               Fltr;
 typedef         StaticPersistence<>             Persistence;
 typedef         PersistenceDiagram<>            PDgm;
 
@@ -48,8 +47,7 @@
     }
 
 
-    Complex c;
-
+    Fltr f;
     std::ifstream in(infilename.c_str());
     unsigned int i = 0;
     std::string s;
@@ -66,21 +64,19 @@
             linestream >> vertex;
         }
         std::cout << simplex << std::endl;
-        c.push_back(simplex);
+        f.push_back(simplex);
         std::getline(in, s);
     }
     
-    std::sort(c.begin(), c.end(), Smplx::VertexComparison());
-    Fltr f(c.begin(), c.end(), Smplx::DataComparison());
+    f.sort(Smplx::DataComparison());
     Persistence pers(f);
     pers.pair_simplices();
 
+    Persistence::SimplexMap<Fltr>   m = pers.make_simplex_map(f);
     std::map<Dimension, PDgm> dgms;
     init_diagrams(dgms, pers.begin(), pers.end(), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, Fltr::Index>(pers.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, Smplx::DataEvaluator())), 
-                  evaluate_through_map(OffsetMap<Persistence::OrderIndex, Fltr::Index>(pers.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, Smplx::DimensionExtractor())));
+                  evaluate_through_map(m, Smplx::DataEvaluator()), 
+                  evaluate_through_map(m, Smplx::DimensionExtractor()));
 
     std::cout << 0 << std::endl << dgms[0] << std::endl;
     std::cout << 1 << std::endl << dgms[1] << std::endl;
--- a/examples/rips/rips-pairwise.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/rips/rips-pairwise.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -21,9 +21,8 @@
 
 typedef         Rips<PairDistances>                                     Generator;
 typedef         Generator::Simplex                                      Smplx;
-typedef         std::vector<Smplx>                                      SimplexVector;
-typedef         Filtration<SimplexVector, unsigned>                     Fltr;
-//typedef         StaticPersistence<>                                     Persistence;
+typedef         Filtration<Smplx>                                       Fltr;
+// typedef         StaticPersistence<>                                     Persistence;
 typedef         DynamicPersistenceChains<>                              Persistence;
 typedef         PersistenceDiagram<>                                    PDgm;
 
@@ -43,44 +42,45 @@
     PairDistances           distances(points);
     Generator               rips(distances);
     Generator::Evaluator    size(distances);
-    SimplexVector           complex;
+    Fltr                    f;
     
     // Generate 2-skeleton of the Rips complex for epsilon = 50
-    rips.generate(skeleton, max_distance, make_push_back_functor(complex));
-    std::sort(complex.begin(), complex.end(), Smplx::VertexComparison());       // unnecessary
-    std::cout << "# Generated complex of size: " << complex.size() << std::endl;
+    rips.generate(skeleton, max_distance, make_push_back_functor(f));
+    std::cout << "# Generated complex of size: " << f.size() << std::endl;
 
     // Generate filtration with respect to distance and compute its persistence
-    Fltr f(complex.begin(), complex.end(), Generator::Comparison(distances));
+    f.sort(Generator::Comparison(distances));
 
     Timer persistence_timer; persistence_timer.start();
     Persistence p(f);
     p.pair_simplices();
     persistence_timer.stop();
 
+#if 1
     // Output cycles
-    for (Persistence::OrderIndex cur = p.begin(); cur != p.end(); ++cur)
+    Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
+    for (Persistence::iterator cur = p.begin(); cur != p.end(); ++cur)
     {
-        Persistence::Cycle& cycle = cur->cycle;
+        const Persistence::Cycle& cycle = cur->cycle;
 
         if (!cur->sign())        // only negative simplices have non-empty cycles
         {
             Persistence::OrderIndex birth = cur->pair;      // the cycle that cur killed was born when we added birth (another simplex)
 
-            const Smplx& b = f.simplex(f.begin() + (birth - p.begin()));        // eventually this will be encapsulated behind an interface
-            const Smplx& d = f.simplex(f.begin() + (cur   - p.begin()));
+            const Smplx& b = m[birth];
+            const Smplx& d = m[cur];
             
             // if (b.dimension() != 1) continue;
             // std::cout << "Pair: (" << size(b) << ", " << size(d) << ")" << std::endl;
             if (b.dimension() >= skeleton) continue;
             std::cout << b.dimension() << " " << size(b) << " " << size(d) << std::endl;
-        } else if (cur->pair == cur)    // positive could be unpaired
+        } else if (cur->unpaired())    // positive could be unpaired
         {
-            const Smplx& b = f.simplex(f.begin() + (cur - p.begin()));
+            const Smplx& b = m[cur];
             // if (b.dimension() != 1) continue;
             
             // std::cout << "Unpaired birth: " << size(b) << std::endl;
-            // cycle = cur->chain;
+            // cycle = cur->chain;      // TODO
             if (b.dimension() >= skeleton) continue;
             std::cout << b.dimension() << " " << size(b) << " inf" << std::endl;
         }
@@ -89,13 +89,14 @@
         // for (Persistence::Cycle::const_iterator si =  cycle.begin();
         //                                                          si != cycle.end();     ++si)
         // {
-        //     const Smplx& s = f.simplex(f.begin() + (*si - p.begin()));
+        //     const Smplx& s = m[*si];
         //     //std::cout << s.dimension() << std::endl;
         //     const Smplx::VertexContainer& vertices = s.vertices();          // std::vector<Vertex> where Vertex = Distances::IndexType
         //     AssertMsg(vertices.size() == s.dimension() + 1, "dimension of a simplex is one less than the number of its vertices");
         //     std::cout << vertices[0] << " " << vertices[1] << std::endl;
         // }
     }
+#endif
     
     persistence_timer.check("# Persistence timer");
 }
--- a/examples/rips/rips.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/rips/rips.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -25,10 +25,9 @@
 //typedef         Rips<ExplicitDistances<Distances> >                   Generator;
 typedef         Rips<Distances>                                         Generator;
 typedef         Generator::Simplex                                      Smplx;
-typedef         std::vector<Smplx>                                      SimplexVector;
-typedef         Filtration<SimplexVector, unsigned>                     Fltr;
-//typedef         StaticPersistence<>                                     Persistence;
-typedef         DynamicPersistenceChains<>                              Persistence;
+typedef         Filtration<Smplx>                                       Fltr;
+typedef         StaticPersistence<>                                     Persistence;
+// typedef         DynamicPersistenceChains<>                              Persistence;
 typedef         PersistenceDiagram<>                                    PDgm;
 
 
@@ -50,26 +49,25 @@
 
     Generator               rips(distances);
     Generator::Evaluator    size(distances);
-    SimplexVector           complex;
+    Fltr                    f;
     
     // Generate 2-skeleton of the Rips complex for epsilon = 50
-    rips.generate(2, 10, make_push_back_functor(complex));
-    std::sort(complex.begin(), complex.end(), Smplx::VertexComparison());       // unnecessary
-    rInfo("Generated complex of size: %d",  complex.size());
+    rips.generate(2, 10, make_push_back_functor(f));
+    rInfo("Generated complex of size: %d",  f.size());
 
     // Generate filtration with respect to distance and compute its persistence
-    Fltr f(complex.begin(), complex.end(), Generator::Comparison(distances));
+    f.sort(Generator::Comparison(distances));
     Persistence p(f);
     p.pair_simplices();
     rInfo("Simplices paired");
 
+    Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
+
     // Record the persistence intervals in the persistence diagrams
     std::map<Dimension, PDgm> dgms;
     init_diagrams(dgms, p.begin(), p.end(), 
-                  evaluate_through_map(make_offset_map(p.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, size)), 
-                  evaluate_through_map(make_offset_map(p.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, Smplx::DimensionExtractor())));
+                  evaluate_through_map(m, size), 
+                  evaluate_through_map(m, Smplx::DimensionExtractor()));
 
     // Serialize the diagrams to a file
     std::ofstream ofs("rips-diagrams");
@@ -77,33 +75,32 @@
     oa << dgms;
 
     // Output cycles
-    for (Persistence::OrderIndex cur = p.begin(); cur != p.end(); ++cur)
+    for (Persistence::iterator cur = p.begin(); cur != p.end(); ++cur)
     {
-        Persistence::Cycle& cycle = cur->cycle;
+        const Persistence::Cycle& cycle = cur->cycle;
 
         if (!cur->sign())        // only negative simplices have non-empty cycles
         {
             Persistence::OrderIndex birth = cur->pair;      // the cycle that cur killed was born when we added birth (another simplex)
 
-            const Smplx& b = f.simplex(f.begin() + (birth - p.begin()));        // eventually this will be encapsulated behind an interface
-            const Smplx& d = f.simplex(f.begin() + (cur   - p.begin()));
+            const Smplx& b = m[birth];
+            const Smplx& d = m[cur];
             
             if (b.dimension() != 1) continue;
             std::cout << "Pair: (" << size(b) << ", " << size(d) << ")" << std::endl;
-        } else if (cur->pair == cur)    // positive could be unpaired
+        } else if (cur->unpaired())    // positive could be unpaired
         {
-            const Smplx& b = f.simplex(f.begin() + (cur - p.begin()));
+            const Smplx& b = m[cur];
             if (b.dimension() != 1) continue;
             
             std::cout << "Unpaired birth: " << size(b) << std::endl;
-            cycle = cur->chain;
+            // cycle = cur->chain;
         }
 
         // Iterate over the cycle
-        for (Persistence::Cycle::const_iterator si =  cycle.begin();
-                                                                 si != cycle.end();     ++si)
+        for (Persistence::Cycle::const_iterator si =  cycle.begin(); si != cycle.end(); ++si)
         {
-            const Smplx& s = f.simplex(f.begin() + (*si - p.begin()));
+            const Smplx& s = m[*si];
             //std::cout << s.dimension() << std::endl;
             const Smplx::VertexContainer& vertices = s.vertices();          // std::vector<Vertex> where Vertex = Distances::IndexType
             AssertMsg(vertices.size() == s.dimension() + 1, "dimension of a simplex is one less than the number of its vertices");
--- a/examples/triangle/triangle.cpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/examples/triangle/triangle.cpp	Wed Dec 16 15:39:06 2009 -0800
@@ -2,7 +2,7 @@
 
 #include "topology/simplex.h"
 #include "topology/filtration.h"
-//#include "topology/static-persistence.h"
+#include "topology/static-persistence.h"
 #include "topology/dynamic-persistence.h"
 #include "topology/persistence-diagram.h"
 #include <utilities/indirect.h>
@@ -19,15 +19,34 @@
 #include <boost/serialization/vector.hpp>
 #endif
 
-typedef         unsigned                        Vertex;
-typedef         Simplex<Vertex, double>         Smplx;
-typedef         std::vector<Smplx>              Complex;
-typedef         Filtration<Complex, unsigned>   Fltr;
-//typedef         StaticPersistence<>             Persistence;
-typedef         DynamicPersistenceTrails<>      Persistence;
-typedef         PersistenceDiagram<>            PDgm;
+typedef         unsigned                                            Vertex;
+typedef         Simplex<Vertex, double>                             Smplx;
+typedef         Filtration<Smplx>                                   Fltr;
+// typedef         StaticPersistence<>                                 Persistence;
+typedef         DynamicPersistenceTrails<>                          Persistence;
+typedef         PersistenceDiagram<>                                PDgm;
+typedef         OffsetBeginMap<Persistence, Fltr, 
+                               Persistence::iterator, 
+                               Fltr::Index>                         PersistenceFiltrationMap;
+typedef         OffsetBeginMap<Fltr, Persistence,
+                               Fltr::Index, 
+                               Persistence::iterator>               FiltrationPersistenceMap;
 
-void fillTriangleSimplices(Complex& c)
+// Transposes elements of the filtration together with the 
+struct FiltrationTranspositionVisitor: public Persistence::TranspositionVisitor
+{
+    typedef     Persistence::iterator                               iterator;
+
+                FiltrationTranspositionVisitor(const Persistence& p,
+                                               Fltr& f):
+                    p_(p), f_(f)                                    {}                                               
+    void        transpose(iterator i)                               { f_.transpose(f_.begin() + (i - p_.begin())); }
+
+    const Persistence&  p_;
+    Fltr&               f_;
+};
+
+void fillTriangleSimplices(Fltr& c)
 {
     typedef std::vector<Vertex> VertexVector;
     VertexVector vertices(4);
@@ -43,8 +62,6 @@
     c.push_back(Smplx(bg + 1, bg + 3, 2.9));               // BC
     c.push_back(Smplx(bg + 2, end,    3.5));               // CA
     c.push_back(Smplx(bg,     bg + 3, 5));                 // ABC
-
-    std::sort(c.begin(), c.end(), Smplx::VertexComparison());
 }
 
 int main(int argc, char** argv)
@@ -57,28 +74,28 @@
     //stdoutLog.subscribeTo(RLOG_CHANNEL("topology/vineyard"));
 #endif
 
-    Complex c;
-    fillTriangleSimplices(c);
+    Fltr f;
+    fillTriangleSimplices(f);
     std::cout << "Simplices filled" << std::endl;
-    for (Complex::const_iterator cur = c.begin(); cur != c.end(); ++cur)
+    for (Fltr::Index cur = f.begin(); cur != f.end(); ++cur)
         std::cout << "  " << *cur << std::endl;
 
-#if 1           // testing serialization of Complex (really Simplex)
+#if 1           // testing serialization of the Filtration (really Simplex)
   {  
     std::ofstream ofs("complex");
     boost::archive::text_oarchive oa(ofs);
-    oa << c;
-    c.clear();
+    oa << f;
+    f.clear();
   }  
 
   {
     std::ifstream ifs("complex");
     boost::archive::text_iarchive ia(ifs);
-    ia >> c;
+    ia >> f;
   }  
 #endif
 
-    Fltr f(c.begin(), c.end(), Smplx::DataComparison());
+    f.sort(Smplx::DataComparison());
     std::cout << "Filtration initialized" << std::endl;
     std::cout << f << std::endl;
 
@@ -88,36 +105,36 @@
     p.pair_simplices();
     std::cout << "Simplices paired" << std::endl;
 
+    Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
     std::map<Dimension, PDgm> dgms;
     init_diagrams(dgms, p.begin(), p.end(), 
-                  evaluate_through_map(make_offset_map(p.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, Smplx::DataEvaluator())), 
-                  evaluate_through_map(make_offset_map(p.begin(), f.begin()), 
-                                       evaluate_through_filtration(f, Smplx::DimensionExtractor())));
+                  evaluate_through_map(m, Smplx::DataEvaluator()),
+                  evaluate_through_map(m, Smplx::DimensionExtractor()));
 
     std::cout << 0 << std::endl << dgms[0] << std::endl;
     std::cout << 1 << std::endl << dgms[1] << std::endl;
 
+    PersistenceFiltrationMap                                    pfmap(p, f);
+    DimensionFunctor<PersistenceFiltrationMap, Fltr>            dim(pfmap, f);
+
     // Transpositions
-    p.transpose(p.begin());         // transposition case 1.2 special
-
-#if 0
+    FiltrationPersistenceMap        fpmap(f, p);
+    FiltrationTranspositionVisitor  visitor(p, f);
     Smplx A;  A.add(0);
     std::cout << A << std::endl;
-    std::cout << *tf.get_index(A) << std::endl;
-    std::cout << "Transposing A: " << tf.transpose(tf.get_index(A)) << std::endl;
-    std::cout << tf;
+    std::cout << "Transposing A: " << p.transpose(fpmap[f.find(A)], dim, visitor) << std::endl;     // 1.2 unpaired
 
     Smplx BC; BC.add(1); BC.add(2);
     Smplx AB; AB.add(0); AB.add(1);
     std::cout << BC << std::endl;
-    std::cout << *tf.get_index(BC) << std::endl;
-    tf.transpose(tf.get_index(BC));
-    std::cout << tf;
+    std::cout << p.transpose(fpmap[f.find(BC)], dim, visitor) << std::endl;         // 3.1
+    // p.transpose(fpmap[f.find(BC)], dim, visitor);
     std::cout << AB << std::endl;
-    std::cout << *tf.get_index(AB) << std::endl;
-    tf.transpose(tf.get_index(AB));
-    std::cout << tf;
-#endif
+    std::cout << p.transpose(fpmap[f.find(AB)], dim, visitor) << std::endl;         // 2.1
+    // p.transpose(fpmap[f.find(AB)], dim, visitor);
+
+    std::cout << p.transpose(p.begin(), dim, visitor) << std::endl;         // transposition case 1.2 special
+    std::cout << p.transpose(boost::next(p.begin()), dim, visitor) << std::endl;
+    std::cout << p.transpose(boost::next(p.begin(),3), dim, visitor) << std::endl;
 }
 
--- a/include/topology/chain.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/chain.h	Wed Dec 16 15:39:06 2009 -0800
@@ -79,6 +79,7 @@
         /// @{
         void                                    remove(iterator i)                              { ChainRepresentation::erase(i); Size::operator--(); }
         void                                    remove(const_reference x)                       { remove(std::find(begin(), end(), x)); }
+        bool                                    remove_if_contains(const_reference x);
 
         template<class ConsistencyComparison>
         void                                    append(const_reference x, const ConsistencyComparison& cmp);
@@ -95,7 +96,7 @@
         const_reference                         top(const OrderComparison& cmp) const;          ///< First element in cmp order
 
         boost::optional<const_iterator>         contains(const_reference x) const;              ///< tests whether chain contains x
-        boost::optional<iterator>               contains(reference x);                          ///< tests whether chain contains x
+        boost::optional<iterator>               contains(const_reference x);                    ///< tests whether chain contains x
         /// @}
     
         /// \name Debugging
--- a/include/topology/chain.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/chain.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -101,19 +101,33 @@
 contains(const_reference x) const
 {
     const_iterator res = std::find(begin(), end(), x);
-    return make_optional(res != end(), res);
+    return boost::make_optional(res != end(), res);
 }
 
 template<class C>
 boost::optional<typename ChainWrapper<C>::iterator>
 ChainWrapper<C>::
-contains(reference x)
+contains(const_reference x)
 {
     iterator res = std::find(begin(), end(), x);
     return boost::make_optional(res != end(), res);
 }
 
 template<class C>
+bool
+ChainWrapper<C>::
+remove_if_contains(const_reference x)
+{
+    boost::optional<iterator> i = contains(x);
+    if (i)
+    {
+        remove(*i);
+        return true;
+    } else
+        return false;
+}
+
+template<class C>
 template<class OutputMap>
 std::string
 ChainWrapper<C>::
--- a/include/topology/complex-traits.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/complex-traits.h	Wed Dec 16 15:39:06 2009 -0800
@@ -43,6 +43,9 @@
 
     static Index    begin(const Complex& complex)                           { return complex.begin(); }
     static Index    end(const Complex& complex)                             { return complex.end(); }
+
+    static const Simplex&
+                    simplex(Index i)                                        { return *i; }
 };
 
 
@@ -66,6 +69,9 @@
 
     static Index    begin(const Complex& complex)                           { return complex.begin(); }
     static Index    end(const Complex& complex)                             { return complex.end(); }
+
+    static const Simplex&
+                    simplex(Index i)                                        { return *i; }
 };
 
 #endif // __COMPLEX_TRAITS_H__
--- a/include/topology/dynamic-persistence.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/dynamic-persistence.h	Wed Dec 16 15:39:06 2009 -0800
@@ -6,42 +6,39 @@
 
 #include <boost/progress.hpp>
 
+#include <boost/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+namespace bl = boost::lambda;
+
 #ifdef COUNTERS
 static Counter*  cTrailLength =             GetCounter("persistence/pair/traillength");     // the size of matrix U in RU decomposition
 static Counter*  cChainLength =             GetCounter("persistence/pair/chainlength");     // the size of matrix V in R=DV decomposition
 #endif // COUNTERS
 
-template<class Data_, class ChainTraits_, class ContainerTraits_, class ConsistencyIndex_>
-struct TrailData: public PairCycleData<Data_, ChainTraits_, ContainerTraits_, 
-                                       TrailData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_> >
+template<class Data_, class ChainTraits_>
+struct TrailData: public PairCycleData<Data_, ChainTraits_, TrailData<Data_, ChainTraits_> >
 {
     typedef     Data_                                                                   Data;
-    typedef     ConsistencyIndex_                                                       ConsistencyIndex;
-
-    typedef     PairCycleData<Data_, ChainTraits_, ContainerTraits_, TrailData>         Parent;
-    typedef     TrailData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_>     Self;
 
-    // typedef     typename ContainerTraits_::template rebind<Self>::other                 ContainerTraits;
-    // typedef     typename ContainerTraits::Index                                         Index;
-    // typedef     typename ChainTraits_::template rebind<Index>::other                    ChainTraits;
-    // typedef     typename ChainTraits::Chain                                             Chain;
+    typedef     PairCycleData<Data_, ChainTraits_, TrailData>                           Parent;
+    typedef     TrailData<Data_, ChainTraits_>                                          Self;
+
     typedef     typename Parent::Index                                                  Index;
+    typedef     typename Parent::Cycle                                                  Cycle;
     typedef     typename Parent::Chain                                                  Chain;
     typedef     Chain                                                                   Trail;
-    
-    template<class Comparison>
-    struct ConsistencyComparison: public std::binary_function<const Index&, const Index&, bool>
-    {
-                        ConsistencyComparison(const Comparison& cmp = Comparison()): 
-                            cmp_(cmp)                                                   {}
+ 
+    // Modifiers
+    template<class Cmp>
+    void        trail_append(Index i, const Cmp& cmp)                                   { trail.append(i, cmp); }
+    template<class Cmp>
+    void        trail_add(const Trail& t, const Cmp& cmp)                               { trail.add(t, cmp); }
 
-        bool            operator()(const Index& a, const Index& b) const                { return cmp_(a->consistency, b->consistency); }
+    template<class Cmp>
+    void        cycle_add(const Cycle& z, const Cmp& cmp)                               { cycle.add(z, cmp); }
 
-        Comparison      cmp_;
-    };
-
-    Trail                                                                       trail;
-    ConsistencyIndex                                                            consistency;
+    using       Parent::cycle;
+    Trail                                                                               trail;
 };
 
 /**
@@ -61,28 +58,31 @@
 // position, or one could provide consistency that is references into the complex
 template<class Data_ =                  Empty<>, 
          class ChainTraits_ =           VectorChains<>,
-         class Comparison_ =            GreaterComparison<>,
-         class ContainerTraits_ =       VectorContainer<>,
-         class ConsistencyIndex_ =      size_t,
-         class ConsistencyComparison_ = std::less<ConsistencyIndex_>,
-         class Element_ =               TrailData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_> >
+         class ContainerTraits_ =       OrderConsistencyContainer<>,
+         class Element_ =               TrailData<Data_, ChainTraits_>,
+         class Comparison_ =            ElementComparison<typename ContainerTraits_::template rebind<Element_>::other::Container,
+                                                          std::greater<typename ContainerTraits_::template rebind<Element_>::other::Container::iterator> >,
+         class ConsistencyComparison_ = ElementComparison<typename ContainerTraits_::template rebind<Element_>::other::ConsistentContainer,
+                                                          std::greater<typename ContainerTraits_::template rebind<Element_>::other::ConsistentContainer::iterator> >
+        >
 class DynamicPersistenceTrails: 
-    public StaticPersistence<Data_, ChainTraits_, Comparison_, ContainerTraits_, Element_>
+    public StaticPersistence<Data_, ChainTraits_, ContainerTraits_, Element_, Comparison_>
 {
     public:
         typedef         Data_                                                           Data;
         typedef         Element_                                                        Element;
-        typedef         StaticPersistence<Data_, ChainTraits_, Comparison_,
-                                          ContainerTraits_, Element_>                   Parent;
+        typedef         StaticPersistence<Data_, ChainTraits_,
+                                          ContainerTraits_, Element_, Comparison_>      Parent;
  
         typedef         typename Parent::ContainerTraits                                Traits;
         typedef         typename Parent::Order                                          Order;
         typedef         typename Parent::OrderComparison                                OrderComparison;
         typedef         typename Parent::OrderIndex                                     OrderIndex;
-        typedef         ConsistencyIndex_                                               ConsistencyIndex;
-        typedef         ThreeOutcomeCompare<
-                            typename Element::
-                            template ConsistencyComparison<ConsistencyComparison_> >    ConsistencyComparison;
+        typedef         ConsistencyComparison_                                          ConsistencyComparison;
+        typedef         typename Parent::iterator                                       iterator;
+
+        typedef         typename Element::Trail                                         Trail;
+        typedef         typename Element::Cycle                                         Cycle;
 
         /**
          * Constructor: DynamicPersistenceTrails()
@@ -91,22 +91,23 @@
          * Template parameters:
          *   Filtration -           filtration of the complex whose persistence we are computing
          */
-        template<class Filtration>      DynamicPersistenceTrails(const Filtration&              f, 
-                                                                 const OrderComparison&         ocmp =  OrderComparison(),
-                                                                 const ConsistencyComparison&   ccmp =  ConsistencyComparison());
+        template<class Filtration>      DynamicPersistenceTrails(const Filtration& f);
         
         void                            pair_simplices();
 
         // Function: transpose(i)
         // Tranpose i and the next element. 
         // Returns: true iff the pairing switched.
-        bool                            transpose(OrderIndex i)                         { return transpose(i, TranspositionVisitor()); }
+        template<class DimensionFunctor, class Visitor>
+        bool                            transpose(iterator i, const DimensionFunctor& dimension, Visitor visitor = Visitor());
         
-        template<class Visitor>
-        bool                            transpose(OrderIndex i, const Visitor& visitor = Visitor());
+        template<class DimensionFunctor>
+        bool                            transpose(iterator i, const DimensionFunctor& dimension)    { return transpose(i,dimension,TranspositionVisitor()); }
 
         using                           Parent::begin;
         using                           Parent::end;
+        using                           Parent::iterator_to;
+        using                           Parent::index;
         using                           Parent::size;
 
         // Struct: TranspositionVisitor
@@ -118,65 +119,71 @@
             // This function is called before transposition is processed 
             // (at the very beginning of <transpose(i, visitor)>). It is meant to update any structures 
             // that may need to be updated, but perhaps it has other uses as well.
-            void                        transpose(OrderIndex i) const                   {}
+            void                        transpose(iterator i) const                     {}
 
             // Function: switched(i, type)
             // This function is called after the transposition if the switch in pairing has occured.
             // `i` is the index of the preceding simplex after the transposition. 
             // `type` indicates the <SwitchType>.
-            void                        switched(OrderIndex i, SwitchType type) const   {}
+            void                        switched(iterator i, SwitchType type) const     {}
         };
 
     protected:
         using                           Parent::order;
+        using                           Parent::set_pair;
+        using                           Parent::swap_cycle;
+
+        bool                            trail_remove_if_contains
+                                            (iterator i, OrderIndex j)                  { TrailRemover rm(j); order().modify(i, rm); return rm.result; }
+        void                            cycle_add(iterator i, const Cycle& z)           { order().modify(i, boost::bind(&Element::template cycle_add<ConsistencyComparison>, bl::_1, boost::ref(z), ccmp_)); }      // i->cycle_add(z, ccmp_)
+        void                            trail_add(iterator i, const Trail& t)           { order().modify(i, boost::bind(&Element::template trail_add<ConsistencyComparison>, bl::_1, boost::ref(t), ccmp_)); }      // i->trail_add(t, ccmp_)
 
     private:
-        void                            swap(OrderIndex i, OrderIndex j);
-        void                            pairing_switch(OrderIndex i, OrderIndex j);
+        void                            swap(iterator i, iterator j);
+        void                            pairing_switch(iterator i, iterator j);
 
         struct PairingTrailsVisitor: public Parent::PairVisitor 
         {
-            // TODO: this is specialized for std::vector
-                                        PairingTrailsVisitor(OrderIndex bg, ConsistencyComparison ccmp): 
-                                            bg_(bg), ccmp_(ccmp)                        {}
+                                        PairingTrailsVisitor(Order& order, ConsistencyComparison ccmp): 
+                                            order_(order), ccmp_(ccmp)                  {}
 
-            void                        init(OrderIndex i) const                        { i->consistency = i - bg_; i->trail.append(i, ccmp_); Count(cTrailLength); }
-            void                        update(OrderIndex j, OrderIndex i) const        { i->pair->trail.append(j, ccmp_); Count(cTrailLength); }
+            void                        init(iterator i) const                          { order_.modify(i,                                  boost::bind(&Element::template trail_append<ConsistencyComparison>, bl::_1, &*i, ccmp_)); Count(cTrailLength); }        // i->trail_append(&*i, ccmp)
+            void                        update(iterator j, iterator i) const            { order_.modify(order_.iterator_to(*(i->pair)),     boost::bind(&Element::template trail_append<ConsistencyComparison>, bl::_1, &*j, ccmp_)); Count(cTrailLength); }        // i->pair->trail_append(&*j, ccmp)
 
-            OrderIndex                  bg_;
+            Order&                      order_;            
             ConsistencyComparison       ccmp_;
         };
 
+        struct TrailRemover;
+
         ConsistencyComparison           ccmp_;
 };
 
-template<class Data_, class ChainTraits_, class ContainerTraits_, class ConsistencyIndex_>
-struct ChainData: public PairCycleData<Data_, ChainTraits_, ContainerTraits_,
-                                       ChainData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_> >
+/* Chains */
+template<class Data_, class ChainTraits_>
+struct ChainData: public PairCycleData<Data_, ChainTraits_, ChainData<Data_, ChainTraits_> >
 {
     typedef     Data_                                                                   Data;
-    typedef     ConsistencyIndex_                                                       ConsistencyIndex;
 
-    typedef     PairCycleData<Data_, ChainTraits_, ContainerTraits_, ChainData>         Parent;
-    typedef     ChainData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_>     Self;
+    typedef     PairCycleData<Data_, ChainTraits_, ChainData>                           Parent;
+    typedef     ChainData<Data_, ChainTraits_>                                          Self;
 
     typedef     typename Parent::Index                                                  Index;
+    typedef     typename Parent::Cycle                                                  Cycle;
     typedef     typename Parent::Chain                                                  Chain;
     typedef     Chain                                                                   Trail;
     
-    template<class Comparison>
-    struct ConsistencyComparison: public std::binary_function<const Index&, const Index&, bool>
-    {
-                        ConsistencyComparison(const Comparison& cmp = Comparison()): 
-                            cmp_(cmp)                                                   {}
+    // Modifiers
+    template<class Cmp>
+    void        chain_append(Index i, const Cmp& cmp)                                   { chain.append(i, cmp); }
+    template<class Cmp>
+    void        chain_add(const Chain& c, const Cmp& cmp)                               { chain.add(c, cmp); }
 
-        bool            operator()(const Index& a, const Index& b) const                { return cmp_(a->consistency, b->consistency); }
+    template<class Cmp>
+    void        cycle_add(const Cycle& z, const Cmp& cmp)                               { cycle.add(z, cmp); }
 
-        Comparison      cmp_;
-    };
-
-    Chain                                                                       chain;
-    ConsistencyIndex                                                            consistency;
+    using       Parent::cycle;
+    Chain                                                                               chain;
 };
 
 /**
@@ -195,28 +202,31 @@
  */
 template<class Data_ =                  Empty<>, 
          class ChainTraits_ =           VectorChains<>,
-         class Comparison_ =            GreaterComparison<>,
-         class ContainerTraits_ =       VectorContainer<>,
-         class ConsistencyIndex_ =      size_t,
-         class ConsistencyComparison_ = std::less<ConsistencyIndex_>,
-         class Element_ =               ChainData<Data_, ChainTraits_, ContainerTraits_, ConsistencyIndex_> >
+         class ContainerTraits_ =       OrderConsistencyContainer<>,
+         class Element_ =               ChainData<Data_, ChainTraits_>,
+         class Comparison_ =            ElementComparison<typename ContainerTraits_::template rebind<Element_>::other::Container,
+                                                          std::greater<typename ContainerTraits_::template rebind<Element_>::other::Container::iterator> >,
+         class ConsistencyComparison_ = ElementComparison<typename ContainerTraits_::template rebind<Element_>::other::ConsistentContainer,
+                                                          std::greater<typename ContainerTraits_::template rebind<Element_>::other::ConsistentContainer::iterator> >
+        >
 class DynamicPersistenceChains: 
-    public StaticPersistence<Data_, ChainTraits_, Comparison_, ContainerTraits_, Element_>
+    public StaticPersistence<Data_, ChainTraits_, ContainerTraits_, Element_, Comparison_>
 {
     public:
         typedef         Data_                                                           Data;
         typedef         Element_                                                        Element;
-        typedef         StaticPersistence<Data_, ChainTraits_, Comparison_,
-                                          ContainerTraits_, Element_>                   Parent;
+        typedef         StaticPersistence<Data_, ChainTraits_,
+                                          ContainerTraits_, Element_, Comparison_>      Parent;
  
         typedef         typename Parent::ContainerTraits                                Traits;
         typedef         typename Parent::Order                                          Order;
         typedef         typename Parent::OrderComparison                                OrderComparison;
         typedef         typename Parent::OrderIndex                                     OrderIndex;
-        typedef         ConsistencyIndex_                                               ConsistencyIndex;
-        typedef         ThreeOutcomeCompare<
-                            typename Element::
-                            template ConsistencyComparison<ConsistencyComparison_> >    ConsistencyComparison;
+        typedef         ConsistencyComparison_                                          ConsistencyComparison;
+        typedef         typename Parent::iterator                                       iterator;
+
+        typedef         typename Element::Chain                                         Chain;
+        typedef         typename Element::Cycle                                         Cycle;
 
         /**
          * Constructor: DynamicPersistenceChains()
@@ -225,9 +235,7 @@
          * Template parameters:
          *   Filtration -           filtration of the complex whose persistence we are computing
          */
-        template<class Filtration>      DynamicPersistenceChains(const Filtration&              f, 
-                                                                 const OrderComparison&         ocmp =  OrderComparison(),
-                                                                 const ConsistencyComparison&   ccmp =  ConsistencyComparison());
+        template<class Filtration>      DynamicPersistenceChains(const Filtration& f);
         
         void                            pair_simplices();
 
@@ -239,10 +247,12 @@
         
         // TODO: the main missing piece to be dynamic
         //template<class Visitor>
-        //bool                            transpose(OrderIndex i, const Visitor& visitor = Visitor());
-
+        //bool                            transpose(OrderIndex i, Visitor& visitor = Visitor());
+        
         using                           Parent::begin;
         using                           Parent::end;
+        using                           Parent::iterator_to;
+        using                           Parent::index;
         using                           Parent::size;
 
         // Struct: TranspositionVisitor
@@ -254,17 +264,22 @@
             // This function is called before transposition is processed 
             // (at the very beginning of <transpose(i, visitor)>). It is meant to update any structures 
             // that may need to be updated, but perhaps it has other uses as well.
-            void                        transpose(OrderIndex i) const                   {}
+            void                        transpose(iterator i) const                     {}
 
             // Function: switched(i, type)
             // This function is called after the transposition if the switch in pairing has occured.
             // `i` is the index of the preceding simplex after the transposition. 
             // `type` indicates the <SwitchType>.
-            void                        switched(OrderIndex i, SwitchType type) const   {}
+            void                        switched(iterator i, SwitchType type) const     {}
         };
 
     protected:
         using                           Parent::order;
+        using                           Parent::set_pair;
+        using                           Parent::swap_cycle;
+        
+        void                            cycle_add(iterator i, const Cycle& z)           { order().modify(i, boost::bind(&Element::template cycle_add<ConsistencyComparison>, bl::_1, boost::ref(z), ccmp_)); }      // i->cycle_add(z, ccmp_)
+        void                            chain_add(iterator i, const Chain& c)           { order().modify(i, boost::bind(&Element::template chain_add<ConsistencyComparison>, bl::_1, boost::ref(c), ccmp_)); }      // i->chain_add(c, ccmp_)
 
     private:
         void                            swap(OrderIndex i, OrderIndex j);
@@ -272,15 +287,14 @@
 
         struct PairingChainsVisitor: public Parent::PairVisitor 
         {
-            // TODO: this is specialized for std::vector
-                                        PairingChainsVisitor(OrderIndex bg, ConsistencyComparison ccmp, unsigned size): 
-                                            bg_(bg), ccmp_(ccmp), show_progress(size)   {}
+                                        PairingChainsVisitor(Order& order, ConsistencyComparison ccmp, unsigned size): 
+                                            order_(order), ccmp_(ccmp), show_progress(size)   {}
 
-            void                        init(OrderIndex i) const                        { i->consistency = i - bg_; i->chain.append(i, ccmp_); }
-            void                        update(OrderIndex j, OrderIndex i) const        { j->chain.add(i->pair->chain, ccmp_); }
-            void                        finished(OrderIndex i) const                    { CountBy(cChainLength, i->chain.size()); ++show_progress; }
+            void                        init(iterator i) const                          { order_.modify(i,                  boost::bind(&Element::template chain_append<ConsistencyComparison>, bl::_1, &*i, ccmp_)); }                 // i->chain_append(&*i, ccmp)
+            void                        update(iterator j, iterator i) const            { order_.modify(j,                  boost::bind(&Element::template chain_add<ConsistencyComparison>, bl::_1, i->pair->chain, ccmp_)); }         // j->chain.add(i->pair->chain, ccmp_)
+            void                        finished(iterator i) const                      { CountBy(cChainLength, i->chain.size()); ++show_progress; }
 
-            OrderIndex                  bg_;
+            Order&                      order_;            
             ConsistencyComparison       ccmp_;
 
             mutable boost::progress_display     
--- a/include/topology/dynamic-persistence.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/dynamic-persistence.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -22,48 +22,45 @@
 
 /* Trails */
 
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 template<class Filtration>
-DynamicPersistenceTrails<D,CT,Cmp,OT,CI,CC,E>::
-DynamicPersistenceTrails(const Filtration& f, const OrderComparison& ocmp, const ConsistencyComparison& ccmp):
-    Parent(f, ocmp), ccmp_(ccmp)
+DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::
+DynamicPersistenceTrails(const Filtration& f):
+    Parent(f), ccmp_(order().get<consistency>())
 {}
         
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 void
-DynamicPersistenceTrails<D,CT,Cmp,OT,CI,CC,E>::
+DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::
 pair_simplices()
 { 
-    Parent::pair_simplices(begin(), end(), PairingTrailsVisitor(begin(), ccmp_));
+    Parent::pair_simplices(begin(), end(), PairingTrailsVisitor(order(), ccmp_));
 }
 
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
-template<class Visitor>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
+template<class DimensionFunctor, class Visitor>
 bool
-DynamicPersistenceTrails<D,CT,Cmp,OT,CI,CC,E>::
-transpose(OrderIndex i, const Visitor& visitor)
+DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::
+transpose(iterator i, const DimensionFunctor& dimension, Visitor visitor)
 {
 #if LOGGING
     typename Traits::OutputMap outmap(order());
 #endif
 
     Count(cTransposition);
-    typedef                 OrderIndex                                  Index;
     typedef                 typename Element::Trail::iterator           TrailIterator;
 
     visitor.transpose(i);
     
-    Index i_prev = i++;
+    iterator i_prev = i++;
 
-#if 0       // Persistence no longer has the notion of dimension
-    if (i_prev->dimension() != i->dimension())
+    if (dimension(i_prev) != dimension(i))
     {
         swap(i_prev, i);
         rLog(rlTranspositions, "Different dimension");
         Count(cTranspositionDiffDim);
         return false;
     }
-#endif
     
     bool si = i_prev->sign(), sii = i->sign();
     if (si && sii)
@@ -71,15 +68,15 @@
         rLog(rlTranspositions, "Trail prev: %s", i_prev->trail.tostring(outmap).c_str());
 
         // Case 1
-        boost::optional<TrailIterator> i_in_i_prev = i_prev->trail.contains(i);
-        if (i_in_i_prev)
-        {
+        if (trail_remove_if_contains(i_prev, index(i)))
             rLog(rlTranspositions, "Case 1, U[i,i+1] = 1");
-            i_prev->trail.remove(*i_in_i_prev);
-        }
 
-        Index k = i_prev->pair;
-        Index l = i->pair;
+        iterator k = iterator_to(i_prev->pair);
+        iterator l = iterator_to(i->pair);
+        
+        // rLog(rlTranspositions, "(i_prev, k), (i, l): (%s, %s), (%s, %s)", 
+        //                         outmap(i_prev).c_str(), outmap(k).c_str(),
+        //                         outmap(i).c_str(),      outmap(l).c_str());
 
         // Explicit treatment of unpaired simplex
         if (l == i)
@@ -91,7 +88,7 @@
             return false;
         } else if (k == i_prev)
         {
-            if (!(l->cycle.contains(i_prev)))
+            if (!(l->cycle.contains(index(i_prev))))
             {
                 // Case 1.2
                 swap(i_prev, i);
@@ -104,7 +101,7 @@
                 // Case 1.2 --- special version (plain swap, but pairing switches)
                 swap(i_prev, i);
                 pairing_switch(i_prev, i);
-                visitor.switched(i_prev, Case12);
+                visitor.switched(i, Case12);
                 rLog(rlTranspositions, "Case 1.2 --- unpaired (pairing switch)");
                 rLog(rlTranspositions, outmap(i_prev).c_str());
                 Count(cTranspositionCase12s);
@@ -113,7 +110,7 @@
         }
         
         rLog(rlTranspositions, "l cycle: %s", l->cycle.tostring(outmap).c_str());
-        if (!(l->cycle.contains(i_prev)))
+        if (!(l->cycle.contains(index(i_prev))))
         {
             // Case 1.2
             swap(i_prev, i);
@@ -123,12 +120,12 @@
         } else
         {
             // Case 1.1
-            if (not2(ccmp_)(k,l))
+            if (std::not2(ccmp_)(index(k),index(l)))
             {
                 // Case 1.1.1
                 swap(i_prev, i);
-                l->cycle.add(k->cycle, ccmp_);        // Add column k to l
-                k->trail.add(l->trail, ccmp_);        // Add row l to k
+                cycle_add(l, k->cycle);               // Add column k to l
+                trail_add(k, l->trail);               // Add row l to k
                 rLog(rlTranspositions, "Case 1.1.1");
                 Count(cTranspositionCase111);
                 return false;
@@ -136,10 +133,10 @@
             {
                 // Case 1.1.2
                 swap(i_prev, i);
-                k->cycle.add(l->cycle, ccmp_);        // Add column l to k
-                l->trail.add(k->trail, ccmp_);        // Add row k to l
+                cycle_add(k, l->cycle);               // Add column l to k
+                trail_add(l, k->trail);               // Add row k to l
                 pairing_switch(i_prev, i);
-                visitor.switched(i_prev, Case112);
+                visitor.switched(i, Case112);
                 rLog(rlTranspositions, "Case 1.1.2");
                 Count(cTranspositionCase112);
                 return true;
@@ -148,7 +145,7 @@
     } else if (!si && !sii)
     {
         // Case 2
-        if (!(i_prev->trail.contains(i)))
+        if (!(i_prev->trail.contains(index(i))))
         {
             // Case 2.2
             swap(i_prev, i);
@@ -158,18 +155,18 @@
         } else
         {
             // Case 2.1
-            Index low_i = i_prev->pair;
-            Index low_ii = i->pair;
-            i_prev->trail.add(i->trail, ccmp_);            // Add row i to i_prev
-            i->cycle.add(i_prev->cycle, ccmp_);            // Add column i_prev to i
+            iterator low_i =    iterator_to(i_prev->pair);
+            iterator low_ii =   iterator_to(i->pair);
+            trail_add(i_prev, i->trail);                   // Add row i to i_prev
+            cycle_add(i, i_prev->cycle);                   // Add column i_prev to i
             swap(i_prev, i);    
-            if (not2(ccmp_)(low_ii, low_i))
+            if (std::not2(ccmp_)(index(low_ii), index(low_i)))
             {
                 // Case 2.1.2
-                i_prev->cycle.add(i->cycle, ccmp_);        // Add column i to i_prev (after transposition)
-                i->trail.add(i_prev->trail, ccmp_);        // Add row i to i_prev
+                cycle_add(i_prev, i->cycle);               // Add column i to i_prev (after transposition)
+                trail_add(i, i_prev->trail);               // Add row i to i_prev
                 pairing_switch(i_prev, i);
-                visitor.switched(i_prev, Case212);
+                visitor.switched(i, Case212);
                 rLog(rlTranspositions, "Case 2.1.2");
                 Count(cTranspositionCase212);
                 return true;
@@ -183,7 +180,7 @@
     } else if (!si && sii)
     {
         // Case 3
-        if (!(i_prev->trail.contains(i)))
+        if (!(i_prev->trail.contains(index(i))))
         {
             // Case 3.2
             swap(i_prev, i);
@@ -193,13 +190,13 @@
         } else
         {
             // Case 3.1
-            i_prev->trail.add(i->trail, ccmp_);            // Add row i to i_prev
-            i->cycle.add(i_prev->cycle, ccmp_);            // Add column i_prev to i
+            trail_add(i_prev, i->trail);                   // Add row i to i_prev
+            cycle_add(i, i_prev->cycle);                   // Add column i_prev to i
             swap(i_prev, i);
-            i_prev->cycle.add(i->cycle, ccmp_);            // Add column i_prev to i (after transposition)
-            i->trail.add(i_prev->trail, ccmp_);            // Add row i to i_prev
+            cycle_add(i_prev, i->cycle);                   // Add column i_prev to i (after transposition)
+            trail_add(i, i_prev->trail);                   // Add row i to i_prev
             pairing_switch(i_prev, i);
-            visitor.switched(i_prev, Case31);
+            visitor.switched(i, Case31);
             rLog(rlTranspositions, "Case 3.1");
             Count(cTranspositionCase31);
             return true;
@@ -207,12 +204,8 @@
     } else if (si && !sii)
     {
         // Case 4
-        boost::optional<TrailIterator> i_in_i_prev = i_prev->trail.contains(i);
-        if (i_in_i_prev)
-        {
+        if (trail_remove_if_contains(i_prev, index(i)))
             rLog(rlTranspositions, "Case 4, U[i,i+1] = 1");
-            i_prev->trail.remove(*i_in_i_prev);
-        }
         swap(i_prev, i);
         rLog(rlTranspositions, "Case 4");
         Count(cTranspositionCase4);
@@ -222,58 +215,69 @@
     return false; // to avoid compiler complaints; we should never reach this point
 }
 
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 void
-DynamicPersistenceTrails<D,CT,Cmp,OT,CI,CC,E>::
-swap(OrderIndex i, OrderIndex j)
+DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::
+swap(iterator i, iterator j)
 {
-    std::swap<Data>(*i, *j);
-    std::swap(i->pair, j->pair);
-
-    std::swap(i->cycle, j->cycle);          // TODO: double-check that the STL container specializations actually get invoked
-    std::swap(i->trail, j->trail);
+    order().relocate(i,j);
 }
 
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 void
-DynamicPersistenceTrails<D,CT,Cmp,OT,CI,CC,E>::
-pairing_switch(OrderIndex i, OrderIndex j)
+DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::
+pairing_switch(iterator i, iterator j)
 {
     OrderIndex i_pair = i->pair;
     OrderIndex j_pair = j->pair;
 
-    if (i_pair == i)
-        j->pair = j;
+    // rLog(rlTranspositions, "  (%x %x %x) (%x %x %x)", &*i, i->pair, i->pair->pair, &*j, j->pair, j->pair->pair);
+    if (i_pair == index(i))
+        set_pair(j, j);
     else
     {
-        j->pair = i_pair;
-        i_pair->pair = j;
+        set_pair(j, i_pair);
+        set_pair(i_pair, j);
     }
 
-    if (j_pair == j)
-        i->pair = i;
+    if (j_pair == index(j))
+        set_pair(i, i);
     else
     {
-        i->pair = j_pair;
-        j_pair->pair = i;
+        set_pair(i, j_pair);
+        set_pair(j_pair, i);
     }
+    // rLog(rlTranspositions, "  (%x %x %x) (%x %x %x)", &*i, i->pair, i->pair->pair, &*j, j->pair, j->pair->pair);
 }
 
+// Helper classes
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
+struct DynamicPersistenceTrails<D,CT,OT,E,Cmp,CCmp>::TrailRemover: 
+    public std::unary_function<Element&, void>
+{
+                                TrailRemover(OrderIndex i):
+                                    i_(i)                                       {}
+    
+    void                        operator()(Element& e)                          { result = e.trail.remove_if_contains(i_); }
+    
+    OrderIndex                  i_;
+    bool                        result;
+};
+
 
 /* Chains */
 
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 template<class Filtration>
-DynamicPersistenceChains<D,CT,Cmp,OT,CI,CC,E>::
-DynamicPersistenceChains(const Filtration& f, const OrderComparison& ocmp, const ConsistencyComparison& ccmp):
-    Parent(f, ocmp), ccmp_(ccmp)
+DynamicPersistenceChains<D,CT,OT,E,Cmp,CCmp>::
+DynamicPersistenceChains(const Filtration& f):
+    Parent(f), ccmp_(order().get<consistency>())
 {}
         
-template<class D, class CT, class Cmp, class OT, class CI, class CC, class E>
+template<class D, class CT, class OT, class E, class Cmp, class CCmp>
 void
-DynamicPersistenceChains<D,CT,Cmp,OT,CI,CC,E>::
+DynamicPersistenceChains<D,CT,OT,E,Cmp,CCmp>::
 pair_simplices()
 { 
-    Parent::pair_simplices(begin(), end(), PairingChainsVisitor(begin(), ccmp_, size()));
+    Parent::pair_simplices(begin(), end(), PairingChainsVisitor(order(), ccmp_, size()));
 }
-
--- a/include/topology/filtration.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/filtration.h	Wed Dec 16 15:39:06 2009 -0800
@@ -3,9 +3,25 @@
 
 #include <vector>
 #include <iostream>
+
 #include "complex-traits.h"
+
 #include "utilities/indirect.h"
 #include "utilities/property-maps.h"
+#include "utilities/types.h"
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/identity.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/serialization.hpp>
+
+
+namespace b = boost;
+namespace bmi = boost::multi_index;
 
 
 // Class: Filtration
@@ -13,61 +29,69 @@
 // 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_, 
-         class Index_ =             size_t, 
-         class ComplexTraits_ =     ComplexTraits<Complex_> >
+template<class Simplex_,
+         class SimplexOrderIndex_ = bmi::ordered_unique<bmi::identity<Simplex_>, 
+                                                        typename Simplex_::VertexComparison> >
 class Filtration
 {
+    private:
+        struct                  order {};           // tag
+
     public:
         // Typedefs: Template parameters
-        typedef                 Index_                                          IntermediateIndex;
-        typedef                 Complex_                                        Complex;
-        typedef                 ComplexTraits_                                  ComplexTraits;
+        typedef                 Simplex_                                        Simplex;
+        typedef                 SimplexOrderIndex_                              SimplexOrderIndex;
 
-        // Typedefs: Complex
-        typedef                 typename ComplexTraits::Index                   ComplexIndex;
-        typedef                 typename ComplexTraits::Simplex                 Simplex;
-        typedef                 typename ComplexTraits::SimplexIndexMap         SimplexIndexMap;
-        typedef                 std::vector<IntermediateIndex>                  IndexBoundary;
+        typedef                 b::multi_index_container<Simplex, 
+                                                         bmi::indexed_by<SimplexOrderIndex,
+                                                                         bmi::random_access<bmi::tag<order> > 
+                                                                        >
+                                                        >                       Container;
+        typedef                 typename Container::value_type                  value_type;
 
-        // Typedefs: Order
-        typedef                 std::vector<ComplexIndex>                       Order;
+        // Typedefs: Complex and Order views
+        typedef                 typename Container::template nth_index<0>::type Complex;
+        typedef                 typename Container::template nth_index<1>::type Order;
         typedef                 typename Order::const_iterator                  Index;
-        typedef                 std::vector<IntermediateIndex>                  ReverseOrder;
-        typedef                 typename ReverseOrder::const_iterator           ReverseOrderIndex;
+
+                                Filtration()                                    {}
 
         // Constructor: Filtration(bg, end, cmp)
-                                template<class Comparison>
-                                Filtration(ComplexIndex bg, ComplexIndex end, const Comparison& cmp = Comparison());
-
-        const Simplex&          simplex(Index i) const                          { return **i; }
+                                template<class ComplexIndex, class Comparison>
+                                Filtration(ComplexIndex bg, ComplexIndex end, const Comparison& cmp = Comparison()):
+                                    container_(bg, end)                         { sort(cmp); }
 
-        // Function: boundary(i, bdry, map)
-        // Computes boundary of a given index `i` in terms of other indices
-        template<class Cycle, class Map>
-        void                    boundary(const Index& i, Cycle& bdry, const Map& map) const;
+        // Lookup
+        const Simplex&          simplex(Index i) const                          { return *i; }
+        Index                   find(const Simplex& s) const                    { return bmi::project<order>(container_, container_.find(s)); }
+        
+        // Modifiers
+        template<class Comparison>
+        void                    sort(const Comparison& cmp = Comparison())      { container_.get<order>().sort(cmp); }
+        void                    push_back(const Simplex& s)                     { container_.get<order>().push_back(s); }
+        void                    transpose(Index i)                              { container_.get<order>().relocate(i, i+1); }
+        void                    clear()                                         { container_.get<order>().clear(); }
 
-        Index                   begin() const                                   { return order_.begin(); }
-        Index                   end() const                                     { return order_.end(); }
-        size_t                  size() const                                    { return order_.size(); }
+        Index                   begin() const                                   { return container_.get<order>().begin(); }
+        Index                   end() const                                     { return container_.get<order>().end(); }
+        size_t                  size() const                                    { return container_.size(); }
 
-        std::ostream&           operator<<(std::ostream& out) const;
+        std::ostream&           operator<<(std::ostream& out) const             { std::copy(begin(), end(), std::ostream_iterator<Simplex>(out, "\n")); return out; }
 
     private:
-        Order                   order_;
-        ReverseOrder            reverse_order_;
-        OffsetMap<ComplexIndex, 
-                  ReverseOrderIndex>        
-                                complex_order_map_;
-        SimplexIndexMap         simplex_index_map_;
+        Container               container_;
+
+    private:
+        // Serialization
+        friend class                            boost::serialization::access;
+        template<class Archive> 
+        void                                    serialize(Archive& ar, const unsigned int)
+        { ar & boost::serialization::make_nvp("order", container_); }
 };
 
-template<class C, class I, class CT>
+template<class S, class SOI>
 std::ostream&
-operator<<(std::ostream& out, const Filtration<C,I,CT>& f)                      { return f.operator<<(out); }
+operator<<(std::ostream& out, const Filtration<S,SOI>& f)                       { return f.operator<<(out); }
 
 
 template<class Functor_, class Filtration_>
@@ -97,6 +121,29 @@
 evaluate_through_filtration(const Filtration& filtration, const Functor& functor)
 { return ThroughFiltration<Functor, Filtration>(filtration, functor); }
 
+
+template<class Map, class Filtration>
+class DimensionFunctor
+{
+    public:
+                                DimensionFunctor(const Map& map, const Filtration& filtration):
+                                    map_(map), filtration_(filtration)
+                                {}
+
+        template<class key_type>
+        Dimension               operator()(key_type i) const                    { return filtration_.simplex(map_[i]).dimension(); }
+
+    private:        
+        const Map&              map_;
+        const Filtration&       filtration_;
+};
+
+template<class Map, class Filtration>
+DimensionFunctor<Map, Filtration>
+make_dimension_functor(const Map& map, const Filtration& filtration)
+{ return DimensionFunctor<Map, Filtration>(map, filtration); }
+
+
 #include "filtration.hpp"
 
 #endif // __FILTRATION_H__
--- a/include/topology/filtration.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/filtration.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -1,46 +1,6 @@
-#include "utilities/containers.h"
-#include <boost/iterator/counting_iterator.hpp>
-
-template<class C, class I, class CT>
-template<class Comparison>
-Filtration<C,I,CT>::
-Filtration(ComplexIndex bg, ComplexIndex end, const Comparison& cmp):
-    order_(boost::counting_iterator<ComplexIndex>(bg), 
-           boost::counting_iterator<ComplexIndex>(end)),
-    reverse_order_(order_.size()),
-    complex_order_map_(bg, reverse_order_.begin()),
-    simplex_index_map_(bg, end)
-{
-    std::sort(order_.begin(), order_.end(), make_indirect_comparison(cmp));
-    for (Index obg = order_.begin(), cur = obg; cur != order_.end(); ++cur)
-        reverse_order_[*cur - bg] = cur - obg;
-}
+#include <utilities/log.h>
 
-template<class C, class I, class CT>
-template<class Cycle, class Map>
-void
-Filtration<C,I,CT>::
-boundary(const Index& i, Cycle& bdry, const Map& map) const
-{
-    AssertMsg(bdry.empty(), "We are initializing the boundary from scratch");
-    ContainerTraits<Cycle>::reserve(bdry, (*i)->boundary_end() - (*i)->boundary_begin());
-    typename Map::template rebind_from<IntermediateIndex>::other    order_bdry_map(0, map.to());
-
-    for (typename Simplex::BoundaryIterator cur = (*i)->boundary_begin(); cur != (*i)->boundary_end(); ++cur)
-    {
-        //std::cout << *cur << std::endl;
-        //std::cout << simplex_index_map_[*cur] - complex_order_map_.from() << std::endl;
-        bdry.push_back(order_bdry_map[*complex_order_map_[simplex_index_map_[*cur]]]);
-        //std::cout << bdry.back() - order_bdry_map.to() << std::endl;
-    }
-}
-
-template<class C, class I, class CT>
-std::ostream&
-Filtration<C,I,CT>::
-operator<<(std::ostream& out) const
-{
-    for (Index i = begin(); i != end(); ++i)
-        out << **i << std::endl;
-    return out;
-}
+#ifdef LOGGING
+static rlog::RLogChannel* rlFiltration =                    DEF_CHANNEL("topology/filtration/info", rlog::Log_Debug);
+static rlog::RLogChannel* rlFiltrationDebug =               DEF_CHANNEL("topology/filtration/debug", rlog::Log_Debug);
+#endif // LOGGING
--- a/include/topology/lowerstarfiltration.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/lowerstarfiltration.h	Wed Dec 16 15:39:06 2009 -0800
@@ -13,21 +13,30 @@
 /**
  * Struct: MaxVertexComparison
  *
- * Functor that determines which simplex has a higher vertex with respect to VertexComparison_
+ * Functor that determines which simplex has a higher vertex with respect to VertexComparison_, breaking ties by dimension
  */
 template<class Simplex_, class VertexComparison_>
 struct MaxVertexComparison
 {
     typedef                     VertexComparison_                                   VertexComparison;
     typedef                     Simplex_                                            Simplex;
+    typedef                     typename Simplex::Vertex                            Vertex;
 
                                 MaxVertexComparison(const VertexComparison& vcmp):
                                     vcmp_(vcmp)                                     {}
 
     bool                        operator()(const Simplex& s1, const Simplex& s2) const
     {
-        return std::max_element(s1.vertices().begin(), s1.vertices().end(), vcmp) <
-               std::max_element(s2.vertices().begin(), s2.vertices().end(), vcmp);
+        const Vertex& max1 = *std::max_element(s1.vertices().begin(), s1.vertices().end(), vcmp_);
+        const Vertex& max2 = *std::max_element(s2.vertices().begin(), s2.vertices().end(), vcmp_);
+        
+        bool less = vcmp_(max1, max2), 
+             more = vcmp_(max2, max1);
+        
+        if (!less && !more)     // equal
+            return s1.dimension() < s2.dimension();
+
+        return less;
     }
 
     VertexComparison            vcmp_;
@@ -37,17 +46,18 @@
 /**
  * Map from i-th vertex to its index in the filtration.
  */
-template<class Index_>
+template<class Index_, class Filtration_>
 class VertexSimplexMap
 {
     public:
         typedef                 Index_                                              Index;
-        typedef                 std::vector<FiltrationIndex>                        VertexVector;
+        typedef                 Filtration_                                         Filtration;
+        typedef                 std::vector<Index>                                  VertexVector;
                                 
-                                VertexSimplexMap(Index begin, Index end, const Map& m)
+                                VertexSimplexMap(Index begin, Index end, const Filtration& f)
         {
-            for (FiltrationIndex cur = begin; cur != end; ++cur)
-                if (m[cur].dimension() == 0)
+            for (Index cur = begin; cur != end; ++cur)
+                if (f.simplex(cur).dimension() == 0)
                     vertices_.push_back(cur);
         }
 
@@ -55,6 +65,5 @@
         VertexVector            vertices_;
 };
 
-// TODO: transpose_vertices(Index, Filtration, Persistence, Visitor);
 
 #endif // __LOWERSTARFILTRATION_H__
--- a/include/topology/order.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/order.h	Wed Dec 16 15:39:06 2009 -0800
@@ -3,48 +3,111 @@
 
 #include "utilities/types.h"
 #include "utilities/indirect.h"
+#include "utilities/property-maps.h"
 
 #include <vector>
+#include <list>
+
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+namespace bmi = boost::multi_index;
 
 //#include <iostream>
 #include <sstream>
 #include <string>
 
 
-template<class Element_ = Empty<> >
-struct VectorContainer
+/* Tags */
+// TODO: pollutes global namespace; find a place to localize
+struct  order           {};
+struct  consistency     {};
+
+template<class Container>
+class OffsetOutputMap
 {
-    typedef         Element_                                                    Element;
-    typedef         std::vector<Element>                                        Container;
-
-    typedef         typename Container::iterator                                Index;
+    public:
+        typedef             const typename Container::value_type*   const_element_pointer;
+        typedef             typename Container::iterator            iterator;
+            
+                            OffsetOutputMap(const Container& order):
+                                om(order.begin(),0), order_(order)  {}
 
-    class OutputMap
-    {
-        public:
-                                OutputMap(const Container& order):
-                                    bg_(order.begin())                          {}
+        // returns a string with (i - bg_)                                
+        std::string         operator()(iterator i) const                       
+        { 
+            std::stringstream s; 
+            s << om[i];
+            return s.str();
+        }
+        
+        std::string         operator()(const_element_pointer p) const
+        { 
+            return (*this)(order_.iterator_to(*p));
+        }
 
-            // returns a string with (i - bg_)                                
-            std::string         operator()(Index i) const                       
-            { 
-                std::stringstream s; s << (i - bg_);
-                return  s.str();
-            }
+    private:
+        OffsetMap<typename Container::iterator, unsigned>           om;
+        const Container&                                            order_;
+};
 
-        private:
-            typename Container::const_iterator          bg_;
-    };
+template<class Element_ = Empty<> >
+struct OrderContainer
+{
+    typedef             Element_                                                        Element;
+    typedef             boost::multi_index_container<Element,
+                                                     bmi::indexed_by<
+                                                        bmi::random_access<bmi::tag<order> >             /* order index */
+                                                     > 
+                                                    >                                   Container;
+    typedef             typename Container::template index<order>::type                 OrderedContainer;
+
+    typedef             OffsetOutputMap<Container>                                      OutputMap;
 
     template<class U> struct rebind
-    { typedef           VectorContainer<U>              other; };
+    { typedef           OrderContainer<U>                                               other; };
+};
+
+
+template<class Container_, class Comparison_>
+struct  ElementComparison: public std::binary_function<const typename Container_::value_type*,
+                                                       const typename Container_::value_type*,
+                                                       bool>
+{
+    typedef             Container_                                                      Container;
+    typedef             Comparison_                                                     Comparison;
+    typedef             typename Container::value_type                                  Element;
+
+                        ElementComparison(const Container& container, 
+                                          const Comparison& cmp = Comparison()): 
+                            container_(container), cmp_(cmp)                            {}
+    
+    bool                operator()(const Element* a, const Element* b) const            { return cmp_(container_.iterator_to(*a), container_.iterator_to(*b)); }
+    
+    const Container&    container_;
+    const Comparison&   cmp_;
 };
 
-template<class Index = int>
-struct GreaterComparison: public std::greater<Index>
+
+
+template<class Element_ = Empty<> >
+struct OrderConsistencyContainer
 {
+    typedef             Element_                                                        Element;
+    typedef             boost::multi_index_container<Element,
+                                                     bmi::indexed_by<
+                                                        bmi::random_access<bmi::tag<order> >,            /* current index */
+                                                        bmi::random_access<bmi::tag<consistency> >       /* original index */
+                                                     > 
+                                                    >                                   Container;
+    
+    typedef             typename Container::template index<order>::type                 OrderedContainer;
+    typedef             typename Container::template index<consistency>::type           ConsistentContainer;
+    
+    typedef             OffsetOutputMap<Container>                                      OutputMap;
+    
     template<class U> struct rebind
-    { typedef           GreaterComparison<U>            other; };
+    { typedef           OrderConsistencyContainer<U>                                    other; };
 };
 
+
 #endif // __ORDER_H__
--- a/include/topology/persistence-diagram.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/persistence-diagram.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -58,10 +58,10 @@
 boost::optional<Point>
 make_point(Iterator i, const Evaluator& evaluator, const Visitor& visitor)
 {
-    RealType x = evaluator(i);
+    RealType x = evaluator(&*i);
     RealType y = Infinity;
-    if (i->pair != i)
-        y = evaluator(i->pair);
+    if (&*(i->pair) != &*i)
+        y = evaluator(&*(i->pair));
     
     Point p(x,y);
     visitor.point(i, p);
@@ -98,7 +98,7 @@
         {
             boost::optional<typename PDiagram::Point> p = make_point<typename PDiagram::Point>(cur, evaluator, visitor);
             if (p)
-                diagrams[dimension(cur)].push_back(*p);
+                diagrams[dimension(&*cur)].push_back(*p);
         }
 }
 
--- a/include/topology/simplex.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/simplex.h	Wed Dec 16 15:39:06 2009 -0800
@@ -95,7 +95,7 @@
         
         /// \name Vertex manipulation
         /// @{
-        //bool                    contains(const Vertex& v) const;
+        bool                    contains(const Vertex& v) const;
         bool                    contains(const Self& s) const;
         void                    add(const Vertex& v);
         template<class Iterator>
--- a/include/topology/simplex.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/simplex.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -57,7 +57,6 @@
     return BoundaryIterator(vertices().end(), vertices());
 }
 
-#if 0
 template<class V, class T>
 bool
 Simplex<V,T>::
@@ -67,7 +66,6 @@
     typename VertexContainer::const_iterator location = std::lower_bound(vertices().begin(), vertices().end(), v); 
     return ((location != vertices().end()) && (*location == v)); 
 }
-#endif
  
 template<class V, class T>
 bool
--- a/include/topology/static-persistence.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/static-persistence.h	Wed Dec 16 15:39:06 2009 -0800
@@ -5,18 +5,21 @@
 #include "cycles.h"
 #include "filtration.h"
 
+#include <boost/ref.hpp>
+#include <boost/lambda/lambda.hpp>
+namespace bl = boost::lambda;
+
 #include <utilities/types.h>
 
 
-template<class Data_, class ChainTraits_, class ContainerTraits_, class Element_ = use_default> 
+// Element_ should derive from PairCycleData
+template<class Data_, class ChainTraits_, class Element_ = use_default>
 struct PairCycleData: public Data_
 {
     typedef     Data_                                                                   Data;
     typedef     typename if_default<Element_, PairCycleData>::type                      Element;
-    typedef     PairCycleData<Data, ChainTraits_, ContainerTraits_, Element>            Self;
 
-    typedef     typename ContainerTraits_::template rebind<Element>::other              ContainerTraits;
-    typedef     typename ContainerTraits::Index                                         Index;
+    typedef     const Element*                                                          Index;
     typedef     typename ChainTraits_::template rebind<Index>::other                    ChainTraits;
     typedef     typename ChainTraits::Chain                                             Chain;
     typedef     Chain                                                                   Cycle;
@@ -26,6 +29,10 @@
                 {}
     
     bool        sign() const                                                            { return cycle.empty(); }
+    bool        unpaired() const                                                        { return pair == this; }
+    
+    void        swap_cycle(Cycle& z)                                                    { cycle.swap(z); }
+    void        set_pair(Index i)                                                       { pair = i; }
 
     Index       pair;
     Cycle       cycle;
@@ -44,9 +51,10 @@
  */
 template<class Data_ =              Empty<>,
          class ChainTraits_ =       VectorChains<>,
-         class Comparison_ =        GreaterComparison<>,
-         class ContainerTraits_ =   VectorContainer<>,
-         class Element_ =           PairCycleData<Data_, ChainTraits_, ContainerTraits_> >
+         class ContainerTraits_ =   OrderContainer<>,
+         class Element_ =           PairCycleData<Data_, ChainTraits_>,
+         class Comparison_ =        ElementComparison<typename ContainerTraits_::template rebind<Element_>::other::Container,
+                                                      std::greater<typename ContainerTraits_::template rebind<Element_>::other::Container::iterator> > >
 class StaticPersistence
 {
     public:
@@ -59,15 +67,16 @@
                                                     template rebind<Element>::other             ContainerTraits;
         typedef                         typename ContainerTraits::Container                     Container;
         typedef                         Container                                               Order;
-        typedef                         typename ContainerTraits::Index                         OrderIndex;
-        typedef                         typename ContainerTraits::Element                       OrderElement;
+        typedef                         typename Element::Index                                 OrderIndex;
+        typedef                         Element                                                 OrderElement;
+        typedef                         typename Order::iterator                                iterator;
+
         typedef                         typename ChainTraits_::
                                                     template rebind<OrderIndex>::other          ChainTraits;
         typedef                         typename ChainTraits::Chain                             Chain;
         typedef                         Chain                                                   Cycle;
         
-        typedef                         typename Comparison_::
-                                                    template rebind<OrderIndex>::other          OrderComparison;
+        typedef                         Comparison_                                             OrderComparison;
 
         /* Constructor: StaticPersistence()
          * TODO: write a description
@@ -75,8 +84,7 @@
          * Template parameters:
          *   Filtration -           filtration of the complex whose persistence we are computing
          */
-        template<class Filtration>      StaticPersistence(const Filtration& f, 
-                                                          const OrderComparison& ocmp = OrderComparison());
+        template<class Filtration>      StaticPersistence(const Filtration& f);
         
         // Function: pair_simplices()                                        
         // Compute persistence of the filtration
@@ -86,16 +94,35 @@
         //   begin() -              returns OrderIndex of the first element
         //   end() -                returns OrderIndex of one past the last element
         //   size() -               number of elements in the StaticPersistence
-        OrderIndex                      begin()                                                 { return order_.begin(); }
-        OrderIndex                      end()                                                   { return order_.end(); }
+        iterator                        begin() const                                           { return order_.begin(); }
+        iterator                        end() const                                             { return order_.end(); }
+        iterator                        iterator_to(OrderIndex i) const                         { return order_.iterator_to(*i); }
+        OrderIndex                      index(iterator i) const                                 { return &*i; }
         size_t                          size() const                                            { return order_.size(); }
         const OrderComparison&          order_comparison() const                                { return ocmp_; }
 
+        // A map to extract simplices
+        template<class Filtration>      class SimplexMap;
+        template<class Filtration>
+        SimplexMap<Filtration>          make_simplex_map(const Filtration& filtration) const    { return SimplexMap<Filtration>(*this, filtration); }
+
+        class                           OrderModifier
+        {
+            public:
+                                        OrderModifier(Order& order): order_(order)              {}
+                template<class Functor> 
+                void                    operator()(iterator i, const Functor& f)                { order_.modify(i, f); }
+
+            private:
+                Order&                  order_;
+        };
+        OrderModifier                   modifier()                                              { return OrderModifier(order()); }
+
     protected:
         // Function: pair_simplices(bg, end)
         // Compute persistence of the simplices in filtration between bg and end
         template<class Visitor>
-        void                            pair_simplices(OrderIndex bg, OrderIndex end, const Visitor& visitor = Visitor());
+        void                            pair_simplices(iterator bg, iterator end, const Visitor& visitor = Visitor());
 
         // Struct: PairVisitor
         // Acts as an archetype and if necessary a base class for visitors passed to <pair_simplices(bg, end, visitor)>.
@@ -104,20 +131,27 @@
             // Function: init(i)
             // Called after OrderElement pointed to by `i` has been initialized 
             // (its cycle is set to be its boundary, and pair is set to self, i.e. `i`)
-            void                        init(OrderIndex i) const                                {}
+            void                        init(iterator i) const                                  {}
             
             // Function: update(j, i)
             // Called after the cycle of `i` has been added to the cycle of `j`, 
             // this allows the derived class to perform the necessary updates 
             // (e.g., add `i`'s chain to `j`'s chain)
-            void                        update(OrderIndex j, OrderIndex i) const                {}
+            void                        update(iterator j, iterator i) const                    {}
 
             // Function: finished(j)
             // Called after the processing of `j` is finished.
-            void                        finished(OrderIndex j) const                            {}
+            void                        finished(iterator j) const                              {}
         };
 
         const Order&                    order() const                                           { return order_; }
+        Order&                          order()                                                 { return order_; }
+
+        void                            set_pair(iterator i,    iterator j)                     { set_pair(i, &*j); }
+        void                            set_pair(iterator i,    OrderIndex j)                   { order_.modify(i, boost::bind(&OrderElement::set_pair, bl::_1, j)); }                  // i->set_pair(j)
+        void                            set_pair(OrderIndex i,  iterator j)                     { set_pair(iterator_to(i), &*j); }
+        void                            set_pair(OrderIndex i,  OrderIndex j)                   { set_pair(iterator_to(i), j); }
+        void                            swap_cycle(iterator i,  Cycle& z)                       { order_.modify(i, boost::bind(&OrderElement::swap_cycle, bl::_1, boost::ref(z))); }    // i->swap_cycle(z)
 
     private:
         Order                           order_;
--- a/include/topology/static-persistence.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/static-persistence.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -1,8 +1,10 @@
 #include <utilities/log.h>
 #include <utilities/containers.h>
+#include <utilities/property-maps.h>
+
 #include <boost/utility/enable_if.hpp>
 #include <boost/utility.hpp>
-#include <utilities/property-maps.h>
+#include <boost/foreach.hpp>
 
 #ifdef LOGGING
 static rlog::RLogChannel* rlPersistence =                   DEF_CHANNEL("topology/persistence", rlog::Log_Debug);
@@ -14,31 +16,34 @@
 static Counter*  cPersistencePairCycleLength =              GetCounter("persistence/pair/cyclelength");
 #endif // COUNTERS
 
-template<class D, class CT, class Cmp, class OT, class E>
+template<class D, class CT, class OT, class E, class Cmp>
 template<class Filtration>
-StaticPersistence<D, CT, Cmp, OT, E>::
-StaticPersistence(const Filtration& filtration, 
-                  const OrderComparison& ocmp):
-    order_(filtration.size()),
-    ocmp_(ocmp)
+StaticPersistence<D, CT, OT, E, Cmp>::
+StaticPersistence(const Filtration& filtration):
+    ocmp_(order_)
 { 
-    OrderIndex                          ocur = begin();
-    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)
+    order_.assign(filtration.size(), OrderElement());
+    rLog(rlPersistence, "Initializing persistence");
+
+    OffsetMap<typename Filtration::Index, iterator>                         om(filtration.begin(), begin());
+    for (typename Filtration::Index cur = filtration.begin(); cur != filtration.end(); ++cur)
     {
-        OrderElement& oe = *ocur;
-        oe.pair = ocur;
+        Cycle z;   
+        BOOST_FOREACH(const typename Filtration::Simplex& s, std::make_pair(cur->boundary_begin(), cur->boundary_end()))
+            z.push_back(index(om[filtration.find(s)]));
+        z.sort(ocmp_); 
 
-        filtration.boundary(cur, oe.cycle, om);
-        oe.cycle.sort(ocmp_); 
+        iterator ocur = om[cur];
+        swap_cycle(ocur, z);
+        set_pair(ocur,   ocur);
     }
 }
 
-template<class D, class CT, class Cmp, class OT, class E>
+template<class D, class CT, class OT, class E, class Cmp>
 template<class Visitor>
 void 
-StaticPersistence<D, CT, Cmp, OT, E>::
-pair_simplices(OrderIndex bg, OrderIndex end, const Visitor& visitor)
+StaticPersistence<D, CT, OT, E, Cmp>::
+pair_simplices(iterator bg, iterator end, const Visitor& visitor)
 {
 #if LOGGING
     typename ContainerTraits::OutputMap outmap(order_);
@@ -46,16 +51,16 @@
 
     // FIXME: need sane output for logging
     rLog(rlPersistence, "Entered: pair_simplices");
-    for (OrderIndex j = bg; j != end; ++j)
+    for (iterator j = bg; j != end; ++j)
     {
         visitor.init(j);
         rLog(rlPersistence, "Simplex %s", outmap(j).c_str());
 
-        OrderElement& oe = *j;
-        typename OrderElement::Cycle& z = oe.cycle;
+        Cycle z;
+        swap_cycle(j, z);
         rLog(rlPersistence, "  has boundary: %s", z.tostring(outmap).c_str());
         
-        CountNum(cPersistencePairBoundaries, oe.cycle.size());
+        CountNum(cPersistencePairBoundaries, z.size());
         Count(cPersistencePair);
 
         while(!z.empty())
@@ -63,33 +68,59 @@
             OrderIndex i = z.top(ocmp_);            // take the youngest element with respect to the OrderComparison
             rLog(rlPersistence, "  %s: %s", outmap(i).c_str(), outmap(i->pair).c_str());
             // TODO: is this even a meaningful assert?
-            AssertMsg(!ocmp_(i, j), 
+            AssertMsg(!ocmp_(i, index(j)), 
                       "Simplices in the cycle must precede current simplex: (%s in cycle of %s)",
                       outmap(i).c_str(), outmap(j).c_str());
 
             // i is not paired, so we pair j with i
-            if (i->pair == i)
+            if (iterator_to(i->pair) == iterator_to(i))
             {
                 rLog(rlPersistence, "  Pairing %s and %s with cycle %s", 
                                    outmap(i).c_str(), outmap(j).c_str(), 
                                    z.tostring(outmap).c_str());
-                i->pair = j;
-                j->pair = i;
-                CountNum(cPersistencePairCycleLength, z.size());
-                CountBy(cPersistencePairCycleLength, z.size());
+             
+                set_pair(i, j);
+                swap_cycle(j, z);
+                set_pair(j, i);
+                
+                CountNum(cPersistencePairCycleLength,   j->cycle.size());
+                CountBy (cPersistencePairCycleLength,   j->cycle.size());
                 break;
             }
 
             // update element
             z.add(i->pair->cycle, ocmp_);
-            visitor.update(j, i);
+            visitor.update(j, iterator_to(i));
             rLog(rlPersistence, "    new cycle: %s", z.tostring(outmap).c_str());
         }
+        // if z was empty, so is (already) j->cycle, so nothing to do
         visitor.finished(j);
         rLog(rlPersistence, "Finished with %s: %s", 
-                            outmap(j).c_str(), outmap(oe.pair).c_str());
+                            outmap(j).c_str(), outmap(j->pair).c_str());
     }
 }
 
+template<class D, class CT, class OT, class E, class Cmp>
+template<class Filtration>
+class StaticPersistence<D, CT, OT, E, Cmp>::SimplexMap
+{
+    public:
+        typedef                             OrderIndex                              key_type;
+        // typedef                             iterator                                key_type;
+        typedef                             const typename Filtration::Simplex&     value_type;
+
+
+                                            SimplexMap(const StaticPersistence& persistence,
+                                                       const Filtration&        filtration):
+                                                persistence_(persistence), 
+                                                filtration_(filtration)             {}
+
+        value_type                          operator[](OrderIndex k) const          { return (*this)[persistence_.iterator_to(k)]; }
+        value_type                          operator[](iterator i) const            { return filtration_.simplex(filtration_.begin() + (i - persistence_.begin())); } 
+
+    private:
+        const StaticPersistence&            persistence_;
+        const Filtration&                   filtration_;
+};
 
 /* Private */
--- a/include/topology/vineyard.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/vineyard.h	Wed Dec 16 15:39:06 2009 -0800
@@ -1,6 +1,6 @@
 /*
  * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
+ * Department of Computer Science, Duke University, 2005 -- 2009
  */
 
 #ifndef __VINEYARD_H__
@@ -14,144 +14,141 @@
 #include <boost/serialization/vector.hpp>
 #include <boost/serialization/nvp.hpp>
 #include <boost/serialization/list.hpp>
-	
+    
+#include <boost/iterator/iterator_traits.hpp>
 
-template<class Smplx>	class Knee;
-template<class Smplx>	class Vine;
+
+class Knee;
+class Vine;
 
 /**
  * Vineyard class. Keeps track of vines and knees. switched() is the key function called
- * by filtration when pairing switches after a Filtration::transpose().
+ * when pairing switches.
  *
  * \ingroup topology
  */
-template<class FltrSmplx>
+template<class Index_, class Iterator_, class Evaluator_>
 class Vineyard
 {
-	public:
-		typedef							FltrSmplx									FiltrationSimplex;
-		typedef							typename FiltrationSimplex::Simplex			Simplex;
-		typedef							Vine<Simplex>								VineS;
-		typedef							Knee<Simplex>								KneeS;
-		typedef							std::list<VineS>						    VineList;
-		typedef							std::list<VineList>						    VineListList;
-        typedef                         std::vector<typename VineListList::iterator> VineListVector;
-		typedef							typename FiltrationSimplex::Cycle			Cycle;
+    public:
+        typedef                         Index_                                          Index;
+        typedef                         Iterator_                                       Iterator;
+        typedef                         Evaluator_                                      Evaluator;
 
-		typedef							typename FiltrationSimplex::Index			Index;
-		typedef							typename FiltrationSimplex::EvaluatorS		Evaluator;
-										
-	public:
-										Vineyard(Evaluator* eval = 0): 
-											evaluator(eval)							{}
+        typedef                         std::list<Vine>                                 VineList;
+        typedef                         std::list<VineList>                             VineListList;
+        typedef                         std::vector<VineListList::iterator>             VineListVector;
+                                        
+    public:
+                                        Vineyard(Evaluator* eval = 0): 
+                                            evaluator(eval)                             {}
 
-		void							start_vines(Index bg, Index end);
-		void							switched(Index i, Index j);
-		void							record_knee(Index i);
-		void							record_diagram(Index bg, Index end);
+        void                            start_vines(Iterator bg, Iterator end);
+        void                            switched(Index i, Index j);
+        template<class Iter>
+        void                            record_knee(Iter i);
+        void                            record_diagram(Iterator bg, Iterator end);
 
-		void							set_evaluator(Evaluator* eval)				{ evaluator = eval; }
-
-		void							save_edges(const std::string& filename) const;
+        void                            set_evaluator(Evaluator* eval)                  { evaluator = eval; }
 
-	protected:
-		typename KneeS::SimplexList  	resolve_cycle(Index i) const;
+        void                            save_edges(const std::string& filename, bool skip_infinite = false) const;
 
-	private:
-		void							start_vine(Index i);
+    private:
+        template<class Iter>
+        void                            start_vine(Iter i);
 
-	private:
-		VineListList                    vines;            // stores vine lists
-		VineListVector                  vines_vector;     // stores pointers (iterators) to vine lists
-		Evaluator*						evaluator;
+    private:
+        VineListList                    vines;            // stores vine lists
+        VineListVector                  vines_vector;     // stores pointers (iterators) to vine lists
+        Evaluator*                      evaluator;
 };
 
 /**
- * Knee class stores the knee in R^3 as well as the cycle that is associated with the Simplex starting from the Knee.
+ * Knee class stores the knee in R^3.
  *
  * \ingroup topology
  */
-template<class S>
 class Knee
 {
-	public:
-		typedef					S												Simplex;
-		typedef					std::list<Simplex>								SimplexList;
-	
-		RealType				birth;
-		RealType				death;
-		RealType				time;
-		SimplexList				cycle;
-			
-								// Default parameters for serialization
-								Knee(RealType b = 0, RealType d = 0, RealType t = 0):
-									birth(b), death(d), time(t)
-								{}
-								Knee(const Knee& other): 
-									birth(other.birth), death(other.death), time(other.time)
-								{}
+    public:
+        RealType                birth;
+        RealType                death;
+        RealType                time;
+            
+                                // Default parameters for serialization
+                                Knee(RealType b = 0, RealType d = 0, RealType t = 0):
+                                    birth(b), death(d), time(t)
+                                {}
+                                Knee(const Knee& other): 
+                                    birth(other.birth), death(other.death), time(other.time)
+                                {}
 
-		bool 					is_diagonal() const								{ return birth == death; }
-		bool					is_infinite() const								{ return (death == Infinity) || (birth == Infinity); }
-		void 					set_cycle(const SimplexList& lst)				{ cycle = lst; }
+        bool                    is_diagonal() const                             { return birth == death; }
+        bool                    is_infinite() const                             { return (death == Infinity) || (birth == Infinity); }
 
-		std::ostream&			operator<<(std::ostream& out) const				{ return out << "(" << birth << ", " 
-																									<< death << ", " 
-																									<< time  << ")"; }
-	
-	private:
-		friend class boost::serialization::access;
+        std::ostream&           operator<<(std::ostream& out) const             { return out << "(" << birth << ", " 
+                                                                                                    << death << ", " 
+                                                                                                    << time  << ")"; }
+    
+    private:
+        friend class boost::serialization::access;
 
-		template<class Archive>
-		void 					serialize(Archive& ar, version_type );
+        template<class Archive>
+        void                    serialize(Archive& ar, version_type );
 };
 
-template<class S>
-std::ostream& operator<<(std::ostream& out, const Knee<S>& k) 					{ return k.operator<<(out); }
+std::ostream& operator<<(std::ostream& out, const Knee& k)                      { return k.operator<<(out); }
 
 /**
  * Vine is a list of Knees
  */
-template<class S>
-class Vine: public std::list<Knee<S> >
-{	
-	public:
-		typedef					S												Simplex;
-		typedef					Knee<Simplex>									KneeS;
-		typedef					std::list<KneeS>								VineRepresentation;
-		typedef					typename VineRepresentation::const_iterator		const_knee_iterator;
-		
-								Vine()											{}
-								Vine(const Vine& other): 
-                                    VineRepresentation(other)	                {}
-								Vine(const VineRepresentation& other): 
-                                    VineRepresentation(other)	                {}
-								Vine(const KneeS& k)						    { add(k); }
-		
-		void 					add(RealType b, RealType d, RealType t)			{ push_back(KneeS(b,d,t)); }
-		void 					add(const KneeS& k)								{ push_back(k); }
+class Vine: public std::list<Knee>
+{   
+    public:
+        typedef                 std::list<Knee>                                 VineRepresentation;
+        typedef                 VineRepresentation::const_iterator              const_knee_iterator;
+        
+                                Vine()                                          {}
+                                Vine(const Vine& other): 
+                                    VineRepresentation(other)                   {}
+                                Vine(const VineRepresentation& other): 
+                                    VineRepresentation(other)                   {}
+                                Vine(const Knee& k)                             { add(k); }
+        
+        void                    add(RealType b, RealType d, RealType t)         { push_back(Knee(b,d,t)); }
+        void                    add(const Knee& k)                              { push_back(k); }
 
-        std::ostream&           operator<<(std::ostream& out) const             { for (const_knee_iterator cur = begin(); cur != end(); ++cur) out << *cur; return out; }
+        std::ostream&           operator<<(std::ostream& out) const             { std::copy(begin(), end(), std::ostream_iterator<Knee>(out, " ")); return out; }
 
-		using VineRepresentation::begin;
-		using VineRepresentation::end;
-		using VineRepresentation::front;
-		using VineRepresentation::back;
-		using VineRepresentation::size;
-		using VineRepresentation::empty;
+        using VineRepresentation::begin;
+        using VineRepresentation::end;
+        using VineRepresentation::front;
+        using VineRepresentation::back;
+        using VineRepresentation::size;
+        using VineRepresentation::empty;
 
-	protected:
-		using VineRepresentation::push_back;
+    protected:
+        using VineRepresentation::push_back;
 
-	private:
-		friend class boost::serialization::access;
+    private:
+        friend class boost::serialization::access;
 
-		template<class Archive>
-		void 					serialize(Archive& ar, version_type );
+        template<class Archive>
+        void                    serialize(Archive& ar, version_type );
 };
 
-template<class S>
-std::ostream& operator<<(std::ostream& out, const Vine<S>& v) 					{ return v.operator<<(out); }
+std::ostream& operator<<(std::ostream& out, const Vine& v)                      { return v.operator<<(out); }
+
+
+class VineData
+{
+    public:
+        void        set_vine(Vine* vine) const                                          { vine_ = vine; }
+        Vine*       vine() const                                                        { return vine_; }
+
+    private:
+        mutable Vine*       vine_;      // cheap trick to work around MultiIndex's constness
+};
 
 
 #include "vineyard.hpp"
--- a/include/topology/vineyard.hpp	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/topology/vineyard.hpp	Wed Dec 16 15:39:06 2009 -0800
@@ -6,160 +6,158 @@
 #include "utilities/log.h"
 
 #ifdef LOGGING
-static rlog::RLogChannel* rlVineyard =			DEF_CHANNEL("topology/vineyard", rlog::Log_Debug);
+static rlog::RLogChannel* rlVineyard =          DEF_CHANNEL("topology/vineyard", rlog::Log_Debug);
 #endif // LOGGING
 
-template<class FS>
+template<class I, class It, class E>
 void
-Vineyard<FS>::
-start_vines(Index bg, Index end)
+Vineyard<I,It,E>::
+start_vines(Iterator bg, Iterator end)
 {
-	AssertMsg(evaluator != 0, "Cannot start vines with a null evaluator");
-	for (Index cur = bg; cur != end; ++cur)
-	{
-		if (!cur->sign()) continue;
-		Dimension dim = cur->dimension();
-		
-		if (dim >= vines.size())
-		{
-			AssertMsg(dim == vines.size(), "New dimension has to be contiguous");
-			vines.push_back(VineList());
+    AssertMsg(evaluator != 0, "Cannot start vines with a null evaluator");
+    for (Iterator cur = bg; cur != end; ++cur)
+    {
+        if (!cur->sign()) continue;
+        Dimension dim = evaluator->dimension(cur);
+        
+        if (dim >= vines.size())
+        {
+            AssertMsg(dim == vines.size(), "New dimension has to be contiguous");
+            vines.push_back(VineList());
             vines_vector.push_back(boost::prior(vines.end()));
-		}
+        }
 
-		start_vine(cur);
-		record_knee(cur);
-	}
+        start_vine(cur);
+        record_knee(cur);
+    }
 }
 
-template<class FS>
+template<class I, class It, class E>
 void
-Vineyard<FS>::
+Vineyard<I,It,E>::
 switched(Index i, Index j)
 {
-	VineS* i_vine = i->vine();
-	VineS* j_vine = j->vine();
-	i->set_vine(j_vine);
-	j->set_vine(i_vine);
+    rLog(rlVineyard, "Switching vines");
+
+    Vine* i_vine = i->vine();
+    Vine* j_vine = j->vine();
+    i->set_vine(j_vine);
+    j->set_vine(i_vine);
+
+    // rLog(rlVineyard, "  %x %x %x %x", i->pair, i->pair->pair, j->pair, j->pair->pair);
+    // rLog(rlVineyard, "  %x %x %x %x", i_vine, i->pair->vine(), j_vine, j->pair->vine());
 
-	// Since the pairing has already been updated, the following assertions should be true
-	AssertMsg(i->vine() == i->pair()->vine(), "i's vine must match the vine of its pair");
-	AssertMsg(j->vine() == j->pair()->vine(), "j's vine must match the vine of its pair");
+    // Since the pairing has already been updated, the following assertions should be true
+    AssertMsg(i->vine() == i->pair->vine(), "i's vine must match the vine of its pair");
+    AssertMsg(j->vine() == j->pair->vine(), "j's vine must match the vine of its pair");
 
-	if (!i->sign()) i = i->pair();
-	if (!j->sign()) j = j->pair();
-	record_knee(i);
-	record_knee(j);
+    if (!i->sign()) i = i->pair;
+    if (!j->sign()) j = j->pair;
+
+    // std::cout << "i sign: " << i->sign() << std::endl;
+    // std::cout << "j sign: " << j->sign() << std::endl;
+
+    record_knee(i);
+    record_knee(j);
 }
 
-template<class FS>
+template<class I, class It, class E>
+template<class Iter>
 void
-Vineyard<FS>::
-start_vine(Index i)
+Vineyard<I,It,E>::
+start_vine(Iter i)
 {
-	rLog(rlVineyard, "Starting new vine");
-	AssertMsg(i->sign(), "Can only start vines for positive simplices");
-		
-	Dimension dim = i->dimension();
-	vines_vector[dim]->push_back(VineS());
-	i->set_vine(&vines_vector[dim]->back());
-	i->pair()->set_vine(i->vine());
+    rLog(rlVineyard, "Starting new vine");
+    AssertMsg(i->sign(), "Can only start vines for positive simplices");
+        
+    Dimension dim = evaluator->dimension(i);
+    vines_vector[dim]->push_back(Vine());
+    i->set_vine(&vines_vector[dim]->back());
+    i->pair->set_vine(i->vine());
 }
-	
+    
 /// Records the current diagram in the vineyard
-template<class FS>
+template<class I, class It, class E>
 void 
-Vineyard<FS>::
-record_diagram(Index bg, Index end)
+Vineyard<I,It,E>::
+record_diagram(Iterator bg, Iterator end)
 {
-	rLog(rlVineyard, "Entered: record_diagram()");
-	AssertMsg(evaluator != 0, "Cannot record diagram with a null evaluator");
-	
-	for (Index i = bg; i != end; ++i)
-	{
-		AssertMsg(i->vine() != 0, "Cannot process a null vine in record_diagram");
-		if (!i->sign())		continue;
-		record_knee(i);
-	}
+    rLog(rlVineyard, "Entered: record_diagram()");
+    AssertMsg(evaluator != 0, "Cannot record diagram with a null evaluator");
+    
+    for (Iterator i = bg; i != end; ++i)
+    {
+        AssertMsg(i->vine() != 0, "Cannot process a null vine in record_diagram");
+        if (!i->sign())     continue;
+        record_knee(i);
+    }
 }
 
 
-template<class FS>
-void			
-Vineyard<FS>::
-save_edges(const std::string& filename) const
+template<class I, class It, class E>
+void            
+Vineyard<I,It,E>::
+save_edges(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() + ".edg";
-		std::ofstream out(fn.c_str());
-		for (typename VineList::const_iterator vi = vines_vector[i]->begin(); vi != vines_vector[i]->end(); ++vi)
-			for (typename VineS::const_iterator ki = vi->begin(), kiprev = ki++; ki != vi->end(); kiprev = ki++)
-			{
-				if (kiprev->is_infinite() || ki->is_infinite()) continue;
-				out << kiprev->birth << ' ' << kiprev->death << ' ' << kiprev->time << std::endl;
-				out << ki->birth << ' ' << ki->death << ' ' << ki->time << std::endl;
-			}
-		out.close();
-	}
+    for (unsigned int i = 0; i < vines_vector.size(); ++i)
+    {
+        std::ostringstream os; os << i;
+        std::string fn = filename + os.str() + ".edg";
+        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(), kiprev = ki++; ki != vi->end(); kiprev = ki++)
+            {
+                if (skip_infinite && (kiprev->is_infinite() || ki->is_infinite()))
+                {
+                    std::cerr << "Warning: skipping an infinite knee in save_edges() in dimension " << i << std::endl;
+                    continue;
+                }
+                out << kiprev->birth << ' ' << kiprev->death << ' ' << kiprev->time << std::endl;
+                out << ki->birth << ' ' << ki->death << ' ' << ki->time << std::endl;
+            }
+        out.close();
+    }
 }
 
 /// Records a knee for the given simplex
-template<class FS>
+template<class I, class It, class E>
+template<class Iter>
 void
-Vineyard<FS>::
-record_knee(Index i)
+Vineyard<I,It,E>::
+record_knee(Iter i)
 {
-	rLog(rlVineyard, "Entered record_knee()");
-	AssertMsg(evaluator != 0, "Cannot record knee with a null evaluator");
-	AssertMsg(i->vine() != 0, "Cannot add a knee to a null vine");
-	AssertMsg(i->sign(), "record_knee() must be called on a positive simplex");
-	
-	if (!i->is_paired())
-		i->vine()->add(evaluator->value(*i), Infinity, evaluator->time());
-	else
-	{
-		rLog(rlVineyard, "Creating knee");
-		KneeS k(evaluator->value(*i), evaluator->value(*(i->pair())), evaluator->time());
-		rLog(rlVineyard, "Knee created: %s", tostring(k).c_str());
+    rLog(rlVineyard, "Entered record_knee()");
+    AssertMsg(evaluator != 0, "Cannot record knee with a null evaluator");
+    AssertMsg(i->vine() != 0, "Cannot add a knee to a null vine");
+    AssertMsg(i->sign(), "record_knee() must be called on a positive simplex");
+    
+    if (i->unpaired())
+        i->vine()->add((*evaluator)(i), Infinity, evaluator->time());
+    else
+    {
+        rLog(rlVineyard, "Creating knee");
+        Knee k((*evaluator)(i), (*evaluator)((i->pair)), evaluator->time());
+        rLog(rlVineyard, "Knee created: %s", tostring(k).c_str());
         rLog(rlVineyard, "Vine: %s", tostring(*(i->vine())).c_str());
 
-		if (!k.is_diagonal() || i->vine()->empty())			// non-diagonal k, or empty vine
-		{
-			rLog(rlVineyard, "Extending a vine");
-			i->vine()->add(k);
-		}
-		else if (i->vine()->back().is_diagonal())			// last knee is diagonal
-		{
-			AssertMsg(i->vine()->size() == 1, "Only first knee may be diagonal for a live vine");
-			rLog(rlVineyard, "Overwriting first diagonal knee");
-			i->vine()->back() = k;
-		} else												// finish this vine
-		{
-			rLog(rlVineyard, "Finishing a vine");
-			i->vine()->add(k);
-			start_vine(i);
-			i->vine()->add(k);
-		}
-	}
-	
-	i->vine()->back().set_cycle(resolve_cycle(i));
-	rLog(rlVineyard, "Leaving record_knee()");
+        if (!k.is_diagonal() || i->vine()->empty())         // non-diagonal k, or empty vine
+        {
+            rLog(rlVineyard, "Extending a vine");
+            i->vine()->add(k);
+        }
+        else if (i->vine()->back().is_diagonal())           // last knee is diagonal
+        {
+            AssertMsg(i->vine()->size() == 1, "Only first knee may be diagonal for a live vine");
+            rLog(rlVineyard, "Overwriting first diagonal knee");
+            i->vine()->back() = k;
+        } else                                              // finish this vine
+        {
+            rLog(rlVineyard, "Finishing a vine");
+            i->vine()->add(k);
+            start_vine(i);
+            i->vine()->add(k);
+        }
+    }
+    
+    rLog(rlVineyard, "Leaving record_knee()");
 }
-
-template<class FS>
-typename Vineyard<FS>::KneeS::SimplexList  
-Vineyard<FS>::
-resolve_cycle(Index i) const
-{
-	rLog(rlVineyard, "Entered resolve_cycle");
-	const Cycle& cycle = i->cycle();
-	
-	// Resolve simplices
-	typename KneeS::SimplexList lst;
-	for (typename Cycle::const_iterator cur = cycle.begin(); cur != cycle.end(); ++cur)
-		lst.push_back(**cur);
-
-	return lst;
-}
--- a/include/utilities/indirect.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/utilities/indirect.h	Wed Dec 16 15:39:06 2009 -0800
@@ -7,6 +7,9 @@
 
 // TODO: write documentation
 
+/**************
+ * Comparison *
+ **************/
 
 template<class Comparison_>
 struct IndirectComparison
@@ -64,6 +67,27 @@
     }
 };
 
+template<class Evaluator_>
+class ThroughEvaluatorComparison
+{
+    public:
+        typedef                 Evaluator_                                                  Evaluator;
+
+                                ThroughEvaluatorComparison(const Evaluator& eval): 
+                                    eval_(eval)                                             {}
+
+        template<class T>                            
+        bool                    operator()(T a, T b) const                                  { return (eval_(a) < eval_(b)); }
+
+    private:
+        const Evaluator&        eval_;
+};
+
+
+/*************
+ * Iterators *
+ *************/
+
 // Iterates over the difference of the two sorted sequences, dereferencing into the first sequence
 template<class Iterator1, class Iterator2, class StrictWeakOrdering>
 class difference_iterator: public boost::iterator_facade<difference_iterator<Iterator1, Iterator2, StrictWeakOrdering>,
--- a/include/utilities/property-maps.h	Tue Jul 28 13:27:13 2009 -0700
+++ b/include/utilities/property-maps.h	Wed Dec 16 15:39:06 2009 -0800
@@ -1,7 +1,7 @@
 #ifndef __PROPERTY_MAPS_H__
 #define __PROPERTY_MAPS_H__
 
-#include <boost/property_map.hpp>
+#include <boost/property_map/property_map.hpp>
 #include <boost/iterator/iterator_traits.hpp>
 #include <algorithm>
 #include "utilities/log.h"
@@ -106,6 +106,46 @@
 { return OffsetMap<From_, To_>(bg_from, bg_to); }
 
 
+template<class From_, class To_, class FromIndex_, class ToIndex_>
+struct OffsetBeginMap
+{
+    typedef             From_                                                   From;
+    typedef             To_                                                     To;
+    typedef             FromIndex_                                              key_type;
+    typedef             ToIndex_                                                value_type;
+
+                        OffsetBeginMap(const From& from, const To& to):
+                            from_(from), to_(to)                                {}
+                        
+    value_type          operator[](key_type i) const                            { return to_.begin() + (i - from_.begin()); }
+
+    const From&         from() const                                            { return from_; }
+    const To&           to() const                                              { return to_; }
+    
+    private:
+                  const From&                                                   from_;
+                  const To&                                                     to_;
+};
+
+
+/* ChainMap */
+template<class Map1, class Map2>
+class ChainMap
+{
+    public:
+        typedef         typename Map1::key_type                                 key_type;
+        typedef         typename Map2::value_type                               value_type;
+
+
+                        ChainMap(const Map1& m1, const Map2& m2): 
+                            m1_(m1), m2_(m2)                                    {}
+        value_type      operator[](const key_type& k) const                     { return m2_[m1_[k]]; }
+
+    private:
+        const Map1&     m1_;
+        const Map2&     m2_;
+};
+
 /* ThroughMap */
 template<class Functor_, class Map_>
 class ThroughMap
@@ -115,7 +155,7 @@
         typedef                 Functor_                                        Functor;
 
         typedef                 typename Functor::result_type                   result_type;
-        typedef                 typename Map::key_type                          first_argument_type;
+        typedef                 typename Map_::key_type                         first_argument_type;
 
                                 ThroughMap(const Map&       map,
                                            const Functor&   functor):