--- a/README Wed Aug 15 11:25:35 2007 -0400
+++ b/README Wed Aug 15 11:39:34 2007 -0400
@@ -5,6 +5,7 @@
boost - great set of C++ libraries
Doxygen - for building documentation
libcwd - for debugging only (is not needed by default)
+ synaps - for solving polynomial (for kinetic kernel), which in turn requires GMP
Configuration
The path to CGAL's Makefile is expected to be set in $CGAL_MAKEFILE, the rest
--- a/examples/CMakeLists.txt Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/CMakeLists.txt Wed Aug 15 11:39:34 2007 -0400
@@ -1,4 +1,5 @@
add_subdirectory (alphashapes)
add_subdirectory (ar-vineyard)
+add_subdirectory (cech-complex)
add_subdirectory (grid)
add_subdirectory (triangle)
--- a/examples/alphashapes/alpharadius.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/alphashapes/alpharadius.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -1,8 +1,8 @@
-#include <sys.h>
-#include <debug.h>
+#include <utilities/sys.h>
+#include <utilities/debug.h>
#include "alphashapes3d.h"
-#include <filtration.h>
+#include <topology/filtration.h>
#include <iostream>
#include <fstream>
--- a/examples/alphashapes/alphashapes3d.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/alphashapes/alphashapes3d.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -1,8 +1,8 @@
-#include <sys.h>
-#include <debug.h>
+#include <utilities/sys.h>
+#include <utilities/debug.h>
#include "alphashapes3d.h"
-#include <filtration.h>
+#include <topology/filtration.h>
#include <iostream>
#include <fstream>
--- a/examples/alphashapes/alphashapes3d.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/alphashapes/alphashapes3d.h Wed Aug 15 11:39:34 2007 -0400
@@ -9,8 +9,8 @@
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Delaunay_triangulation_3.h>
-#include <simplex.h>
-#include <types.h>
+#include <topology/simplex.h>
+#include <utilities/types.h>
#include <vector>
#include <set>
--- a/examples/ar-vineyard/ar-simplex3d.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/ar-vineyard/ar-simplex3d.h Wed Aug 15 11:39:34 2007 -0400
@@ -11,8 +11,8 @@
//#include <CGAL/Kernel/global_functions_3.h> // FIXME: what do we include for circumcenter?
#include <CGAL/squared_distance_3.h>
-#include <simplex.h>
-#include <types.h>
+#include <topology/simplex.h>
+#include <utilities/types.h>
#include <vector>
#include <set>
--- a/examples/ar-vineyard/ar-vineyard.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/ar-vineyard/ar-vineyard.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -1,5 +1,5 @@
-#include <sys.h>
-#include <debug.h>
+#include <utilities/sys.h>
+#include <utilities/debug.h>
#include "ar-vineyard.h"
--- a/examples/ar-vineyard/ar-vineyard.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/ar-vineyard/ar-vineyard.h Wed Aug 15 11:39:34 2007 -0400
@@ -6,11 +6,11 @@
#ifndef __AR_VINEYARD_H__
#define __AR_VINEYARD_H__
-#include "sys.h"
-#include "debug.h"
+#include "utilities/sys.h"
+#include "utilities/debug.h"
-#include "conesimplex.h"
-#include "filtration.h"
+#include "topology/conesimplex.h"
+#include "topology/filtration.h"
#include <CGAL/Kinetic/Inexact_simulation_traits_1.h>
#include <CGAL/Kinetic/Sort.h>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/cech-complex/CMakeLists.txt Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,7 @@
+set (targets
+ cech-complex)
+
+foreach (t ${targets})
+ add_executable (${t} ${t}.cpp ${external_sources})
+ target_link_libraries (${t} ${libraries} ${cgal_libraries})
+endforeach (t ${targets})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/cech-complex/Miniball_dynamic_d.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,581 @@
+// Copright (C) 1999-2006, Bernd Gaertner
+// $Revision: 1.3 $
+// $Date: 2006/11/16 08:01:52 $
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA,
+// or download the License terms from prep.ai.mit.edu/pub/gnu/COPYING-2.0.
+//
+// Contact:
+// --------
+// Bernd Gaertner
+// Institute of Theoretical Computer Science
+// ETH Zuerich
+// CAB G32.2
+// CH-8092 Zuerich, Switzerland
+// http://www.inf.ethz.ch/personal/gaertner
+
+#include <cstdlib>
+#include <cassert>
+#include <cmath>
+#include <iostream>
+#include <list>
+
+// Functions
+// =========
+inline double mb_sqr (double r) {return r*r;}
+
+// Class Declarations
+// ==================
+
+// smallest enclosing ball of a set of n points in dimension d
+class Miniball;
+
+// smallest ball with a set of n <= d+1 points *on the boundary*
+class Miniball_b;
+
+// point in dimension d
+class Point;
+
+
+// Class Definitions
+// =================
+
+// Miniball_b
+// ----------
+class Miniball_b {
+private:
+
+ // data members
+ int d; // dimension
+ int m, s; // size and number of support points
+ double* q0;
+
+ double* z;
+ double* f;
+ double** v;
+ double** a;
+
+ double** c;
+ double* sqr_r;
+
+ double* current_c; // refers to some c[j]
+ double current_sqr_r;
+
+ // if you want the copy constructor and assignment operator, please
+ // properly implement them yourself. The default copy/assignment
+ // semantics fails since a Miniball_b object stores pointers to
+ // dynamically allocated memory
+ Miniball_b (const Miniball_b& mb);
+ Miniball_b& operator=(const Miniball_b& mb);
+
+public:
+ Miniball_b(int dim)
+ : d(dim)
+ {
+ q0 = new double[d];
+ z = new double[d+1];
+ f = new double[d+1];
+ v = new double*[d+1];
+ for (int i=0; i<d+1; ++i) v[i] = new double[d];
+ a = new double*[d+1];
+ for (int i=0; i<d+1; ++i) a[i] = new double[d];
+ c = new double*[d+1];
+ for (int i=0; i<d+1; ++i) c[i] = new double[d];
+ sqr_r = new double[d+1];
+ reset();
+ }
+
+ ~Miniball_b()
+ {
+ delete[] sqr_r;
+ for (int i=0; i<d+1; ++i) delete[] c[i];
+ delete[] c;
+ for (int i=0; i<d+1; ++i) delete[] a[i];
+ delete[] a;
+ for (int i=0; i<d+1; ++i) delete[] v[i];
+ delete[] v;
+ delete[] f;
+ delete[] z;
+ delete[] q0;
+ }
+
+ // access
+ const double* center() const;
+ double squared_radius() const;
+ int size() const;
+ int support_size() const;
+ double excess (const Point& p) const;
+
+ // modification
+ void reset(); // generates empty sphere with m=s=0
+ bool push (const Point& p);
+ void pop ();
+
+ // checking
+ double slack() const;
+};
+
+// Miniball
+// --------
+class Miniball {
+public:
+ // types
+ typedef std::list<Point>::iterator It;
+ typedef std::list<Point>::const_iterator Cit;
+
+private:
+ // data members
+ int d; // dimension
+ std::list<Point> L; // internal point set
+ Miniball_b B; // the current ball
+ It support_end; // past-the-end iterator of support set
+
+ // private methods
+ void mtf_mb (It k);
+ void pivot_mb (It k);
+ void move_to_front (It j);
+ double max_excess (It t, It i, It& pivot) const;
+
+public:
+ // creates an empty ball
+ Miniball(int dim) : d(dim), B(dim) {}
+
+ // copies p to the internal point set
+ void check_in (const Point& p);
+
+ // builds the smallest enclosing ball of the internal point set
+ void build ();
+
+ // returns center of the ball (undefined if ball is empty)
+ Point center() const;
+
+ // returns squared_radius of the ball (-1 if ball is empty)
+ double squared_radius () const;
+
+ // returns size of internal point set
+ int nr_points () const;
+
+ // returns begin- and past-the-end iterators for internal point set
+ Cit points_begin () const;
+ Cit points_end () const;
+
+ // returns size of support point set; this set has the following properties:
+ // - there are at most d+1 support points,
+ // - all support points are on the boundary of the computed ball, and
+ // - the smallest enclosing ball of the support point set equals the
+ // smallest enclosing ball of the internal point set
+ int nr_support_points () const;
+
+ // returns begin- and past-the-end iterators for internal point set
+ Cit support_points_begin () const;
+ Cit support_points_end () const;
+
+ // assesses the quality of the computed ball. The return value is the
+ // maximum squared distance of any support point or point outside the
+ // ball to the boundary of the ball, divided by the squared radius of
+ // the ball. If everything went fine, this will be less than e-15 and
+ // says that the computed ball approximately contains all the internal
+ // points and has all the support points on the boundary.
+ //
+ // The slack parameter that is set by the method says something about
+ // whether the computed ball is really the *smallest* enclosing ball
+ // of the support points; if everything went fine, this value will be 0;
+ // a positive value may indicate that the ball is not smallest possible,
+ // with the deviation from optimality growing with the slack
+ double accuracy (double& slack) const;
+
+ // returns true if the accuracy is below the given tolerance and the
+ // slack is 0
+ bool is_valid (double tolerance = 1e-15) const;
+};
+
+// Point (inline)
+// --------------
+
+class Point {
+private:
+ int d;
+ double* coord;
+
+public:
+ // default
+ Point(int dim)
+ : d (dim), coord(new double[dim])
+ {}
+
+ ~Point ()
+ {
+ delete[] coord;
+ }
+
+ // copy from Point
+ Point (const Point& p)
+ : d (p.dim()), coord(new double[p.dim()])
+ {
+ for (int i=0; i<d; ++i)
+ coord[i] = p.coord[i];
+ }
+
+ // copy from double*
+ Point (int dim, const double* p)
+ : d (dim), coord(new double[dim])
+ {
+ for (int i=0; i<d; ++i)
+ coord[i] = p[i];
+ }
+
+ // assignment
+ Point& operator = (const Point& p)
+ {
+ assert (d == p.dim());
+ if (this != &p)
+ for (int i=0; i<d; ++i)
+ coord[i] = p.coord[i];
+ return *this;
+ }
+
+ // coordinate access
+ double& operator [] (int i)
+ {
+ return coord[i];
+ }
+ const double& operator [] (int i) const
+ {
+ return coord[i];
+ }
+ const double* begin() const
+ {
+ return coord;
+ }
+ const double* end() const
+ {
+ return coord+d;
+ }
+
+ // dimension access
+ int dim() const
+ {
+ return d;
+ }
+};
+
+
+// Class Implementations
+// =====================
+
+// Miniball
+// --------
+
+
+void Miniball::check_in (const Point& p)
+{
+ assert (d == p.dim());
+ L.push_back(p);
+}
+
+void Miniball::build ()
+{
+ B.reset();
+ support_end = L.begin();
+ pivot_mb (L.end());
+}
+
+
+
+void Miniball::mtf_mb (It i)
+{
+ support_end = L.begin();
+ if ((B.size())==d+1) return;
+ for (It k=L.begin(); k!=i;) {
+ It j=k++;
+ if (B.excess(*j) > 0) {
+ if (B.push(*j)) {
+ mtf_mb (j);
+ B.pop();
+ move_to_front(j);
+ }
+ }
+ }
+}
+
+
+void Miniball::move_to_front (It j)
+{
+ if (support_end == j)
+ support_end++;
+ L.splice (L.begin(), L, j);
+}
+
+
+
+void Miniball::pivot_mb (It i)
+{
+ It t = ++L.begin();
+ mtf_mb (t);
+ double max_e, old_sqr_r = -1;
+ do {
+ It pivot;
+ max_e = max_excess (t, i, pivot);
+ if (max_e > 0) {
+ t = support_end;
+ if (t==pivot) ++t;
+ old_sqr_r = B.squared_radius();
+ B.push (*pivot);
+ mtf_mb (support_end);
+ B.pop();
+ move_to_front (pivot);
+ }
+ } while ((max_e > 0) && (B.squared_radius() > old_sqr_r));
+}
+
+
+
+double Miniball::max_excess (It t, It i, It& pivot) const
+{
+ const double *c = B.center(), sqr_r = B.squared_radius();
+ double e, max_e = 0;
+ for (It k=t; k!=i; ++k) {
+ const double *p = (*k).begin();
+ e = -sqr_r;
+ for (int j=0; j<d; ++j)
+ e += mb_sqr(p[j]-c[j]);
+ if (e > max_e) {
+ max_e = e;
+ pivot = k;
+ }
+ }
+ return max_e;
+}
+
+
+
+
+Point Miniball::center () const
+{
+ return Point(d, B.center());
+}
+
+
+double Miniball::squared_radius () const
+{
+ return B.squared_radius();
+}
+
+
+
+int Miniball::nr_points () const
+{
+ return L.size();
+}
+
+
+Miniball::Cit Miniball::points_begin () const
+{
+ return L.begin();
+}
+
+
+Miniball::Cit Miniball::points_end () const
+{
+ return L.end();
+}
+
+int Miniball::nr_support_points () const
+{
+ return B.support_size();
+}
+
+
+Miniball::Cit Miniball::support_points_begin () const
+{
+ return L.begin();
+}
+
+
+Miniball::Cit Miniball::support_points_end () const
+{
+ return support_end;
+}
+
+double Miniball::accuracy (double& slack) const
+{
+ double e, max_e = 0;
+ int n_supp=0;
+ Cit i;
+ for (i=L.begin(); i!=support_end; ++i,++n_supp)
+ if ((e = std::abs (B.excess (*i))) > max_e)
+ max_e = e;
+
+ // you've found a non-numerical problem if the following ever fails
+ assert (n_supp == nr_support_points());
+
+ for (i=support_end; i!=L.end(); ++i)
+ if ((e = B.excess (*i)) > max_e)
+ max_e = e;
+
+ slack = B.slack();
+ return (max_e/squared_radius());
+}
+
+
+bool Miniball::is_valid (double tolerance) const
+{
+ double slack;
+ return ( (accuracy (slack) < tolerance) && (slack == 0) );
+}
+
+// Miniball_b
+// ----------
+
+
+const double* Miniball_b::center () const
+{
+ return current_c;
+}
+
+
+double Miniball_b::squared_radius() const
+{
+ return current_sqr_r;
+}
+
+
+int Miniball_b::size() const
+{
+ return m;
+}
+
+
+int Miniball_b::support_size() const
+{
+ return s;
+}
+
+
+double Miniball_b::excess (const Point& p) const
+{
+ double e = -current_sqr_r;
+ for (int k=0; k<d; ++k)
+ e += mb_sqr(p[k]-current_c[k]);
+ return e;
+}
+
+
+
+
+void Miniball_b::reset ()
+{
+ m = s = 0;
+ // we misuse c[0] for the center of the empty sphere
+ for (int j=0; j<d; ++j)
+ c[0][j]=0;
+ current_c = c[0];
+ current_sqr_r = -1;
+}
+
+
+void Miniball_b::pop ()
+{
+ --m;
+}
+
+
+
+bool Miniball_b::push (const Point& p)
+{
+ int i, j;
+ double eps = 1e-32;
+ if (m==0) {
+ for (i=0; i<d; ++i)
+ q0[i] = p[i];
+ for (i=0; i<d; ++i)
+ c[0][i] = q0[i];
+ sqr_r[0] = 0;
+ } else {
+ // set v_m to Q_m
+ for (i=0; i<d; ++i)
+ v[m][i] = p[i]-q0[i];
+
+ // compute the a_{m,i}, i< m
+ for (i=1; i<m; ++i) {
+ a[m][i] = 0;
+ for (j=0; j<d; ++j)
+ a[m][i] += v[i][j] * v[m][j];
+ a[m][i]*=(2/z[i]);
+ }
+
+ // update v_m to Q_m-\bar{Q}_m
+ for (i=1; i<m; ++i) {
+ for (j=0; j<d; ++j)
+ v[m][j] -= a[m][i]*v[i][j];
+ }
+
+ // compute z_m
+ z[m]=0;
+ for (j=0; j<d; ++j)
+ z[m] += mb_sqr(v[m][j]);
+ z[m]*=2;
+
+ // reject push if z_m too small
+ if (z[m]<eps*current_sqr_r) {
+ return false;
+ }
+
+ // update c, sqr_r
+ double e = -sqr_r[m-1];
+ for (i=0; i<d; ++i)
+ e += mb_sqr(p[i]-c[m-1][i]);
+ f[m]=e/z[m];
+
+ for (i=0; i<d; ++i)
+ c[m][i] = c[m-1][i]+f[m]*v[m][i];
+ sqr_r[m] = sqr_r[m-1] + e*f[m]/2;
+ }
+ current_c = c[m];
+ current_sqr_r = sqr_r[m];
+ s = ++m;
+ return true;
+}
+
+
+double Miniball_b::slack () const
+{
+ double l[d+1], min_l=0;
+ l[0] = 1;
+ for (int i=s-1; i>0; --i) {
+ l[i] = f[i];
+ for (int k=s-1; k>i; --k)
+ l[i]-=a[k][i]*l[k];
+ if (l[i] < min_l) min_l = l[i];
+ l[0] -= l[i];
+ }
+ if (l[0] < min_l) min_l = l[0];
+ return ( (min_l < 0) ? -min_l : 0);
+}
+
+// Point
+// -----
+
+// Output
+
+std::ostream& operator << (std::ostream& os, const Point& p)
+{
+ os << "(";
+ int d = p.dim();
+ for (int i=0; i<d-1; ++i)
+ os << p[i] << ", ";
+ os << p[d-1] << ")";
+ return os;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/cech-complex/cech-complex.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,129 @@
+#include <utilities/sys.h>
+#include <utilities/debug.h>
+
+#include <topology/simplex.h>
+#include <topology/filtration.h>
+#include "Miniball_dynamic_d.h"
+#include <algorithm>
+
+#include <iostream>
+#include <fstream>
+
+
+typedef std::vector<Point> PointContainer;
+typedef unsigned int PointIndex;
+typedef SimplexWithValue<PointIndex> Simplex;
+typedef std::vector<Simplex> SimplexVector;
+typedef Filtration<Simplex> CechFiltration;
+
+class DimensionValueComparison
+{
+ public:
+ bool operator()(const Simplex& s1, const Simplex& s2) const
+ {
+ if (s1.dimension() == s2.dimension())
+ return s1.get_value() < s2.get_value();
+ else
+ return s1.dimension() < s2.dimension();
+ }
+};
+
+int choose(int n, int k)
+{
+ if (k > n/2) k = n-k;
+ int numerator = 1, denominator = 1;
+ for (int i = 0; i < k; ++i)
+ { numerator *= (n-i); denominator *= (i+1); }
+ return numerator/denominator;
+}
+
+void add_simplices(SimplexVector& sv, int d, const PointContainer& points)
+{
+ PointIndex indices[d+1];
+ for (int i = 0; i < d+1; ++i)
+ indices[i] = d - i;
+
+ while(indices[d] < points.size() - d)
+ {
+ // Add simplex
+ Miniball mb(points[indices[0]].dim());
+ Simplex s;
+ for (int i = 0; i < d+1; ++i)
+ {
+ s.add(indices[i]);
+ mb.check_in(points[indices[i]]);
+ }
+ mb.build();
+ s.set_value(mb.squared_radius());
+ sv.push_back(s);
+
+
+ // Advance indices
+ for (int i = 0; i < d+1; ++i)
+ {
+ ++indices[i];
+ if (indices[i] < points.size() - i)
+ {
+ for (int j = i-1; j >= 0; --j)
+ indices[j] = indices[j+1] + 1;
+ break;
+ }
+ }
+ }
+}
+
+int main(int argc, char** argv)
+{
+ // Read in the point set and compute its Delaunay triangulation
+ std::istream& in = std::cin;
+ int ambient_d, homology_d;
+ in >> ambient_d >> homology_d;
+
+ std::cout << "Ambient dimension: " << ambient_d << std::endl;
+ std::cout << "Will compute PD up to dimension: " << homology_d << std::endl;
+
+ // Read points
+ PointContainer points;
+ while(in)
+ {
+ Point p(ambient_d);
+ for (int i = 0; i < ambient_d; ++i)
+ in >> p[i];
+ points.push_back(p);
+ }
+ std::cout << "Points read: " << points.size() << std::endl;
+
+ // Compute Cech values
+ CechFiltration cf;
+ { // resource acquisition is initialization
+ 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);
+ std::cout << "Reserved SimplexVector of size: " << num_simplices << std::endl;
+
+ for (int i = 0; i <= homology_d + 1; ++i)
+ add_simplices(sv, i, points);
+ std::cout << "Size of SimplexVector: " << sv.size() << std::endl;
+
+ std::sort(sv.begin(), sv.end(), DimensionValueComparison());
+
+ for (SimplexVector::const_iterator cur = sv.begin(); cur != sv.end(); ++cur)
+ cf.append(*cur);
+ }
+
+ // Compute persistence
+ cf.fill_simplex_index_map();
+ cf.pair_simplices(cf.begin(), cf.end());
+ std::cout << "Simplices paired" << std::endl;
+
+ for (CechFiltration::Index i = cf.begin(); i != cf.end(); ++i)
+ if (i->is_paired())
+ {
+ if (i->sign())
+ std::cout << i->dimension() << " " << i->get_value() << " " << i->pair()->get_value() << std::endl;
+ } //else std::cout << i->value() << std::endl;
+
+}
+
--- a/examples/grid/combustion-vineyard.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/grid/combustion-vineyard.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -3,8 +3,8 @@
* Department of Computer Science, Duke University, 2005
*/
-#include <sys.h>
-#include <debug.h>
+#include <utilities/sys.h>
+#include <utilities/debug.h>
#include <iostream>
#include <fstream>
--- a/examples/grid/grid2D.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/grid/grid2D.h Wed Aug 15 11:39:34 2007 -0400
@@ -18,7 +18,7 @@
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/nvp.hpp>
-#include "types.h"
+#include "utilities/types.h"
#include <boost/serialization/export.hpp>
--- a/examples/grid/grid2Dvineyard.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/grid/grid2Dvineyard.h Wed Aug 15 11:39:34 2007 -0400
@@ -6,11 +6,11 @@
#ifndef __GRID2DVINEYARD_H__
#define __GRID2DVINEYARD_H__
-#include "sys.h"
-#include "debug.h"
+#include "utilities/sys.h"
+#include "utilities/debug.h"
#include "grid2D.h"
-#include "lowerstarfiltration.h"
+#include "topology/lowerstarfiltration.h"
#include <CGAL/Kinetic/Inexact_simulation_traits_1.h>
#include <CGAL/Kinetic/Sort.h>
--- a/examples/grid/pdbdistance-vineyard.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/grid/pdbdistance-vineyard.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -1,6 +1,6 @@
//#include <boost/archive/binary_oarchive.hpp>
-#include "sys.h"
-#include "debug.h"
+#include "utilities/sys.h"
+#include "utilities/debug.h"
#include "pdbdistance.h"
#include "grid2Dvineyard.h"
--- a/examples/grid/pdbdistance.h Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/grid/pdbdistance.h Wed Aug 15 11:39:34 2007 -0400
@@ -16,7 +16,7 @@
#include <boost/serialization/access.hpp>
-#include "types.h"
+#include "utilities/types.h"
#include "grid2D.h"
#include <boost/serialization/export.hpp>
--- a/examples/triangle/triangle.cpp Wed Aug 15 11:25:35 2007 -0400
+++ b/examples/triangle/triangle.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -1,5 +1,5 @@
-#include "filtration.h"
-#include "simplex.h"
+#include "topology/filtration.h"
+#include "topology/simplex.h"
#include <vector>
#include <iostream>
--- a/include/circular_list.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/**
- * Singly-linked circular list implementation by Donovan Rebbechi <elflord@pegasus.rutgers.edu>.
- * Tiny modifications by DM to make ISO C++ compliant (i.e., so that the compiler stops complaining),
- * added size(), and boost serialization
- */
-
-#ifndef __CIRCULAR_LIST_H__
-#define __CIRCULAR_LIST_H__
-
-#include <iterator>
-
-#include <boost/serialization/access.hpp>
-#include <boost/serialization/split_member.hpp>
-#include <boost/serialization/nvp.hpp>
-#include <boost/serialization/binary_object.hpp>
-
-#include "types.h"
-
-
-template <class T>
-class List
-{
- struct Node
- {
- Node(const T& x,Node* y = 0):m_data(x),m_next(y){}
- T m_data;
- Node* m_next;
-
- private:
- // Serialization
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type )
- {
- ar & make_nvp("data", m_data);
- ar & make_nvp("next", m_next);
- }
- };
-
- Node* m_node;
- size_t sz;
-
- private:
- // Serialization
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type )
- { ar & make_nvp("root", m_node); }
-
-public:
- class const_iterator;
-
- class iterator
- : public std::iterator<std::forward_iterator_tag, T>
- {
- Node* m_rep;
- public:
- friend class List;
- friend class const_iterator;
- typedef T value_type;
- typedef T& reference;
- typedef T* pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- inline iterator(Node* x=0):m_rep(x){}
- inline iterator(const iterator& x):m_rep(x.m_rep) {}
- inline iterator(const const_iterator& x):m_rep(const_cast<Node*>(x.m_rep)) {} // not very safe
- inline iterator& operator=(const iterator& x)
- {
- m_rep=x.m_rep; return *this;
- }
- inline iterator& operator++()
- {
- m_rep = m_rep->m_next; return *this;
- }
- inline iterator operator++(int)
- {
- iterator tmp(*this); m_rep = m_rep->m_next; return tmp;
- }
- inline reference operator*() const { return m_rep->m_next->m_data; }
- inline pointer operator->() const { return m_rep->m_next; }
- inline bool operator==(const iterator& x) const
- {
- return m_rep == x.m_rep;
- }
- inline bool operator!=(const iterator& x) const
- {
- return m_rep != x.m_rep;
- }
-
- };
-
- class const_iterator
- : public std::iterator<std::forward_iterator_tag, const T>
- {
- const Node* m_rep;
- public:
- friend class List;
- friend class iterator;
- typedef T value_type;
- typedef T& reference;
- typedef T* pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
- inline const_iterator(const Node* x=0):m_rep(x){}
- inline const_iterator(const const_iterator& x):m_rep(x.m_rep) {}
- inline const_iterator(const iterator& x):m_rep(x.m_rep){}
- inline const_iterator& operator=(const const_iterator& x)
- {
- m_rep=x.m_rep; return *this;
- }
- inline const_iterator& operator=(const iterator& x)
- {
- m_rep=x.m_rep; return *this;
- }
- inline const_iterator& operator++()
- {
- m_rep = m_rep->m_next; return *this;
- }
- inline const_iterator operator++(int)
- {
- const_iterator tmp(*this); m_rep = m_rep->m_next; return tmp;
- }
- inline reference operator*() const { return m_rep->m_next->m_data; }
- inline pointer operator->() const { return m_rep->m_next; }
- inline bool operator==(const const_iterator& x) const
- {
- return m_rep == x.m_rep;
- }
- inline bool operator!=(const const_iterator& x) const
- {
- return m_rep != x.m_rep;
- }
- };
-
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- List() : m_node(new Node(T())), sz(0) { m_node->m_next = m_node; }
-
- List(const List& L) : m_node(new Node(T())), sz(L.sz)
- {
- m_node->m_next=m_node;
- for ( const_iterator i = L.begin(); i!= L.end(); ++i )
- push_front(*i);
- reverse();
- }
-
- void reverse()
- {
- if (empty())
- return;
- Node* new_m_node = m_node->m_next->m_next;
- Node* p = m_node; Node* i = m_node->m_next; Node* n;
- do
- {
- n = i->m_next;
- i->m_next = p;
- p = i; i = n;
- }
- while (p!=m_node);
- m_node = new_m_node;
- }
-
- void swap(List& x)
- {
- std::swap(m_node, x.m_node);
- std::swap(sz, x.sz);
- }
-
- List& operator=(const List& x)
- {
- List tmp(x);
- swap(tmp);
- return *this;
- }
-
- ~List() { clear(); delete m_node; }
- void clear() { while (!empty()) pop_front(); sz = 0; }
-
-
- inline size_t size() const { return sz; }
-
- inline void push_front(const T&x)
- {
- insert (begin(),x);
- }
- inline void push_back(const T& x)
- {
- insert (end(),x);
- }
- inline void pop_front()
- {
- erase(begin());
- }
- inline bool empty() const { return m_node == m_node->m_next; }
-
- inline T& front() { return *begin(); }
- inline const T& front() const { return *begin(); }
- inline T& back() { return m_node->m_data; }
- inline const T& back() const { return m_node->m_data; }
-
- inline iterator begin() { return iterator(m_node->m_next); }
- inline iterator end() { return iterator(m_node); }
- inline const_iterator begin() const
- {
- return const_iterator(m_node->m_next);
- }
- inline const_iterator end() const
- {
- return const_iterator(m_node);
- }
-
- iterator erase (iterator x)
- {
- if (x == end())
- return x;
-
- if (x.m_rep->m_next == m_node)
- m_node = x.m_rep;
-
- Node* tmp = x.m_rep->m_next;
- x.m_rep->m_next = x.m_rep->m_next->m_next;
- delete tmp;
- --sz;
-
- return x;
- }
-
- iterator insert (iterator x, const T& y)
- {
- Node* tmp = new Node(y,x.m_rep->m_next);
- if (x.m_rep == m_node) // if inserting before end
- m_node = tmp;
- x.m_rep->m_next = tmp;
- ++sz;
-
- return x++; // x points to the new data, return it, and slide it over
- }
-
- // rotate x to beginning
- void rotate (iterator x)
- {
- if (x == end())
- return;
- Node* sentinel = m_node->m_next;
- m_node->m_next = m_node->m_next->m_next;
- sentinel->m_next = x.m_rep->m_next;
- x.m_rep->m_next = sentinel;
- m_node = x.m_rep;
- }
-};
-
-#endif // __CIRCULAR_LIST_H__
--- a/include/conesimplex.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/**
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2007
- */
-
-#ifndef __CONESIMPLEX_H__
-#define __CONESIMPLEX_H__
-
-#include <list>
-#include <iostream>
-
-template<class S>
-class ConeSimplex: public S
-{
- public:
- typedef S Parent;
- typedef ConeSimplex<S> Self;
- typedef std::list<Self> Cycle;
-
- public:
- ConeSimplex(const Parent& parent,
- bool coned = false):
- Parent(parent), coned_(coned) {}
-
- Cycle boundary() const;
- bool coned() const { return coned_; }
-
- std::ostream& operator<<(std::ostream& out) const;
-
- private:
- bool coned_;
-};
-
-template<class S>
-std::ostream& operator<<(std::ostream& out, const ConeSimplex<S>& s) { return s.operator<<(out); }
-
-#include "conesimplex.hpp"
-
-#endif // __CONESIMPLEX_H__
--- a/include/conesimplex.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-template<class S>
-typename ConeSimplex<S>::Cycle
-ConeSimplex<S>::boundary() const
-{
- Cycle bdry;
- typename Parent::Cycle pbdry = Parent::boundary();
-
- for (typename Parent::Cycle::const_iterator cur = pbdry.begin(); cur != pbdry.end(); ++cur)
- bdry.push_back(Self(*cur, coned_));
-
- if (coned_)
- bdry.push_back(Self(*this, false));
-
- return bdry;
-}
-
-template<class S>
-std::ostream&
-ConeSimplex<S>::operator<<(std::ostream& out) const
-{
- Parent::operator<<(out) << ' ';
- if (coned_) out << "[coned]";
- return out;
-}
--- a/include/consistencylist.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2006
- */
-
-#ifndef __CONSISTENCYLIST_H__
-#define __CONSISTENCYLIST_H__
-
-#include "orderlist.h"
-
-#include <iterator>
-#include <iostream>
-#include <list>
-#include "types.h"
-
-#include <boost/utility.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-//#include <boost/type_traits/is_convertible.hpp>
-//#include <boost/utility/enable_if.hpp>
-
-
-template<class T> struct ConsistencyListNode;
-template<class T> class ConsistencyListIterator;
-template<class T> class const_ConsistencyListIterator;
-
-/**
- * ConsistencyList adds consistency order to OrderList which remains unchanged
- * through the lifetime of the list.
- */
-template<class T>
-class ConsistencyList: public OrderList<ConsistencyListNode<T> >
-{
- public:
- class OrderComparison;
- class LessThanComparison;
- class GreaterThanComparison;
- class ConsistencyComparison;
-
- /// \name Comparison types
- /// @{
- // Explicit typedefs for Doxygen
- typedef LessThanComparison LessThanComparison;
- typedef GreaterThanComparison GreaterThanComparison;
- typedef ConsistencyComparison ConsistencyComparison;
- /// @}
-
- typedef ConsistencyListNode<T> NodeType;
- typedef ConsistencyList<T> Self;
- typedef OrderList<NodeType > Parent;
-
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef ConsistencyListIterator<T> iterator;
- typedef const_ConsistencyListIterator<T> const_iterator;
-
- ConsistencyList(): sz(0) {}
- ~ConsistencyList() { clear(); }
-
- /// \name Order operations
- void swap(iterator i, iterator j); ///< Exchanges the order of simplices pointed to by i and j
- template<class BinaryPredicate>
- void sort(BinaryPredicate cmp); ///< Sorts the elements in accordance with cmp
-
- /// \name Container operations
- /// @{
- // Explicit calls instead of using declarations for Doxygen
- iterator push_back(const_reference x);
- iterator insert(iterator predecessor, const_reference x); ///< Inserts x immediately after predecessor (has to be a valid iterator)
- void erase(iterator x) { Parent::erase(x.get_base()); --sz; }
-
- void clear() { return Parent::clear(); }
- bool empty() const { return Parent::empty(); }
- SizeType size() const { return sz; }
- iterator begin() { return iterator(Parent::begin()); }
- const_iterator begin() const { return const_iterator(Parent::begin()); }
- iterator end() { return iterator(Parent::end()); }
- const_iterator end() const { return const_iterator(Parent::end()); }
- reference back() { return Parent::back(); }
- const_reference back() const { return Parent::back(); }
- void pop_back() { return Parent::pop_back(); }
-
- iterator last() { return iterator(boost::prior(end())); }
- const_iterator last() const { return const_iterator(boost::prior(end())); }
- /// @}
-
- private:
- unsigned int sz;
-};
-
-/// Basic comparison that LessThan and GreaterThan derive from
-template<class T>
-class ConsistencyList<T>::OrderComparison
-{
- public:
- typedef typename ConsistencyList<T>::const_iterator ComparableType;
-
- int compare(ComparableType a, ComparableType b) const; /// (-1,0,1) = a (precedes, ==, succeeds) b
-};
-
-/// Determines if the first element is less than the second one
-template<class T>
-class ConsistencyList<T>::LessThanComparison: public OrderComparison
-{
- public:
- typedef OrderComparison Parent;
- typedef typename Parent::ComparableType ComparableType;
-
- int compare(ComparableType a, ComparableType b) const;
- bool operator()(ComparableType a, ComparableType b) const;
-};
-
-/// Determines if the first element is greater than the second one
-template<class T>
-class ConsistencyList<T>::GreaterThanComparison: public OrderComparison
-{
- public:
- typedef OrderComparison Parent;
- typedef typename Parent::ComparableType ComparableType;
-
- int compare(ComparableType a, ComparableType b) const;
- bool operator()(ComparableType a, ComparableType b) const;
-};
-
-/// Determines the order of the two elements in the consistency order (that doesn't change during the execution)
-template<class T>
-class ConsistencyList<T>::ConsistencyComparison
-{
- public:
- typedef typename ConsistencyList<T>::const_iterator ComparableType;
-
- int compare(ComparableType a, ComparableType b) const; ///< (-1,0,1) = a (precedes, ==, succeeds) b
- bool operator()(ComparableType a, ComparableType b) const;
-};
-
-/// Structure storing auxilliary information requred for each node of ConsistencyList
-template<class T>
-struct ConsistencyListNode
-{
- ConsistencyListNode(const T& d, unsigned int c):
- data(d), consistency(c)
- {}
-
- T data;
- OrderType consistency;
-
- std::ostream& operator<<(std::ostream& out) const { return out << data << ": " << consistency; }
-};
-
-template<class T>
-std::ostream& operator<<(std::ostream& out, const ConsistencyListNode<T>& n) { return n.operator<<(out); }
-
-template<class T>
-class ConsistencyListIterator: public boost::iterator_adaptor<ConsistencyListIterator<T>,
- typename ConsistencyList<T>::Parent::iterator,
- T>
-{
- private:
- struct enabler {};
-
- public:
- typedef typename ConsistencyList<T>::Parent ConsistencyListParent;
- typedef boost::iterator_adaptor<ConsistencyListIterator<T>,
- typename ConsistencyListParent::iterator,
- T> Parent;
- typedef typename Parent::reference reference;
- typedef typename Parent::base_type base_type;
-
- ConsistencyListIterator() {}
- ConsistencyListIterator(const typename ConsistencyListParent::iterator& iter):
- ConsistencyListIterator::iterator_adaptor_(iter)
- {}
- ConsistencyListIterator(const ConsistencyListIterator<T>& other):
- ConsistencyListIterator::iterator_adaptor_(other.base())
- {}
-
- private:
- friend class boost::iterator_core_access;
- reference dereference() const { return Parent::base_reference()->data; }
- base_type& get_base() { return Parent::base_reference(); }
-
- friend class ConsistencyList<T>;
-};
-
-template<class T>
-class const_ConsistencyListIterator: public boost::iterator_adaptor<const_ConsistencyListIterator<T>,
- typename ConsistencyList<T>::Parent::const_iterator,
- const T>
-{
- private:
- struct enabler {};
-
- public:
- typedef typename ConsistencyList<T>::Parent ConsistencyListParent;
- typedef boost::iterator_adaptor<const_ConsistencyListIterator<T>,
- typename ConsistencyListParent::const_iterator,
- const T> Parent;
- typedef typename Parent::reference reference;
- typedef typename Parent::base_type base_type;
-
- const_ConsistencyListIterator() {}
- const_ConsistencyListIterator(const typename ConsistencyListParent::const_iterator& iter):
- const_ConsistencyListIterator::iterator_adaptor_(iter)
- {}
- const_ConsistencyListIterator(const const_ConsistencyListIterator<T>& other):
- const_ConsistencyListIterator::iterator_adaptor_(other.base())
- {}
- const_ConsistencyListIterator(const ConsistencyListIterator<T>& other):
- const_ConsistencyListIterator::iterator_adaptor_(other.base())
- {}
-
- private:
- friend class boost::iterator_core_access;
- reference dereference() const { return Parent::base_reference()->data; }
- const base_type&
- get_base() { return Parent::base_reference(); }
-
- friend class ConsistencyList<T>::OrderComparison;
- friend class ConsistencyList<T>::ConsistencyComparison;
-};
-
-
-#include "consistencylist.hpp"
-
-#endif // __CONSISTENCYLIST_H__
--- a/include/consistencylist.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/* Implementations */
-
-template<class T>
-void
-ConsistencyList<T>::
-swap(iterator i, iterator j)
-{
- Parent::swap(i.get_base(),j.get_base());
-}
-
-template<class T>
-template<class BinaryPredicate>
-void
-ConsistencyList<T>::
-sort(BinaryPredicate cmp)
-{
- Parent::sort(cmp);
- OrderType cur_order = 0;
- for (typename Parent::iterator cur = begin(); cur != end(); ++cur)
- cur->consistency = cur_order++;
-}
-
-
-template<class T>
-typename ConsistencyList<T>::iterator
-ConsistencyList<T>::
-push_back(const_reference x)
-{
- ++sz;
- return Parent::push_back(NodeType(x, sz));
-}
-
-template<class T>
-typename ConsistencyList<T>::iterator
-ConsistencyList<T>::
-insert(iterator p, const_reference x)
-{
- ++sz;
- return Parent::insert(p.get_base(), NodeType(x, sz));
-}
-
-
-/* OrderComparison */
-template<class T>
-int
-ConsistencyList<T>::
-OrderComparison::compare(ComparableType a, ComparableType b) const
-{
- typename Parent::OrderComparison cmp;
- return cmp.compare(a.get_base(), b.get_base());
-}
-
-
-/* LessThanComparison */
-template<class T>
-int ConsistencyList<T>::LessThanComparison::compare(ComparableType a, ComparableType b) const
-{ return Parent::compare(a,b); }
-
-template<class T>
-bool ConsistencyList<T>::LessThanComparison::operator()(ComparableType a, ComparableType b) const
-{ return compare(a,b) == -1; }
-
-
-/* GreaterThanComparison */
-template<class T>
-int ConsistencyList<T>::GreaterThanComparison::compare(ComparableType a, ComparableType b) const
-{ return -Parent::compare(a,b); }
-
-template<class T>
-bool ConsistencyList<T>::GreaterThanComparison::operator()(ComparableType a, ComparableType b) const
-{ return compare(a,b) == -1; }
-
-
-/* ConsistencyComparison */
-template<class T>
-int ConsistencyList<T>::ConsistencyComparison::compare(ComparableType a, ComparableType b) const
-{
- if (a.get_base()->consistency < b.get_base()->consistency) return -1;
- else if (a.get_base()->consistency == b.get_base()->consistency) return 0;
- else return 1;
-}
-
-template<class T>
-bool ConsistencyList<T>::ConsistencyComparison::operator()(ComparableType a, ComparableType b) const
-{ return compare(a,b) == -1; }
-
--- a/include/counter.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
- */
-
-#ifndef __COUNTER_H__
-#define __COUNTER_H__
-
-/* This should be integrated with the logging facilities. Written in the same framework. */
-
-#include <map>
-#include <string>
-#include <iostream>
-
-#ifndef COUNTERS
-#define Count(x)
-#define CountNum(x,y)
-#else // COUNTERS
-#define Count(x) counters.inc(x)
-#define CountNum(x,y) counters.inc(x,y)
-#endif
-
-typedef unsigned long CounterType;
-typedef std::string KeyType;
-
-class CounterFactory
-{
- private:
- typedef std::map<int, CounterType> CountersMap;
- typedef std::map<KeyType, CountersMap> KeyMap;
- KeyMap ctrs;
-
- public:
- ~CounterFactory()
- {
-#ifdef COUNTERS
- std::cout << "Counters:" << std::endl;
- for (KeyMap::const_iterator cur = ctrs.begin(); cur != ctrs.end(); ++cur)
- {
- std::cout << cur->first << ": ";
- if (cur->second.size() == 1)
- {
- std::cout << cur->second.begin()->second << std::endl;
- continue;
- }
- std::cout << std::endl;
- for (CountersMap::const_iterator ccur = cur->second.begin();
- ccur != cur->second.end();
- ++ccur)
- std::cout << " " << ccur->first << ": " << ccur->second << std::endl;
- }
-#endif // COUNTERS
- }
-
- void inc(const KeyType& key, int num = 0)
- {
- ctrs[key][num]++;
- }
-
- CounterType lookup(const KeyType& key, int num = 0) const
- {
- return const_cast<KeyMap&>(ctrs)[key][num];
- }
-};
-
-static CounterFactory counters;
-
-#endif // __COUNTER_H__
--- a/include/cycle.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/**
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005-2006
- */
-
-#ifndef __CYCLE_H__
-#define __CYCLE_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include "types.h"
-#include "circular_list.h"
-#include <list>
-#include <boost/serialization/access.hpp>
-
-/**
- * Class storing a cycle of simplices. Stores items in the order defined by ConsistencyCmp.
- * The actual order of the elements is defined by OrderCmp. Instances of those
- * classes are not stored in Cycle for efficiency, and are passed as arguments to those methods
- * that require them.
- */
-template <class Itm, class OrderCmp, class ConsistencyCmp = OrderCmp>
-class Cycle: public List<Itm>
-{
- public:
- /// \name Template Parameters
- /// @{
- typedef Itm Item;
- typedef OrderCmp OrderComparison;
- typedef ConsistencyCmp ConsistencyComparison;
- /// @}
-
- typedef Cycle<Item, OrderComparison, ConsistencyCmp> Self;
- typedef List<Item> CycleRepresentation;
-
- /// \name Accessor typedefs
- /// @{
- typedef typename CycleRepresentation::iterator iterator;
- typedef typename CycleRepresentation::const_iterator const_iterator;
- typedef typename CycleRepresentation::const_reference const_reference;
- typedef typename CycleRepresentation::reference reference;
- typedef typename CycleRepresentation::pointer pointer;
- typedef typename CycleRepresentation::const_pointer const_pointer;
- /// @}
-
- public:
- Cycle();
- Cycle(const Cycle& c);
-
- /// \name Whole Cycle operations
- /// @{
- /** Add c to *this assuming both Cycles are sorted in increasing order according to cmp. */
- Self& add(const Self& c, const ConsistencyComparison& cmp);
- void swap(Cycle& c); ///< Swaps the contents of c and *this (like STL's swap destroys c)
- //void insertion_sort(const Comparison& cmp); ///< Sort list[i] using insertion sort
- void sort(const ConsistencyComparison& cmp); ///< Sort elements to enforce consistency
- using CycleRepresentation::empty;
- using CycleRepresentation::clear;
- using CycleRepresentation::size;
- /// @}
-
- /// \name Modifiers
- /// @{
- using CycleRepresentation::erase;
- void append(const_reference x, const ConsistencyComparison& cmp);
- /// @}
-
- /// \name Accessors
- /// @{
- using CycleRepresentation::begin;
- using CycleRepresentation::end;
- const_reference top(const OrderComparison& cmp) const; ///< First element in cmp order
- iterator get_second(const OrderComparison& cmp) const; ///< Second element in cmp order
- /// @}
-
- /// \name Block access optimizations
- // Between operations used in optimization of transpositions for regular vertices. Maybe we don't need these? TODO
- /// @{
- /** Return first after i, but before or equal j; return i if no such element found */
- const_reference first_between(const_reference i, const_reference j, const OrderComparison& cmp);
- /// Add lists and remove all elements after i and before or equal to j
- const_reference add_and_first_between(const Self& c, const ConsistencyComparison& consistency_cmp,
- const_reference i, const_reference j, const OrderComparison& order_cmp);
- /// Erase everything after i, but before or equal to j
- void erase_between(const_reference i, const_reference j, const OrderComparison& cmp);
- /// @}
-
- /// \name Debugging
- /// @{
- const_reference get_first(const OrderComparison& cmp) const; ///< First element in cmp order
- std::ostream& operator<<(std::ostream& out) const;
- /// @}
-
- private:
- typedef std::list<Item> TemporaryCycleRepresenation;
-
- using CycleRepresentation::push_back;
- using CycleRepresentation::insert;
-
- private:
- size_t sz;
-
- private:
- // Serialization
- typedef List<Item> Parent;
- friend class boost::serialization::access;
- template<class Archive>
- void serialize(Archive& ar, version_type );
-};
-
-#include "cycle.hpp"
-
-#endif // __CYCLE_H__
-
--- a/include/cycle.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-#include <algorithm>
-#include <vector>
-
-#include <boost/serialization/split_member.hpp>
-#include <boost/serialization/nvp.hpp>
-#include <boost/serialization/binary_object.hpp>
-#include <boost/utility.hpp>
-
-using boost::serialization::make_nvp;
-using boost::serialization::make_binary_object;
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-Cycle<I,OrderCmp,ConsistencyCmp>::
-Cycle(): sz(0)
-{}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-Cycle<I,OrderCmp,ConsistencyCmp>::
-Cycle(const Cycle& c): CycleRepresentation(c), sz(c.sz)
-{}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-void
-Cycle<I,OrderCmp,ConsistencyCmp>::
-append(const_reference x, const ConsistencyCmp& cmp)
-{
- // First try the special cases that x goes at the end
- const_reference last = CycleRepresentation::back();
- if (empty() || cmp(last, x))
- {
- push_back(x);
- return;
- }
-
- for (iterator cur = begin(); cur != end(); ++cur)
- if (cmp(x, *cur))
- {
- insert(cur, x);
- return;
- }
-}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
-Cycle<I,OrderCmp,ConsistencyCmp>::
-top(const OrderComparison& cmp) const
-{
- AssertMsg(!empty(), "Cycle must not be empty for top()");
- const_iterator min = begin();
- for (const_iterator cur = ++begin(); cur != end(); ++cur)
- if (cmp(*cur, *min))
- min = cur;
- return *min;
-}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-void
-Cycle<I,OrderCmp,ConsistencyCmp>::
-swap(Cycle& c)
-{
- CycleRepresentation::swap(c);
- std::swap(sz, c.sz);
-}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-void
-Cycle<I,OrderCmp,ConsistencyCmp>::
-sort(const ConsistencyComparison& cmp)
-{
- std::vector<Item> tmp(begin(), end());
- std::sort(tmp.begin(), tmp.end(), cmp);
- std::copy(tmp.begin(), tmp.end(), begin());
-}
-
-template<class I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I,OrderCmp,ConsistencyCmp>::iterator
-Cycle<I,OrderCmp,ConsistencyCmp>::
-get_second(const OrderComparison& cmp) const
-{
- AssertMsg(!empty(), "Cycle must not be empty for get_second()");
- if (size() < 2) return begin(); // Indicates that there is no second.
-
- Dout(dc::cycle, "Looking for second");
- AssertMsg(size() >= 2, "Cycle must have at least two elements for get_second()");
- iterator min = begin();
- iterator second = ++begin();
- if (cmp(*second, *min))
- std::swap(min, second);
- for (iterator cur = boost::next(begin(),2); cur != end(); ++cur)
- {
- if (cmp(*cur, *min))
- {
- second = min;
- min = cur;
- } else if (cmp(*cur, *second))
- {
- second = cur;
- }
- }
-
- Dout(dc::cycle, "Looked up: " << **second);
- return second;
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
-Cycle<I,OrderCmp,ConsistencyCmp>::
-first_between(const_reference i, const_reference j, const OrderComparison& cmp)
-{
- // Find the first element in ConsistencyComparison order (> i and <= j)
- const_pointer first = &i;
- iterator cur = begin();
- for (; cur != end(); ++cur)
- {
- if ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur)))
- {
- first = &(*cur);
- break;
- }
- }
-
- // If no such element found, then we are done
- if (cur == end())
- return i;
-
- // Find first element in OrderComparison order (> i and <= j)
- for (++cur; cur != end(); ++cur)
- {
- if ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur)))
- {
- if (cmp(*cur, *first))
- first = &(*cur);
- }
- }
- return *first;
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-void
-Cycle<I,OrderCmp,ConsistencyCmp>::
-erase_between(const_reference i, const_reference j, const OrderComparison& cmp)
-{
- for (iterator cur = begin(); cur != end(); ++cur)
- while ((cur != end()) && ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur))))
- {
- Dout(dc::cycle, "Iteration of the erase while loop");
- cur = erase(cur);
- }
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-std::ostream&
-Cycle<I,OrderCmp,ConsistencyCmp>::
-operator<<(std::ostream& out) const
-{
- for (const_iterator cur = begin(); cur != end(); ++cur)
- {
- out << **cur << ", ";
- }
- // out << "(last: " << *last << ")"; // For debugging only
- return out;
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-std::ostream&
-operator<<(std::ostream& out, const Cycle<I, OrderCmp, ConsistencyCmp>& c)
-{
- return c.operator<<(out);
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I, OrderCmp, ConsistencyCmp>::Self&
-Cycle<I, OrderCmp, ConsistencyCmp>::
-add(const Self& c, const ConsistencyCmp& cmp)
-{
- Dout(dc::cycle, "Adding cycles: " << *this << " + " << c);
-
- iterator cur1 = begin();
- const_iterator cur2 = c.begin();
-
- while (cur2 != c.end())
- {
- if (cur1 == end())
- {
- while (cur2 != c.end())
- push_back(*cur2++);
- Dout(dc::cycle, "After addition: " << *this);
- return *this;
- }
-
- // mod 2
- int res = cmp.compare(*cur1, *cur2);
- Dout(dc::cycle, "Comparison result: " << res);
- if (res == 0) // *cur1 == *cur2
- {
- Dout(dc::cycle, "Equality");
- cur1 = erase(cur1); // erase cur1 --- as a result cur1 will be pointing at old_cur1++
- --sz;
- ++cur2;
- } else if (res < 0) // *cur1 < *cur2
- {
- Dout(dc::cycle, "Less than");
- cur1++;
- } else if (res > 0) // *cur1 > *cur2
- {
- Dout(dc::cycle, "Greater than");
- insert(cur1, *cur2);
- ++cur2;
- ++sz;
- }
- }
-
- Dout(dc::cycle, "After addition: " << *this);
- return *this;
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
-Cycle<I,OrderCmp,ConsistencyCmp>::
-add_and_first_between(const Self& c, const ConsistencyComparison& consistency_cmp,
- const_reference i, const_reference j, const OrderComparison& order_cmp)
-{
- add(c, consistency_cmp);
- return first_between(i,j, order_cmp);
-}
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
-Cycle<I,OrderCmp,ConsistencyCmp>::
-get_first(const OrderComparison& cmp) const
-{ return top(cmp); }
-
-
-template<typename I, class OrderCmp, class ConsistencyCmp>
-template<class Archive>
-void
-Cycle<I,OrderCmp,ConsistencyCmp>::
-serialize(Archive& ar, version_type )
-{
- ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
- ar & make_nvp("size", sz);;
-}
-
-
-/*
-template<typename I, class Cmp>
-void
-Cycle<I, Cmp>::
-insertion_sort(const Comparison& cmp)
-{
- TemporaryCycleRepresenation tmp;
-
- // Insertion sort into the temporary list
- for (const_iterator cur = begin(); cur != end(); ++cur)
- {
- typename TemporaryCycleRepresenation::iterator tmp_cur = tmp.end();
- typename TemporaryCycleRepresenation::iterator tmp_next = tmp_cur--;
-
- while (tmp_next != tmp.begin())
- {
- if (cmp(*cur, *tmp_cur))
- tmp_next = tmp_cur--;
- else
- break;
- }
- tmp.insert(tmp_next, *cur);
- }
-
- // Copy temporary list back into ourselves
- iterator cur = begin();
- typename TemporaryCycleRepresenation::const_iterator tmp_cur = tmp.begin();
- while(tmp_cur != tmp.end())
- {
- *cur = *tmp_cur;
- ++cur; ++tmp_cur;
- }
-}
-*/
-
-
--- a/include/debug.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#ifndef CWDEBUG
-
-#include <iostream> // std::cerr
-#include <cstdlib> // std::exit, EXIT_FAILURE
-#include <cassert>
-
-#define AllocTag1(p)
-#define AllocTag2(p, desc)
-#define AllocTag_dynamic_description(p, data)
-#define AllocTag(p, data)
-#define Debug(STATEMENT...)
-#define Dout(cntrl, data)
-#define DoutFatal(cntrl, data) LibcwDoutFatal(, , cntrl, data)
-#define ForAllDebugChannels(STATEMENT...)
-#define ForAllDebugObjects(STATEMENT...)
-#define LibcwDebug(dc_namespace, STATEMENT...)
-#define LibcwDout(dc_namespace, d, cntrl, data)
-#define LibcwDoutFatal(dc_namespace, d, cntrl, data) do { ::std::cerr << data << ::std::endl; ::std::exit(EXIT_FAILURE); } while(1)
-#define LibcwdForAllDebugChannels(dc_namespace, STATEMENT...)
-#define LibcwdForAllDebugObjects(dc_namespace, STATEMENT...)
-#define NEW(x) new x
-#define CWDEBUG_ALLOC 0
-#define CWDEBUG_MAGIC 0
-#define CWDEBUG_LOCATION 0
-#define CWDEBUG_LIBBFD 0
-#define CWDEBUG_DEBUG 0
-#define CWDEBUG_DEBUGOUTPUT 0
-#define CWDEBUG_DEBUGM 0
-#define CWDEBUG_DEBUGT 0
-#define CWDEBUG_MARKER 0
-#define AssertMsg(TEST,MSG)
-//#define AssertMsg(TEST,STRM,MSG)
-
-
-#else // CWDEBUG
-
-// This must be defined before <libcwd/debug.h> is included and must be the
-// name of the namespace containing your `dc' (Debug Channels) namespace
-// (see below). You can use any namespace(s) you like, except existing
-// namespaces (like ::, ::std and ::libcwd).
-#define DEBUGCHANNELS ::dionysus::debug::channels
-#include <libcwd/debug.h>
-
-namespace dionysus
-{
- namespace debug
- {
- void init(void); // Initialize debugging code from main().
- void init_thread(void); // Initialize debugging code from new threads.
-
- namespace channels // This is the DEBUGCHANNELS namespace, see above.
- {
- namespace dc // 'dc' is defined inside DEBUGCHANNELS.
- {
- using namespace libcwd::channels::dc;
- using libcwd::channel_ct;
-
- // Add the declaration of new debug channels here
- // and add their definition in a custom debug.cc file.
- extern channel_ct filtration;
- extern channel_ct transpositions;
- extern channel_ct vineyard;
- extern channel_ct cycle;
- extern channel_ct lsfiltration;
- extern channel_ct orderlist;
- } // namespace dc
- } // namespace DEBUGCHANNELS
- }
-}
-
-
-#define AssertMsg(TEST,MSG) \
- ( (TEST) ? (void)0 \
- : (std::cerr << __FILE__ ":" << __LINE__ \
- << ": Assertion failed " #TEST \
- << " - " << MSG << std::endl,abort()))
-/*
-#define AssertMsg(TEST,STRM,MSG) \
- ( (TEST) ? (void)0 \
- : (DoutFatal(STRM, __FILE__ "(" << __LINE__ \
- << "): Assertion failed " #TEST \
- << MSG << std::endl)))
-*/
-
-#endif // CWDEBUG
-
-#endif // DEBUG_H
--- a/include/filtration.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
- */
-
-#ifndef __FILTRATION_H__
-#define __FILTRATION_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include "filtrationcontainer.h"
-#include "filtrationsimplex.h"
-#include "vineyard.h"
-
-#include <map>
-#include <vector>
-
-#include <boost/serialization/access.hpp>
-
-/**
- * Filtration class. Serves as an (ordered) container for the simplices,
- * and provides pair_simplices() method that computes the RU-decomposition
- * for the simplex order stored in the filtration. Iterators remain valid
- * through all the operations.
- */
-template<class Smplx, class FltrSmplx = FiltrationSimplex<Smplx>, class Vnrd = Vineyard<FltrSmplx> >
-class Filtration: public FltrSmplx::Container
-{
- public:
- typedef Smplx Simplex;
- typedef FltrSmplx FiltrationSimplex;
- typedef Vnrd Vineyard;
-
- /// \name Container Types
- /// @{
- /** The actual container type (which is the parent of the Filtration) */
- typedef typename FiltrationSimplex::Container FiltrationContainer;
- typedef typename FiltrationContainer::Index Index;
- typedef typename FiltrationContainer::const_Index const_Index;
- /// @}
-
- /// \name Cycles and Trails
- /// @{
- typedef typename FiltrationContainer::GreaterThanComparison CyclesComparator;
- typedef typename FiltrationContainer::LessThanComparison TrailsComparator;
- typedef typename FiltrationContainer::ConsistencyComparison ConsistencyComparator;
- typedef typename FiltrationContainer::Cycle Cycle;
- typedef typename FiltrationContainer::Trail Trail;
- typedef typename Cycle::iterator CycleIterator;
- typedef typename Trail::iterator TrailIterator;
- /// @}
-
- typedef Filtration<Simplex, FiltrationSimplex, Vineyard> Self;
- typedef FiltrationContainer Parent;
-
- public:
- Filtration(Vineyard* vineyard);
-
- /// \name Core Functionality
- /// @{
- /// Computes RU decomposition of the simplices in [bg, end) range, assuming that everything before bg has been paired
- void pair_simplices(Index bg, Index end);
- void pair_simplices() { pair_simplices(begin(), end()); }
- bool transpose(Index i, bool maintain_lazy = true);
- bool is_paired() const;
- Index append(const Simplex& s); ///< Appends s to the filtration
- Index insert(Index prior, const Simplex& s); ///< Inserts s after prior
- const_Index get_index(const Simplex& s) const; /**< Returns the iterator pointing to s
- (end() if s not in filtration) */
- Index get_index(const Simplex& s); ///< \overload
- void fill_simplex_index_map(); ///< Fills the mapping for get_index()
- /// @}
-
- /// \name Accessors
- /// @{
- Vineyard* vineyard() { return vineyard_; }
- const Vineyard* vineyard() const { return vineyard_; }
- /// @}
-
- protected:
- using Parent::swap;
- bool transpose_simplices(Index i, bool maintain_lazy);
-
- public:
- /// \name Container Operations
- /// @{
- using Parent::size;
- using Parent::begin;
- using Parent::end;
- /// @}
-
- std::ostream& operator<<(std::ostream& out) const;
-
- protected:
- /// \name Comparator accessors (protected)
- /// @{
- const ConsistencyComparator& get_consistency_cmp() const { return consistency_cmp; }
- const CyclesComparator& get_cycles_cmp() const { return cycles_cmp; }
- const TrailsComparator& get_trails_cmp() const { return trails_cmp; }
- /// @}
-
- private:
- typedef std::map<Simplex, Index> SimplexMap;
-
- /// Initializes the cycle with the indices of the simplices in the boundary, and the trail with the index of this simplex
- void init_cycle_trail(Index j);
- void pairing_switch(Index i, Index j);
-
- bool paired;
- SimplexMap inverse_simplices;
-
- Vineyard* vineyard_;
-
- CyclesComparator cycles_cmp;
- TrailsComparator trails_cmp;
- ConsistencyComparator consistency_cmp;
-
- private:
- /* Serialization */
- friend class boost::serialization::access;
-
- typedef std::map<const_Index, SizeType, ConsistencyComparator> IndexIntMap;
- typedef std::vector<Index> IndexVector;
-
- template<class Archive> void save(Archive& ar, version_type ) const;
- template<class Archive> void load(Archive& ar, version_type );
- BOOST_SERIALIZATION_SPLIT_MEMBER()
-};
-
-#include "filtration.hpp"
-
-#endif // __FILTRATION_H__
--- a/include/filtration.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,463 +0,0 @@
-#include "counter.h"
-#include "types.h"
-#include <algorithm>
-
-#include <boost/utility.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/nvp.hpp>
-#include <boost/serialization/list.hpp>
-#include <boost/serialization/is_abstract.hpp>
-
-using boost::serialization::make_nvp;
-
-/* Filtration Public */
-
-template<class S, class FS, class V>
-Filtration<S, FS, V>::
-Filtration(Vineyard* vnrd = 0): paired(false), vineyard_(vnrd)
-{}
-
-template<class S, class FS, class V>
-void
-Filtration<S, FS, V>::
-pair_simplices(Index bg, Index end)
-{
- Dout(dc::filtration, "Entered: compute_pairing");
- for (Index j = bg; j != end; ++j)
- {
- Dout(dc::filtration|flush_cf|continued_cf, *j << ": ");
- init_cycle_trail(j);
- Cycle& bdry = j->cycle();
- Dout(dc::finish, bdry);
-
- CountNum("Boundaries", j->dimension());
- Count("SimplexCount");
-
- while(!bdry.empty())
- {
- Index i = bdry.top(cycles_cmp);
- Dout(dc::filtration, *i << ": " << *(i->pair()));
- AssertMsg(!cycles_cmp(i, j), "Simplices in the cycle must precede current simplex: " <<
- "(" << *i << " in cycle of " << *j << ")");
-
- // i is not paired, so we pair j with i
- if (i->pair() == i)
- {
- Dout(dc::filtration, "Pairing " << *i << " and " << *j << " with cycle " << j->cycle());
- i->set_pair(j);
- j->set_pair(i);
- CountNum("DepositedCycleLength", j->cycle().size());
- break;
- }
-
- // continue searching --- change the Dout to the continued mode with newlines FIXME
- Dout(dc::filtration, " Adding: [" << bdry << "] + ");
- Dout(dc::filtration, " [" << i->pair()->cycle() << "]");
- bdry.add(i->pair()->cycle(), get_consistency_cmp());
- i->pair()->trail().append(j, get_consistency_cmp());
- Dout(dc::filtration, "After addition: " << bdry);
- }
- Dout(dc::filtration, "Finished with " << *j << ": " << *(j->pair()));
- }
- paired = true;
-}
-
-template<class S, class FS, class V>
-bool
-Filtration<S, FS, V>::
-is_paired() const
-{ return paired; }
-
-/**
- * Transposes simplices at i and i+1, and records the knee in the vineyard if there is a change in pairing.
- * Returns true if the pairing changed.
- */
-template<class S, class FS, class V>
-bool
-Filtration<S,FS,V>::
-transpose(Index i, bool maintain_lazy)
-{
- AssertMsg(vineyard() != 0, "We must have a vineyard for transpositions");
-
- Index i_orig = i++;
-
- AssertMsg(i_orig->pair() != i, "Transposing simplices must not be paired");
- bool result = transpose_simplices(i_orig, maintain_lazy);
- AssertMsg(i_orig == boost::next(i), "Wrong indices after transposition");
-
- if (result) vineyard()->switched(i, i_orig);
- return result;
-}
-
-template<class S, class FS, class V>
-typename Filtration<S, FS, V>::Index
-Filtration<S, FS, V>::
-append(const Simplex& s)
-{
- Index i = push_back(FiltrationSimplex(s));
- return i;
-}
-
-template<class S, class FS, class V>
-typename Filtration<S, FS, V>::Index
-Filtration<S, FS, V>::
-insert(Index prior, const Simplex& s)
-{
- Index i = Parent::insert(prior, FiltrationSimplex(s));
- paired = false;
-
- return i;
-}
-
-template<class S, class FS, class V>
-typename Filtration<S, FS, V>::const_Index
-Filtration<S, FS, V>::
-get_index(const Simplex& s) const
-{
- typename SimplexMap::const_iterator i = inverse_simplices.find(s);
- if (i == inverse_simplices.end())
- return end();
- else
- return i->second;
-}
-
-template<class S, class FS, class V>
-typename Filtration<S, FS, V>::Index
-Filtration<S, FS, V>::
-get_index(const Simplex& s)
-{
- typename SimplexMap::const_iterator i = inverse_simplices.find(s);
- if (i == inverse_simplices.end())
- return end();
- else
- return i->second;
-}
-
-template<class S, class FS, class V>
-void
-Filtration<S, FS, V>::
-fill_simplex_index_map()
-{
- for (Index i = begin(); i != end(); ++i)
- inverse_simplices[*i] = i;
-}
-
-template<class S, class FS, class V>
-std::ostream&
-Filtration<S, FS, V>::
-operator<<(std::ostream& out) const
-{
- out << "Pairing: " << std::endl;
- for (const_Index i = begin(); i != end(); ++i)
- {
- out << "(" << *i << ", " << *(i->pair()) << "): ";
- out << i->cycle() << std::endl;
- }
- out << std::endl << std::endl;
-
- return out;
-}
-
-
-/* Filtration Protected */
-/// Transposes simplices at i and i+1. Returns true if the pairing switched.
-template<class S, class FS, class V>
-bool
-Filtration<S,FS,V>::
-transpose_simplices(Index i, bool maintain_lazy)
-{
- AssertMsg(is_paired(), "Pairing must be computed before transpositions");
- Count("SimplexTransposition");
-
- Index i_prev = i++;
-
- if (i_prev->dimension() != i->dimension())
- {
- swap(i_prev, i);
- Dout(dc::transpositions, "Different dimension");
- Count("Case DiffDim");
- return false;
- }
-
- bool si = i_prev->sign(), sii = i->sign();
- if (si && sii)
- {
- Dout(dc::transpositions, "Trail prev: " << i_prev->trail());
-
- // Case 1
- TrailIterator i_in_i_prev = std::find(i_prev->trail().begin(), i_prev->trail().end(), i);
- if (i_in_i_prev != i_prev->trail().end())
- {
- Dout(dc::transpositions, "Case 1, U[i,i+1] = 1");
- i_prev->trail().erase(i_in_i_prev);
- }
-
- Index k = i_prev->pair();
- Index l = i->pair();
-
- // Explicit treatment of unpaired simplex
- if (l == i)
- {
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 1.2 --- unpaired");
- Dout(dc::transpositions, *i_prev);
- Count("Case 1.2");
- return false;
- } else if (k == i_prev)
- {
- if (std::find(l->cycle().begin(), l->cycle().end(), i_prev) == l->cycle().end())
- {
- // Case 1.2
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 1.2 --- unpaired");
- Dout(dc::transpositions, *i_prev);
- Count("Case 1.2");
- return false;
- } else
- {
- // Case 1.1.2 --- special version (plain swap, but pairing switches)
- swap(i_prev, i);
- pairing_switch(i_prev, i);
- Dout(dc::transpositions, "Case 1.1.2 --- unpaired");
- Dout(dc::transpositions, *i_prev);
- Count("Case 1.1.2");
- return true;
- }
- }
-
- Dout(dc::transpositions, "l cycle: " << l->cycle());
- if (std::find(l->cycle().begin(), l->cycle().end(), i_prev) == l->cycle().end())
- {
- // Case 1.2
- if (maintain_lazy)
- {
- TrailIterator k_in_l = std::find(l->trail().begin(), l->trail().end(), k);
- if (k_in_l != l->trail().end())
- {
- l->trail().add(k->trail(), Filtration::get_consistency_cmp()); // Add row k to l
- k->cycle().add(l->cycle(), Filtration::get_consistency_cmp()); // Add column l to k
- }
- }
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 1.2");
- Count("Case 1.2");
- return false;
- } else
- {
- // Case 1.1
- if (trails_cmp(k,l))
- {
- // Case 1.1.1
- swap(i_prev, i);
- l->cycle().add(k->cycle(), Filtration::get_consistency_cmp()); // Add column k to l
- k->trail().add(l->trail(), Filtration::get_consistency_cmp()); // Add row l to k
- Dout(dc::transpositions, "Case 1.1.1");
- Count("Case 1.1.1");
- return false;
- } else
- {
- // Case 1.1.2
- swap(i_prev, i);
- k->cycle().add(l->cycle(), Filtration::get_consistency_cmp()); // Add column l to k
- l->trail().add(k->trail(), Filtration::get_consistency_cmp()); // Add row k to l
- pairing_switch(i_prev, i);
- Dout(dc::transpositions, "Case 1.1.2");
- Count("Case 1.1.2");
- return true;
- }
- }
- } else if (!si && !sii)
- {
- // Case 2
- if (std::find(i_prev->trail().begin(), i_prev->trail().end(), i) == i_prev->trail().end())
- {
- // Case 2.2
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 2.2");
- Count("Case 2.2");
- return false;
- } else
- {
- // Case 2.1
- Index low_i = i_prev->pair();
- Index low_ii = i->pair();
- i_prev->trail().add(i->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
- i->cycle().add(i_prev->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i
- swap(i_prev, i);
- if (Filtration::get_trails_cmp()(low_ii, low_i))
- {
- // Case 2.1.2
- i_prev->cycle().add(i->cycle(), Filtration::get_consistency_cmp()); // Add column i to i_prev (after transposition)
- i->trail().add(i_prev->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
- pairing_switch(i_prev, i);
- Dout(dc::transpositions, "Case 2.1.2");
- Count("Case 2.1.2");
- return true;
- }
-
- // Case 2.1.1
- Dout(dc::transpositions, "Case 2.1.1");
- Count("Case 2.1.1");
- return false;
- }
- } else if (!si && sii)
- {
- // Case 3
- if (std::find(i_prev->trail().begin(), i_prev->trail().end(), i) == i_prev->trail().end())
- {
- // Case 3.2
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 3.2");
- Count("Case 3.2");
- return false;
- } else
- {
- // Case 3.1
- i_prev->trail().add(i->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
- i->cycle().add(i_prev->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i
- swap(i_prev, i);
- i_prev->cycle().add(i->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i (after transposition)
- i->trail().add(i_prev->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
- pairing_switch(i_prev, i);
- Dout(dc::transpositions, "Case 3.1");
- Count("Case 3.1");
- return true;
- }
- } else if (si && !sii)
- {
- // Case 4
- TrailIterator i_in_i_prev = std::find(i_prev->trail().begin(), i_prev->trail().end(), i);
- if (i_in_i_prev != i_prev->trail().end())
- {
- Dout(dc::transpositions, "Case 4, U[i,i+1] = 1");
- i_prev->trail().erase(i_in_i_prev);
- }
- swap(i_prev, i);
- Dout(dc::transpositions, "Case 4");
- Count("Case 4");
- return false;
- }
-
- return false; // to avoid compiler complaints, should never reach this point
-}
-
-
-/* Filtration Private */
-template<class S, class FS, class V>
-void
-Filtration<S, FS, V>::
-init_cycle_trail(Index j)
-{
- typename Simplex::Cycle bdry = j->boundary();
-
- for (typename Simplex::Cycle::const_iterator cur = bdry.begin(); cur != bdry.end(); ++cur)
- {
- Dout(dc::filtration, "Appending in init_cycle_trail(): " << *cur);
- AssertMsg(get_index(*cur) != end(), "Non-existent simplex in the cycle");
- j->cycle().append(get_index(*cur), get_consistency_cmp());
- }
- j->trail().append(j, get_consistency_cmp());
- j->set_pair(j);
-}
-
-/// Update the pairing, so that whoever was paired with i is now paired with j and vice versa.
-template<class S, class FS, class V>
-void
-Filtration<S,FS,V>::
-pairing_switch(Index i, Index j)
-{
- Index i_pair = i->pair();
- Index j_pair = j->pair();
-
- if (i_pair == i)
- j->set_pair(j);
- else
- {
- j->set_pair(i_pair);
- i_pair->set_pair(j);
- }
-
- if (j_pair == j)
- i->set_pair(i);
- else
- {
- i->set_pair(j_pair);
- j_pair->set_pair(i);
- }
-}
-
-/* Serialization */
-template<class S, class FS, class V>
-template<class Archive>
-void
-Filtration<S, FS, V>::
-save(Archive& ar, version_type ) const
-{
- ar << BOOST_SERIALIZATION_NVP(paired);
- ar << BOOST_SERIALIZATION_NVP(cycles_cmp);
- ar << BOOST_SERIALIZATION_NVP(trails_cmp);
- ar << BOOST_SERIALIZATION_NVP(consistency_cmp);
-
- SizeType sz = size();
- ar << make_nvp("size", sz);
- Dout(dc::filtration, "Size: " << sz);
-
- /* Record integer indices */
- IndexIntMap index_map; SizeType i = 0;
- for (const_Index cur = begin(); cur != end(); ++cur)
- { index_map[cur] = i++; }
-
- /* Save the simplices */
- int count = 0;
- for (const_Index cur = begin(); cur != end(); ++cur)
- {
- count++;
- // FIXME
- //FiltrationSimplexSerialization simplex = FiltrationSimplexSerialization(*cur, index_map);
- //ar << make_nvp("FiltrationSimplex", simplex);
- }
- Dout(dc::filtration, count << " simplices serialized");
-}
-
-template<class S, class FS, class V>
-template<class Archive>
-void
-Filtration<S, FS, V>::
-load(Archive& ar, version_type )
-{
- Dout(dc::filtration, "Starting to read filtration");
- ar >> BOOST_SERIALIZATION_NVP(paired);
- ar >> BOOST_SERIALIZATION_NVP(cycles_cmp);
- ar >> BOOST_SERIALIZATION_NVP(trails_cmp);
- ar >> BOOST_SERIALIZATION_NVP(consistency_cmp);
- Dout(dc::filtration, "In Filtration: first block read");
-
- SizeType sz;
- ar >> make_nvp("size", sz);
- Dout(dc::filtration, "In Filtration: size read " << sz);
-
- IndexVector index_vector(sz);
- for (SizeType i = 0; i < sz; ++i)
- {
- index_vector[i] = append(Simplex());
- }
-
- int count = 0;
- for (SizeType i = 0; i < sz; ++i)
- {
- // FIXME
- //FiltrationSimplexSerialization simplex;
- //ar >> make_nvp("FiltrationSimplex", simplex);
- count++;
- Dout(dc::filtration, "In Filtration: simplex read (" << count << ")");
- //simplex.set_filtration_simplex(*index_vector[i], index_vector);
- }
- Dout(dc::filtration, "In Filtration: simplices read");
-}
-
-template<class S, class FS, class V>
-std::ostream&
-operator<<(std::ostream& out, const Filtration<S, FS, V>& f)
-{ return f.operator<<(out); }
-
-
--- a/include/filtrationcontainer.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2006
- */
-
-#ifndef __FILTRATIONCONTAINER_H__
-#define __FILTRATIONCONTAINER_H__
-
-#include "consistencylist.h"
-#include "cycle.h"
-
-/**
- * FiltrationContainer class. Serves as a parent of Filtration that
- * describes the container functionality. Used by FiltrationSimplex
- * to get Cycle representation.
- */
-template<class FltrSmplx>
-class FiltrationContainer: public ConsistencyList<FltrSmplx>
-{
- public:
- typedef FltrSmplx FiltrationSimplex;
- typedef ConsistencyList<FiltrationSimplex> ConsistencyList;
-
- /// \name Cycles and Trails
- /// @{
- /// Index is and therfore acts like an iterator. The name is preserved for historical reasons.
- typedef typename ConsistencyList::iterator Index;
- /// const_Index is a const_iterator
- typedef typename ConsistencyList::const_iterator const_Index;
- /// @}
-
- /// \name Cycles and Trails
- /// @{
- typedef typename ConsistencyList::GreaterThanComparison CyclesComparator;
- typedef typename ConsistencyList::LessThanComparison TrailsComparator;
- typedef typename ConsistencyList::ConsistencyComparison ConsistencyComparator;
- typedef ::Cycle<Index, CyclesComparator, ConsistencyComparator> Cycle;
- typedef ::Cycle<Index, TrailsComparator, ConsistencyComparator> Trail;
- /// @}
-
- template<class U>
- struct rebind { typedef FiltrationContainer<U> other; };
-};
-
-#endif // __FILTRATIONCONTAINER_H__
--- a/include/filtrationsimplex.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2006
- */
-
-#ifndef __FILTRATIONSIMPLEX_H__
-#define __FILTRATIONSIMPLEX_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include "filtrationcontainer.h"
-#include "vineyard.h"
-#include "types.h"
-
-#include <list>
-
-#if 0
-#include <boost/serialization/access.hpp>
-#include <boost/serialization/nvp.hpp>
-#include <boost/serialization/list.hpp>
-#endif
-
-/**
- * Evaluator is a base class for the structures that are able to return a value
- * given a simplex.
- */
-template<class Smplx>
-class Evaluator
-{
- public:
- typedef Smplx Simplex;
-
- virtual RealType time() const { return 0; }
- virtual RealType value(const Simplex& s) const { return 0; }
-
- virtual ~Evaluator() {}
-};
-
-/**
- * FiltrationSimplex stores information needed for the RU-decomposition:
- * cycle (column of R), trail (row of U), and pair.
- */
-template<class Smplx>
-class FiltrationSimplex: public Smplx
-{
- public:
- typedef Smplx Simplex;
- typedef FiltrationSimplex<Simplex> Self;
- typedef FiltrationContainer<Self> Container;
- typedef Simplex Parent;
-
- typedef Vine<Simplex> Vine;
- typedef typename Container::Cycle Cycle;
- typedef typename Container::Trail Trail;
- typedef typename Container::Index Index;
-
- typedef Evaluator<Simplex> Evaluator;
-
- FiltrationSimplex(const Simplex& s):
- Simplex(s), vine_(0) {}
-
-
- /// \name Core functionality
- /// @{
- void set_pair(Index pair) { pair_ = pair; }
- bool sign() const { return cycles_column.empty(); }
- bool is_paired() const { return pair() != pair()->pair(); }
- void set_vine(Vine* v) { vine_ = v; }
- using Parent::dimension;
- /// @}
-
-
- /// \name Accessors
- /// @{
- Cycle& cycle() { return cycles_column; }
- Trail& trail() { return trails_row; }
- const Cycle& cycle() const { return cycles_column; }
- const Trail& trail() const { return trails_row; }
- Index pair() const { return pair_; }
- Vine* vine() const { return vine_; }
- /// @}
-
- private:
- Cycle cycles_column;
- Trail trails_row;
- Index pair_;
- Vine* vine_;
-};
-
-#endif // __FILTRATIONSIMPLEX_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/NOTES Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,69 @@
+== Predicates/Constructions
+ * circumsphere, side of circumsphere
+ * barycentric coordinates
+ * degenerate simplex
+ * projection on a k-flat, squared distance to the k-flat
+ * signed square distance to an oriented (d-1)-flat (?)
+
+
+== Computing circumcenter and circumradius of a k-simplex in d dimensions.
+
+ * Ken Clarkson's Gram-Schmidt-based algorithm works perfectly over any field.
+ The idea is as follows.
+
+ Given points p_i, the circumcenter c satisfies (p_i-c)^2 = r^2. By
+ translation, we can assume that some p_i is at the origin, so that c^c=r^2,
+ and that equation becomes p_i \cdot c - p_i^2/2 = 0. That is, [c -1/2] is
+ normal to [p_i p_i^2]. Also, c must be an affine combination of the p_i,
+ so if we start with a point [c' 0] with c' in the affine hull of the p_i,
+ and remove all multiples of all [p_i p_i^2] from it, via Gram-Schmidt for
+ example, and then scale the result so that the last entry is -1/2, we get
+ c (alternatively we can start with [0 1]). Note that if the simplex is
+ degenerate (its affine hull is less than k-dimensional), the last entry of
+ c is 0.
+
+ P = {p_0, ..., p_k}
+ p'_i = p_i - p_0 # make p_0 the origin
+ p''_i = [p'_i p'_i^2] # lift the points
+ c' = 0 # c is in the affine hull of p'_i
+ c'' = [c' 1] # c'' is not in the affine hull of p'_i^2
+
+ for i = 1 to k: # create an orthogonal basis for aff(p''_i)
+ a''_i = p''_i
+ for j = k-1 downto 1:
+ a''_i -= a''_j * (a''_i \cdot c''_j)/c''_j^2
+
+ for i = 1 to k:
+ c'' -= a''_i * (c'' \cdot a''_i) / (a''_i^2)
+ c' = c''[1..d]/(-2 * c''[d+1]) # scale c'' down
+
+ * Ulfar Erlingsson's, Erich Kaltofen's and David Musser's "Generic
+ Gram-Schmidt Orthogonalization by Exact Division" (ISSAC'96) gives an
+ algorithm to compute Gram-Schmidt for vector space with integral domain
+ coefficients. I need to understand the paper better to see the advantages
+ over normalizing rationals at every step of the computation above
+ (the paper's introduction says that it avoids "costly GCD computations").
+
+ * Using QR decomposition (or any other orthogonal decomposition), and
+ then using the formula of the circumsphere on the matrix R (which is
+ just the simplex rotated into a k-dimensional space):
+
+ * Only (d-2) determinants of a k by k matrix are required which is nice.
+
+ * All (implemented) computation of the QR decomposition that I have found
+ so far requires square roots (for norms), divisions, and often
+ comparisons. While divisions are acceptable, square roots and
+ comparisons aren't.
+
+ * There is a string of papers in late 80s, early 90s on square root free
+ and division free algorithms for QR decomposition out of VLSI community.
+ There is a paper that claims to put all such techniques into one
+ framework. There is also a paper that says that all such techniques don't
+ work, and square root implementation needs to be reconsidered. (authors
+ to look up if searching for these papers are K.J.R. Liu and E.
+ Frantzeskakis)
+
+ * Using the formulas from Herbert's Weighted Alpha Shapes paper which are
+ derived from formulas of the planes that are lifted Voronoi cells. This
+ approach requires (d-k)*(d+2) determinants of k by k matrices, which is not
+ great.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/euclidean.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,105 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2007
+ */
+
+#ifndef __EUCLEDIAN_H__
+#define __EUCLEDIAN_H__
+
+#include <utility>
+#include <vector>
+#include <algorithm>
+
+#include "linalg.h"
+#include "number-traits.h"
+
+
+template<class NumberType_ = double>
+class Kernel
+{
+ public:
+ typedef unsigned int DimensionType;
+ typedef NumberType_ NumberType;
+ typedef LinearAlgebra<NumberType> LinearAlgebra;
+ typedef typename LinearAlgebra::MatrixType MatrixType;
+ typedef typename LinearAlgebra::VectorType VectorType;
+
+ class Point;
+ class Sphere;
+ typedef std::vector<const Point*> PointContainer;
+
+
+ Kernel(DimensionType dimension);
+
+ DimensionType dimension() const { return dimension_; }
+ Point origin() const { return origin_; }
+
+ /** Returns matrix describing the equation of a circumsphere of points */
+ Sphere circumsphere(const PointContainer& points) const;
+
+ /** Returns squared radius of the circumsphere */
+ NumberType circumradius(const PointContainer& points) const;
+
+ /** Returns center of the circumsphere */
+ Point circumcenter(const PointContainer& points) const;
+
+ /** The result is positive if points[0] lies outside the circumsphere of points,
+ 0 if points[0] is on the circumsphere, and negative if it's inside */
+ NumberType side_of_circumsphere(const PointContainer& points, const Point& p) const;
+
+ private:
+ NumberType& normalize(NumberType& n) const;
+ Point& normalize(Point& p) const;
+
+ DimensionType dimension_;
+ Point origin_;
+};
+
+
+/* Point */
+template<class NumberType_>
+class Kernel<NumberType_>::Point: public VectorType
+{
+ public:
+ typedef VectorType Parent;
+ typedef NumberType_ NumberType;
+
+ Point(DimensionType d): Parent(d) {}
+ template<class Vec> Point(const Vec& v): Parent(v) {}
+ Point(const Point& p, const NumberType& pp);
+
+
+ //operator VectorType() const { return *this; }
+
+ NumberType squared_distance(const Point& p) const;
+
+ using Parent::size;
+};
+
+
+/* Sphere */
+template<class NumberType_>
+class Kernel<NumberType_>::Sphere
+{
+ public:
+ Sphere(const Point& center,
+ const NumberType& squared_radius):
+ center_(center), squared_radius_(squared_radius)
+ {}
+
+ /** The result is positive if p lies outside the sphere,
+ 0 if p is on the sphere, and negative if it's inside */
+ NumberType side_of(const Point& p) const;
+
+ const Point& center() const { return center_; }
+ const NumberType& squared_radius() const { return squared_radius_; }
+
+ private:
+ Point center_;
+ NumberType squared_radius_;
+};
+
+
+#include "euclidean.hpp"
+
+#endif // __EUCLEDIAN_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/euclidean.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,141 @@
+/* --- Point --- */
+template<class NumberType_>
+Kernel<NumberType_>::
+Kernel(DimensionType dimension): dimension_(dimension), origin_(dimension)
+{
+ for (unsigned int i = 0; i < dimension; ++i)
+ origin_(i) = NumberType(0);
+}
+
+
+template<class NumberType_>
+Kernel<NumberType_>::Point::
+Point(const Point& p, const NumberType& pp): Parent(p.size() + 1)
+{
+ using boost::numeric::ublas::vector_range;
+ using boost::numeric::ublas::range;
+
+ vector_range<VectorType> vr(*this, range(0, size() - 1));
+ vr = p;
+ (*this)(size() - 1) = pp;
+}
+
+template<class NumberType_>
+typename Kernel<NumberType_>::NumberType
+Kernel<NumberType_>::Point::
+squared_distance(const Point& p) const
+{
+ return boost::numeric::ublas::inner_prod(*this - p, *this - p);
+}
+
+template<class NumberType_>
+std::istream&
+operator>>(std::istream& in, typename Kernel<NumberType_>::Point& p)
+{
+ for (unsigned int i = 0; i < p.size(); ++i)
+ in >> p[i];
+ return in;
+}
+
+template<class NumberType_>
+std::ostream&
+operator<<(std::ostream& out, typename Kernel<NumberType_>::Point& p)
+{
+ for (unsigned int i = 0; p.size(); ++i)
+ out << p[i];
+ return out;
+}
+
+/* --- Sphere --- */
+template<class NumberType_>
+typename Kernel<NumberType_>::NumberType
+Kernel<NumberType_>::Sphere::
+side_of(const Point& p) const
+{ return p.squared_distance(center_) - squared_radius(); }
+
+
+/* --- Kernel --- */
+template<class NumberType_>
+typename Kernel<NumberType_>::Sphere
+Kernel<NumberType_>::
+circumsphere(const PointContainer& points) const
+{
+ if (points.size() == 0) return Sphere(origin(), NumberType(0)); // FIXME: should this be an assertion instead?
+
+ using boost::numeric::ublas::inner_prod;
+ using boost::numeric::ublas::vector_range;
+ using boost::numeric::ublas::range;
+
+ std::vector<Point> basis;
+ basis.reserve(points.size() - 1);
+ for (unsigned int i = 1; i < points.size(); ++i)
+ {
+ Point pt = *points[i] - *points[0];
+ basis.push_back(Point(pt, inner_prod(pt, pt)));
+ for (unsigned int j = 0; j < i - 1; ++j)
+ {
+ basis[i-1] -= basis[j] * inner_prod(basis[i-1], basis[j]) / inner_prod(basis[j], basis[j]);
+ normalize(basis[i-1]);
+ }
+ }
+ Point clifted(origin(), NumberType(1));
+ for (unsigned int j = 0; j < basis.size(); ++j)
+ {
+ clifted -= basis[j] * inner_prod(clifted, basis[j]) / inner_prod(basis[j], basis[j]);
+ normalize(clifted);
+ }
+
+ Point center(vector_range<VectorType>(clifted, range(0, dimension())));
+ center /= NumberType_(-2) * clifted(dimension());
+ NumberType squared_radius = inner_prod(center,center);
+ center += *points[0];
+
+ normalize(center);
+ normalize(squared_radius);
+
+ return Sphere(center, squared_radius);
+}
+
+template<class NumberType_>
+typename Kernel<NumberType_>::NumberType
+Kernel<NumberType_>::
+circumradius(const PointContainer& points) const
+{
+ return circumsphere(points).squared_radius();
+}
+
+template<class NumberType_>
+typename Kernel<NumberType_>::Point
+Kernel<NumberType_>::
+circumcenter(const PointContainer& points) const
+{
+ return circumsphere(points).center();
+}
+
+template<class NumberType_>
+typename Kernel<NumberType_>::NumberType
+Kernel<NumberType_>::
+side_of_circumsphere(const PointContainer& points, const Point& p) const
+{
+ Sphere s = circumsphere(points);
+ return s.side_of(p);
+}
+
+/* --- Kernel Private --- */
+template<class NumberType_>
+typename Kernel<NumberType_>::NumberType&
+Kernel<NumberType_>::
+normalize(NumberType& n) const
+{
+ return number_traits<typename Point::NumberType>::normalize(n);
+}
+
+template<class NumberType_>
+typename Kernel<NumberType_>::Point&
+Kernel<NumberType_>::
+normalize(Point& p) const
+{
+ for (unsigned int i = 0; i < p.size(); ++i)
+ number_traits<typename Point::NumberType>::normalize(p(i));
+ return p;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/kinetic-sort.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,78 @@
+#ifndef __KINETIC_SORT_H__
+#define __KINETIC_SORT_H__
+
+#include <list>
+#include <boost/function.hpp>
+#include <boost/utility.hpp>
+#include <iostream>
+
+/**
+ * Maintains elements of the given data structure in the sorted order assuming the elements follow
+ * trajectories given by TrajectoryExtractor_.
+ *
+ * \arg SortDS_ should be forward and backward iterable, swaps are handles via SwapCallback
+ * \arg TrajectoryExtractor_ applied to the iterator into SortDS_ should return a rational
+ * function describing the
+ * \arg Simulator_ the Simulator type, e.g. Simulator. Note that KineticSort does not store
+ * a pointer to the Simulator (so a pointer is passed in each relevant operation)
+ */
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+class KineticSort
+{
+ public:
+ typedef Simulator_ Simulator;
+ typedef typename Simulator::PolynomialKernel PolynomialKernel;
+ typedef SortDS_ SortDS;
+ typedef TrajectoryExtractor_ TrajectoryExtractor;
+
+ typedef typename Simulator::Key SimulatorKey;
+ typedef typename SortDS::iterator SortDSIterator;
+
+
+ private:
+ /* Implementation */
+ struct Node
+ {
+ SortDSIterator element;
+ SimulatorKey swap_event_key;
+
+ Node(SortDSIterator e, SimulatorKey k):
+ element(e), swap_event_key(k) {}
+ };
+
+ typedef std::list<Node> NodeList;
+
+ public:
+ typedef typename NodeList::iterator iterator;
+ typedef boost::function<void(SortDS*, SortDSIterator pos)>
+ SwapCallback;
+
+
+ /// \name Core Functionality
+ /// @{
+ KineticSort(SortDS* sort, Simulator* simulator, SwapCallback swap_callback);
+
+ template<class InputIterator>
+ void insert(iterator pos, InputIterator f, InputIterator l, Simulator* simulator);
+ void erase(iterator pos, Simulator* simulator);
+ void update_trajectory(iterator pos, Simulator* simulator);
+
+ void swap(iterator pos, Simulator* simulator);
+
+ bool audit(Simulator* simulator) const;
+ /// @}
+
+ private:
+ class SwapEvent;
+ void schedule_swaps(iterator b, iterator e, Simulator* s);
+ void schedule_swaps(iterator i, Simulator* s);
+
+ private:
+ NodeList list_;
+ SortDS* sort_;
+ SwapCallback swap_callback_;
+};
+
+#include "kinetic-sort.hpp"
+
+#endif // __KINETIC_SORT_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/kinetic-sort.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,220 @@
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+KineticSort(SortDS* sort, Simulator* simulator, SwapCallback swap_callback):
+ sort_(sort), swap_callback_(swap_callback)
+{
+ for (SortDSIterator cur = sort->begin(); cur != sort->end(); ++cur)
+ list_.push_back(Node(cur, simulator->null_key()));
+ schedule_swaps(list_.begin(), list_.end(), simulator);
+}
+
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+template<class InputIterator>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+insert(iterator pos, InputIterator f, InputIterator l, Simulator* simulator)
+{
+ iterator previous = pos; --previous;
+ if (previous != list_.end()) simulator->remove(previous->swap_event_key);
+
+ sort_->insert(pos->element, f, l);
+
+ SortDSIterator cur = boost::next(previous)->element;
+ while(cur != pos->element)
+ list_.insert(pos->element, Node(cur++));
+ if (previous != list_.end())
+ schedule_swaps(previous, pos, simulator);
+ else
+ schedule_swaps(list_.begin(), pos, simulator);
+}
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+erase(iterator pos, Simulator* simulator)
+{
+ simulator->remove(pos->swap_event_key);
+ sort_->erase(pos->element);
+ iterator prev = pos; --prev;
+ list_.erase(pos);
+ schedule_swaps(prev, simulator);
+}
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+update_trajectory(iterator pos, Simulator* simulator)
+{
+ iterator prev = boost::prior(pos);
+ if (prev != list_.end())
+ {
+ simulator->remove(prev->swap_event_key);
+ schedule_swaps(prev, simulator);
+ }
+
+ if (boost::next(pos) != list_.end())
+ {
+ simulator->remove(pos->swap_event_key);
+ schedule_swaps(pos, simulator);
+ }
+}
+
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+swap(iterator pos, Simulator* simulator)
+{
+ swap_callback_(sort_, pos->element);
+
+ // TODO: add assertion that boost::next(pos) != list_.end()
+
+ // Remove events
+ iterator prev = boost::prior(pos);
+ if (prev != list_.end())
+ simulator->remove(prev->swap_event_key);
+ iterator next = boost::next(pos);
+ simulator->remove(next->swap_event_key);
+
+ // Swap
+ list_.splice(pos, list_, next);
+
+ // update events
+ next->swap_event_key = pos->swap_event_key;
+ static_cast<SwapEvent*>(*(next->swap_event_key))->set_position(next);
+ schedule_swaps(prev, simulator);
+ schedule_swaps(pos, simulator);
+ //audit(simulator);
+}
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+bool
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+audit(Simulator* simulator) const
+{
+ typedef typename Simulator::RationalFunction RationalFunction;
+ typedef typename Simulator::Time Time;
+
+ Time t = simulator->audit_time();
+ std::cout << "Auditing at " << t << std::endl;
+
+ TrajectoryExtractor te;
+
+ typename NodeList::const_iterator next = list_.begin();
+ typename NodeList::const_iterator cur = next++;
+ RationalFunction cur_trajectory = te(cur->element);
+ while (next != list_.end())
+ {
+ (*(cur->swap_event_key))->print(std::cout << " ") << std::endl;
+
+ RationalFunction next_trajectory = te(next->element);
+ std::cout << " Auditing: " << cur_trajectory << ", " << next_trajectory << std::endl;
+ std::cout << " Difference: " << next_trajectory - cur_trajectory << std::endl;
+ std::cout << " Sign at: " << t << ", " << PolynomialKernel::sign_at(next_trajectory - cur_trajectory, t) << std::endl;
+ if (PolynomialKernel::sign_at(next_trajectory - cur_trajectory, t) == -1)
+ {
+ std::cout << "Audit failed at " << *cur->element << ", " << *next->element << std::endl;
+ return false;
+ }
+
+ cur_trajectory = next_trajectory;
+ cur = next++;
+ }
+ if (cur != list_.end()) (*(cur->swap_event_key))->print(std::cout << " ") << std::endl;
+ return true;
+}
+
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+schedule_swaps(iterator b, iterator e, Simulator* simulator)
+{
+ typedef typename Simulator::RationalFunction RationalFunction;
+
+ TrajectoryExtractor te;
+
+ iterator next = b;
+ iterator cur = next++;
+ RationalFunction cur_trajectory = te(cur->element);
+ while (next != e)
+ {
+ RationalFunction next_trajectory = te(next->element);
+ std::cout << "Next trajectory: " << next_trajectory << std::endl;
+ // TODO: add assertion that (next_trajectory - cur_trajectory)(s->curren_time()) > 0
+ cur->swap_event_key = simulator->add(next_trajectory - cur_trajectory, SwapEvent(this, cur));
+ cur = next++;
+ cur_trajectory = next_trajectory;
+ }
+ if (cur != e) schedule_swaps(cur, simulator);
+}
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+void
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::
+schedule_swaps(iterator i, Simulator* simulator)
+{
+ typedef typename Simulator::RationalFunction RationalFunction;
+
+ if (i == list_.end()) return;
+ if (boost::next(i) == list_.end())
+ {
+ i->swap_event_key = simulator->add(SwapEvent(this, i));
+ return;
+ }
+
+ TrajectoryExtractor te;
+
+ iterator next = boost::next(i);
+ RationalFunction i_trajectory = te(i->element);
+ RationalFunction next_trajectory = te(next->element);
+
+ //std::cout << "Updating swaps for: " << i_trajectory << ", " << next_trajectory << std::endl;
+ //std::cout << "Difference: " << next_trajectory - i_trajectory << std::endl;
+
+ i->swap_event_key = simulator->add(next_trajectory - i_trajectory, SwapEvent(this, i));
+ //i->swap_event_key = simulator->add(next_trajectory, SwapEvent(this, i));
+}
+
+/* SwapEvent */
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+class KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::SwapEvent: public Simulator::Event
+{
+ public:
+ typedef typename Simulator::Event Parent;
+
+ SwapEvent(const SwapEvent& e):
+ sort_(e.sort_), pos_(e.pos_) {}
+ SwapEvent(KineticSort* sort, iterator pos):
+ sort_(sort), pos_(pos) {}
+
+ virtual bool process(Simulator* s) const;
+ void set_position(iterator i) { pos_ = i; }
+ iterator position() const { return pos_; }
+ std::ostream& print(std::ostream& out) const;
+
+ private:
+ KineticSort* sort_;
+ iterator pos_;
+};
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+bool
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::SwapEvent::
+process(Simulator* s) const
+{
+ std::cout << "Swapping. Current time: " << s->current_time() << std::endl;
+ sort_->swap(pos_, s);
+ return true;
+}
+
+template<class SortDS_, class TrajectoryExtractor_, class Simulator_>
+std::ostream&
+KineticSort<SortDS_, TrajectoryExtractor_, Simulator_>::SwapEvent::
+print(std::ostream& out) const
+{
+ Parent::print(out) << ", SwapEvent at " << TrajectoryExtractor_()(position()->element);
+ return out;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/linalg.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,31 @@
+#ifndef __LINALG_H__
+#define __LINALG_H__
+
+#include <vector>
+
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/lu.hpp>
+#include <boost/numeric/ublas/io.hpp>
+
+template<class ValueType_>
+class LinearAlgebra
+{
+ public:
+ typedef ValueType_ ValueType;
+ typedef boost::numeric::ublas::matrix<ValueType> MatrixType;
+ typedef boost::numeric::ublas::vector<ValueType> VectorType;
+
+
+ /* Currently don't need any of this */
+ static ValueType determinant(const MatrixType& a);
+ static void solve(const MatrixType& a, const VectorType& b, VectorType& x);
+
+ private:
+ template<class TriangularType_>
+ static ValueType determinant(const boost::numeric::ublas::triangular_adaptor<MatrixType, TriangularType_>& t);
+};
+
+#include "linalg.hpp"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/linalg.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,38 @@
+template<class ValueType_>
+typename LinearAlgebra<ValueType_>::ValueType
+LinearAlgebra<ValueType_>::
+determinant(const MatrixType& a)
+{
+ using namespace boost::numeric::ublas;
+ MatrixType m = a;
+ lu_factorize(m);
+ return determinant(triangular_adaptor<MatrixType, upper>(m));
+}
+
+template<class ValueType_>
+void
+LinearAlgebra<ValueType_>::
+solve(const MatrixType& a, const VectorType& b, VectorType& x)
+{
+ using namespace boost::numeric::ublas;
+ MatrixType m = a;
+ x = b;
+ lu_factorize(m);
+ //lu_substitute(m, x);
+ inplace_solve(m,x,unit_lower_tag());
+ inplace_solve(m,x,upper_tag());
+}
+
+
+/* Private */
+template<class ValueType_>
+template<class TriangularType_>
+typename LinearAlgebra<ValueType_>::ValueType
+LinearAlgebra<ValueType_>::
+determinant(const boost::numeric::ublas::triangular_adaptor<MatrixType, TriangularType_>& t)
+{
+ ValueType res = ValueType(1);
+ for (typename MatrixType::size_type i = 0; i < t.size1(); ++i)
+ res *= t(i,i);
+ return res;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/number-traits.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,13 @@
+#ifndef __NUMBER_TRAITS_H__
+#define __NUMBER_TRAITS_H__
+
+template<class NumberType_>
+class number_traits
+{
+ public:
+ typedef NumberType_ NumberType;
+
+ static NumberType& normalize(NumberType& n) { return n; }
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/polynomial.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,66 @@
+#ifndef __POLYNOMIAL_H__
+#define __POLYNOMIAL_H__
+
+#include <synaps/upol.h>
+#include <synaps/upol/gcd.h>
+#include <synaps/usolve/Algebraic.h>
+#include <synaps/usolve/algebraic/sign_fct.h>
+#include <synaps/usolve/bezier/SlvBzStd.h>
+//#include <synaps/usolve/Sturm.h>
+//#include <synaps/arithm/Infinity.h>
+
+#include <stack>
+
+#include "rational-function.h"
+
+template<class T> class SynapsTraits;
+
+template<class T>
+class UPolynomial
+{
+ public:
+ typedef typename SynapsTraits<T>::Polynomial Polynomial;
+ typedef RationalFunction<Polynomial> RationalFunction;
+
+ typedef typename SynapsTraits<T>::Solver Solver;
+ typedef typename SynapsTraits<T>::RootType RootType;
+ typedef std::stack<RootType> RootStack;
+
+ static void solve(const RationalFunction& rf, RootStack& stack);
+ static RootType root(const T& r) { return SynapsTraits<T>::root(r); }
+ static int sign_at(const RationalFunction& rf, const RootType& r);
+ static RootType between(const RootType& r1, const RootType& r2) { return SynapsTraits<T>::between(r1,r2); }
+};
+
+template<class T>
+struct SynapsTraits ///< Suitable for double
+{
+ typedef T CoefficientType;
+ typedef SYNAPS::UPolDse<CoefficientType> Polynomial;
+ typedef SYNAPS::SlvBzStd<CoefficientType> Solver;
+ typedef T RootType;
+
+ static RootType root(CoefficientType r) { return r; }
+ static unsigned int multiplicity(RootType r) { return 1; }
+ static int sign_at(const Polynomial& p, RootType r) { return SYNAPS::UPOLDAR::sign_at(p, r); }
+ static RootType between(RootType r1, RootType r2) { return (r1 + r2)/2; }
+};
+
+template<>
+struct SynapsTraits<ZZ>
+{
+ typedef ZZ CoefficientType;
+ typedef SYNAPS::UPolDse<CoefficientType> Polynomial;
+ typedef SYNAPS::Algebraic<CoefficientType> Solver;
+ typedef Solver::root_t RootType;
+
+ static RootType root(const CoefficientType& r) { CoefficientType p[2] = {-r, 1}; return SYNAPS::solve(Polynomial(2, p), Solver(), 0);}
+ static unsigned int multiplicity(const RootType& r) { return r.multiplicity(); }
+ static int sign_at(const Polynomial& p,
+ const RootType& r) { return SYNAPS::ALGEBRAIC::sign_at(p, r); }
+ //static RootType between(const RootType& r1, const RootType& r2) { RootType r = r1; r += r2; r /= root(2); return r; }
+};
+
+#include "polynomial.hpp"
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/polynomial.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,34 @@
+template<class T>
+void
+UPolynomial<T>::
+solve(const RationalFunction& rf, RootStack& stack)
+{
+ typedef SYNAPS::Seq<RootType> RootSeq;
+
+ RootSeq seq_num = SYNAPS::solve(rf.numerator(), Solver());
+ RootSeq seq_den = SYNAPS::solve(rf.denominator(), Solver());
+
+ // TODO: assert that all roots in seq_den have positive multiplicity
+ // TODO: deal with multiplicities for the numerator
+ for (typename RootSeq::const_reverse_iterator cur = seq_num.rbegin();
+ cur != seq_num.rend();
+ ++cur)
+ {
+ if (SynapsTraits<T>::multiplicity(*cur) % 2 != 0)
+ {
+ if (!stack.empty() && stack.top() == *cur) // get rid of even multiplicities
+ // TODO: add logging information for this
+ stack.pop();
+ else
+ stack.push(*cur);
+ }
+ }
+}
+
+template<class T>
+int
+UPolynomial<T>::
+sign_at(const RationalFunction& rf, const RootType& r)
+{
+ return SynapsTraits<T>::sign_at(rf.numerator(), r) * SynapsTraits<T>::sign_at(rf.denominator(), r);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/rational-function.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,107 @@
+#ifndef __RATIONAL_FUNCTION_H__
+#define __RATIONAL_FUNCTION_H__
+
+#include <iostream>
+#include "number-traits.h"
+
+template <class Polynomial_>
+class RationalFunction
+{
+ public:
+ typedef Polynomial_ Polynomial;
+ typedef typename Polynomial::coeff_t CoefficientType;
+ typedef typename Polynomial::value_type ValueType;
+
+ /// \name Constructors
+ /// @{
+ RationalFunction():
+ numerator_(CoefficientType(0)),
+ denominator_(CoefficientType(1)) {}
+ RationalFunction(const Polynomial& p):
+ numerator_(p),
+ denominator_(CoefficientType(1)) {}
+ RationalFunction(const Polynomial& num, const Polynomial& denom):
+ numerator_(num), denominator_(denom) { normalize(); }
+ RationalFunction(const RationalFunction& other):
+ numerator_(other.numerator_),
+ denominator_(other.denominator_) { normalize(); }
+ /// @}
+
+ /// \name Operators
+ /// @{
+ RationalFunction operator-() const;
+ RationalFunction operator+(const RationalFunction& o) const;
+ RationalFunction operator-(const RationalFunction& o) const;
+ RationalFunction operator*(const RationalFunction& o) const;
+ RationalFunction operator/(const RationalFunction& o) const;
+ RationalFunction operator+(const CoefficientType& a) const;
+ RationalFunction operator-(const CoefficientType& a) const;
+ RationalFunction operator*(const CoefficientType& a) const;
+ RationalFunction operator/(const CoefficientType& a) const;
+ /// @}
+
+ /// \name Modifiers
+ /// @{
+ RationalFunction& operator+=(const RationalFunction& o);
+ RationalFunction& operator-=(const RationalFunction& o);
+ RationalFunction& operator*=(const RationalFunction& o);
+ RationalFunction& operator/=(const RationalFunction& o);
+ /// @}
+
+ /// \name Assignment
+ /// @{
+ RationalFunction& operator=(const RationalFunction& o);
+ //RationalFunction& operator=(const Polynomial& o);
+ /// @}
+
+ /// \name Evaluation
+ /// @{
+ ValueType operator()(const ValueType& t) const;
+ bool operator==(const RationalFunction& o) const;
+ bool operator!=(const RationalFunction& o) const { return !operator==(o); }
+ /// @}
+
+ /// \name Accessors
+ /// @{
+ const Polynomial& numerator() const { return numerator_; }
+ const Polynomial& denominator() const { return denominator_; }
+ /// @}
+
+ RationalFunction& normalize();
+
+ private:
+ Polynomial numerator_, denominator_;
+};
+
+template<class P>
+struct number_traits<RationalFunction<P> >
+{
+ typedef RationalFunction<P> NumberType;
+ static NumberType& normalize(NumberType& n) { return n.normalize(); }
+};
+
+
+template<class Polynomial_>
+std::ostream&
+operator<<(std::ostream& out, const RationalFunction<Polynomial_>& r)
+{ return out << r.numerator() << " / " << r.denominator(); }// << ", gcd: " << gcd(r.numerator(), r.denominator()); }
+
+template<class Polynomial_>
+inline RationalFunction<Polynomial_>
+operator*(const typename RationalFunction<Polynomial_>::CoefficientType& a, const RationalFunction<Polynomial_>& r)
+{ return (r * a); }
+
+template<class Polynomial_>
+inline RationalFunction<Polynomial_>
+operator+(const typename RationalFunction<Polynomial_>::CoefficientType& a, const RationalFunction<Polynomial_>& r)
+{ return (r + a); }
+
+template<class Polynomial_>
+inline RationalFunction<Polynomial_>
+operator-(const typename RationalFunction<Polynomial_>::NT& a, const RationalFunction<Polynomial_>& r)
+{ return -(r - a); }
+
+
+#include "rational-function.hpp"
+
+#endif // __RATIONAL_FUNCTION_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/rational-function.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,150 @@
+/* Operators */
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator-() const
+{ return RationalFunction(-numerator_,denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator+(const RationalFunction& o) const
+{ return RationalFunction(numerator_*o.denominator_ + o.numerator_*denominator_, denominator_*o.denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator-(const RationalFunction& o) const
+{ RationalFunction tmp(*this); tmp -= o; return tmp; }
+//{ return RationalFunction(numerator_*o.denominator_ - o.numerator_*denominator_, denominator_*o.denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator*(const RationalFunction& o) const
+{ return RationalFunction(numerator_*o.numerator_, denominator_*o.denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator/(const RationalFunction& o) const
+{ return RationalFunction(numerator_*o.denominator_, denominator_*o.numerator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator+(const typename RationalFunction<P>::CoefficientType& a) const
+{ return RationalFunction(numerator_ + a*denominator_, denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator-(const typename RationalFunction<P>::CoefficientType& a) const
+{ return operator+(-a); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator*(const typename RationalFunction<P>::CoefficientType& a) const
+{ return RationalFunction(a*numerator_, denominator_); }
+
+template<class P>
+RationalFunction<P>
+RationalFunction<P>::
+operator/(const typename RationalFunction<P>::CoefficientType& a) const
+{ return RationalFunction(numerator_, a*denominator_); }
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator+=(const RationalFunction& o)
+{
+ numerator_ *= o.denominator_;
+ numerator_ += o.numerator_*denominator_;
+ denominator_ *= o.denominator_;
+ return *this;
+}
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator-=(const RationalFunction& o)
+{
+ numerator_ *= o.denominator_;
+ numerator_ -= o.numerator_*denominator_;
+ denominator_ *= o.denominator_;
+ return *this;
+}
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator*=(const RationalFunction& o)
+{
+ numerator_ *= o.numerator_;
+ denominator_ *= o.denominator_;
+ return *this;
+}
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator/=(const RationalFunction& o)
+{
+ numerator_ *= o.denominator_;
+ denominator_ *= o.numerator_;
+ return *this;
+}
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator=(const RationalFunction& o)
+{
+ numerator_ = o.numerator_;
+ denominator_ = o.denominator_;
+ return *this;
+}
+
+#if 0
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+operator=(const Polynomial& o)
+{
+ numerator_ = o;
+ denominator_ = 1;
+ return *this;
+}
+#endif
+
+/* Evaluation */
+template<class P>
+typename RationalFunction<P>::ValueType
+RationalFunction<P>::
+operator()(const typename RationalFunction<P>::ValueType& t) const
+{ return numerator_(t)/denominator_(t); }
+
+template<class P>
+bool
+RationalFunction<P>::
+operator==(const RationalFunction& o) const
+{ return (numerator_ == o.numerator_) && (denominator_ == o.denominator_); }
+
+template<class P>
+RationalFunction<P>&
+RationalFunction<P>::
+normalize()
+{
+#if 0
+ std::cout << "This: " << std::flush << this << std::endl;
+ std::cout << "Numerator address: " << std::flush << &numerator_ << std::endl;
+ std::cout << "Denominator address: " << std::flush << &denominator_ << std::endl;
+ std::cout << "Normalizing (numerator): " << std::flush << numerator_ << std::endl;
+ std::cout << "Normalizing (denominator): " << std::flush << denominator_ << std::endl;
+#endif
+ Polynomial divisor = gcd(numerator_, denominator_);
+ numerator_ /= divisor;
+ denominator_ /= divisor;
+ return *this;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/simulator.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,108 @@
+#ifndef __SIMULATOR_H__
+#define __SIMULATOR_H__
+
+#include "utilities/eventqueue.h"
+#include "polynomial.h"
+
+template<class Comparison> class IndirectComparison;
+template<class PolyKernel_, class Simulator_> class Event;
+
+template<class PolyKernel_, template<class Event> class EventComparison_ = std::less>
+class Simulator
+{
+ public:
+ typedef PolyKernel_ PolynomialKernel;
+ typedef typename PolynomialKernel::Polynomial Polynomial;
+ typedef typename PolynomialKernel::RationalFunction RationalFunction;
+ typedef typename PolynomialKernel::RootStack RootStack;
+ typedef typename PolynomialKernel::RootType RootType;
+ typedef RootType Time;
+
+ class Event;
+ typedef EventComparison_<Event> EventComparison;
+ typedef EventQueue<Event*, IndirectComparison<EventComparison> >
+ EventQueue;
+ typedef typename EventQueue::iterator Key;
+ typedef typename EventQueue::const_iterator const_Key;
+
+
+ Simulator(Time start = PolynomialKernel::root(0)):
+ current_(start),
+ reached_infinity_(false) {}
+
+
+ template<class Event_>
+ Key add(const Event_& e);
+ template<class Event_>
+ Key add(const RationalFunction& f, const Event_& e);
+ void process();
+ void update(Key k, const RationalFunction& f);
+
+ void remove(Key k) { queue_.remove(k); }
+ Key null_key() { return queue_.end(); }
+
+ Time current_time() const { return current_; }
+ Time audit_time() const;
+ bool reached_infinity() const { return reached_infinity_; }
+
+ std::ostream& print(std::ostream& out) const;
+
+ private:
+ void update(Key i);
+
+ private:
+ Time current_;
+ EventQueue queue_;
+ bool reached_infinity_;
+};
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+class Simulator<PolyKernel_, EventComparison_>::Event
+{
+ public:
+ typedef PolyKernel_ PolynomialKernel;
+ typedef typename PolynomialKernel::RootStack RootStack;
+
+ /// Returns true if the event needs to remain in the Simulator
+ /// (top of the root_stack() will be used for new time)
+ virtual bool process(Simulator* s) const =0;
+
+ RootStack& root_stack() { return root_stack_; }
+ const RootStack& root_stack() const { return root_stack_; }
+
+ bool operator<(const Event& e) const
+ {
+ if (root_stack().empty())
+ return false;
+ else if (e.root_stack().empty())
+ return true;
+ else
+ return root_stack().top() < e.root_stack().top();
+ }
+
+ int sign_before() const { return root_stack().top().sign_low(); }
+ int sign_after() const { return root_stack().top().sign_high(); }
+
+ virtual std::ostream& print(std::ostream& out) const { return out << "Event with " << root_stack_.size() << " roots"; }
+
+ private:
+ RootStack root_stack_;
+};
+
+template<class Comparison_>
+class IndirectComparison: public std::binary_function<const typename Comparison_::first_argument_type*,
+ const typename Comparison_::second_argument_type*,
+ bool>
+{
+ public:
+ typedef Comparison_ Comparison;
+ typedef const typename Comparison::first_argument_type* first_argument_type;
+ typedef const typename Comparison::second_argument_type* second_argument_type;
+
+ bool operator()(first_argument_type e1, second_argument_type e2) const
+ { return Comparison()(*e1, *e2); }
+};
+
+#include "simulator.hpp"
+
+#endif // __SIMULATOR_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/geometry/simulator.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,82 @@
+template<class PolyKernel_, template<class Event> class EventComparison_>
+template<class Event_>
+typename Simulator<PolyKernel_, EventComparison_>::Key
+Simulator<PolyKernel_, EventComparison_>::
+add(const Event_& e)
+{
+ Event* ee = new Event_(e);
+ return queue_.push(ee);
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+template<class Event_>
+typename Simulator<PolyKernel_, EventComparison_>::Key
+Simulator<PolyKernel_, EventComparison_>::
+add(const RationalFunction& f, const Event_& e)
+{
+ Event* ee = new Event_(e);
+ //std::cout << "Solving: " << f << std::endl;
+ PolynomialKernel::solve(f, ee->root_stack());
+ while (!ee->root_stack().empty() && ee->root_stack().top() < current_time())
+ ee->root_stack().pop();
+ //std::cout << "Pushing: " << ee->root_stack().top() << std::endl;
+ return queue_.push(ee);
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+void
+Simulator<PolyKernel_, EventComparison_>::
+update(Key k, const RationalFunction& f)
+{
+ Event* ee = *k;
+ ee->root_stack() = RootStack(); // no clear() in std::stack
+ PolynomialKernel::solve(f, ee->root_stack());
+ while (!ee->root_stack().empty() && ee->root_stack().top() < current_time())
+ ee->root_stack().pop();
+ update(k);
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+void
+Simulator<PolyKernel_, EventComparison_>::
+process()
+{
+ std::cout << "Queue size: " << queue_.size() << std::endl;
+ Key top = queue_.top();
+ Event* e = *top;
+
+ if (e->root_stack().empty()) { reached_infinity_ = true; return; }
+ else { current_ = e->root_stack().top(); e->root_stack().pop(); }
+
+ if (e->process(this)) update(top);
+ else { queue_.pop(); delete e; }
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+void
+Simulator<PolyKernel_, EventComparison_>::
+update(Key i)
+{
+ queue_.update(i);
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+typename Simulator<PolyKernel_, EventComparison_>::Time
+Simulator<PolyKernel_, EventComparison_>::
+audit_time() const
+{
+ const_Key top = queue_.top();
+ Event* e = *top;
+
+ if (e->root_stack().empty()) return current_ + 1;
+ else return PolynomialKernel::between(e->root_stack().top(), current_);
+}
+
+template<class PolyKernel_, template<class Event> class EventComparison_>
+std::ostream&
+Simulator<PolyKernel_, EventComparison_>::
+print(std::ostream& out) const
+{
+ out << "Simulator: " << std::endl;
+ return queue_.print(out, " ");
+}
--- a/include/lowerstarfiltration.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
- */
-
-#ifndef __LOWERSTARFILTRATION_H__
-#define __LOWERSTARFILTRATION_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include "filtration.h"
-#include "simplex.h"
-#include "consistencylist.h"
-#include <boost/utility.hpp>
-#include <list>
-#include "types.h"
-
-#include <boost/serialization/access.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/map.hpp>
-#include <boost/serialization/base_object.hpp>
-#include <boost/serialization/nvp.hpp>
-
-
-template<class VI,
- class Smplx = SimplexWithAttachment<VI>,
- class FltrSmplx = FiltrationSimplex<Smplx>,
- class Vnrd = Vineyard<FltrSmplx> >
-class LowerStarFiltration: public Filtration<Smplx, FltrSmplx, Vnrd>
-{
- public:
- // Treat VertexIndex as an iterator
- typedef VI VertexIndex;
- typedef Smplx Simplex;
- typedef Filtration<Simplex> Parent;
- typedef typename Parent::Vineyard Vineyard;
-
- typedef typename Parent::Index Index;
- typedef typename Parent::const_Index const_Index;
- typedef typename Parent::Cycle Cycle;
- typedef typename Parent::Trail Trail;
- typedef typename Simplex::Cycle SimplexBoundaryCycle;
-
- struct VertexDescriptor;
- typedef ConsistencyList<VertexDescriptor> VertexOrder;
- typedef typename VertexOrder::iterator VertexOrderIndex;
- typedef typename VertexOrder::const_iterator const_VertexOrderIndex;
- typedef typename VertexOrder::LessThanComparison VertexOrderComparison;
- struct SimplexAttachmentComparison;
-
- public:
- template<class VertexCmp>
- LowerStarFiltration(VertexIndex begin, VertexIndex end, const VertexCmp& cmp, Vineyard* vineyard);
-
- using Parent::size;
- using Parent::begin;
- using Parent::end;
- VertexIndex num_vertices() const { return vertex_order.size(); }
- const VertexOrderComparison&
- get_vertex_cmp() const { return vertex_cmp; }
-
- Index append(const Simplex& s);
- bool transpose_vertices(const VertexOrderIndex& voi);
-
- protected:
- /// Hint function: if unsure, should return true
- virtual bool neighbors(VertexIndex v1, VertexIndex v2) const { return true; }
-
- private:
- bool transpose(Index i);
- void assert_pairing(Index i);
-
- private:
- VertexOrder vertex_order;
- VertexOrderComparison vertex_cmp;
-
- /* Serialization */
- protected:
- LowerStarFiltration() {}
-
- private:
- friend class boost::serialization::access;
-
- template<class Archive>
- void save(Archive& ar, version_type ) const { ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent); }
-
- template<class Archive>
- void load(Archive& ar, version_type );
-
- BOOST_SERIALIZATION_SPLIT_MEMBER()
-};
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-struct LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::VertexDescriptor
-{
- VertexDescriptor(VertexIndex vi, Index si):
- vertex_index(vi), simplex_index(si)
- {}
-
- VertexIndex vertex_index;
- Index simplex_index;
-};
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-struct LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::SimplexAttachmentComparison
-{
- bool operator()(const Simplex& first, const Simplex& second) const;
- VertexOrderComparison vertex_cmp;
-};
-
-#include "lowerstarfiltration.hpp"
-
-#endif // __LOWERSTARFILTRATION_H__
--- a/include/lowerstarfiltration.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/* Implementations */
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-template<class VertexCmp>
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-LowerStarFiltration(VertexIndex begin, VertexIndex end, const VertexCmp& cmp, Vineyard* vineyard):
- Parent(vineyard)
-{
- // Record VertexIndexes in a temporary list
- typedef std::list<VertexIndex> VertexIndexList;
- VertexIndexList tmp_list;
- while (begin != end)
- tmp_list.push_back(begin++);
-
- // Sort the temporary list
- tmp_list.sort(cmp);
-
- // Record vertex order
- for(typename VertexIndexList::const_iterator cur = tmp_list.begin(); cur != tmp_list.end(); ++cur)
- (*cur)->set_order(vertex_order.push_back(VertexDescriptor(*cur, Parent::append(Simplex(*cur)))));
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-typename LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::Index
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-append(const Simplex& s)
-{
- AssertMsg(s.dimension() != 0, "All vertices must have been inserted in the constructor");
-
- // Find the highest vertex
- typename Simplex::VertexContainer::const_iterator cur = s.vertices().begin(), max = cur++;
- for (; cur != s.vertices().end(); ++cur)
- if (!vertex_cmp((*cur)->get_order(), (*max)->get_order()))
- max = cur;
-
- Index ms = (*max)->get_order()->simplex_index; Index prior;
- do { prior = ms++; } while (ms->dimension() <= s.dimension() && ms != Parent::end() && ms->get_attachment() == *max);
-
- Index i = Parent::insert(prior, s);
- i->set_attachment(*max);
-
- return i;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::SimplexAttachmentComparison::
-operator()(const Simplex& first, const Simplex& second) const
-{
- int cmp = vertex_cmp.compare(first.get_attachment()->get_order(), second.get_attachment()->get_order());
- if (cmp == 0)
- return first.dimension() < second.dimension();
- else
- return cmp == -1;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-transpose_vertices(const VertexOrderIndex& order)
-{
- Count("VertexTransposition");
-
-#if COUNTERS
- if ((counters.lookup("VertexTransposition") % 1000000) == 0)
- {
- Dout(dc::lsfiltration, "Vertex transpositions: " << counters.lookup("VertexTransposition"));
- Dout(dc::lsfiltration, "Simplex transpositions: " << counters.lookup("SimplexTransposition"));
- Dout(dc::lsfiltration, "Attachment changed: " << counters.lookup("ChangedAttachment"));
- Dout(dc::lsfiltration, "Regular disconnected: " << counters.lookup("RegularDisconnected"));
- Dout(dc::lsfiltration, "Pairing Changed: " << counters.lookup("ChangedPairing"));
- Dout(dc::lsfiltration, "------------------------");
- }
-#endif // COUNTERS
-
- Dout(dc::lsfiltration, "Transposing vertices (" << order->vertex_index << ", "
- << boost::next(order)->vertex_index << ")");
-
- Index i = order->simplex_index;
- Index i_prev = boost::prior(i);
- Index i_next = boost::next(order)->simplex_index;
- Index i_next_prev = boost::prior(i_next); // transpositions are done in terms of the first index in the pair
- Index j = boost::next(i_next);
-
- const VertexIndex& v_i = order->vertex_index;
- const VertexIndex& v_i_next = boost::next(order)->vertex_index;
- bool nbghrs = neighbors(v_i, v_i_next);
-
- bool result = false;
-
- // First, move the vertex --- this can be sped up if we devise special "vertex transpose" operation
- while (i_next_prev != i_prev)
- {
- result |= transpose(i_next_prev);
- i_next_prev = boost::prior(i_next);
- }
- Dout(dc::lsfiltration, "Done moving the vertex");
-
- // Second, move the simplices attached to it
- Dout(dc::lsfiltration, "Moving attached simplices");
- while (j != Parent::end() && j->get_attachment() == v_i_next)
- {
- Dout(dc::lsfiltration, " Considering " << *j);
- if (nbghrs && j->contains(v_i)) // short circuit
- {
- Count("ChangedAttachment");
- Dout(dc::lsfiltration, " Attachment changed for " << *j);
- j->set_attachment(v_i);
- ++j;
- continue;
- }
-
- Index j_prev = j; ++j;
- while ((--j_prev)->get_attachment() != v_i_next) // i.e., until we have reached v_i_next
- // (and the simplices that follow it) again
- {
- Dout(dc::lsfiltration, " Moving: " << *j_prev << ", " << *boost::next(j_prev));
- AssertMsg(j_prev->get_attachment() == v_i, "Simplex preceding the one being moved must be attached to v_i");
- result |= transpose(j_prev);
- --j_prev;
- }
- }
- Dout(dc::lsfiltration, "Done moving attached simplices");
- vertex_order.swap(order, boost::next(order));
-
- return result;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-transpose(Index i)
-{
- Index j = boost::next(i);
-
- Dout(dc::lsfiltration, " Transposing (" << *i << ", " << *(i->pair()) << ") and ("
- << *j << ", " << *(j->pair()) << ")");
-
- assert_pairing(i);
- assert_pairing(j);
-
- bool res = Parent::transpose(i, false);
- Dout(dc::lsfiltration, " " << *j << ": " << *(j->pair()) << ", " << *i << ": " << *(i->pair()));
-
- assert_pairing(j);
- assert_pairing(i);
-
- return res;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-void
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-assert_pairing(Index i)
-{
-#ifndef NDEBUG
- AssertMsg(i != Parent::end(), "Cannot assert pairing of end()");
- if (!i->sign())
- {
- if (i->pair() != i->cycle().top(Parent::get_cycles_cmp()))
- {
- Dout(dc::lsfiltration, "i (negative): " << *i);
- Dout(dc::lsfiltration, "pair(i): " << *(i->pair()));
- Dout(dc::lsfiltration, "i->cycle().top(): " << *(i->cycle().top(Parent::get_cycles_cmp())));
- DoutFatal(dc::fatal, "Pairing not matching the matrix at " << *i);
- }
- } else
- {
- if (i->pair() != i)
- {
- if (i->pair()->cycle().top(Parent::get_cycles_cmp()) != i)
- {
- Dout(dc::lsfiltration, "i (positive): " << *i);
- Dout(dc::lsfiltration, "pair(i): " << *(i->pair()));
- Dout(dc::lsfiltration, "pair(i)->cycle(): " << i->pair()->cycle());
- Dout(dc::lsfiltration, "pair->cycle().top(): " << *(i->pair()->cycle().top(Parent::get_cycles_cmp())));
- DoutFatal(dc::fatal, "Pairing not matching the matrix at " << *(i->pair()));
- }
- }
- }
-#endif
-}
-
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-template<class Archive>
-void
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-load(Archive& ar, version_type )
-{
-/*
- ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
-
- // Count the number of vertices
- VertexIndex num_vertices = 0;
- for (Index cur = begin(); cur != end(); ++cur)
- if (dimension(cur) == 0)
- num_vertices++;
-
- // Second pass to record vertex_order
- vertex_order.resize(num_vertices);
- inverse_vertex_order.resize(num_vertices);
- num_vertices = 0;
- for (Index cur = begin(); cur != end(); ++cur)
- {
- if (dimension(cur) == 0)
- {
- vertex_order[num_vertices].index = cur;
- vertex_order[num_vertices].vertex_index = *(cur->get_vertices().begin());
- inverse_vertex_order[vertex_order[num_vertices].vertex_index] = num_vertices;
- ++num_vertices;
- }
- }
-*/
-}
-
-
--- a/include/orderlist.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2006
- *
- * Implements the simplified order list data strcutre given in ``Two Simplified
- * Algorithms for Maintaining Order in a List'' by Bender et al.
- *
- * Indirection is not implemented, so the insertion cost is amortized O(log n),
- * while comparison and deletion are O(1).
- */
-
-#ifndef __ORDERLIST_H__
-#define __ORDERLIST_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include <iterator>
-#include <iostream>
-#include <list>
-
-#include "types.h"
-//#include "counter.h"
-
-#include <boost/utility.hpp>
-#include <boost/iterator/iterator_adaptor.hpp>
-//#include <boost/type_traits/is_convertible.hpp>
-//#include <boost/utility/enable_if.hpp>
-
-
-typedef unsigned int OrderType;
-
-template<class T> struct OrderListNode;
-template<class T> class OrderListIterator;
-template<class T> class const_OrderListIterator;
-
-/**
- * OrderList stores a list of objects while maintaining their total order under
- * the operations of insert(), swap(), and delete(). push_back() is provided for
- * uniformity, OrderComparison member class carries out comparison of the
- * elements.
- */
-template<class T>
-class OrderList: public std::list<OrderListNode<T> >
-{
- public:
- class OrderComparison;
-
- /// OrderComparison type
- typedef OrderComparison OrderComparison;
-
- typedef OrderListNode<T> NodeType;
- typedef OrderList<T> Self;
- typedef std::list<NodeType > Parent;
-
- typedef T value_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef OrderListIterator<T> iterator;
- typedef const_OrderListIterator<T> const_iterator;
-
- OrderList() {}
- ~OrderList() { clear(); }
-
- /// \name Order operations
- void swap(iterator i, iterator j); ///< Exchanges the order of simplices pointed to by i and j
- template<class BinaryPredicate>
- void sort(BinaryPredicate cmp); ///< Sorts the elements in accordance with cmp
-
- /// \name Container operations
- /// @{
- // Explicit calls instead of using declarations for Doxygen
- iterator push_back(const_reference x);
- iterator insert(iterator predecessor, const_reference x); ///< Inserts x immediately after predecessor (has to be a valid iterator)
- void erase(iterator x) { Parent::erase(x.get_base()); }
-
- void clear() { return Parent::clear(); }
- bool empty() const { return Parent::empty(); }
- SizeType size() const { return Parent::size(); }
- iterator begin() { return iterator(Parent::begin()); }
- const_iterator begin() const { return const_iterator(Parent::begin()); }
- iterator end() { return iterator(Parent::end()); }
- const_iterator end() const { return const_iterator(Parent::end()); }
- reference back() { return Parent::back(); }
- const_reference back() const { return Parent::back(); }
- void pop_back() { return Parent::pop_back(); }
-
- iterator last() { return iterator(boost::prior(end())); }
- const_iterator last() const { return const_iterator(boost::prior(end())); }
- /// @}
-
- /// \name Debugging operations
- /// @{
- void show_elements() const;
- /// @}
-
- private:
- static const float density_threshold = 1.2;
-};
-
-/// Basic comparison that LessThan and GreaterThan derive from
-template<class T>
-class OrderList<T>::OrderComparison
-{
- public:
- typedef typename OrderList<T>::const_iterator ComparableType;
- int compare(ComparableType a, ComparableType b) const; /// (-1,0,1) = a (precedes, ==, succeeds) b
- bool operator()(ComparableType a, ComparableType b) const;
-};
-
-/// Structure storing auxilliary information requred for each node of OrderList
-template<class T>
-struct OrderListNode
-{
- OrderListNode(const T& d, unsigned int t):
- data(d), tag(t)
- {}
-
- T data;
- OrderType tag;
-
- std::ostream& operator<<(std::ostream& out) const { return out << data << ": " << tag; }
-};
-
-template<class T, class BinaryPredicate>
-class OrderListNodeComparison
-{
- public:
- typedef OrderListNode<T> Node;
- OrderListNodeComparison(BinaryPredicate cmp): cmp_(cmp) {}
- bool operator()(const Node& a, const Node& b) const { return cmp_(a.data, b.data); }
-
- private:
- BinaryPredicate cmp_;
-};
-
-template<class T>
-std::ostream& operator<<(std::ostream& out, const OrderListNode<T>& n) { return n.operator<<(out); }
-
-template<class T>
-class OrderListIterator: public boost::iterator_adaptor<OrderListIterator<T>,
- typename OrderList<T>::Parent::iterator,
- T>
-{
- private:
- struct enabler {};
-
- public:
- typedef typename OrderList<T>::Parent OrderListParent;
- typedef boost::iterator_adaptor<OrderListIterator<T>,
- typename OrderListParent::iterator,
- T> Parent;
- typedef typename Parent::reference reference;
- typedef typename Parent::base_type base_type;
-
- OrderListIterator() {}
- OrderListIterator(const typename OrderListParent::iterator& iter):
- OrderListIterator::iterator_adaptor_(iter)
- {}
- OrderListIterator(const OrderListIterator<T>& other):
- OrderListIterator::iterator_adaptor_(other.base())
- {}
-
- private:
- friend class boost::iterator_core_access;
- reference dereference() const { return Parent::base_reference()->data; }
- base_type& get_base() { return Parent::base_reference(); }
-
- friend class OrderList<T>;
-};
-
-template<class T>
-class const_OrderListIterator: public boost::iterator_adaptor<const_OrderListIterator<T>,
- typename OrderList<T>::Parent::const_iterator,
- const T>
-{
- private:
- struct enabler {};
-
- public:
- typedef typename OrderList<T>::Parent OrderListParent;
- typedef boost::iterator_adaptor<const_OrderListIterator<T>,
- typename OrderListParent::const_iterator,
- const T> Parent;
- typedef typename Parent::reference reference;
- typedef typename Parent::base_type base_type;
-
- const_OrderListIterator() {}
- const_OrderListIterator(const typename OrderListParent::const_iterator& iter):
- const_OrderListIterator::iterator_adaptor_(iter)
- {}
- const_OrderListIterator(const const_OrderListIterator<T>& other):
- const_OrderListIterator::iterator_adaptor_(other.base())
- {}
- const_OrderListIterator(const OrderListIterator<T>& other):
- const_OrderListIterator::iterator_adaptor_(other.base())
- {}
-
- private:
- friend class boost::iterator_core_access;
- reference dereference() const { return Parent::base_reference()->data; }
- const base_type&
- get_base() { return Parent::base_reference(); }
-
- friend class OrderList<T>;
- friend class OrderList<T>::OrderComparison;
-};
-
-
-#include "orderlist.hpp"
-
-#endif // __ORDERLIST_H__
--- a/include/orderlist.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/* Implementations */
-
-template<class T>
-void
-OrderList<T>::
-swap(iterator i, iterator j)
-{
- typename Parent::iterator i_base = i.get_base();
- typename Parent::iterator j_base = j.get_base();
- std::swap(i_base->tag, j_base->tag);
-
- // Exchange the actual elements in the list --- so that iterators behave as expected
- typename Parent::iterator after_j = boost::next(j_base);
- Parent::splice(i_base, *this, j_base);
- Parent::splice(after_j, *this, i_base);
-}
-
-template<class T>
-template<class BinaryPredicate>
-void
-OrderList<T>::
-sort(BinaryPredicate cmp)
-{
- Parent::sort(OrderListNodeComparison<T, BinaryPredicate>(cmp));
- OrderType cur_order = 0;
- for (typename Parent::iterator cur = Parent::begin(); cur != Parent::end(); ++cur)
- cur->tag = cur_order++;
-}
-
-template<class T>
-typename OrderList<T>::iterator
-OrderList<T>::
-push_back(const_reference x)
-{
- if (empty())
- Parent::push_back(NodeType(x, 0));
- else
- Parent::push_back(NodeType(x, last().get_base()->tag + 1));
-
- return last();
-}
-
-template<class T>
-typename OrderList<T>::iterator
-OrderList<T>::
-insert(iterator p, const_reference x)
-{
- typename Parent::iterator p_base = p.get_base();
- OrderType tag = (p_base++)->tag + 1;
- typename Parent::iterator new_base = Parent::insert(p_base, NodeType(x, tag));
-
- if (p_base->tag != tag)
- return iterator(new_base);
-
- // Find non-overflowing region
- unsigned int num_elements = 1, maximum = 1, lower = tag, upper = tag, level = 0;
- float inv_density = 1;
- typename Parent::iterator prev = p_base, next = p_base;
- --(--prev); ++next; // move prev back twice to skip over the newly inserted element
-
- do
- {
- lower &= ~(1 << level);
- upper |= (1 << level);
- maximum <<= 1; inv_density *= density_threshold;
- ++level;
-
- while (prev != Parent::end() && prev->tag >= lower) { --prev; ++num_elements; }
- while (next != Parent::end() && next->tag <= upper) { ++next; ++num_elements; }
- } while (inv_density * num_elements >= maximum);
- ++num_elements; // for the extra element inserted
-
- Dout(dc::orderlist, num_elements << ", " << lower << ", " << upper);
- Dout(dc::orderlist, "prev is at the end: " << (prev == Parent::end()));
- Dout(dc::orderlist, "next is at the end: " << (next == Parent::end()));
-
- // Reorder
- AssertMsg((upper - lower + 1)/num_elements > 0, "Spacing between new tags must be non-zero");
- for (int i = 0; i < num_elements; ++i)
- {
- (++prev)->tag = lower + i*((upper - lower + 1)/num_elements);
- Dout(dc::orderlist, prev->tag);
- AssertMsg(prev->tag != 0 || prev == Parent::begin(), "Cannot assign 0 tag except at the beginning of OrderList");
- }
-
- AssertMsg(++prev == next, "prev + num_elements != next in OrderList::insert()");
-
- return iterator(new_base);
-}
-
-template<class T>
-void
-OrderList<T>::
-show_elements() const
-{
- for (const_iterator cur = begin(); cur != end(); ++cur)
- std::cout << *(cur.get_base()) << std::endl;
- std::cout << std::endl;
-}
-
-/* OrderComparison */
-template<class T>
-int
-OrderList<T>::OrderComparison::
-compare(ComparableType a, ComparableType b) const
-{
- if (a.get_base()->tag == b.get_base()->tag) return 0;
- if (a.get_base()->tag < b.get_base()->tag) return -1;
- return 1;
-}
-
-template<class T>
-bool
-OrderList<T>::OrderComparison::
-operator()(ComparableType a, ComparableType b) const
-{
- return (compare(a,b) < 0);
-}
--- a/include/simplex.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
- */
-
-#ifndef __SIMPLEX_H__
-#define __SIMPLEX_H__
-
-#include "sys.h"
-#include "debug.h"
-
-#include <set>
-#include <list>
-#include <iostream>
-
-#include "types.h"
-
-#include <boost/serialization/access.hpp>
-
-
-/**
- * SimplexWithVertices is a basic simplex class. It stores vertices of a given type,
- * and knows how to compute its own boundary. It should probably be used as a base
- * class for any explicit simplex representation.
- */
-template<class V>
-class SimplexWithVertices
-{
- public:
- typedef V Vertex;
- typedef SimplexWithVertices<Vertex> Self;
-
- typedef std::set<Vertex> VertexContainer;
- typedef std::list<Self> Cycle;
-
- /// \name Constructors
- /// @{
- SimplexWithVertices() {}
- SimplexWithVertices(const Self& s):
- vertices_(s.vertices_) {}
- template<class Iterator>
- SimplexWithVertices(Iterator bg, Iterator end):
- vertices_(bg, end) {}
- SimplexWithVertices(const VertexContainer& v):
- vertices_(v) {}
- SimplexWithVertices(Vertex v):
- vertices_() { vertices_.insert(v); }
- /// @}
-
- /// \name Core
- /// @{
- Cycle boundary() const;
- Dimension dimension() const { return vertices_.size()-1; }
- /// @}
-
- /// \name Vertex manipulation
- /// @{
- bool contains(const Vertex& v) const { return (vertices_.find(v) != vertices_.end()); }
- const VertexContainer& vertices() const { return vertices_; }
- void add(const Vertex& v) { vertices_.insert(v); }
- /// @}
-
- /// \name Assignment and comparison
- /// Gives an ordering on simplices (for example, so that simplices can be used as keys for std::map)
- /// @{
- const Self& operator=(const Self& s) { vertices_ = s.vertices_; return *this; }
- bool operator==(const Self& s) const { return vertices_ == s.vertices_; }
- bool operator<(const Self& s) const { return vertices_ < s.vertices_; }
- /// @}
-
- std::ostream& operator<<(std::ostream& out) const;
-
- private:
- VertexContainer vertices_;
-
- private:
- /* Serialization */
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type );
-};
-
-/**
- * SimplexWithValue explicitly adds a RealType value to the SimplexWithVertices.
- */
-template<class Vert>
-class SimplexWithValue: public SimplexWithVertices<Vert>
-{
- public:
- typedef Vert Vertex;
- typedef RealType Value;
- typedef SimplexWithValue<Vertex> Self;
- typedef SimplexWithVertices<Vertex> Parent;
-
- typedef typename Parent::VertexContainer VertexContainer;
-
- /// \name Constructors
- /// @{
- SimplexWithValue(Value value = 0): val(value) {}
- SimplexWithValue(const Self& s):
- Parent(s), val(s.val) {}
- SimplexWithValue(const Parent& s, Value value = 0):
- Parent(s), val(value) {}
- template<class Iterator>
- SimplexWithValue(Iterator bg, Iterator end, Value value = 0):
- Parent(bg, end), val(value) {}
- SimplexWithValue(const VertexContainer& v, Value value = 0):
- Parent(v), val(value) {}
- /// @}
-
- /// \name Core
- /// @{
- void set_value(Value value) { val = value; }
- Value get_value() const { return val; }
- /// @}
-
- const Self& operator=(const Self& s);
- std::ostream& operator<<(std::ostream& out) const;
-
- private:
- Value val;
-
- /* Serialization */
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type );
-};
-
-/**
- * SimplexWithAttachment stores the vertex to which the simplex is attached (meant for lower-star filtrations)
- */
-template<typename V>
-class SimplexWithAttachment: public SimplexWithVertices<V>
-{
- public:
- typedef V VertexIndex;
- typedef SimplexWithVertices<VertexIndex> Parent;
-
- /// \name Constructors
- /// @{
- SimplexWithAttachment():
- attachment(VertexIndex()) {}
- template<class Iterator>
- SimplexWithAttachment(Iterator bg, Iterator end):
- Parent(bg, end) {}
- SimplexWithAttachment(const Parent& s):
- Parent(s) {}
- SimplexWithAttachment(VertexIndex vi):
- Parent(vi), attachment(vi) {}
- /// @}
-
- void set_attachment(VertexIndex v) { attachment = v; }
- VertexIndex get_attachment() const { return attachment; }
-
- private:
- VertexIndex attachment;
-
- private:
- // Serialization
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type );
-};
-
-#include "simplex.hpp"
-
-#endif // __SIMPLEX_H__
--- a/include/simplex.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-#include <boost/serialization/base_object.hpp>
-#include <boost/serialization/set.hpp>
-#include <boost/serialization/nvp.hpp>
-
-
-/* Implementations */
-
-/* SimplexWithVertices */
-template<class V>
-typename SimplexWithVertices<V>::Cycle
-SimplexWithVertices<V>::
-boundary() const
-{
- Cycle bdry;
- if (dimension() == 0) return bdry;
-
- for (typename VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
- {
- bdry.push_back(*this);
- Self& s = bdry.back();
- s.vertices_.erase(*cur);
- }
-
- return bdry;
-}
-
-template<class V>
-std::ostream&
-SimplexWithVertices<V>::
-operator<<(std::ostream& out) const
-{
- for (typename VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
- out << *cur << ' ';
-
- return out;
-}
-
-template<class V>
-template<class Archive>
-void
-SimplexWithVertices<V>::
-serialize(Archive& ar, version_type )
-{ ar & BOOST_SERIALIZATION_NVP(vertices_); }
-
-template<class V>
-std::ostream& operator<<(std::ostream& out, const SimplexWithVertices<V>& s)
-{ return s.operator<<(out); }
-
-
-/* SimplexWithValue */
-template<class V>
-std::ostream&
-SimplexWithValue<V>::
-operator<<(std::ostream& out) const
-{
- Parent::operator<<(out);
- out << "(val = " << val << ")";
- return out;
-}
-
-template<class V>
-const typename SimplexWithValue<V>::Self&
-SimplexWithValue<V>::
-operator=(const Self& s)
-{
- Parent::operator=(s);
- val = s.val;
- return *this;
-}
-
-template<class V>
-template<class Archive>
-void
-SimplexWithValue<V>::
-serialize(Archive& ar, version_type )
-{
- ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
- ar & BOOST_SERIALIZATION_NVP(val);
-}
-
-template<typename V>
-template<class Archive>
-void
-SimplexWithAttachment<V>::
-serialize(Archive& ar, version_type )
-{
- ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
- ar & BOOST_SERIALIZATION_NVP(attachment);
-}
-
-
-template<class V>
-std::ostream& operator<<(std::ostream& out, const SimplexWithValue<V>& s)
-{ return s.operator<<(out); }
--- a/include/sys.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-// sys.h
-//
-// This header file is included at the top of every source file,
-// before any other header file.
-// It is intended to add defines that are needed globally and
-// to work around Operating System dependend incompatibilities.
-
-// EXAMPLE: If you use autoconf you can add the following here.
-// #ifdef HAVE_CONFIG_H
-// #include "config.h"
-// #endif
-
-// EXAMPLE: You could add stuff like this here too
-// (Otherwise add -DCWDEBUG to your CFLAGS).
-// #if defined(WANTSDEBUGGING) && defined(HAVE_LIBCWD_BLAHBLAH)
-// #define CWDEBUG
-// #endif
-
-// The following is the libcwd related mandatory part.
-// It must be included before any system header file is included!
-#ifdef CWDEBUG
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-#include <libcwd/sys.h>
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/conesimplex.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,39 @@
+/**
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2007
+ */
+
+#ifndef __CONESIMPLEX_H__
+#define __CONESIMPLEX_H__
+
+#include <list>
+#include <iostream>
+
+template<class S>
+class ConeSimplex: public S
+{
+ public:
+ typedef S Parent;
+ typedef ConeSimplex<S> Self;
+ typedef std::list<Self> Cycle;
+
+ public:
+ ConeSimplex(const Parent& parent,
+ bool coned = false):
+ Parent(parent), coned_(coned) {}
+
+ Cycle boundary() const;
+ bool coned() const { return coned_; }
+
+ std::ostream& operator<<(std::ostream& out) const;
+
+ private:
+ bool coned_;
+};
+
+template<class S>
+std::ostream& operator<<(std::ostream& out, const ConeSimplex<S>& s) { return s.operator<<(out); }
+
+#include "conesimplex.hpp"
+
+#endif // __CONESIMPLEX_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/conesimplex.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,24 @@
+template<class S>
+typename ConeSimplex<S>::Cycle
+ConeSimplex<S>::boundary() const
+{
+ Cycle bdry;
+ typename Parent::Cycle pbdry = Parent::boundary();
+
+ for (typename Parent::Cycle::const_iterator cur = pbdry.begin(); cur != pbdry.end(); ++cur)
+ bdry.push_back(Self(*cur, coned_));
+
+ if (coned_)
+ bdry.push_back(Self(*this, false));
+
+ return bdry;
+}
+
+template<class S>
+std::ostream&
+ConeSimplex<S>::operator<<(std::ostream& out) const
+{
+ Parent::operator<<(out) << ' ';
+ if (coned_) out << "[coned]";
+ return out;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/cycle.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,115 @@
+/**
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005-2006
+ */
+
+#ifndef __CYCLE_H__
+#define __CYCLE_H__
+
+#include "utilities/sys.h"
+#include "utilities/debug.h"
+
+#include "utilities/types.h"
+#include "utilities/circular_list.h"
+#include <list>
+#include <boost/serialization/access.hpp>
+
+/**
+ * Class storing a cycle of simplices. Stores items in the order defined by ConsistencyCmp.
+ * The actual order of the elements is defined by OrderCmp. Instances of those
+ * classes are not stored in Cycle for efficiency, and are passed as arguments to those methods
+ * that require them.
+ */
+template <class Itm, class OrderCmp, class ConsistencyCmp = OrderCmp>
+class Cycle: public List<Itm>
+{
+ public:
+ /// \name Template Parameters
+ /// @{
+ typedef Itm Item;
+ typedef OrderCmp OrderComparison;
+ typedef ConsistencyCmp ConsistencyComparison;
+ /// @}
+
+ typedef Cycle<Item, OrderComparison, ConsistencyCmp> Self;
+ typedef List<Item> CycleRepresentation;
+
+ /// \name Accessor typedefs
+ /// @{
+ typedef typename CycleRepresentation::iterator iterator;
+ typedef typename CycleRepresentation::const_iterator const_iterator;
+ typedef typename CycleRepresentation::const_reference const_reference;
+ typedef typename CycleRepresentation::reference reference;
+ typedef typename CycleRepresentation::pointer pointer;
+ typedef typename CycleRepresentation::const_pointer const_pointer;
+ /// @}
+
+ public:
+ Cycle();
+ Cycle(const Cycle& c);
+
+ /// \name Whole Cycle operations
+ /// @{
+ /** Add c to *this assuming both Cycles are sorted in increasing order according to cmp. */
+ Self& add(const Self& c, const ConsistencyComparison& cmp);
+ void swap(Cycle& c); ///< Swaps the contents of c and *this (like STL's swap destroys c)
+ //void insertion_sort(const Comparison& cmp); ///< Sort list[i] using insertion sort
+ void sort(const ConsistencyComparison& cmp); ///< Sort elements to enforce consistency
+ using CycleRepresentation::empty;
+ using CycleRepresentation::clear;
+ using CycleRepresentation::size;
+ /// @}
+
+ /// \name Modifiers
+ /// @{
+ using CycleRepresentation::erase;
+ void append(const_reference x, const ConsistencyComparison& cmp);
+ /// @}
+
+ /// \name Accessors
+ /// @{
+ using CycleRepresentation::begin;
+ using CycleRepresentation::end;
+ const_reference top(const OrderComparison& cmp) const; ///< First element in cmp order
+ iterator get_second(const OrderComparison& cmp) const; ///< Second element in cmp order
+ /// @}
+
+ /// \name Block access optimizations
+ // Between operations used in optimization of transpositions for regular vertices. Maybe we don't need these? TODO
+ /// @{
+ /** Return first after i, but before or equal j; return i if no such element found */
+ const_reference first_between(const_reference i, const_reference j, const OrderComparison& cmp);
+ /// Add lists and remove all elements after i and before or equal to j
+ const_reference add_and_first_between(const Self& c, const ConsistencyComparison& consistency_cmp,
+ const_reference i, const_reference j, const OrderComparison& order_cmp);
+ /// Erase everything after i, but before or equal to j
+ void erase_between(const_reference i, const_reference j, const OrderComparison& cmp);
+ /// @}
+
+ /// \name Debugging
+ /// @{
+ const_reference get_first(const OrderComparison& cmp) const; ///< First element in cmp order
+ std::ostream& operator<<(std::ostream& out) const;
+ /// @}
+
+ private:
+ typedef std::list<Item> TemporaryCycleRepresenation;
+
+ using CycleRepresentation::push_back;
+ using CycleRepresentation::insert;
+
+ private:
+ size_t sz;
+
+ private:
+ // Serialization
+ typedef List<Item> Parent;
+ friend class boost::serialization::access;
+ template<class Archive>
+ void serialize(Archive& ar, version_type );
+};
+
+#include "cycle.hpp"
+
+#endif // __CYCLE_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/cycle.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,280 @@
+#include <algorithm>
+#include <vector>
+
+#include <boost/serialization/split_member.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/binary_object.hpp>
+#include <boost/utility.hpp>
+
+using boost::serialization::make_nvp;
+using boost::serialization::make_binary_object;
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+Cycle<I,OrderCmp,ConsistencyCmp>::
+Cycle(): sz(0)
+{}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+Cycle<I,OrderCmp,ConsistencyCmp>::
+Cycle(const Cycle& c): CycleRepresentation(c), sz(c.sz)
+{}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+void
+Cycle<I,OrderCmp,ConsistencyCmp>::
+append(const_reference x, const ConsistencyCmp& cmp)
+{
+ // First try the special cases that x goes at the end
+ const_reference last = CycleRepresentation::back();
+ if (empty() || cmp(last, x))
+ {
+ push_back(x);
+ return;
+ }
+
+ for (iterator cur = begin(); cur != end(); ++cur)
+ if (cmp(x, *cur))
+ {
+ insert(cur, x);
+ return;
+ }
+}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
+Cycle<I,OrderCmp,ConsistencyCmp>::
+top(const OrderComparison& cmp) const
+{
+ AssertMsg(!empty(), "Cycle must not be empty for top()");
+ const_iterator min = begin();
+ for (const_iterator cur = ++begin(); cur != end(); ++cur)
+ if (cmp(*cur, *min))
+ min = cur;
+ return *min;
+}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+void
+Cycle<I,OrderCmp,ConsistencyCmp>::
+swap(Cycle& c)
+{
+ CycleRepresentation::swap(c);
+ std::swap(sz, c.sz);
+}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+void
+Cycle<I,OrderCmp,ConsistencyCmp>::
+sort(const ConsistencyComparison& cmp)
+{
+ std::vector<Item> tmp(begin(), end());
+ std::sort(tmp.begin(), tmp.end(), cmp);
+ std::copy(tmp.begin(), tmp.end(), begin());
+}
+
+template<class I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I,OrderCmp,ConsistencyCmp>::iterator
+Cycle<I,OrderCmp,ConsistencyCmp>::
+get_second(const OrderComparison& cmp) const
+{
+ AssertMsg(!empty(), "Cycle must not be empty for get_second()");
+ if (size() < 2) return begin(); // Indicates that there is no second.
+
+ Dout(dc::cycle, "Looking for second");
+ AssertMsg(size() >= 2, "Cycle must have at least two elements for get_second()");
+ iterator min = begin();
+ iterator second = ++begin();
+ if (cmp(*second, *min))
+ std::swap(min, second);
+ for (iterator cur = boost::next(begin(),2); cur != end(); ++cur)
+ {
+ if (cmp(*cur, *min))
+ {
+ second = min;
+ min = cur;
+ } else if (cmp(*cur, *second))
+ {
+ second = cur;
+ }
+ }
+
+ Dout(dc::cycle, "Looked up: " << **second);
+ return second;
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
+Cycle<I,OrderCmp,ConsistencyCmp>::
+first_between(const_reference i, const_reference j, const OrderComparison& cmp)
+{
+ // Find the first element in ConsistencyComparison order (> i and <= j)
+ const_pointer first = &i;
+ iterator cur = begin();
+ for (; cur != end(); ++cur)
+ {
+ if ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur)))
+ {
+ first = &(*cur);
+ break;
+ }
+ }
+
+ // If no such element found, then we are done
+ if (cur == end())
+ return i;
+
+ // Find first element in OrderComparison order (> i and <= j)
+ for (++cur; cur != end(); ++cur)
+ {
+ if ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur)))
+ {
+ if (cmp(*cur, *first))
+ first = &(*cur);
+ }
+ }
+ return *first;
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+void
+Cycle<I,OrderCmp,ConsistencyCmp>::
+erase_between(const_reference i, const_reference j, const OrderComparison& cmp)
+{
+ for (iterator cur = begin(); cur != end(); ++cur)
+ while ((cur != end()) && ((*cur == j) || (cmp(*cur, j) && cmp(i, *cur))))
+ {
+ Dout(dc::cycle, "Iteration of the erase while loop");
+ cur = erase(cur);
+ }
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+std::ostream&
+Cycle<I,OrderCmp,ConsistencyCmp>::
+operator<<(std::ostream& out) const
+{
+ for (const_iterator cur = begin(); cur != end(); ++cur)
+ {
+ out << **cur << ", ";
+ }
+ // out << "(last: " << *last << ")"; // For debugging only
+ return out;
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+std::ostream&
+operator<<(std::ostream& out, const Cycle<I, OrderCmp, ConsistencyCmp>& c)
+{
+ return c.operator<<(out);
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I, OrderCmp, ConsistencyCmp>::Self&
+Cycle<I, OrderCmp, ConsistencyCmp>::
+add(const Self& c, const ConsistencyCmp& cmp)
+{
+ Dout(dc::cycle, "Adding cycles: " << *this << " + " << c);
+
+ iterator cur1 = begin();
+ const_iterator cur2 = c.begin();
+
+ while (cur2 != c.end())
+ {
+ if (cur1 == end())
+ {
+ while (cur2 != c.end())
+ push_back(*cur2++);
+ Dout(dc::cycle, "After addition: " << *this);
+ return *this;
+ }
+
+ // mod 2
+ int res = cmp.compare(*cur1, *cur2);
+ Dout(dc::cycle, "Comparison result: " << res);
+ if (res == 0) // *cur1 == *cur2
+ {
+ Dout(dc::cycle, "Equality");
+ cur1 = erase(cur1); // erase cur1 --- as a result cur1 will be pointing at old_cur1++
+ --sz;
+ ++cur2;
+ } else if (res < 0) // *cur1 < *cur2
+ {
+ Dout(dc::cycle, "Less than");
+ cur1++;
+ } else if (res > 0) // *cur1 > *cur2
+ {
+ Dout(dc::cycle, "Greater than");
+ insert(cur1, *cur2);
+ ++cur2;
+ ++sz;
+ }
+ }
+
+ Dout(dc::cycle, "After addition: " << *this);
+ return *this;
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
+Cycle<I,OrderCmp,ConsistencyCmp>::
+add_and_first_between(const Self& c, const ConsistencyComparison& consistency_cmp,
+ const_reference i, const_reference j, const OrderComparison& order_cmp)
+{
+ add(c, consistency_cmp);
+ return first_between(i,j, order_cmp);
+}
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+typename Cycle<I,OrderCmp,ConsistencyCmp>::const_reference
+Cycle<I,OrderCmp,ConsistencyCmp>::
+get_first(const OrderComparison& cmp) const
+{ return top(cmp); }
+
+
+template<typename I, class OrderCmp, class ConsistencyCmp>
+template<class Archive>
+void
+Cycle<I,OrderCmp,ConsistencyCmp>::
+serialize(Archive& ar, version_type )
+{
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
+ ar & make_nvp("size", sz);;
+}
+
+
+/*
+template<typename I, class Cmp>
+void
+Cycle<I, Cmp>::
+insertion_sort(const Comparison& cmp)
+{
+ TemporaryCycleRepresenation tmp;
+
+ // Insertion sort into the temporary list
+ for (const_iterator cur = begin(); cur != end(); ++cur)
+ {
+ typename TemporaryCycleRepresenation::iterator tmp_cur = tmp.end();
+ typename TemporaryCycleRepresenation::iterator tmp_next = tmp_cur--;
+
+ while (tmp_next != tmp.begin())
+ {
+ if (cmp(*cur, *tmp_cur))
+ tmp_next = tmp_cur--;
+ else
+ break;
+ }
+ tmp.insert(tmp_next, *cur);
+ }
+
+ // Copy temporary list back into ourselves
+ iterator cur = begin();
+ typename TemporaryCycleRepresenation::const_iterator tmp_cur = tmp.begin();
+ while(tmp_cur != tmp.end())
+ {
+ *cur = *tmp_cur;
+ ++cur; ++tmp_cur;
+ }
+}
+*/
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/filtration.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,133 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2006
+ */
+
+#ifndef __FILTRATION_H__
+#define __FILTRATION_H__
+
+#include "utilities/sys.h"
+#include "utilities/debug.h"
+
+#include "filtrationcontainer.h"
+#include "filtrationsimplex.h"
+#include "vineyard.h"
+
+#include <map>
+#include <vector>
+
+#include <boost/serialization/access.hpp>
+
+/**
+ * Filtration class. Serves as an (ordered) container for the simplices,
+ * and provides pair_simplices() method that computes the RU-decomposition
+ * for the simplex order stored in the filtration. Iterators remain valid
+ * through all the operations.
+ */
+template<class Smplx, class FltrSmplx = FiltrationSimplex<Smplx>, class Vnrd = Vineyard<FltrSmplx> >
+class Filtration: public FltrSmplx::Container
+{
+ public:
+ typedef Smplx Simplex;
+ typedef FltrSmplx FiltrationSimplex;
+ typedef Vnrd Vineyard;
+
+ /// \name Container Types
+ /// @{
+ /** The actual container type (which is the parent of the Filtration) */
+ typedef typename FiltrationSimplex::Container FiltrationContainer;
+ typedef typename FiltrationContainer::Index Index;
+ typedef typename FiltrationContainer::const_Index const_Index;
+ /// @}
+
+ /// \name Cycles and Trails
+ /// @{
+ typedef typename FiltrationContainer::GreaterThanComparison CyclesComparator;
+ typedef typename FiltrationContainer::LessThanComparison TrailsComparator;
+ typedef typename FiltrationContainer::ConsistencyComparison ConsistencyComparator;
+ typedef typename FiltrationContainer::Cycle Cycle;
+ typedef typename FiltrationContainer::Trail Trail;
+ typedef typename Cycle::iterator CycleIterator;
+ typedef typename Trail::iterator TrailIterator;
+ /// @}
+
+ typedef Filtration<Simplex, FiltrationSimplex, Vineyard> Self;
+ typedef FiltrationContainer Parent;
+
+ public:
+ Filtration(Vineyard* vineyard);
+
+ /// \name Core Functionality
+ /// @{
+ /// Computes RU decomposition of the simplices in [bg, end) range, assuming that everything before bg has been paired
+ void pair_simplices(Index bg, Index end);
+ void pair_simplices() { pair_simplices(begin(), end()); }
+ bool transpose(Index i, bool maintain_lazy = true);
+ bool is_paired() const;
+ Index append(const Simplex& s); ///< Appends s to the filtration
+ Index insert(Index prior, const Simplex& s); ///< Inserts s after prior
+ const_Index get_index(const Simplex& s) const; /**< Returns the iterator pointing to s
+ (end() if s not in filtration) */
+ Index get_index(const Simplex& s); ///< \overload
+ void fill_simplex_index_map(); ///< Fills the mapping for get_index()
+ /// @}
+
+ /// \name Accessors
+ /// @{
+ Vineyard* vineyard() { return vineyard_; }
+ const Vineyard* vineyard() const { return vineyard_; }
+ /// @}
+
+ protected:
+ using Parent::swap;
+ bool transpose_simplices(Index i, bool maintain_lazy);
+
+ public:
+ /// \name Container Operations
+ /// @{
+ using Parent::size;
+ using Parent::begin;
+ using Parent::end;
+ /// @}
+
+ std::ostream& operator<<(std::ostream& out) const;
+
+ protected:
+ /// \name Comparator accessors (protected)
+ /// @{
+ const ConsistencyComparator& get_consistency_cmp() const { return consistency_cmp; }
+ const CyclesComparator& get_cycles_cmp() const { return cycles_cmp; }
+ const TrailsComparator& get_trails_cmp() const { return trails_cmp; }
+ /// @}
+
+ private:
+ typedef std::map<Simplex, Index> SimplexMap;
+
+ /// Initializes the cycle with the indices of the simplices in the boundary, and the trail with the index of this simplex
+ void init_cycle_trail(Index j);
+ void pairing_switch(Index i, Index j);
+
+ bool paired;
+ SimplexMap inverse_simplices;
+
+ Vineyard* vineyard_;
+
+ CyclesComparator cycles_cmp;
+ TrailsComparator trails_cmp;
+ ConsistencyComparator consistency_cmp;
+
+ private:
+ /* Serialization */
+ friend class boost::serialization::access;
+
+ typedef std::map<const_Index, SizeType, ConsistencyComparator> IndexIntMap;
+ typedef std::vector<Index> IndexVector;
+
+ template<class Archive> void save(Archive& ar, version_type ) const;
+ template<class Archive> void load(Archive& ar, version_type );
+ BOOST_SERIALIZATION_SPLIT_MEMBER()
+};
+
+#include "filtration.hpp"
+
+#endif // __FILTRATION_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/filtration.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,463 @@
+#include "utilities/counter.h"
+#include "utilities/types.h"
+#include <algorithm>
+
+#include <boost/utility.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/is_abstract.hpp>
+
+using boost::serialization::make_nvp;
+
+/* Filtration Public */
+
+template<class S, class FS, class V>
+Filtration<S, FS, V>::
+Filtration(Vineyard* vnrd = 0): paired(false), vineyard_(vnrd)
+{}
+
+template<class S, class FS, class V>
+void
+Filtration<S, FS, V>::
+pair_simplices(Index bg, Index end)
+{
+ Dout(dc::filtration, "Entered: compute_pairing");
+ for (Index j = bg; j != end; ++j)
+ {
+ Dout(dc::filtration|flush_cf|continued_cf, *j << ": ");
+ init_cycle_trail(j);
+ Cycle& bdry = j->cycle();
+ Dout(dc::finish, bdry);
+
+ CountNum("Boundaries", j->dimension());
+ Count("SimplexCount");
+
+ while(!bdry.empty())
+ {
+ Index i = bdry.top(cycles_cmp);
+ Dout(dc::filtration, *i << ": " << *(i->pair()));
+ AssertMsg(!cycles_cmp(i, j), "Simplices in the cycle must precede current simplex: " <<
+ "(" << *i << " in cycle of " << *j << ")");
+
+ // i is not paired, so we pair j with i
+ if (i->pair() == i)
+ {
+ Dout(dc::filtration, "Pairing " << *i << " and " << *j << " with cycle " << j->cycle());
+ i->set_pair(j);
+ j->set_pair(i);
+ CountNum("DepositedCycleLength", j->cycle().size());
+ break;
+ }
+
+ // continue searching --- change the Dout to the continued mode with newlines FIXME
+ Dout(dc::filtration, " Adding: [" << bdry << "] + ");
+ Dout(dc::filtration, " [" << i->pair()->cycle() << "]");
+ bdry.add(i->pair()->cycle(), get_consistency_cmp());
+ i->pair()->trail().append(j, get_consistency_cmp());
+ Dout(dc::filtration, "After addition: " << bdry);
+ }
+ Dout(dc::filtration, "Finished with " << *j << ": " << *(j->pair()));
+ }
+ paired = true;
+}
+
+template<class S, class FS, class V>
+bool
+Filtration<S, FS, V>::
+is_paired() const
+{ return paired; }
+
+/**
+ * Transposes simplices at i and i+1, and records the knee in the vineyard if there is a change in pairing.
+ * Returns true if the pairing changed.
+ */
+template<class S, class FS, class V>
+bool
+Filtration<S,FS,V>::
+transpose(Index i, bool maintain_lazy)
+{
+ AssertMsg(vineyard() != 0, "We must have a vineyard for transpositions");
+
+ Index i_orig = i++;
+
+ AssertMsg(i_orig->pair() != i, "Transposing simplices must not be paired");
+ bool result = transpose_simplices(i_orig, maintain_lazy);
+ AssertMsg(i_orig == boost::next(i), "Wrong indices after transposition");
+
+ if (result) vineyard()->switched(i, i_orig);
+ return result;
+}
+
+template<class S, class FS, class V>
+typename Filtration<S, FS, V>::Index
+Filtration<S, FS, V>::
+append(const Simplex& s)
+{
+ Index i = push_back(FiltrationSimplex(s));
+ return i;
+}
+
+template<class S, class FS, class V>
+typename Filtration<S, FS, V>::Index
+Filtration<S, FS, V>::
+insert(Index prior, const Simplex& s)
+{
+ Index i = Parent::insert(prior, FiltrationSimplex(s));
+ paired = false;
+
+ return i;
+}
+
+template<class S, class FS, class V>
+typename Filtration<S, FS, V>::const_Index
+Filtration<S, FS, V>::
+get_index(const Simplex& s) const
+{
+ typename SimplexMap::const_iterator i = inverse_simplices.find(s);
+ if (i == inverse_simplices.end())
+ return end();
+ else
+ return i->second;
+}
+
+template<class S, class FS, class V>
+typename Filtration<S, FS, V>::Index
+Filtration<S, FS, V>::
+get_index(const Simplex& s)
+{
+ typename SimplexMap::const_iterator i = inverse_simplices.find(s);
+ if (i == inverse_simplices.end())
+ return end();
+ else
+ return i->second;
+}
+
+template<class S, class FS, class V>
+void
+Filtration<S, FS, V>::
+fill_simplex_index_map()
+{
+ for (Index i = begin(); i != end(); ++i)
+ inverse_simplices[*i] = i;
+}
+
+template<class S, class FS, class V>
+std::ostream&
+Filtration<S, FS, V>::
+operator<<(std::ostream& out) const
+{
+ out << "Pairing: " << std::endl;
+ for (const_Index i = begin(); i != end(); ++i)
+ {
+ out << "(" << *i << ", " << *(i->pair()) << "): ";
+ out << i->cycle() << std::endl;
+ }
+ out << std::endl << std::endl;
+
+ return out;
+}
+
+
+/* Filtration Protected */
+/// Transposes simplices at i and i+1. Returns true if the pairing switched.
+template<class S, class FS, class V>
+bool
+Filtration<S,FS,V>::
+transpose_simplices(Index i, bool maintain_lazy)
+{
+ AssertMsg(is_paired(), "Pairing must be computed before transpositions");
+ Count("SimplexTransposition");
+
+ Index i_prev = i++;
+
+ if (i_prev->dimension() != i->dimension())
+ {
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Different dimension");
+ Count("Case DiffDim");
+ return false;
+ }
+
+ bool si = i_prev->sign(), sii = i->sign();
+ if (si && sii)
+ {
+ Dout(dc::transpositions, "Trail prev: " << i_prev->trail());
+
+ // Case 1
+ TrailIterator i_in_i_prev = std::find(i_prev->trail().begin(), i_prev->trail().end(), i);
+ if (i_in_i_prev != i_prev->trail().end())
+ {
+ Dout(dc::transpositions, "Case 1, U[i,i+1] = 1");
+ i_prev->trail().erase(i_in_i_prev);
+ }
+
+ Index k = i_prev->pair();
+ Index l = i->pair();
+
+ // Explicit treatment of unpaired simplex
+ if (l == i)
+ {
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 1.2 --- unpaired");
+ Dout(dc::transpositions, *i_prev);
+ Count("Case 1.2");
+ return false;
+ } else if (k == i_prev)
+ {
+ if (std::find(l->cycle().begin(), l->cycle().end(), i_prev) == l->cycle().end())
+ {
+ // Case 1.2
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 1.2 --- unpaired");
+ Dout(dc::transpositions, *i_prev);
+ Count("Case 1.2");
+ return false;
+ } else
+ {
+ // Case 1.1.2 --- special version (plain swap, but pairing switches)
+ swap(i_prev, i);
+ pairing_switch(i_prev, i);
+ Dout(dc::transpositions, "Case 1.1.2 --- unpaired");
+ Dout(dc::transpositions, *i_prev);
+ Count("Case 1.1.2");
+ return true;
+ }
+ }
+
+ Dout(dc::transpositions, "l cycle: " << l->cycle());
+ if (std::find(l->cycle().begin(), l->cycle().end(), i_prev) == l->cycle().end())
+ {
+ // Case 1.2
+ if (maintain_lazy)
+ {
+ TrailIterator k_in_l = std::find(l->trail().begin(), l->trail().end(), k);
+ if (k_in_l != l->trail().end())
+ {
+ l->trail().add(k->trail(), Filtration::get_consistency_cmp()); // Add row k to l
+ k->cycle().add(l->cycle(), Filtration::get_consistency_cmp()); // Add column l to k
+ }
+ }
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 1.2");
+ Count("Case 1.2");
+ return false;
+ } else
+ {
+ // Case 1.1
+ if (trails_cmp(k,l))
+ {
+ // Case 1.1.1
+ swap(i_prev, i);
+ l->cycle().add(k->cycle(), Filtration::get_consistency_cmp()); // Add column k to l
+ k->trail().add(l->trail(), Filtration::get_consistency_cmp()); // Add row l to k
+ Dout(dc::transpositions, "Case 1.1.1");
+ Count("Case 1.1.1");
+ return false;
+ } else
+ {
+ // Case 1.1.2
+ swap(i_prev, i);
+ k->cycle().add(l->cycle(), Filtration::get_consistency_cmp()); // Add column l to k
+ l->trail().add(k->trail(), Filtration::get_consistency_cmp()); // Add row k to l
+ pairing_switch(i_prev, i);
+ Dout(dc::transpositions, "Case 1.1.2");
+ Count("Case 1.1.2");
+ return true;
+ }
+ }
+ } else if (!si && !sii)
+ {
+ // Case 2
+ if (std::find(i_prev->trail().begin(), i_prev->trail().end(), i) == i_prev->trail().end())
+ {
+ // Case 2.2
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 2.2");
+ Count("Case 2.2");
+ return false;
+ } else
+ {
+ // Case 2.1
+ Index low_i = i_prev->pair();
+ Index low_ii = i->pair();
+ i_prev->trail().add(i->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
+ i->cycle().add(i_prev->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i
+ swap(i_prev, i);
+ if (Filtration::get_trails_cmp()(low_ii, low_i))
+ {
+ // Case 2.1.2
+ i_prev->cycle().add(i->cycle(), Filtration::get_consistency_cmp()); // Add column i to i_prev (after transposition)
+ i->trail().add(i_prev->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
+ pairing_switch(i_prev, i);
+ Dout(dc::transpositions, "Case 2.1.2");
+ Count("Case 2.1.2");
+ return true;
+ }
+
+ // Case 2.1.1
+ Dout(dc::transpositions, "Case 2.1.1");
+ Count("Case 2.1.1");
+ return false;
+ }
+ } else if (!si && sii)
+ {
+ // Case 3
+ if (std::find(i_prev->trail().begin(), i_prev->trail().end(), i) == i_prev->trail().end())
+ {
+ // Case 3.2
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 3.2");
+ Count("Case 3.2");
+ return false;
+ } else
+ {
+ // Case 3.1
+ i_prev->trail().add(i->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
+ i->cycle().add(i_prev->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i
+ swap(i_prev, i);
+ i_prev->cycle().add(i->cycle(), Filtration::get_consistency_cmp()); // Add column i_prev to i (after transposition)
+ i->trail().add(i_prev->trail(), Filtration::get_consistency_cmp()); // Add row i to i_prev
+ pairing_switch(i_prev, i);
+ Dout(dc::transpositions, "Case 3.1");
+ Count("Case 3.1");
+ return true;
+ }
+ } else if (si && !sii)
+ {
+ // Case 4
+ TrailIterator i_in_i_prev = std::find(i_prev->trail().begin(), i_prev->trail().end(), i);
+ if (i_in_i_prev != i_prev->trail().end())
+ {
+ Dout(dc::transpositions, "Case 4, U[i,i+1] = 1");
+ i_prev->trail().erase(i_in_i_prev);
+ }
+ swap(i_prev, i);
+ Dout(dc::transpositions, "Case 4");
+ Count("Case 4");
+ return false;
+ }
+
+ return false; // to avoid compiler complaints, should never reach this point
+}
+
+
+/* Filtration Private */
+template<class S, class FS, class V>
+void
+Filtration<S, FS, V>::
+init_cycle_trail(Index j)
+{
+ typename Simplex::Cycle bdry = j->boundary();
+
+ for (typename Simplex::Cycle::const_iterator cur = bdry.begin(); cur != bdry.end(); ++cur)
+ {
+ Dout(dc::filtration, "Appending in init_cycle_trail(): " << *cur);
+ AssertMsg(get_index(*cur) != end(), "Non-existent simplex in the cycle");
+ j->cycle().append(get_index(*cur), get_consistency_cmp());
+ }
+ j->trail().append(j, get_consistency_cmp());
+ j->set_pair(j);
+}
+
+/// Update the pairing, so that whoever was paired with i is now paired with j and vice versa.
+template<class S, class FS, class V>
+void
+Filtration<S,FS,V>::
+pairing_switch(Index i, Index j)
+{
+ Index i_pair = i->pair();
+ Index j_pair = j->pair();
+
+ if (i_pair == i)
+ j->set_pair(j);
+ else
+ {
+ j->set_pair(i_pair);
+ i_pair->set_pair(j);
+ }
+
+ if (j_pair == j)
+ i->set_pair(i);
+ else
+ {
+ i->set_pair(j_pair);
+ j_pair->set_pair(i);
+ }
+}
+
+/* Serialization */
+template<class S, class FS, class V>
+template<class Archive>
+void
+Filtration<S, FS, V>::
+save(Archive& ar, version_type ) const
+{
+ ar << BOOST_SERIALIZATION_NVP(paired);
+ ar << BOOST_SERIALIZATION_NVP(cycles_cmp);
+ ar << BOOST_SERIALIZATION_NVP(trails_cmp);
+ ar << BOOST_SERIALIZATION_NVP(consistency_cmp);
+
+ SizeType sz = size();
+ ar << make_nvp("size", sz);
+ Dout(dc::filtration, "Size: " << sz);
+
+ /* Record integer indices */
+ IndexIntMap index_map; SizeType i = 0;
+ for (const_Index cur = begin(); cur != end(); ++cur)
+ { index_map[cur] = i++; }
+
+ /* Save the simplices */
+ int count = 0;
+ for (const_Index cur = begin(); cur != end(); ++cur)
+ {
+ count++;
+ // FIXME
+ //FiltrationSimplexSerialization simplex = FiltrationSimplexSerialization(*cur, index_map);
+ //ar << make_nvp("FiltrationSimplex", simplex);
+ }
+ Dout(dc::filtration, count << " simplices serialized");
+}
+
+template<class S, class FS, class V>
+template<class Archive>
+void
+Filtration<S, FS, V>::
+load(Archive& ar, version_type )
+{
+ Dout(dc::filtration, "Starting to read filtration");
+ ar >> BOOST_SERIALIZATION_NVP(paired);
+ ar >> BOOST_SERIALIZATION_NVP(cycles_cmp);
+ ar >> BOOST_SERIALIZATION_NVP(trails_cmp);
+ ar >> BOOST_SERIALIZATION_NVP(consistency_cmp);
+ Dout(dc::filtration, "In Filtration: first block read");
+
+ SizeType sz;
+ ar >> make_nvp("size", sz);
+ Dout(dc::filtration, "In Filtration: size read " << sz);
+
+ IndexVector index_vector(sz);
+ for (SizeType i = 0; i < sz; ++i)
+ {
+ index_vector[i] = append(Simplex());
+ }
+
+ int count = 0;
+ for (SizeType i = 0; i < sz; ++i)
+ {
+ // FIXME
+ //FiltrationSimplexSerialization simplex;
+ //ar >> make_nvp("FiltrationSimplex", simplex);
+ count++;
+ Dout(dc::filtration, "In Filtration: simplex read (" << count << ")");
+ //simplex.set_filtration_simplex(*index_vector[i], index_vector);
+ }
+ Dout(dc::filtration, "In Filtration: simplices read");
+}
+
+template<class S, class FS, class V>
+std::ostream&
+operator<<(std::ostream& out, const Filtration<S, FS, V>& f)
+{ return f.operator<<(out); }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/filtrationcontainer.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,45 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2006
+ */
+
+#ifndef __FILTRATIONCONTAINER_H__
+#define __FILTRATIONCONTAINER_H__
+
+#include "utilities/consistencylist.h"
+#include "cycle.h"
+
+/**
+ * FiltrationContainer class. Serves as a parent of Filtration that
+ * describes the container functionality. Used by FiltrationSimplex
+ * to get Cycle representation.
+ */
+template<class FltrSmplx>
+class FiltrationContainer: public ConsistencyList<FltrSmplx>
+{
+ public:
+ typedef FltrSmplx FiltrationSimplex;
+ typedef ConsistencyList<FiltrationSimplex> ConsistencyList;
+
+ /// \name Cycles and Trails
+ /// @{
+ /// Index is and therfore acts like an iterator. The name is preserved for historical reasons.
+ typedef typename ConsistencyList::iterator Index;
+ /// const_Index is a const_iterator
+ typedef typename ConsistencyList::const_iterator const_Index;
+ /// @}
+
+ /// \name Cycles and Trails
+ /// @{
+ typedef typename ConsistencyList::GreaterThanComparison CyclesComparator;
+ typedef typename ConsistencyList::LessThanComparison TrailsComparator;
+ typedef typename ConsistencyList::ConsistencyComparison ConsistencyComparator;
+ typedef ::Cycle<Index, CyclesComparator, ConsistencyComparator> Cycle;
+ typedef ::Cycle<Index, TrailsComparator, ConsistencyComparator> Trail;
+ /// @}
+
+ template<class U>
+ struct rebind { typedef FiltrationContainer<U> other; };
+};
+
+#endif // __FILTRATIONCONTAINER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/filtrationsimplex.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,91 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2006
+ */
+
+#ifndef __FILTRATIONSIMPLEX_H__
+#define __FILTRATIONSIMPLEX_H__
+
+#include "utilities/sys.h"
+#include "utilities/debug.h"
+
+#include "filtrationcontainer.h"
+#include "vineyard.h"
+#include "utilities/types.h"
+
+#include <list>
+
+#if 0
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/list.hpp>
+#endif
+
+/**
+ * Evaluator is a base class for the structures that are able to return a value
+ * given a simplex.
+ */
+template<class Smplx>
+class Evaluator
+{
+ public:
+ typedef Smplx Simplex;
+
+ virtual RealType time() const { return 0; }
+ virtual RealType value(const Simplex& s) const { return 0; }
+
+ virtual ~Evaluator() {}
+};
+
+/**
+ * FiltrationSimplex stores information needed for the RU-decomposition:
+ * cycle (column of R), trail (row of U), and pair.
+ */
+template<class Smplx>
+class FiltrationSimplex: public Smplx
+{
+ public:
+ typedef Smplx Simplex;
+ typedef FiltrationSimplex<Simplex> Self;
+ typedef FiltrationContainer<Self> Container;
+ typedef Simplex Parent;
+
+ typedef Vine<Simplex> Vine;
+ typedef typename Container::Cycle Cycle;
+ typedef typename Container::Trail Trail;
+ typedef typename Container::Index Index;
+
+ typedef Evaluator<Simplex> Evaluator;
+
+ FiltrationSimplex(const Simplex& s):
+ Simplex(s), vine_(0) {}
+
+
+ /// \name Core functionality
+ /// @{
+ void set_pair(Index pair) { pair_ = pair; }
+ bool sign() const { return cycles_column.empty(); }
+ bool is_paired() const { return pair() != pair()->pair(); }
+ void set_vine(Vine* v) { vine_ = v; }
+ using Parent::dimension;
+ /// @}
+
+
+ /// \name Accessors
+ /// @{
+ Cycle& cycle() { return cycles_column; }
+ Trail& trail() { return trails_row; }
+ const Cycle& cycle() const { return cycles_column; }
+ const Trail& trail() const { return trails_row; }
+ Index pair() const { return pair_; }
+ Vine* vine() const { return vine_; }
+ /// @}
+
+ private:
+ Cycle cycles_column;
+ Trail trails_row;
+ Index pair_;
+ Vine* vine_;
+};
+
+#endif // __FILTRATIONSIMPLEX_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/lowerstarfiltration.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,114 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2006
+ */
+
+#ifndef __LOWERSTARFILTRATION_H__
+#define __LOWERSTARFILTRATION_H__
+
+#include "utilities/sys.h"
+#include "utilities/debug.h"
+
+#include "filtration.h"
+#include "simplex.h"
+#include "utilities/consistencylist.h"
+#include <boost/utility.hpp>
+#include <list>
+#include "utilities/types.h"
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/map.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/nvp.hpp>
+
+
+template<class VI,
+ class Smplx = SimplexWithAttachment<VI>,
+ class FltrSmplx = FiltrationSimplex<Smplx>,
+ class Vnrd = Vineyard<FltrSmplx> >
+class LowerStarFiltration: public Filtration<Smplx, FltrSmplx, Vnrd>
+{
+ public:
+ // Treat VertexIndex as an iterator
+ typedef VI VertexIndex;
+ typedef Smplx Simplex;
+ typedef Filtration<Simplex> Parent;
+ typedef typename Parent::Vineyard Vineyard;
+
+ typedef typename Parent::Index Index;
+ typedef typename Parent::const_Index const_Index;
+ typedef typename Parent::Cycle Cycle;
+ typedef typename Parent::Trail Trail;
+ typedef typename Simplex::Cycle SimplexBoundaryCycle;
+
+ struct VertexDescriptor;
+ typedef ConsistencyList<VertexDescriptor> VertexOrder;
+ typedef typename VertexOrder::iterator VertexOrderIndex;
+ typedef typename VertexOrder::const_iterator const_VertexOrderIndex;
+ typedef typename VertexOrder::LessThanComparison VertexOrderComparison;
+ struct SimplexAttachmentComparison;
+
+ public:
+ template<class VertexCmp>
+ LowerStarFiltration(VertexIndex begin, VertexIndex end, const VertexCmp& cmp, Vineyard* vineyard);
+
+ using Parent::size;
+ using Parent::begin;
+ using Parent::end;
+ VertexIndex num_vertices() const { return vertex_order.size(); }
+ const VertexOrderComparison&
+ get_vertex_cmp() const { return vertex_cmp; }
+
+ Index append(const Simplex& s);
+ bool transpose_vertices(const VertexOrderIndex& voi);
+
+ protected:
+ /// Hint function: if unsure, should return true
+ virtual bool neighbors(VertexIndex v1, VertexIndex v2) const { return true; }
+
+ private:
+ bool transpose(Index i);
+ void assert_pairing(Index i);
+
+ private:
+ VertexOrder vertex_order;
+ VertexOrderComparison vertex_cmp;
+
+ /* Serialization */
+ protected:
+ LowerStarFiltration() {}
+
+ private:
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void save(Archive& ar, version_type ) const { ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent); }
+
+ template<class Archive>
+ void load(Archive& ar, version_type );
+
+ BOOST_SERIALIZATION_SPLIT_MEMBER()
+};
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+struct LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::VertexDescriptor
+{
+ VertexDescriptor(VertexIndex vi, Index si):
+ vertex_index(vi), simplex_index(si)
+ {}
+
+ VertexIndex vertex_index;
+ Index simplex_index;
+};
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+struct LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::SimplexAttachmentComparison
+{
+ bool operator()(const Simplex& first, const Simplex& second) const;
+ VertexOrderComparison vertex_cmp;
+};
+
+#include "lowerstarfiltration.hpp"
+
+#endif // __LOWERSTARFILTRATION_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/lowerstarfiltration.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,217 @@
+/* Implementations */
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+template<class VertexCmp>
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+LowerStarFiltration(VertexIndex begin, VertexIndex end, const VertexCmp& cmp, Vineyard* vineyard):
+ Parent(vineyard)
+{
+ // Record VertexIndexes in a temporary list
+ typedef std::list<VertexIndex> VertexIndexList;
+ VertexIndexList tmp_list;
+ while (begin != end)
+ tmp_list.push_back(begin++);
+
+ // Sort the temporary list
+ tmp_list.sort(cmp);
+
+ // Record vertex order
+ for(typename VertexIndexList::const_iterator cur = tmp_list.begin(); cur != tmp_list.end(); ++cur)
+ (*cur)->set_order(vertex_order.push_back(VertexDescriptor(*cur, Parent::append(Simplex(*cur)))));
+}
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+typename LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::Index
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+append(const Simplex& s)
+{
+ AssertMsg(s.dimension() != 0, "All vertices must have been inserted in the constructor");
+
+ // Find the highest vertex
+ typename Simplex::VertexContainer::const_iterator cur = s.vertices().begin(), max = cur++;
+ for (; cur != s.vertices().end(); ++cur)
+ if (!vertex_cmp((*cur)->get_order(), (*max)->get_order()))
+ max = cur;
+
+ Index ms = (*max)->get_order()->simplex_index; Index prior;
+ do { prior = ms++; } while (ms->dimension() <= s.dimension() && ms != Parent::end() && ms->get_attachment() == *max);
+
+ Index i = Parent::insert(prior, s);
+ i->set_attachment(*max);
+
+ return i;
+}
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+bool
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::SimplexAttachmentComparison::
+operator()(const Simplex& first, const Simplex& second) const
+{
+ int cmp = vertex_cmp.compare(first.get_attachment()->get_order(), second.get_attachment()->get_order());
+ if (cmp == 0)
+ return first.dimension() < second.dimension();
+ else
+ return cmp == -1;
+}
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+bool
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+transpose_vertices(const VertexOrderIndex& order)
+{
+ Count("VertexTransposition");
+
+#if COUNTERS
+ if ((counters.lookup("VertexTransposition") % 1000000) == 0)
+ {
+ Dout(dc::lsfiltration, "Vertex transpositions: " << counters.lookup("VertexTransposition"));
+ Dout(dc::lsfiltration, "Simplex transpositions: " << counters.lookup("SimplexTransposition"));
+ Dout(dc::lsfiltration, "Attachment changed: " << counters.lookup("ChangedAttachment"));
+ Dout(dc::lsfiltration, "Regular disconnected: " << counters.lookup("RegularDisconnected"));
+ Dout(dc::lsfiltration, "Pairing Changed: " << counters.lookup("ChangedPairing"));
+ Dout(dc::lsfiltration, "------------------------");
+ }
+#endif // COUNTERS
+
+ Dout(dc::lsfiltration, "Transposing vertices (" << order->vertex_index << ", "
+ << boost::next(order)->vertex_index << ")");
+
+ Index i = order->simplex_index;
+ Index i_prev = boost::prior(i);
+ Index i_next = boost::next(order)->simplex_index;
+ Index i_next_prev = boost::prior(i_next); // transpositions are done in terms of the first index in the pair
+ Index j = boost::next(i_next);
+
+ const VertexIndex& v_i = order->vertex_index;
+ const VertexIndex& v_i_next = boost::next(order)->vertex_index;
+ bool nbghrs = neighbors(v_i, v_i_next);
+
+ bool result = false;
+
+ // First, move the vertex --- this can be sped up if we devise special "vertex transpose" operation
+ while (i_next_prev != i_prev)
+ {
+ result |= transpose(i_next_prev);
+ i_next_prev = boost::prior(i_next);
+ }
+ Dout(dc::lsfiltration, "Done moving the vertex");
+
+ // Second, move the simplices attached to it
+ Dout(dc::lsfiltration, "Moving attached simplices");
+ while (j != Parent::end() && j->get_attachment() == v_i_next)
+ {
+ Dout(dc::lsfiltration, " Considering " << *j);
+ if (nbghrs && j->contains(v_i)) // short circuit
+ {
+ Count("ChangedAttachment");
+ Dout(dc::lsfiltration, " Attachment changed for " << *j);
+ j->set_attachment(v_i);
+ ++j;
+ continue;
+ }
+
+ Index j_prev = j; ++j;
+ while ((--j_prev)->get_attachment() != v_i_next) // i.e., until we have reached v_i_next
+ // (and the simplices that follow it) again
+ {
+ Dout(dc::lsfiltration, " Moving: " << *j_prev << ", " << *boost::next(j_prev));
+ AssertMsg(j_prev->get_attachment() == v_i, "Simplex preceding the one being moved must be attached to v_i");
+ result |= transpose(j_prev);
+ --j_prev;
+ }
+ }
+ Dout(dc::lsfiltration, "Done moving attached simplices");
+ vertex_order.swap(order, boost::next(order));
+
+ return result;
+}
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+bool
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+transpose(Index i)
+{
+ Index j = boost::next(i);
+
+ Dout(dc::lsfiltration, " Transposing (" << *i << ", " << *(i->pair()) << ") and ("
+ << *j << ", " << *(j->pair()) << ")");
+
+ assert_pairing(i);
+ assert_pairing(j);
+
+ bool res = Parent::transpose(i, false);
+ Dout(dc::lsfiltration, " " << *j << ": " << *(j->pair()) << ", " << *i << ": " << *(i->pair()));
+
+ assert_pairing(j);
+ assert_pairing(i);
+
+ return res;
+}
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+void
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+assert_pairing(Index i)
+{
+#ifndef NDEBUG
+ AssertMsg(i != Parent::end(), "Cannot assert pairing of end()");
+ if (!i->sign())
+ {
+ if (i->pair() != i->cycle().top(Parent::get_cycles_cmp()))
+ {
+ Dout(dc::lsfiltration, "i (negative): " << *i);
+ Dout(dc::lsfiltration, "pair(i): " << *(i->pair()));
+ Dout(dc::lsfiltration, "i->cycle().top(): " << *(i->cycle().top(Parent::get_cycles_cmp())));
+ DoutFatal(dc::fatal, "Pairing not matching the matrix at " << *i);
+ }
+ } else
+ {
+ if (i->pair() != i)
+ {
+ if (i->pair()->cycle().top(Parent::get_cycles_cmp()) != i)
+ {
+ Dout(dc::lsfiltration, "i (positive): " << *i);
+ Dout(dc::lsfiltration, "pair(i): " << *(i->pair()));
+ Dout(dc::lsfiltration, "pair(i)->cycle(): " << i->pair()->cycle());
+ Dout(dc::lsfiltration, "pair->cycle().top(): " << *(i->pair()->cycle().top(Parent::get_cycles_cmp())));
+ DoutFatal(dc::fatal, "Pairing not matching the matrix at " << *(i->pair()));
+ }
+ }
+ }
+#endif
+}
+
+
+template<class VI, class Smplx, class FltrSmplx, class Vnrd>
+template<class Archive>
+void
+LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
+load(Archive& ar, version_type )
+{
+/*
+ ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
+
+ // Count the number of vertices
+ VertexIndex num_vertices = 0;
+ for (Index cur = begin(); cur != end(); ++cur)
+ if (dimension(cur) == 0)
+ num_vertices++;
+
+ // Second pass to record vertex_order
+ vertex_order.resize(num_vertices);
+ inverse_vertex_order.resize(num_vertices);
+ num_vertices = 0;
+ for (Index cur = begin(); cur != end(); ++cur)
+ {
+ if (dimension(cur) == 0)
+ {
+ vertex_order[num_vertices].index = cur;
+ vertex_order[num_vertices].vertex_index = *(cur->get_vertices().begin());
+ inverse_vertex_order[vertex_order[num_vertices].vertex_index] = num_vertices;
+ ++num_vertices;
+ }
+ }
+*/
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/simplex.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,170 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2006
+ */
+
+#ifndef __SIMPLEX_H__
+#define __SIMPLEX_H__
+
+#include "utilities/sys.h"
+#include "utilities/debug.h"
+
+#include <set>
+#include <list>
+#include <iostream>
+
+#include "utilities/types.h"
+
+#include <boost/serialization/access.hpp>
+
+
+/**
+ * SimplexWithVertices is a basic simplex class. It stores vertices of a given type,
+ * and knows how to compute its own boundary. It should probably be used as a base
+ * class for any explicit simplex representation.
+ */
+template<class V>
+class SimplexWithVertices
+{
+ public:
+ typedef V Vertex;
+ typedef SimplexWithVertices<Vertex> Self;
+
+ typedef std::set<Vertex> VertexContainer;
+ typedef std::list<Self> Cycle;
+
+ /// \name Constructors
+ /// @{
+ SimplexWithVertices() {}
+ SimplexWithVertices(const Self& s):
+ vertices_(s.vertices_) {}
+ template<class Iterator>
+ SimplexWithVertices(Iterator bg, Iterator end):
+ vertices_(bg, end) {}
+ SimplexWithVertices(const VertexContainer& v):
+ vertices_(v) {}
+ SimplexWithVertices(Vertex v):
+ vertices_() { vertices_.insert(v); }
+ /// @}
+
+ /// \name Core
+ /// @{
+ Cycle boundary() const;
+ Dimension dimension() const { return vertices_.size()-1; }
+ /// @}
+
+ /// \name Vertex manipulation
+ /// @{
+ bool contains(const Vertex& v) const { return (vertices_.find(v) != vertices_.end()); }
+ const VertexContainer& vertices() const { return vertices_; }
+ void add(const Vertex& v) { vertices_.insert(v); }
+ /// @}
+
+ /// \name Assignment and comparison
+ /// Gives an ordering on simplices (for example, so that simplices can be used as keys for std::map)
+ /// @{
+ const Self& operator=(const Self& s) { vertices_ = s.vertices_; return *this; }
+ bool operator==(const Self& s) const { return vertices_ == s.vertices_; }
+ bool operator<(const Self& s) const { return vertices_ < s.vertices_; }
+ /// @}
+
+ std::ostream& operator<<(std::ostream& out) const;
+
+ private:
+ VertexContainer vertices_;
+
+ private:
+ /* Serialization */
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type );
+};
+
+/**
+ * SimplexWithValue explicitly adds a RealType value to the SimplexWithVertices.
+ */
+template<class Vert>
+class SimplexWithValue: public SimplexWithVertices<Vert>
+{
+ public:
+ typedef Vert Vertex;
+ typedef RealType Value;
+ typedef SimplexWithValue<Vertex> Self;
+ typedef SimplexWithVertices<Vertex> Parent;
+
+ typedef typename Parent::VertexContainer VertexContainer;
+
+ /// \name Constructors
+ /// @{
+ SimplexWithValue(Value value = 0): val(value) {}
+ SimplexWithValue(const Self& s):
+ Parent(s), val(s.val) {}
+ SimplexWithValue(const Parent& s, Value value = 0):
+ Parent(s), val(value) {}
+ template<class Iterator>
+ SimplexWithValue(Iterator bg, Iterator end, Value value = 0):
+ Parent(bg, end), val(value) {}
+ SimplexWithValue(const VertexContainer& v, Value value = 0):
+ Parent(v), val(value) {}
+ /// @}
+
+ /// \name Core
+ /// @{
+ void set_value(Value value) { val = value; }
+ Value get_value() const { return val; }
+ /// @}
+
+ const Self& operator=(const Self& s);
+ std::ostream& operator<<(std::ostream& out) const;
+
+ private:
+ Value val;
+
+ /* Serialization */
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type );
+};
+
+/**
+ * SimplexWithAttachment stores the vertex to which the simplex is attached (meant for lower-star filtrations)
+ */
+template<typename V>
+class SimplexWithAttachment: public SimplexWithVertices<V>
+{
+ public:
+ typedef V VertexIndex;
+ typedef SimplexWithVertices<VertexIndex> Parent;
+
+ /// \name Constructors
+ /// @{
+ SimplexWithAttachment():
+ attachment(VertexIndex()) {}
+ template<class Iterator>
+ SimplexWithAttachment(Iterator bg, Iterator end):
+ Parent(bg, end) {}
+ SimplexWithAttachment(const Parent& s):
+ Parent(s) {}
+ SimplexWithAttachment(VertexIndex vi):
+ Parent(vi), attachment(vi) {}
+ /// @}
+
+ void set_attachment(VertexIndex v) { attachment = v; }
+ VertexIndex get_attachment() const { return attachment; }
+
+ private:
+ VertexIndex attachment;
+
+ private:
+ // Serialization
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type );
+};
+
+#include "simplex.hpp"
+
+#endif // __SIMPLEX_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/simplex.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,94 @@
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/set.hpp>
+#include <boost/serialization/nvp.hpp>
+
+
+/* Implementations */
+
+/* SimplexWithVertices */
+template<class V>
+typename SimplexWithVertices<V>::Cycle
+SimplexWithVertices<V>::
+boundary() const
+{
+ Cycle bdry;
+ if (dimension() == 0) return bdry;
+
+ for (typename VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+ {
+ bdry.push_back(*this);
+ Self& s = bdry.back();
+ s.vertices_.erase(*cur);
+ }
+
+ return bdry;
+}
+
+template<class V>
+std::ostream&
+SimplexWithVertices<V>::
+operator<<(std::ostream& out) const
+{
+ for (typename VertexContainer::const_iterator cur = vertices_.begin(); cur != vertices_.end(); ++cur)
+ out << *cur << ' ';
+
+ return out;
+}
+
+template<class V>
+template<class Archive>
+void
+SimplexWithVertices<V>::
+serialize(Archive& ar, version_type )
+{ ar & BOOST_SERIALIZATION_NVP(vertices_); }
+
+template<class V>
+std::ostream& operator<<(std::ostream& out, const SimplexWithVertices<V>& s)
+{ return s.operator<<(out); }
+
+
+/* SimplexWithValue */
+template<class V>
+std::ostream&
+SimplexWithValue<V>::
+operator<<(std::ostream& out) const
+{
+ Parent::operator<<(out);
+ out << "(val = " << val << ")";
+ return out;
+}
+
+template<class V>
+const typename SimplexWithValue<V>::Self&
+SimplexWithValue<V>::
+operator=(const Self& s)
+{
+ Parent::operator=(s);
+ val = s.val;
+ return *this;
+}
+
+template<class V>
+template<class Archive>
+void
+SimplexWithValue<V>::
+serialize(Archive& ar, version_type )
+{
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
+ ar & BOOST_SERIALIZATION_NVP(val);
+}
+
+template<typename V>
+template<class Archive>
+void
+SimplexWithAttachment<V>::
+serialize(Archive& ar, version_type )
+{
+ ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
+ ar & BOOST_SERIALIZATION_NVP(attachment);
+}
+
+
+template<class V>
+std::ostream& operator<<(std::ostream& out, const SimplexWithValue<V>& s)
+{ return s.operator<<(out); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/vineyard.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,145 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2006
+ */
+
+#ifndef __VINEYARD_H__
+#define __VINEYARD_H__
+
+#include "utilities/types.h"
+#include <list>
+#include <string>
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/list.hpp>
+#include <boost/serialization/is_abstract.hpp>
+
+
+template<class Smplx> class Knee;
+template<class Smplx> 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().
+ */
+template<class FltrSmplx>
+class Vineyard
+{
+ public:
+ typedef FltrSmplx FiltrationSimplex;
+ typedef typename FiltrationSimplex::Simplex Simplex;
+ typedef Vine<Simplex> Vine;
+ typedef Knee<Simplex> Knee;
+ typedef std::list<Vine> VineList;
+ typedef std::vector<VineList> VineListVector;
+ typedef typename FiltrationSimplex::Cycle Cycle;
+
+ typedef typename FiltrationSimplex::Index Index;
+ typedef typename FiltrationSimplex::Evaluator Evaluator;
+
+ public:
+ Vineyard(Evaluator* eval = 0):
+ evaluator(eval) {}
+
+ void start_vines(Index bg, Index end);
+ void switched(Index i, Index j);
+ void record_diagram(Index bg, Index end);
+
+ void set_evaluator(Evaluator* eval) { evaluator = eval; }
+
+ void save_edges(const std::string& filename) const;
+
+ protected:
+ typename Knee::SimplexList resolve_cycle(Index i) const;
+
+ private:
+ void record_knee(Index i);
+ void start_vine(Index i);
+
+ private:
+ VineListVector vines;
+ 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.
+ */
+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)
+ {}
+
+ bool is_diagonal() const { return birth == death; }
+ bool is_infinite() const { return (death == Infinity) || (birth == Infinity); }
+ void set_cycle(const SimplexList& lst) { cycle = lst; }
+
+ 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 S>
+std::ostream& operator<<(std::ostream& out, const Knee<S>& 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> Knee;
+ typedef std::list<Knee> VineRepresentation;
+ typedef typename VineRepresentation::const_iterator const_knee_iterator;
+
+ Vine() {}
+ 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); }
+
+ using VineRepresentation::begin;
+ using VineRepresentation::end;
+ using VineRepresentation::front;
+ using VineRepresentation::back;
+ using VineRepresentation::size;
+ using VineRepresentation::empty;
+
+ protected:
+ using VineRepresentation::push_back;
+
+ private:
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type );
+};
+
+
+#include "vineyard.hpp"
+
+#endif // __VINEYARD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/topology/vineyard.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,157 @@
+/* Implementations */
+
+#include <fstream>
+#include <sstream>
+
+template<class FS>
+void
+Vineyard<FS>::
+start_vines(Index bg, Index 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(std::list<Vine>());
+ }
+
+ start_vine(cur);
+ record_knee(cur);
+ }
+}
+
+template<class FS>
+void
+Vineyard<FS>::
+switched(Index i, Index j)
+{
+ Vine* i_vine = i->vine();
+ Vine* j_vine = j->vine();
+ i->set_vine(j_vine);
+ j->set_vine(i_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");
+
+ if (!i->sign()) i = i->pair();
+ if (!j->sign()) j = j->pair();
+ record_knee(i);
+ record_knee(j);
+}
+
+template<class FS>
+void
+Vineyard<FS>::
+start_vine(Index i)
+{
+ Dout(dc::vineyard, "Starting new vine");
+ AssertMsg(i->sign(), "Can only start vines for positive simplices");
+
+ Dimension dim = i->dimension();
+ vines[dim].push_back(Vine());
+ i->set_vine(&vines[dim].back());
+ i->pair()->set_vine(i->vine());
+}
+
+/// Records the current diagram in the vineyard
+template<class FS>
+void
+Vineyard<FS>::
+record_diagram(Index bg, Index end)
+{
+ Dout(dc::vineyard, "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);
+ }
+}
+
+
+template<class FS>
+void
+Vineyard<FS>::
+save_edges(const std::string& filename) const
+{
+ for (unsigned int i = 0; i < vines.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[i].begin(); vi != vines[i].end(); ++vi)
+ for (typename Vine::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();
+ }
+}
+
+/// Records a knee for the given simplex
+template<class FS>
+void
+Vineyard<FS>::
+record_knee(Index i)
+{
+ Dout(dc::vineyard, "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
+ {
+ Dout(dc::vineyard, "Creating knee");
+ Knee k(evaluator->value(*i), evaluator->value(*(i->pair())), evaluator->time());
+ Dout(dc::vineyard, "Knee created: " << k);
+
+ if (!k.is_diagonal() || i->vine()->empty()) // non-diagonal k, or empty vine
+ {
+ Dout(dc::vineyard, "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");
+ Dout(dc::vineyard, "Overwriting first diagonal knee");
+ i->vine()->back() = k;
+ } else // finish this vine
+ {
+ Dout(dc::vineyard, "Finishing a vine");
+ i->vine()->add(k);
+ start_vine(i);
+ i->vine()->add(k);
+ }
+ }
+
+ i->vine()->back().set_cycle(resolve_cycle(i));
+ Dout(dc::vineyard, "Leaving record_knee()");
+}
+
+template<class FS>
+typename Vineyard<FS>::Knee::SimplexList
+Vineyard<FS>::
+resolve_cycle(Index i) const
+{
+ Dout(dc::vineyard, "Entered resolve_cycle");
+ const Cycle& cycle = i->cycle();
+
+ // Resolve simplices
+ typename Knee::SimplexList lst;
+ for (typename Cycle::const_iterator cur = cycle.begin(); cur != cycle.end(); ++cur)
+ lst.push_back(**cur);
+
+ return lst;
+}
--- a/include/types.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#ifndef __TYPES_H__
-#define __TYPES_H__
-
-#include <limits>
-
-/* Types */
-typedef bool Sign;
-typedef short int Dimension;
-const Sign POS = true;
-const Sign NEG = false;
-typedef double RealType;
-typedef unsigned int SizeType;
-
-static RealType Infinity = std::numeric_limits<RealType>::infinity();
-
-typedef const unsigned int& version_type;
-
-#endif // __TYPES_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/circular_list.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,259 @@
+/**
+ * Singly-linked circular list implementation by Donovan Rebbechi <elflord@pegasus.rutgers.edu>.
+ * Tiny modifications by DM to make ISO C++ compliant (i.e., so that the compiler stops complaining),
+ * added size(), and boost serialization
+ */
+
+#ifndef __CIRCULAR_LIST_H__
+#define __CIRCULAR_LIST_H__
+
+#include <iterator>
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/split_member.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/binary_object.hpp>
+
+#include "types.h"
+
+
+template <class T>
+class List
+{
+ struct Node
+ {
+ Node(const T& x,Node* y = 0):m_data(x),m_next(y){}
+ T m_data;
+ Node* m_next;
+
+ private:
+ // Serialization
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type )
+ {
+ ar & make_nvp("data", m_data);
+ ar & make_nvp("next", m_next);
+ }
+ };
+
+ Node* m_node;
+ size_t sz;
+
+ private:
+ // Serialization
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar, version_type )
+ { ar & make_nvp("root", m_node); }
+
+public:
+ class const_iterator;
+
+ class iterator
+ : public std::iterator<std::forward_iterator_tag, T>
+ {
+ Node* m_rep;
+ public:
+ friend class List;
+ friend class const_iterator;
+ typedef T value_type;
+ typedef T& reference;
+ typedef T* pointer;
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ inline iterator(Node* x=0):m_rep(x){}
+ inline iterator(const iterator& x):m_rep(x.m_rep) {}
+ inline iterator(const const_iterator& x):m_rep(const_cast<Node*>(x.m_rep)) {} // not very safe
+ inline iterator& operator=(const iterator& x)
+ {
+ m_rep=x.m_rep; return *this;
+ }
+ inline iterator& operator++()
+ {
+ m_rep = m_rep->m_next; return *this;
+ }
+ inline iterator operator++(int)
+ {
+ iterator tmp(*this); m_rep = m_rep->m_next; return tmp;
+ }
+ inline reference operator*() const { return m_rep->m_next->m_data; }
+ inline pointer operator->() const { return m_rep->m_next; }
+ inline bool operator==(const iterator& x) const
+ {
+ return m_rep == x.m_rep;
+ }
+ inline bool operator!=(const iterator& x) const
+ {
+ return m_rep != x.m_rep;
+ }
+
+ };
+
+ class const_iterator
+ : public std::iterator<std::forward_iterator_tag, const T>
+ {
+ const Node* m_rep;
+ public:
+ friend class List;
+ friend class iterator;
+ typedef T value_type;
+ typedef T& reference;
+ typedef T* pointer;
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+ inline const_iterator(const Node* x=0):m_rep(x){}
+ inline const_iterator(const const_iterator& x):m_rep(x.m_rep) {}
+ inline const_iterator(const iterator& x):m_rep(x.m_rep){}
+ inline const_iterator& operator=(const const_iterator& x)
+ {
+ m_rep=x.m_rep; return *this;
+ }
+ inline const_iterator& operator=(const iterator& x)
+ {
+ m_rep=x.m_rep; return *this;
+ }
+ inline const_iterator& operator++()
+ {
+ m_rep = m_rep->m_next; return *this;
+ }
+ inline const_iterator operator++(int)
+ {
+ const_iterator tmp(*this); m_rep = m_rep->m_next; return tmp;
+ }
+ inline reference operator*() const { return m_rep->m_next->m_data; }
+ inline pointer operator->() const { return m_rep->m_next; }
+ inline bool operator==(const const_iterator& x) const
+ {
+ return m_rep == x.m_rep;
+ }
+ inline bool operator!=(const const_iterator& x) const
+ {
+ return m_rep != x.m_rep;
+ }
+ };
+
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+
+ List() : m_node(new Node(T())), sz(0) { m_node->m_next = m_node; }
+
+ List(const List& L) : m_node(new Node(T())), sz(L.sz)
+ {
+ m_node->m_next=m_node;
+ for ( const_iterator i = L.begin(); i!= L.end(); ++i )
+ push_front(*i);
+ reverse();
+ }
+
+ void reverse()
+ {
+ if (empty())
+ return;
+ Node* new_m_node = m_node->m_next->m_next;
+ Node* p = m_node; Node* i = m_node->m_next; Node* n;
+ do
+ {
+ n = i->m_next;
+ i->m_next = p;
+ p = i; i = n;
+ }
+ while (p!=m_node);
+ m_node = new_m_node;
+ }
+
+ void swap(List& x)
+ {
+ std::swap(m_node, x.m_node);
+ std::swap(sz, x.sz);
+ }
+
+ List& operator=(const List& x)
+ {
+ List tmp(x);
+ swap(tmp);
+ return *this;
+ }
+
+ ~List() { clear(); delete m_node; }
+ void clear() { while (!empty()) pop_front(); sz = 0; }
+
+
+ inline size_t size() const { return sz; }
+
+ inline void push_front(const T&x)
+ {
+ insert (begin(),x);
+ }
+ inline void push_back(const T& x)
+ {
+ insert (end(),x);
+ }
+ inline void pop_front()
+ {
+ erase(begin());
+ }
+ inline bool empty() const { return m_node == m_node->m_next; }
+
+ inline T& front() { return *begin(); }
+ inline const T& front() const { return *begin(); }
+ inline T& back() { return m_node->m_data; }
+ inline const T& back() const { return m_node->m_data; }
+
+ inline iterator begin() { return iterator(m_node->m_next); }
+ inline iterator end() { return iterator(m_node); }
+ inline const_iterator begin() const
+ {
+ return const_iterator(m_node->m_next);
+ }
+ inline const_iterator end() const
+ {
+ return const_iterator(m_node);
+ }
+
+ iterator erase (iterator x)
+ {
+ if (x == end())
+ return x;
+
+ if (x.m_rep->m_next == m_node)
+ m_node = x.m_rep;
+
+ Node* tmp = x.m_rep->m_next;
+ x.m_rep->m_next = x.m_rep->m_next->m_next;
+ delete tmp;
+ --sz;
+
+ return x;
+ }
+
+ iterator insert (iterator x, const T& y)
+ {
+ Node* tmp = new Node(y,x.m_rep->m_next);
+ if (x.m_rep == m_node) // if inserting before end
+ m_node = tmp;
+ x.m_rep->m_next = tmp;
+ ++sz;
+
+ return x++; // x points to the new data, return it, and slide it over
+ }
+
+ // rotate x to beginning
+ void rotate (iterator x)
+ {
+ if (x == end())
+ return;
+ Node* sentinel = m_node->m_next;
+ m_node->m_next = m_node->m_next->m_next;
+ sentinel->m_next = x.m_rep->m_next;
+ x.m_rep->m_next = sentinel;
+ m_node = x.m_rep;
+ }
+};
+
+#endif // __CIRCULAR_LIST_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/consistencylist.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,225 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2006
+ */
+
+#ifndef __CONSISTENCYLIST_H__
+#define __CONSISTENCYLIST_H__
+
+#include "orderlist.h"
+
+#include <iterator>
+#include <iostream>
+#include <list>
+#include "types.h"
+
+#include <boost/utility.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+//#include <boost/type_traits/is_convertible.hpp>
+//#include <boost/utility/enable_if.hpp>
+
+
+template<class T> struct ConsistencyListNode;
+template<class T> class ConsistencyListIterator;
+template<class T> class const_ConsistencyListIterator;
+
+/**
+ * ConsistencyList adds consistency order to OrderList which remains unchanged
+ * through the lifetime of the list.
+ */
+template<class T>
+class ConsistencyList: public OrderList<ConsistencyListNode<T> >
+{
+ public:
+ class OrderComparison;
+ class LessThanComparison;
+ class GreaterThanComparison;
+ class ConsistencyComparison;
+
+ /// \name Comparison types
+ /// @{
+ // Explicit typedefs for Doxygen
+ typedef LessThanComparison LessThanComparison;
+ typedef GreaterThanComparison GreaterThanComparison;
+ typedef ConsistencyComparison ConsistencyComparison;
+ /// @}
+
+ typedef ConsistencyListNode<T> NodeType;
+ typedef ConsistencyList<T> Self;
+ typedef OrderList<NodeType > Parent;
+
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef ConsistencyListIterator<T> iterator;
+ typedef const_ConsistencyListIterator<T> const_iterator;
+
+ ConsistencyList(): sz(0) {}
+ ~ConsistencyList() { clear(); }
+
+ /// \name Order operations
+ void swap(iterator i, iterator j); ///< Exchanges the order of simplices pointed to by i and j
+ template<class BinaryPredicate>
+ void sort(BinaryPredicate cmp); ///< Sorts the elements in accordance with cmp
+
+ /// \name Container operations
+ /// @{
+ // Explicit calls instead of using declarations for Doxygen
+ iterator push_back(const_reference x);
+ iterator insert(iterator predecessor, const_reference x); ///< Inserts x immediately after predecessor (has to be a valid iterator)
+ void erase(iterator x) { Parent::erase(x.get_base()); --sz; }
+
+ void clear() { return Parent::clear(); }
+ bool empty() const { return Parent::empty(); }
+ SizeType size() const { return sz; }
+ iterator begin() { return iterator(Parent::begin()); }
+ const_iterator begin() const { return const_iterator(Parent::begin()); }
+ iterator end() { return iterator(Parent::end()); }
+ const_iterator end() const { return const_iterator(Parent::end()); }
+ reference back() { return Parent::back(); }
+ const_reference back() const { return Parent::back(); }
+ void pop_back() { return Parent::pop_back(); }
+
+ iterator last() { return iterator(boost::prior(end())); }
+ const_iterator last() const { return const_iterator(boost::prior(end())); }
+ /// @}
+
+ private:
+ unsigned int sz;
+};
+
+/// Basic comparison that LessThan and GreaterThan derive from
+template<class T>
+class ConsistencyList<T>::OrderComparison
+{
+ public:
+ typedef typename ConsistencyList<T>::const_iterator ComparableType;
+
+ int compare(ComparableType a, ComparableType b) const; /// (-1,0,1) = a (precedes, ==, succeeds) b
+};
+
+/// Determines if the first element is less than the second one
+template<class T>
+class ConsistencyList<T>::LessThanComparison: public OrderComparison
+{
+ public:
+ typedef OrderComparison Parent;
+ typedef typename Parent::ComparableType ComparableType;
+
+ int compare(ComparableType a, ComparableType b) const;
+ bool operator()(ComparableType a, ComparableType b) const;
+};
+
+/// Determines if the first element is greater than the second one
+template<class T>
+class ConsistencyList<T>::GreaterThanComparison: public OrderComparison
+{
+ public:
+ typedef OrderComparison Parent;
+ typedef typename Parent::ComparableType ComparableType;
+
+ int compare(ComparableType a, ComparableType b) const;
+ bool operator()(ComparableType a, ComparableType b) const;
+};
+
+/// Determines the order of the two elements in the consistency order (that doesn't change during the execution)
+template<class T>
+class ConsistencyList<T>::ConsistencyComparison
+{
+ public:
+ typedef typename ConsistencyList<T>::const_iterator ComparableType;
+
+ int compare(ComparableType a, ComparableType b) const; ///< (-1,0,1) = a (precedes, ==, succeeds) b
+ bool operator()(ComparableType a, ComparableType b) const;
+};
+
+/// Structure storing auxilliary information requred for each node of ConsistencyList
+template<class T>
+struct ConsistencyListNode
+{
+ ConsistencyListNode(const T& d, unsigned int c):
+ data(d), consistency(c)
+ {}
+
+ T data;
+ OrderType consistency;
+
+ std::ostream& operator<<(std::ostream& out) const { return out << data << ": " << consistency; }
+};
+
+template<class T>
+std::ostream& operator<<(std::ostream& out, const ConsistencyListNode<T>& n) { return n.operator<<(out); }
+
+template<class T>
+class ConsistencyListIterator: public boost::iterator_adaptor<ConsistencyListIterator<T>,
+ typename ConsistencyList<T>::Parent::iterator,
+ T>
+{
+ private:
+ struct enabler {};
+
+ public:
+ typedef typename ConsistencyList<T>::Parent ConsistencyListParent;
+ typedef boost::iterator_adaptor<ConsistencyListIterator<T>,
+ typename ConsistencyListParent::iterator,
+ T> Parent;
+ typedef typename Parent::reference reference;
+ typedef typename Parent::base_type base_type;
+
+ ConsistencyListIterator() {}
+ ConsistencyListIterator(const typename ConsistencyListParent::iterator& iter):
+ ConsistencyListIterator::iterator_adaptor_(iter)
+ {}
+ ConsistencyListIterator(const ConsistencyListIterator<T>& other):
+ ConsistencyListIterator::iterator_adaptor_(other.base())
+ {}
+
+ private:
+ friend class boost::iterator_core_access;
+ reference dereference() const { return Parent::base_reference()->data; }
+ base_type& get_base() { return Parent::base_reference(); }
+
+ friend class ConsistencyList<T>;
+};
+
+template<class T>
+class const_ConsistencyListIterator: public boost::iterator_adaptor<const_ConsistencyListIterator<T>,
+ typename ConsistencyList<T>::Parent::const_iterator,
+ const T>
+{
+ private:
+ struct enabler {};
+
+ public:
+ typedef typename ConsistencyList<T>::Parent ConsistencyListParent;
+ typedef boost::iterator_adaptor<const_ConsistencyListIterator<T>,
+ typename ConsistencyListParent::const_iterator,
+ const T> Parent;
+ typedef typename Parent::reference reference;
+ typedef typename Parent::base_type base_type;
+
+ const_ConsistencyListIterator() {}
+ const_ConsistencyListIterator(const typename ConsistencyListParent::const_iterator& iter):
+ const_ConsistencyListIterator::iterator_adaptor_(iter)
+ {}
+ const_ConsistencyListIterator(const const_ConsistencyListIterator<T>& other):
+ const_ConsistencyListIterator::iterator_adaptor_(other.base())
+ {}
+ const_ConsistencyListIterator(const ConsistencyListIterator<T>& other):
+ const_ConsistencyListIterator::iterator_adaptor_(other.base())
+ {}
+
+ private:
+ friend class boost::iterator_core_access;
+ reference dereference() const { return Parent::base_reference()->data; }
+ const base_type&
+ get_base() { return Parent::base_reference(); }
+
+ friend class ConsistencyList<T>::OrderComparison;
+ friend class ConsistencyList<T>::ConsistencyComparison;
+};
+
+
+#include "consistencylist.hpp"
+
+#endif // __CONSISTENCYLIST_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/consistencylist.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,86 @@
+/* Implementations */
+
+template<class T>
+void
+ConsistencyList<T>::
+swap(iterator i, iterator j)
+{
+ Parent::swap(i.get_base(),j.get_base());
+}
+
+template<class T>
+template<class BinaryPredicate>
+void
+ConsistencyList<T>::
+sort(BinaryPredicate cmp)
+{
+ Parent::sort(cmp);
+ OrderType cur_order = 0;
+ for (typename Parent::iterator cur = begin(); cur != end(); ++cur)
+ cur->consistency = cur_order++;
+}
+
+
+template<class T>
+typename ConsistencyList<T>::iterator
+ConsistencyList<T>::
+push_back(const_reference x)
+{
+ ++sz;
+ return Parent::push_back(NodeType(x, sz));
+}
+
+template<class T>
+typename ConsistencyList<T>::iterator
+ConsistencyList<T>::
+insert(iterator p, const_reference x)
+{
+ ++sz;
+ return Parent::insert(p.get_base(), NodeType(x, sz));
+}
+
+
+/* OrderComparison */
+template<class T>
+int
+ConsistencyList<T>::
+OrderComparison::compare(ComparableType a, ComparableType b) const
+{
+ typename Parent::OrderComparison cmp;
+ return cmp.compare(a.get_base(), b.get_base());
+}
+
+
+/* LessThanComparison */
+template<class T>
+int ConsistencyList<T>::LessThanComparison::compare(ComparableType a, ComparableType b) const
+{ return Parent::compare(a,b); }
+
+template<class T>
+bool ConsistencyList<T>::LessThanComparison::operator()(ComparableType a, ComparableType b) const
+{ return compare(a,b) == -1; }
+
+
+/* GreaterThanComparison */
+template<class T>
+int ConsistencyList<T>::GreaterThanComparison::compare(ComparableType a, ComparableType b) const
+{ return -Parent::compare(a,b); }
+
+template<class T>
+bool ConsistencyList<T>::GreaterThanComparison::operator()(ComparableType a, ComparableType b) const
+{ return compare(a,b) == -1; }
+
+
+/* ConsistencyComparison */
+template<class T>
+int ConsistencyList<T>::ConsistencyComparison::compare(ComparableType a, ComparableType b) const
+{
+ if (a.get_base()->consistency < b.get_base()->consistency) return -1;
+ else if (a.get_base()->consistency == b.get_base()->consistency) return 0;
+ else return 1;
+}
+
+template<class T>
+bool ConsistencyList<T>::ConsistencyComparison::operator()(ComparableType a, ComparableType b) const
+{ return compare(a,b) == -1; }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/counter.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,68 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2005 -- 2006
+ */
+
+#ifndef __COUNTER_H__
+#define __COUNTER_H__
+
+/* This should be integrated with the logging facilities. Written in the same framework. */
+
+#include <map>
+#include <string>
+#include <iostream>
+
+#ifndef COUNTERS
+#define Count(x)
+#define CountNum(x,y)
+#else // COUNTERS
+#define Count(x) counters.inc(x)
+#define CountNum(x,y) counters.inc(x,y)
+#endif
+
+typedef unsigned long CounterType;
+typedef std::string KeyType;
+
+class CounterFactory
+{
+ private:
+ typedef std::map<int, CounterType> CountersMap;
+ typedef std::map<KeyType, CountersMap> KeyMap;
+ KeyMap ctrs;
+
+ public:
+ ~CounterFactory()
+ {
+#ifdef COUNTERS
+ std::cout << "Counters:" << std::endl;
+ for (KeyMap::const_iterator cur = ctrs.begin(); cur != ctrs.end(); ++cur)
+ {
+ std::cout << cur->first << ": ";
+ if (cur->second.size() == 1)
+ {
+ std::cout << cur->second.begin()->second << std::endl;
+ continue;
+ }
+ std::cout << std::endl;
+ for (CountersMap::const_iterator ccur = cur->second.begin();
+ ccur != cur->second.end();
+ ++ccur)
+ std::cout << " " << ccur->first << ": " << ccur->second << std::endl;
+ }
+#endif // COUNTERS
+ }
+
+ void inc(const KeyType& key, int num = 0)
+ {
+ ctrs[key][num]++;
+ }
+
+ CounterType lookup(const KeyType& key, int num = 0) const
+ {
+ return const_cast<KeyMap&>(ctrs)[key][num];
+ }
+};
+
+static CounterFactory counters;
+
+#endif // __COUNTER_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/debug.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,90 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#ifndef CWDEBUG
+
+#include <iostream> // std::cerr
+#include <cstdlib> // std::exit, EXIT_FAILURE
+#include <cassert>
+
+#define AllocTag1(p)
+#define AllocTag2(p, desc)
+#define AllocTag_dynamic_description(p, data)
+#define AllocTag(p, data)
+#define Debug(STATEMENT...)
+#define Dout(cntrl, data)
+#define DoutFatal(cntrl, data) LibcwDoutFatal(, , cntrl, data)
+#define ForAllDebugChannels(STATEMENT...)
+#define ForAllDebugObjects(STATEMENT...)
+#define LibcwDebug(dc_namespace, STATEMENT...)
+#define LibcwDout(dc_namespace, d, cntrl, data)
+#define LibcwDoutFatal(dc_namespace, d, cntrl, data) do { ::std::cerr << data << ::std::endl; ::std::exit(EXIT_FAILURE); } while(1)
+#define LibcwdForAllDebugChannels(dc_namespace, STATEMENT...)
+#define LibcwdForAllDebugObjects(dc_namespace, STATEMENT...)
+#define NEW(x) new x
+#define CWDEBUG_ALLOC 0
+#define CWDEBUG_MAGIC 0
+#define CWDEBUG_LOCATION 0
+#define CWDEBUG_LIBBFD 0
+#define CWDEBUG_DEBUG 0
+#define CWDEBUG_DEBUGOUTPUT 0
+#define CWDEBUG_DEBUGM 0
+#define CWDEBUG_DEBUGT 0
+#define CWDEBUG_MARKER 0
+#define AssertMsg(TEST,MSG)
+//#define AssertMsg(TEST,STRM,MSG)
+
+
+#else // CWDEBUG
+
+// This must be defined before <libcwd/debug.h> is included and must be the
+// name of the namespace containing your `dc' (Debug Channels) namespace
+// (see below). You can use any namespace(s) you like, except existing
+// namespaces (like ::, ::std and ::libcwd).
+#define DEBUGCHANNELS ::dionysus::debug::channels
+#include <libcwd/debug.h>
+
+namespace dionysus
+{
+ namespace debug
+ {
+ void init(void); // Initialize debugging code from main().
+ void init_thread(void); // Initialize debugging code from new threads.
+
+ namespace channels // This is the DEBUGCHANNELS namespace, see above.
+ {
+ namespace dc // 'dc' is defined inside DEBUGCHANNELS.
+ {
+ using namespace libcwd::channels::dc;
+ using libcwd::channel_ct;
+
+ // Add the declaration of new debug channels here
+ // and add their definition in a custom debug.cc file.
+ extern channel_ct filtration;
+ extern channel_ct transpositions;
+ extern channel_ct vineyard;
+ extern channel_ct cycle;
+ extern channel_ct lsfiltration;
+ extern channel_ct orderlist;
+ } // namespace dc
+ } // namespace DEBUGCHANNELS
+ }
+}
+
+
+#define AssertMsg(TEST,MSG) \
+ ( (TEST) ? (void)0 \
+ : (std::cerr << __FILE__ ":" << __LINE__ \
+ << ": Assertion failed " #TEST \
+ << " - " << MSG << std::endl,abort()))
+/*
+#define AssertMsg(TEST,STRM,MSG) \
+ ( (TEST) ? (void)0 \
+ : (DoutFatal(STRM, __FILE__ "(" << __LINE__ \
+ << "): Assertion failed " #TEST \
+ << MSG << std::endl)))
+*/
+
+#endif // CWDEBUG
+
+#endif // DEBUG_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/eventqueue.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,71 @@
+#ifndef __EVENTQUEUE_H__
+#define __EVENTQUEUE_H__
+
+#include <list>
+#include <functional>
+#include <boost/utility.hpp>
+
+#include <iostream>
+#include <cassert> // TODO: switch to internal debugging system
+#include <string>
+
+// TODO: change inefficient list-based implementation to something heap-based
+// Need a queue that supports deleting arbitrary items (given by iterator),
+// and maintaining correctness of iterators when different operations (notably
+// remove and update are performed)
+
+template<class Event_, class EventComparison_>
+class EventQueue
+{
+
+ public:
+ typedef Event_ Event;
+ typedef EventComparison_ EventComparison;
+
+ typedef std::list<Event> QueueRepresentation;
+ typedef typename QueueRepresentation::iterator iterator;
+ typedef typename QueueRepresentation::const_iterator const_iterator;
+
+ EventQueue() {}
+
+ const_iterator top() const { assert(!empty()); return queue_.begin(); }
+ iterator top() { assert(!empty()); return queue_.begin(); }
+ iterator push(Event e) { queue_.push_front(e); iterator i = top(); update(i); return i; }
+ void pop() { assert(!empty()); queue_.erase(queue_.begin()); }
+ void remove(iterator i) { queue_.erase(i); }
+ void update(iterator i);
+
+ iterator end() { return queue_.end(); }
+ const_iterator end() const { return queue_.end(); }
+ bool empty() const { return queue_.empty(); }
+ size_t size() const { return queue_.size(); }
+
+ std::ostream& print(std::ostream& out, const std::string& prefix) const;
+
+ private:
+ QueueRepresentation queue_;
+};
+
+
+template<class Event_, class EventComparison_>
+void
+EventQueue<Event_, EventComparison_>::
+update(iterator i)
+{
+ QueueRepresentation tmp;
+ tmp.splice(tmp.end(), queue_, i);
+ iterator pos = std::find_if(queue_.begin(), queue_.end(), std::not1(std::bind2nd(EventComparison(), *i)));
+ queue_.splice(pos, tmp);
+}
+
+template<class Event_, class EventComparison_>
+std::ostream&
+EventQueue<Event_, EventComparison_>::
+print(std::ostream& out, const std::string& prefix) const
+{
+ for (typename QueueRepresentation::const_iterator cur = queue_.begin(); cur != queue_.end(); ++cur)
+ (*cur)->print(out << prefix) << std::endl;
+ return out;
+}
+
+#endif // __EVENTQUEUE_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/orderlist.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,212 @@
+/*
+ * Author: Dmitriy Morozov
+ * Department of Computer Science, Duke University, 2006
+ *
+ * Implements the simplified order list data strcutre given in ``Two Simplified
+ * Algorithms for Maintaining Order in a List'' by Bender et al.
+ *
+ * Indirection is not implemented, so the insertion cost is amortized O(log n),
+ * while comparison and deletion are O(1).
+ */
+
+#ifndef __ORDERLIST_H__
+#define __ORDERLIST_H__
+
+#include "sys.h"
+#include "debug.h"
+
+#include <iterator>
+#include <iostream>
+#include <list>
+
+#include "types.h"
+//#include "counter.h"
+
+#include <boost/utility.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+//#include <boost/type_traits/is_convertible.hpp>
+//#include <boost/utility/enable_if.hpp>
+
+
+typedef unsigned int OrderType;
+
+template<class T> struct OrderListNode;
+template<class T> class OrderListIterator;
+template<class T> class const_OrderListIterator;
+
+/**
+ * OrderList stores a list of objects while maintaining their total order under
+ * the operations of insert(), swap(), and delete(). push_back() is provided for
+ * uniformity, OrderComparison member class carries out comparison of the
+ * elements.
+ */
+template<class T>
+class OrderList: public std::list<OrderListNode<T> >
+{
+ public:
+ class OrderComparison;
+
+ /// OrderComparison type
+ typedef OrderComparison OrderComparison;
+
+ typedef OrderListNode<T> NodeType;
+ typedef OrderList<T> Self;
+ typedef std::list<NodeType > Parent;
+
+ typedef T value_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef OrderListIterator<T> iterator;
+ typedef const_OrderListIterator<T> const_iterator;
+
+ OrderList() {}
+ ~OrderList() { clear(); }
+
+ /// \name Order operations
+ void swap(iterator i, iterator j); ///< Exchanges the order of simplices pointed to by i and j
+ template<class BinaryPredicate>
+ void sort(BinaryPredicate cmp); ///< Sorts the elements in accordance with cmp
+
+ /// \name Container operations
+ /// @{
+ // Explicit calls instead of using declarations for Doxygen
+ iterator push_back(const_reference x);
+ iterator insert(iterator predecessor, const_reference x); ///< Inserts x immediately after predecessor (has to be a valid iterator)
+ void erase(iterator x) { Parent::erase(x.get_base()); }
+
+ void clear() { return Parent::clear(); }
+ bool empty() const { return Parent::empty(); }
+ SizeType size() const { return Parent::size(); }
+ iterator begin() { return iterator(Parent::begin()); }
+ const_iterator begin() const { return const_iterator(Parent::begin()); }
+ iterator end() { return iterator(Parent::end()); }
+ const_iterator end() const { return const_iterator(Parent::end()); }
+ reference back() { return Parent::back(); }
+ const_reference back() const { return Parent::back(); }
+ void pop_back() { return Parent::pop_back(); }
+
+ iterator last() { return iterator(boost::prior(end())); }
+ const_iterator last() const { return const_iterator(boost::prior(end())); }
+ /// @}
+
+ /// \name Debugging operations
+ /// @{
+ void show_elements() const;
+ /// @}
+
+ private:
+ static const float density_threshold = 1.2;
+};
+
+/// Basic comparison that LessThan and GreaterThan derive from
+template<class T>
+class OrderList<T>::OrderComparison
+{
+ public:
+ typedef typename OrderList<T>::const_iterator ComparableType;
+ int compare(ComparableType a, ComparableType b) const; /// (-1,0,1) = a (precedes, ==, succeeds) b
+ bool operator()(ComparableType a, ComparableType b) const;
+};
+
+/// Structure storing auxilliary information requred for each node of OrderList
+template<class T>
+struct OrderListNode
+{
+ OrderListNode(const T& d, unsigned int t):
+ data(d), tag(t)
+ {}
+
+ T data;
+ OrderType tag;
+
+ std::ostream& operator<<(std::ostream& out) const { return out << data << ": " << tag; }
+};
+
+template<class T, class BinaryPredicate>
+class OrderListNodeComparison
+{
+ public:
+ typedef OrderListNode<T> Node;
+ OrderListNodeComparison(BinaryPredicate cmp): cmp_(cmp) {}
+ bool operator()(const Node& a, const Node& b) const { return cmp_(a.data, b.data); }
+
+ private:
+ BinaryPredicate cmp_;
+};
+
+template<class T>
+std::ostream& operator<<(std::ostream& out, const OrderListNode<T>& n) { return n.operator<<(out); }
+
+template<class T>
+class OrderListIterator: public boost::iterator_adaptor<OrderListIterator<T>,
+ typename OrderList<T>::Parent::iterator,
+ T>
+{
+ private:
+ struct enabler {};
+
+ public:
+ typedef typename OrderList<T>::Parent OrderListParent;
+ typedef boost::iterator_adaptor<OrderListIterator<T>,
+ typename OrderListParent::iterator,
+ T> Parent;
+ typedef typename Parent::reference reference;
+ typedef typename Parent::base_type base_type;
+
+ OrderListIterator() {}
+ OrderListIterator(const typename OrderListParent::iterator& iter):
+ OrderListIterator::iterator_adaptor_(iter)
+ {}
+ OrderListIterator(const OrderListIterator<T>& other):
+ OrderListIterator::iterator_adaptor_(other.base())
+ {}
+
+ private:
+ friend class boost::iterator_core_access;
+ reference dereference() const { return Parent::base_reference()->data; }
+ base_type& get_base() { return Parent::base_reference(); }
+
+ friend class OrderList<T>;
+};
+
+template<class T>
+class const_OrderListIterator: public boost::iterator_adaptor<const_OrderListIterator<T>,
+ typename OrderList<T>::Parent::const_iterator,
+ const T>
+{
+ private:
+ struct enabler {};
+
+ public:
+ typedef typename OrderList<T>::Parent OrderListParent;
+ typedef boost::iterator_adaptor<const_OrderListIterator<T>,
+ typename OrderListParent::const_iterator,
+ const T> Parent;
+ typedef typename Parent::reference reference;
+ typedef typename Parent::base_type base_type;
+
+ const_OrderListIterator() {}
+ const_OrderListIterator(const typename OrderListParent::const_iterator& iter):
+ const_OrderListIterator::iterator_adaptor_(iter)
+ {}
+ const_OrderListIterator(const const_OrderListIterator<T>& other):
+ const_OrderListIterator::iterator_adaptor_(other.base())
+ {}
+ const_OrderListIterator(const OrderListIterator<T>& other):
+ const_OrderListIterator::iterator_adaptor_(other.base())
+ {}
+
+ private:
+ friend class boost::iterator_core_access;
+ reference dereference() const { return Parent::base_reference()->data; }
+ const base_type&
+ get_base() { return Parent::base_reference(); }
+
+ friend class OrderList<T>;
+ friend class OrderList<T>::OrderComparison;
+};
+
+
+#include "orderlist.hpp"
+
+#endif // __ORDERLIST_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/orderlist.hpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,118 @@
+/* Implementations */
+
+template<class T>
+void
+OrderList<T>::
+swap(iterator i, iterator j)
+{
+ typename Parent::iterator i_base = i.get_base();
+ typename Parent::iterator j_base = j.get_base();
+ std::swap(i_base->tag, j_base->tag);
+
+ // Exchange the actual elements in the list --- so that iterators behave as expected
+ typename Parent::iterator after_j = boost::next(j_base);
+ Parent::splice(i_base, *this, j_base);
+ Parent::splice(after_j, *this, i_base);
+}
+
+template<class T>
+template<class BinaryPredicate>
+void
+OrderList<T>::
+sort(BinaryPredicate cmp)
+{
+ Parent::sort(OrderListNodeComparison<T, BinaryPredicate>(cmp));
+ OrderType cur_order = 0;
+ for (typename Parent::iterator cur = Parent::begin(); cur != Parent::end(); ++cur)
+ cur->tag = cur_order++;
+}
+
+template<class T>
+typename OrderList<T>::iterator
+OrderList<T>::
+push_back(const_reference x)
+{
+ if (empty())
+ Parent::push_back(NodeType(x, 0));
+ else
+ Parent::push_back(NodeType(x, last().get_base()->tag + 1));
+
+ return last();
+}
+
+template<class T>
+typename OrderList<T>::iterator
+OrderList<T>::
+insert(iterator p, const_reference x)
+{
+ typename Parent::iterator p_base = p.get_base();
+ OrderType tag = (p_base++)->tag + 1;
+ typename Parent::iterator new_base = Parent::insert(p_base, NodeType(x, tag));
+
+ if (p_base->tag != tag)
+ return iterator(new_base);
+
+ // Find non-overflowing region
+ unsigned int num_elements = 1, maximum = 1, lower = tag, upper = tag, level = 0;
+ float inv_density = 1;
+ typename Parent::iterator prev = p_base, next = p_base;
+ --(--prev); ++next; // move prev back twice to skip over the newly inserted element
+
+ do
+ {
+ lower &= ~(1 << level);
+ upper |= (1 << level);
+ maximum <<= 1; inv_density *= density_threshold;
+ ++level;
+
+ while (prev != Parent::end() && prev->tag >= lower) { --prev; ++num_elements; }
+ while (next != Parent::end() && next->tag <= upper) { ++next; ++num_elements; }
+ } while (inv_density * num_elements >= maximum);
+ ++num_elements; // for the extra element inserted
+
+ Dout(dc::orderlist, num_elements << ", " << lower << ", " << upper);
+ Dout(dc::orderlist, "prev is at the end: " << (prev == Parent::end()));
+ Dout(dc::orderlist, "next is at the end: " << (next == Parent::end()));
+
+ // Reorder
+ AssertMsg((upper - lower + 1)/num_elements > 0, "Spacing between new tags must be non-zero");
+ for (unsigned int i = 0; i < num_elements; ++i)
+ {
+ (++prev)->tag = lower + i*((upper - lower + 1)/num_elements);
+ Dout(dc::orderlist, prev->tag);
+ AssertMsg(prev->tag != 0 || prev == Parent::begin(), "Cannot assign 0 tag except at the beginning of OrderList");
+ }
+
+ AssertMsg(++prev == next, "prev + num_elements != next in OrderList::insert()");
+
+ return iterator(new_base);
+}
+
+template<class T>
+void
+OrderList<T>::
+show_elements() const
+{
+ for (const_iterator cur = begin(); cur != end(); ++cur)
+ std::cout << *(cur.get_base()) << std::endl;
+ std::cout << std::endl;
+}
+
+/* OrderComparison */
+template<class T>
+int
+OrderList<T>::OrderComparison::
+compare(ComparableType a, ComparableType b) const
+{
+ if (a.get_base()->tag == b.get_base()->tag) return 0;
+ if (a.get_base()->tag < b.get_base()->tag) return -1;
+ return 1;
+}
+
+template<class T>
+bool
+OrderList<T>::OrderComparison::
+operator()(ComparableType a, ComparableType b) const
+{
+ return (compare(a,b) < 0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/sys.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,26 @@
+// sys.h
+//
+// This header file is included at the top of every source file,
+// before any other header file.
+// It is intended to add defines that are needed globally and
+// to work around Operating System dependend incompatibilities.
+
+// EXAMPLE: If you use autoconf you can add the following here.
+// #ifdef HAVE_CONFIG_H
+// #include "config.h"
+// #endif
+
+// EXAMPLE: You could add stuff like this here too
+// (Otherwise add -DCWDEBUG to your CFLAGS).
+// #if defined(WANTSDEBUGGING) && defined(HAVE_LIBCWD_BLAHBLAH)
+// #define CWDEBUG
+// #endif
+
+// The following is the libcwd related mandatory part.
+// It must be included before any system header file is included!
+#ifdef CWDEBUG
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <libcwd/sys.h>
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/utilities/types.h Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,18 @@
+#ifndef __TYPES_H__
+#define __TYPES_H__
+
+#include <limits>
+
+/* Types */
+typedef bool Sign;
+typedef short int Dimension;
+const Sign POS = true;
+const Sign NEG = false;
+typedef double RealType;
+typedef unsigned int SizeType;
+
+static RealType Infinity = std::numeric_limits<RealType>::infinity();
+
+typedef const unsigned int& version_type;
+
+#endif // __TYPES_H__
--- a/include/vineyard.h Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*
- * Author: Dmitriy Morozov
- * Department of Computer Science, Duke University, 2005 -- 2006
- */
-
-#ifndef __VINEYARD_H__
-#define __VINEYARD_H__
-
-#include "types.h"
-#include <list>
-#include <string>
-
-#include <boost/serialization/access.hpp>
-#include <boost/serialization/vector.hpp>
-#include <boost/serialization/nvp.hpp>
-#include <boost/serialization/list.hpp>
-#include <boost/serialization/is_abstract.hpp>
-
-
-template<class Smplx> class Knee;
-template<class Smplx> 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().
- */
-template<class FltrSmplx>
-class Vineyard
-{
- public:
- typedef FltrSmplx FiltrationSimplex;
- typedef typename FiltrationSimplex::Simplex Simplex;
- typedef Vine<Simplex> Vine;
- typedef Knee<Simplex> Knee;
- typedef std::list<Vine> VineList;
- typedef std::vector<VineList> VineListVector;
- typedef typename FiltrationSimplex::Cycle Cycle;
-
- typedef typename FiltrationSimplex::Index Index;
- typedef typename FiltrationSimplex::Evaluator Evaluator;
-
- public:
- Vineyard(Evaluator* eval = 0):
- evaluator(eval) {}
-
- void start_vines(Index bg, Index end);
- void switched(Index i, Index j);
- void record_diagram(Index bg, Index end);
-
- void set_evaluator(Evaluator* eval) { evaluator = eval; }
-
- void save_edges(const std::string& filename) const;
-
- protected:
- typename Knee::SimplexList resolve_cycle(Index i) const;
-
- private:
- void record_knee(Index i);
- void start_vine(Index i);
-
- private:
- VineListVector vines;
- 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.
- */
-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)
- {}
-
- bool is_diagonal() const { return birth == death; }
- bool is_infinite() const { return (death == Infinity) || (birth == Infinity); }
- void set_cycle(const SimplexList& lst) { cycle = lst; }
-
- 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 S>
-std::ostream& operator<<(std::ostream& out, const Knee<S>& 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> Knee;
- typedef std::list<Knee> VineRepresentation;
- typedef typename VineRepresentation::const_iterator const_knee_iterator;
-
- Vine() {}
- 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); }
-
- using VineRepresentation::begin;
- using VineRepresentation::end;
- using VineRepresentation::front;
- using VineRepresentation::back;
- using VineRepresentation::size;
- using VineRepresentation::empty;
-
- protected:
- using VineRepresentation::push_back;
-
- private:
- friend class boost::serialization::access;
-
- template<class Archive>
- void serialize(Archive& ar, version_type );
-};
-
-
-#include "vineyard.hpp"
-
-#endif // __VINEYARD_H__
--- a/include/vineyard.hpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/* Implementations */
-
-#include <fstream>
-#include <sstream>
-
-template<class FS>
-void
-Vineyard<FS>::
-start_vines(Index bg, Index 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(std::list<Vine>());
- }
-
- start_vine(cur);
- record_knee(cur);
- }
-}
-
-template<class FS>
-void
-Vineyard<FS>::
-switched(Index i, Index j)
-{
- Vine* i_vine = i->vine();
- Vine* j_vine = j->vine();
- i->set_vine(j_vine);
- j->set_vine(i_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");
-
- if (!i->sign()) i = i->pair();
- if (!j->sign()) j = j->pair();
- record_knee(i);
- record_knee(j);
-}
-
-template<class FS>
-void
-Vineyard<FS>::
-start_vine(Index i)
-{
- Dout(dc::vineyard, "Starting new vine");
- AssertMsg(i->sign(), "Can only start vines for positive simplices");
-
- Dimension dim = i->dimension();
- vines[dim].push_back(Vine());
- i->set_vine(&vines[dim].back());
- i->pair()->set_vine(i->vine());
-}
-
-/// Records the current diagram in the vineyard
-template<class FS>
-void
-Vineyard<FS>::
-record_diagram(Index bg, Index end)
-{
- Dout(dc::vineyard, "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);
- }
-}
-
-
-template<class FS>
-void
-Vineyard<FS>::
-save_edges(const std::string& filename) const
-{
- for (int i = 0; i < vines.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[i].begin(); vi != vines[i].end(); ++vi)
- for (typename Vine::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();
- }
-}
-
-/// Records a knee for the given simplex
-template<class FS>
-void
-Vineyard<FS>::
-record_knee(Index i)
-{
- Dout(dc::vineyard, "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
- {
- Dout(dc::vineyard, "Creating knee");
- Knee k(evaluator->value(*i), evaluator->value(*(i->pair())), evaluator->time());
- Dout(dc::vineyard, "Knee created: " << k);
-
- if (!k.is_diagonal() || i->vine()->empty()) // non-diagonal k, or empty vine
- {
- Dout(dc::vineyard, "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");
- Dout(dc::vineyard, "Overwriting first diagonal knee");
- i->vine()->back() = k;
- } else // finish this vine
- {
- Dout(dc::vineyard, "Finishing a vine");
- i->vine()->add(k);
- start_vine(i);
- i->vine()->add(k);
- }
- }
-
- i->vine()->back().set_cycle(resolve_cycle(i));
- Dout(dc::vineyard, "Leaving record_knee()");
-}
-
-template<class FS>
-typename Vineyard<FS>::Knee::SimplexList
-Vineyard<FS>::
-resolve_cycle(Index i) const
-{
- Dout(dc::vineyard, "Entered resolve_cycle");
- const Cycle& cycle = i->cycle();
-
- // Resolve simplices
- typename Knee::SimplexList lst;
- for (typename Cycle::const_iterator cur = cycle.begin(); cur != cycle.end(); ++cur)
- lst.push_back(**cur);
-
- return lst;
-}
--- a/tests/CMakeLists.txt Wed Aug 15 11:25:35 2007 -0400
+++ b/tests/CMakeLists.txt Wed Aug 15 11:39:34 2007 -0400
@@ -1,8 +1,1 @@
-set (targets
- test-consistencylist
- test-orderlist)
-
-foreach (t ${targets})
- add_executable (${t} ${t}.cpp ${external_sources})
- target_link_libraries (${t} ${libraries})
-endforeach (t ${targets})
+add_subdirectory (utilities)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/Makefile Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,26 @@
+SYNAPS_LIBS = -L/usr/lib -L/usr/lib -lsynaps -llapack -lblas -lgmpxx -lgmp -lmps -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../.. -lgfortranbegin -lgfortran -lm -lgcc_s
+
+INCLUDE_PATH=-I../../include/geometry
+DEFINES=-DBOOST_UBLAS_TYPE_CHECK=0 -g
+LIBRARIES=-lsynaps -lgmp -lgmpxx #${SYNAPS_LIBS}
+#CPPFLAGS=-march=i686 -mtune=native -Wall
+#CPPFLAGS=-march=i686 -mtune=generic -Wall
+CPPFLAGS=-Wall
+GCC=g++
+
+all: test-linalg euclidean polynomial test-eventqueue test-kinetic-sort
+
+test-linalg: test-linalg.cpp
+ ${GCC} test-linalg.cpp -o test-linalg ${INCLUDE_PATH} ${DEFINES} ${LIBRARIES} ${CPPFLAGS}
+
+euclidean: euclidean.cpp
+ ${GCC} euclidean.cpp -o euclidean ${INCLUDE_PATH} ${DEFINES} ${CPPFLAGS}
+
+polynomial: polynomial.cpp
+ ${GCC} polynomial.cpp -o polynomial ${INCLUDE_PATH} ${DEFINES} ${LIBRARIES} ${CPPFLAGS}
+
+test-eventqueue: test-eventqueue.cpp
+ ${GCC} test-eventqueue.cpp -o test-eventqueue ${CPPFLAGS} ${DEFINES} ${INCLUDE_PATH}
+
+test-kinetic-sort: test-kinetic-sort.cpp
+ ${GCC} test-kinetic-sort.cpp -o test-kinetic-sort ${INCLUDE_PATH} ${DEFINES} ${LIBRARIES} ${CPPFLAGS}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/NOTES Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,5 @@
+Write an audit for the data structure.
+
+-DBOOST_UBLAS_TYPE_CHECK=0 is necessary since otherwise Boost's uBLAS gives a compile-time error
+when it doesn't find sqrt for polynomials. It doesn't actually need it (e.g., for LU-decomposition,
+but it looks for it during type check). (File a bug report with Boost?)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/euclidean.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,86 @@
+#include "euclidean.h"
+#include <vector>
+#include <iostream>
+#include <cmath>
+
+typedef Kernel<double> K;
+typedef K::Point Point;
+typedef K::Sphere Sphere;
+typedef K::PointContainer PointContainer;
+typedef K::MatrixType MatrixType;
+
+int main()
+{
+ K k(3);
+ std::vector<Point> points(6, k.origin());
+ points[0][0] = 0; points[0][1] = 0; points[0][2] = 0;
+ points[1][0] = 0; points[1][1] = 2; points[1][2] = 0;
+ points[2][0] = 0; points[2][1] = 0; points[2][2] = 5;
+ points[3][0] = 1; points[3][1] = 1; points[3][2] = 1;
+ points[4][0] = 0; points[4][1] = 1; points[4][2] = 0;
+ points[5][0] = 1; points[5][1] = 0; points[5][2] = 0;
+
+
+ // Edges
+ {
+ PointContainer vertices(2);
+ vertices[0] = &points[0]; vertices[1] = &points[2];
+ std::cout << "{0, 2}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ std::cout << std::endl;
+
+ vertices[0] = &points[0]; vertices[1] = &points[3];
+ std::cout << "{0, 3}:" << std::endl;
+ s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ std::cout << std::endl;
+ }
+
+ // Triangles
+ {
+ PointContainer vertices(3);
+ vertices[0] = &points[0]; vertices[1] = &points[3]; vertices[2] = &points[1];
+ std::cout << "{0, 3, 1}:" << std::endl;;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ std::cout << std::endl;
+
+ vertices[0] = &points[0]; vertices[1] = &points[4]; vertices[2] = &points[5];
+ std::cout << "{0, 4, 5}:" << std::endl;
+ s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ std::cout << std::endl;
+ }
+
+ // Tetrahedron
+ {
+ PointContainer vertices(4);
+ vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2]; vertices[3] = &points[0];
+ std::cout << "{3, 1, 2, 0}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+
+ std::cout << s.center().squared_distance(points[0]) << std::endl;
+ std::cout << std::endl;
+ }
+
+ {
+ PointContainer vertices(3);
+ vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2];
+ std::cout << "{3, 1, 2}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, points[0]) << std::endl;
+
+ std::cout << "Distance: " << points[0].squared_distance(s.center()) << std::endl;
+
+ std::cout << s.center().squared_distance(points[0]) << std::endl;
+ std::cout << std::endl;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/polynomial.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,140 @@
+#include <euclidean.h>
+#include <polynomial.h>
+
+#include <vector>
+#include <iostream>
+#include <cmath>
+
+typedef UPolynomial<ZZ> PolynomialKernel;
+typedef PolynomialKernel::Polynomial Polynomial;
+typedef PolynomialKernel::RationalFunction RationalF;
+
+typedef Kernel<RationalF> K;
+typedef K::Point Point;
+typedef K::Sphere Sphere;
+typedef K::PointContainer PointContainer;
+typedef K::MatrixType MatrixType;
+
+int main()
+{
+ K k(3);
+ std::vector<Point> points(7, k.origin());
+ points[0][0] = Polynomial(0); points[0][1] = Polynomial(0); points[0][2] = Polynomial(0);
+ points[1][0] = Polynomial(0); points[1][1] = Polynomial("x+2"); points[1][2] = Polynomial(0);
+ points[2][0] = Polynomial(0); points[2][1] = Polynomial(0); points[2][2] = Polynomial("x^2 + 5");
+ points[3][0] = Polynomial("x^3"); points[3][1] = Polynomial(1); points[3][2] = Polynomial("x");
+ points[4][0] = Polynomial(0); points[4][1] = Polynomial("x^2 + 2*x + 5"); points[4][2] = Polynomial(0);
+ points[5][0] = Polynomial("x^3 + 3*x + 7"); points[5][1] = Polynomial(0); points[5][2] = Polynomial(0);
+ points[6][0] = Polynomial(0); points[6][1] = Polynomial("x + 6"); points[6][2] = Polynomial("x");
+
+ // Solving polynomials
+ {
+ PolynomialKernel::RootStack roots;
+ std::cout << "Solving " << points[5][0] << ": " << std::endl;
+ PolynomialKernel::solve(points[5][0], roots);
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+ }
+
+ {
+ Polynomial p("x^3 - 2*x + 1");
+ PolynomialKernel::RootStack roots;
+ std::cout << "Solving " << p << ": " << std::endl;
+ PolynomialKernel::solve(p, roots);
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+ }
+
+#if 0
+ // FIXME: explore
+ {
+ UPolynomial<QQ>::Polynomial p("1.2*x + 3.67");
+ UPolynomial<QQ>::RootStack roots;
+ UPolynomial<QQ>::solve(p, roots);
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+ }
+#endif
+
+ {
+ RationalF r1 = Polynomial("2*x - 4");
+ RationalF r2 = Polynomial("x^3 - 3");
+ RationalF r3 = Polynomial("x^2 - 3*x^3");
+ std::cout << r2 - r1 << std::endl;
+ std::cout << RationalF(Polynomial("2*x"), Polynomial(1)*Polynomial(1)) << std::endl;
+
+ PolynomialKernel::RootStack roots;
+ std::cout << "Solving " << (r2 - r1) << ": " << std::endl;
+ PolynomialKernel::solve(r2 - r1, roots);
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+
+ std::cout << "Solving " << (r3 - r1) << ": " << std::endl;
+ PolynomialKernel::solve(r3 - r1, roots);
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+
+ std::cout << "Solving " << (r3 - r2) << ": " << std::endl;
+ PolynomialKernel::solve(r3 - r2, roots);
+ //std::cout << "Sign of r3 at " << roots.top() << " is " << PolynomialKernel::sign_at(r3, roots.top()) << std::endl;
+ while (!roots.empty()) { std::cout << roots.top() << std::endl; roots.pop(); }
+ }
+
+ return 0;
+
+ // Edges
+ {
+ PointContainer vertices(2);
+ vertices[0] = &points[0]; vertices[1] = &points[2];
+ std::cout << "{0, 2}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+
+ vertices[0] = &points[0]; vertices[1] = &points[3];
+ std::cout << "{0, 3}:" << std::endl;
+ s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ }
+
+#if 1
+ // Triangles
+ {
+ PointContainer vertices(3);
+ vertices[0] = &points[0]; vertices[1] = &points[3]; vertices[2] = &points[1];
+ std::cout << "{0, 3, 1}:" << std::endl;;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+
+ vertices[0] = &points[0]; vertices[1] = &points[4]; vertices[2] = &points[5];
+ std::cout << "{0, 4, 5}:" << std::endl;
+ s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+
+ // Degenerate
+ vertices[0] = &points[0]; vertices[1] = &points[1]; vertices[2] = &points[6];
+ std::cout << "{0, 1, 6}:" << std::endl;
+ s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ }
+
+ // Tetrahedron
+ {
+ PointContainer vertices(4);
+ vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2]; vertices[3] = &points[0];
+ std::cout << "{3, 1, 2, 0}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << " " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, *vertices[1]) << std::endl;
+ }
+
+ // Tetrahedron
+ {
+ PointContainer vertices(3);
+ vertices[0] = &points[3]; vertices[1] = &points[1]; vertices[2] = &points[2];
+ std::cout << "{3, 1, 2}:" << std::endl;
+ Sphere s = k.circumsphere(vertices);
+ std::cout << "Circumsphere: " << s.center() << ", radius: " << s.squared_radius() << std::endl;
+ std::cout << "Side of: " << k.side_of_circumsphere(vertices, points[0]) << std::endl;
+ }
+#endif
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/test-eventqueue.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,27 @@
+#include <eventqueue.h>
+#include <functional>
+#include <iostream>
+
+int main()
+{
+ typedef EventQueue<int, std::less<int> > EQ;
+ typedef EQ::iterator iterator;
+
+ EQ queue;
+
+ iterator i = queue.push(4);
+ queue.push(2);
+ queue.push(7);
+ iterator j = queue.push(6);
+ queue.push(5);
+
+ *i = 8;
+ queue.update(i);
+ queue.remove(j);
+
+ while (!queue.empty())
+ {
+ std::cout << *queue.top() << std::endl;
+ queue.pop();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/test-kinetic-sort.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,66 @@
+#include <polynomial.h>
+#include <simulator.h>
+#include <kinetic-sort.h>
+#include <iostream>
+
+#include <boost/utility.hpp>
+
+//typedef double FieldType;
+//typedef ZZ FieldType;
+typedef QQ FieldType;
+typedef UPolynomial<FieldType> PolyKernel;
+typedef PolyKernel::Polynomial Polynomial;
+typedef std::list<Polynomial> SortDS;
+typedef Simulator<PolyKernel> SimulatorFT;
+
+class TrajectoryExtractor
+{
+ public:
+ Polynomial operator()(SortDS::iterator i) const { return *i; }
+};
+
+typedef KineticSort<SortDS, TrajectoryExtractor, SimulatorFT> KineticSortDS;
+
+struct EvaluatedComparison: public std::binary_function<const Polynomial&, const Polynomial&, bool>
+{
+ EvaluatedComparison(FieldType v): vv(v) {}
+ bool operator()(const Polynomial& p1, const Polynomial& p2)
+ { return p1(vv) < p2(vv); }
+ FieldType vv;
+};
+
+void swap(SortDS* s, SortDS::iterator i)
+{
+ std::cout << "Swapping " << *i << " " << *boost::next(i) << std::endl;
+ s->splice(i, *s, boost::next(i));
+}
+
+int main()
+{
+ SimulatorFT simulator;
+ SortDS list;
+
+ // Insert polynomials and sort the list for current time
+ list.push_back(Polynomial("x^3 - 3"));
+ list.push_back(Polynomial("x^2 - 2*x - 2"));
+ list.push_back(Polynomial("2*x - 4"));
+ //list.sort(EvaluatedComparison(simulator.current_time()));
+ list.sort(EvaluatedComparison(0));
+
+ // Print out the list
+ for (SortDS::const_iterator cur = list.begin(); cur != list.end(); ++cur)
+ std::cout << *cur << std::endl;
+
+ // Setup kinetic sort
+ KineticSortDS ks(&list, &simulator, swap);
+
+ while(!simulator.reached_infinity() && simulator.current_time() < 1)
+ {
+ //std::cout << "Current time before: " << simulator.current_time() << std::endl;
+ if (!ks.audit(&simulator)) return 1;
+ //simulator.print(std::cout << "Auditing ");
+ simulator.process();
+ //std::cout << "Current time after: " << simulator.current_time() << std::endl;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/geometry/test-linalg.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,32 @@
+#include "linalg.h"
+#include <iostream>
+
+#include <synaps/upol.h>
+#include <synaps/upol/gcd.h>
+#include "rational-function.h"
+
+
+typedef UPolDse<double> Polynomial;
+typedef RationalFunction<Polynomial> RationalF;
+
+//typedef LinearAlgebra<double> LinAlg;
+//typedef LinearAlgebra<Polynomial> LinAlg;
+typedef LinearAlgebra<RationalF> LinAlg;
+
+int main()
+{
+ LinAlg::MatrixType a(2,2);
+ a(0,0) = Polynomial("3*x"); a(1,0) = Polynomial(4); a(0,1) = Polynomial(0); a(1,1) = Polynomial(7);
+
+ std::cout << a << std::endl;
+ std::cout << LinAlg::determinant(a) << std::endl;
+ std::cout << Polynomial("3*x^2 + 4*x") / Polynomial("3*x^2") << std::endl;
+
+ LinAlg::VectorType b(2), x;
+ b(0) = Polynomial(4); b(1) = Polynomial(3);
+ LinAlg::solve(a, b, x);
+ std::cout << x << std::endl;
+
+ x(0).normalize(); x(1).normalize();
+ std::cout << x << std::endl;
+}
--- a/tests/test-consistencylist.cpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#include "consistencylist.h"
-#include <iostream>
-
-typedef ConsistencyList<int> OList;
-typedef OList::OrderComparison Comparison;
-typedef OList::iterator iterator;
-
-int main()
-{
-#ifdef CWDEBUG
- dionysus::debug::init();
-
- //Debug(dc::orderlist.on());
-#endif
-
- OList list; Comparison cmp;
- iterator i20 = list.push_back(20);
- iterator i50 = list.push_back(50);
- list.show_elements();
-
- iterator i30 = list.insert(i20, 30);
- list.show_elements();
-
- iterator i40 = list.insert(i30, 40);
- iterator i60 = list.insert(i50, 60);
- list.show_elements();
-
- iterator i70 = list.push_back(70);
- iterator i45 = list.insert(i40,45);
- iterator i25 = list.insert(i20,25);
- iterator i35 = list.insert(i30,35);
- iterator i55 = list.insert(i50,55);
- iterator i65 = list.insert(i60,65);
- iterator i57 = list.insert(i55,57);
- std::cout << "Before swaps" << std::endl;
- list.show_elements();
-
- list.swap(i45, i50);
- list.swap(i45, i65);
- std::cout << "After swaps" << std::endl;
- list.show_elements();
-
- std::cout << *(++list.end()) << std::endl;
- std::cout << *(--list.end()) << std::endl;
- std::cout << std::endl;
-
- for (int i = 0; i < 100000; ++i)
- {
- list.insert(i20,i);
- }
- list.show_elements();
-
- std::cout << "20 < 30: " << cmp.compare(i20,i30) << std::endl;
- std::cout << "60 < 40: " << cmp.compare(i60,i40) << std::endl;
- std::cout << "50 < 70: " << cmp.compare(i50,i70) << std::endl;
- std::cout << "60 < 70: " << cmp.compare(i60,i70) << std::endl;
-}
--- a/tests/test-orderlist.cpp Wed Aug 15 11:25:35 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#include "orderlist.h"
-#include <iostream>
-
-typedef OrderList<int> OList;
-typedef OList::OrderComparison Comparison;
-typedef OList::iterator iterator;
-
-int main()
-{
-#ifdef CWDEBUG
- dionysus::debug::init();
-
- Debug(dc::orderlist.on());
-#endif
-
- OList list; Comparison cmp;
- iterator i20 = list.push_back(20);
- iterator i50 = list.push_back(50);
- list.show_elements();
-
- iterator i30 = list.insert(i20, 30);
- list.show_elements();
-
- iterator i40 = list.insert(i30, 40);
- iterator i60 = list.insert(i50, 60);
- list.show_elements();
-
- iterator i70 = list.push_back(70);
- iterator i45 = list.insert(i40,45);
- iterator i25 = list.insert(i20,25);
- iterator i35 = list.insert(i30,35);
- iterator i55 = list.insert(i50,55);
- iterator i65 = list.insert(i60,65);
- iterator i57 = list.insert(i55,57);
- list.show_elements();
-
- std::cout << *(++list.end()) << std::endl;
- std::cout << *(--list.end()) << std::endl;
- std::cout << std::endl;
-
- std::cout << "20 < 30: " << cmp.compare(i20,i30) << std::endl;
- std::cout << "60 < 40: " << cmp.compare(i60,i40) << std::endl;
- std::cout << "50 < 70: " << cmp.compare(i50,i70) << std::endl;
- std::cout << "60 < 70: " << cmp.compare(i60,i70) << std::endl;
- std::cout << std::endl;
-
- std::cout << "60 < 40: " << cmp(i60, i40) << std::endl;
- std::cout << "60 < 70: " << cmp(i60, i70) << std::endl;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/utilities/CMakeLists.txt Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,8 @@
+set (targets
+ test-consistencylist
+ test-orderlist)
+
+foreach (t ${targets})
+ add_executable (${t} ${t}.cpp ${external_sources})
+ target_link_libraries (${t} ${libraries})
+endforeach (t ${targets})
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/utilities/test-consistencylist.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,57 @@
+#include "utilities/consistencylist.h"
+#include <iostream>
+
+typedef ConsistencyList<int> OList;
+typedef OList::OrderComparison Comparison;
+typedef OList::iterator iterator;
+
+int main()
+{
+#ifdef CWDEBUG
+ dionysus::debug::init();
+
+ //Debug(dc::orderlist.on());
+#endif
+
+ OList list; Comparison cmp;
+ iterator i20 = list.push_back(20);
+ iterator i50 = list.push_back(50);
+ list.show_elements();
+
+ iterator i30 = list.insert(i20, 30);
+ list.show_elements();
+
+ iterator i40 = list.insert(i30, 40);
+ iterator i60 = list.insert(i50, 60);
+ list.show_elements();
+
+ iterator i70 = list.push_back(70);
+ iterator i45 = list.insert(i40,45);
+ iterator i25 = list.insert(i20,25);
+ iterator i35 = list.insert(i30,35);
+ iterator i55 = list.insert(i50,55);
+ iterator i65 = list.insert(i60,65);
+ iterator i57 = list.insert(i55,57);
+ std::cout << "Before swaps" << std::endl;
+ list.show_elements();
+
+ list.swap(i45, i50);
+ list.swap(i45, i65);
+ std::cout << "After swaps" << std::endl;
+ list.show_elements();
+
+ std::cout << *(++list.end()) << std::endl;
+ std::cout << *(--list.end()) << std::endl;
+ std::cout << std::endl;
+
+ for (int i = 0; i < 100000; ++i)
+ {
+ list.insert(i20,i);
+ }
+ list.show_elements();
+
+ std::cout << "20 < 30: " << cmp.compare(i20,i30) << std::endl;
+ std::cout << "60 < 40: " << cmp.compare(i60,i40) << std::endl;
+ std::cout << "50 < 70: " << cmp.compare(i50,i70) << std::endl;
+ std::cout << "60 < 70: " << cmp.compare(i60,i70) << std::endl;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/utilities/test-orderlist.cpp Wed Aug 15 11:39:34 2007 -0400
@@ -0,0 +1,49 @@
+#include "utilities/orderlist.h"
+#include <iostream>
+
+typedef OrderList<int> OList;
+typedef OList::OrderComparison Comparison;
+typedef OList::iterator iterator;
+
+int main()
+{
+#ifdef CWDEBUG
+ dionysus::debug::init();
+
+ Debug(dc::orderlist.on());
+#endif
+
+ OList list; Comparison cmp;
+ iterator i20 = list.push_back(20);
+ iterator i50 = list.push_back(50);
+ list.show_elements();
+
+ iterator i30 = list.insert(i20, 30);
+ list.show_elements();
+
+ iterator i40 = list.insert(i30, 40);
+ iterator i60 = list.insert(i50, 60);
+ list.show_elements();
+
+ iterator i70 = list.push_back(70);
+ iterator i45 = list.insert(i40,45);
+ iterator i25 = list.insert(i20,25);
+ iterator i35 = list.insert(i30,35);
+ iterator i55 = list.insert(i50,55);
+ iterator i65 = list.insert(i60,65);
+ iterator i57 = list.insert(i55,57);
+ list.show_elements();
+
+ std::cout << *(++list.end()) << std::endl;
+ std::cout << *(--list.end()) << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "20 < 30: " << cmp.compare(i20,i30) << std::endl;
+ std::cout << "60 < 40: " << cmp.compare(i60,i40) << std::endl;
+ std::cout << "50 < 70: " << cmp.compare(i50,i70) << std::endl;
+ std::cout << "60 < 70: " << cmp.compare(i60,i70) << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "60 < 40: " << cmp(i60, i40) << std::endl;
+ std::cout << "60 < 70: " << cmp(i60, i70) << std::endl;
+}