Files

``````--- ./apps/topaz/src/isomorphic_complexes.cc.orig	2011-04-13 01:51:10.000000000 -0600
+++ ./apps/topaz/src/isomorphic_complexes.cc	2013-01-10 11:05:09.551105078 -0700
@@ -34,7 +34,7 @@ find_facet_vertex_permutations(perl::Obj
return graph::find_row_col_permutation(M1,M2);
}

-UserFunction4perl("CREDIT nauty\n\n"
+UserFunction4perl("CREDIT bliss\n\n"
"# @category Comparing\n"
"# Determine whether two given complexes are combinatorially isomorphic.\n"
"# The problem is reduced to graph isomorphism of the vertex-facet incidence graphs.\n"
--- ./apps/topaz/src/bistellar.cc.orig	2011-05-11 04:34:18.000000000 -0600
+++ ./apps/topaz/src/bistellar.cc	2013-01-10 11:05:09.551105078 -0700
@@ -381,7 +381,7 @@ UserFunction4perl("# @category Producing
"# @return SimplicialComplex",
&bistellar_simplification,"bistellar_simplification(SimplicialComplex { rounds => undef, abs => 0,  obj => undef,  relax => undef, heat => undef, constant => 0, allow_rev_move=> 0, min_n_facets => undef, verbose => undef, seed => undef, quiet => 0, distribution => undef })");

-UserFunction4perl("CREDIT nauty\n\n"
+UserFunction4perl("CREDIT bliss\n\n"
"# @category Comparing"
"# Tries to determine wheter two complexes are pl-homeomorphic by using"
"#  bistellar flips and a simulated annealing strategy."
--- ./apps/graph/src/graph_compare.cc.orig	2010-12-12 16:36:28.000000000 -0700
+++ ./apps/graph/src/graph_compare.cc	2013-01-10 11:05:09.560103386 -0700
@@ -15,150 +15,137 @@
\$Project: polymake \$\$Id: graph_compare.cc 9991 2010-12-12 23:36:28Z gawrilow \$
*/

-#define graph nauty_graph
-#define set nauty_set
-#define permutation nauty_permutation
-
-#include <nauty.h>
-
-namespace {
-inline nauty_set* graph_row(nauty_graph *g, int v, int m) { return GRAPHROW(g,v,m); }
-}
-
-#undef GRAPHROW
-#undef graph
-#undef set
-#undef permutation
-
+#include <cstring>
+#include <bliss/graph.hh>
#include "polymake/graph/graph_compare.h"

namespace polymake { namespace graph {
-namespace {
-
-DEFAULTOPTIONS_GRAPH(default_options);
-NautyGraph *in_processing=0;

-}
-
-struct NautyGraph::impl {
-   int n, m;
-   nauty_graph *src_graph, *canon_graph;
-   int *orbits, *canon_labels, *partitions;
-   optionblk options;
+struct BlissGraph::impl {
+   bliss::AbstractGraph *src_graph;
+   unsigned int *canon_labels;
+   bool digraph;

-   explicit impl(int n_arg)
-      : n(n_arg), m((n + WORDSIZE - 1) / WORDSIZE),
-        src_graph(0), canon_graph(0),
-        orbits(0), canon_labels(0), partitions(0)
+   explicit impl(int n_arg, bool dir) : digraph(dir)
{
-      src_graph=new nauty_graph[n*m];
-      EMPTYSET(src_graph,n*m);
-      canon_graph=new nauty_graph[n*m];
-      orbits=new int[n];
-      canon_labels=new int[n];
-      partitions=new int[n];
-      options=default_options;
+      if (dir)
+         src_graph = new bliss::Digraph(n_arg);
+      else
+         src_graph = new bliss::Graph(n_arg);
+      canon_labels=new unsigned int[n_arg];
}

~impl()
{
-      delete[] partitions;
delete[] canon_labels;
-      delete[] orbits;
-      delete[] canon_graph;
-      delete[] src_graph;
+      delete src_graph;
}

-   static void store_autom(int n_autom, nauty_permutation *perm, int*, int, int, int n)
+   static void store_autom(void *graph, unsigned int n, const unsigned int *aut)
{
-      in_processing->n_autom=n_autom;
-      in_processing->autom.push_back( Array<int>(n, perm) );
+      BlissGraph *g=reinterpret_cast<BlissGraph *>(graph);
+      g->n_autom++;
+      g->autom.push_back( Array<unsigned int>(n, aut) );
}
};

-NautyGraph::impl* NautyGraph::alloc_impl(int n, bool dir)
+BlissGraph::impl* BlissGraph::alloc_impl(int n, bool dir)
{
-   impl* i=new impl(n);
-   i->options.digraph=dir;
-   i->options.getcanon=true;
-   return i;
+   return new impl(n, dir);
}

-NautyGraph::~NautyGraph() { delete p_impl; }
+BlissGraph::~BlissGraph() { delete p_impl; }

+void BlissGraph::add_edge(unsigned int from, unsigned int to)
{
-   nauty_set *gv=graph_row(p_impl->src_graph, from, p_impl->m);
+   if (p_impl->digraph) {
+      bliss::Digraph *g = reinterpret_cast<bliss::Digraph *>(p_impl->src_graph);
+   } else {
+      bliss::Graph *g = reinterpret_cast<bliss::Graph *>(p_impl->src_graph);
+   }
}

-void NautyGraph::partition(int at)
+void BlissGraph::color(unsigned int at, unsigned int color)
{
-   p_impl->options.defaultptn=false;
-   std::fill(p_impl->partitions, p_impl->partitions+p_impl->n-1, 1);
-   copy(entire(sequence(0,p_impl->n)), p_impl->canon_labels);
-   p_impl->partitions[at-1]=0;
-   p_impl->partitions[p_impl->n-1]=0;
+   if (p_impl->digraph) {
+      bliss::Digraph *g = reinterpret_cast<bliss::Digraph *>(p_impl->src_graph);
+      g->change_color(at, color);
+   } else {
+      bliss::Graph *g = reinterpret_cast<bliss::Graph *>(p_impl->src_graph);
+      g->change_color(at, color);
+   }
}

-int* NautyGraph::partitions()
+void BlissGraph::color(unsigned int from, unsigned int to, unsigned int color)
{
-   p_impl->options.defaultptn=false;
-   return p_impl->partitions;
+   if (p_impl->digraph) {
+      bliss::Digraph *g = reinterpret_cast<bliss::Digraph *>(p_impl->src_graph);
+      for (unsigned int i = from; i < to; i++)
+         g->change_color(i, color);
+   } else {
+      bliss::Graph *g = reinterpret_cast<bliss::Graph *>(p_impl->src_graph);
+      for (unsigned int i = from; i < to; i++)
+         g->change_color(i, color);
+   }
}

-int* NautyGraph::labels()
+void BlissGraph::partition(unsigned int at)
{
-   return p_impl->canon_labels;
+   color(0U, at, 0U);
+   color(at, p_impl->src_graph->get_nof_vertices(), 1U);
}

-void NautyGraph::finalize(bool gather_automorphisms)
+void BlissGraph::finalize(bool gather_automorphisms)
{
-   statsblk stats;
-   const int worksize=100*1024*1024;    // 100MB
-   nauty_set *workspace=new nauty_set[worksize];
+   bliss::Stats stats;
+   size_t n=p_impl->src_graph->get_nof_vertices();
+   const unsigned int *perm;
+
if (gather_automorphisms) {
-      p_impl->options.userautomproc=&impl::store_autom;
-      in_processing=this;
+      n_autom=0;
+      perm=p_impl->src_graph->canonical_form(stats, &impl::store_autom, this);
+   } else {
+      perm=p_impl->src_graph->canonical_form(stats, NULL, NULL);
}
-   nauty(p_impl->src_graph, p_impl->canon_labels, p_impl->partitions, 0, p_impl->orbits,
-         &p_impl->options, &stats, workspace, worksize, p_impl->m, p_impl->n, p_impl->canon_graph);
-   delete[] workspace;
+   std::memcpy(p_impl->canon_labels, perm, n * sizeof(unsigned int));
}

-bool NautyGraph::operator== (const NautyGraph& g2) const
+bool BlissGraph::operator== (const BlissGraph& g2) const
{
-   if (p_impl->n != g2.p_impl->n) return false;
-   nauty_set *cg1=p_impl->canon_graph, *cg1_end=cg1+p_impl->n*p_impl->m, *cg2=g2.p_impl->canon_graph;
-   return std::equal(cg1, cg1_end, cg2);
+   size_t n=p_impl->src_graph->get_nof_vertices();
+   return n == g2.p_impl->src_graph->get_nof_vertices() &&
+      !std::memcmp(p_impl->canon_labels, g2.p_impl->canon_labels,
+                   n * sizeof(unsigned int));
}

-Array<int> NautyGraph::find_permutation(const NautyGraph& g2) const
+Array<unsigned int> BlissGraph::find_permutation(const BlissGraph& g2) const
{
if (*this != g2)
throw no_match("not isomorphic");

-   Array<int> perm(p_impl->n);
-   for (int *dst=perm.begin(), *lab1=p_impl->canon_labels, *lab1_end=lab1+p_impl->n, *lab2=g2.p_impl->canon_labels;
+   Array<unsigned int> perm(p_impl->src_graph->get_nof_vertices());
+   for (unsigned int *dst=perm.begin(), *lab1=p_impl->canon_labels, *lab1_end=lab1+p_impl->src_graph->get_nof_vertices(), *lab2=g2.p_impl->canon_labels;
lab1<lab1_end; ++lab1, ++lab2)
dst[*lab2]=*lab1;
return perm;
}

-std::pair< Array<int>, Array<int> >
-NautyGraph::find_permutations(const NautyGraph& g2, int n_cols) const
+std::pair< Array<unsigned int>, Array<unsigned int> >
+BlissGraph::find_permutations(const BlissGraph& g2, int n_cols) const
{
if (*this != g2)
throw no_match("not isomorphic");

-   Array<int> row_perm(p_impl->n-n_cols), col_perm(n_cols);
+   Array<unsigned int> row_perm(p_impl->src_graph->get_nof_vertices()-n_cols), col_perm(n_cols);

-   int *lab1=p_impl->canon_labels, *lab1_end=lab1+n_cols, *lab2=g2.p_impl->canon_labels;
-   for (int *dst=col_perm.begin(); lab1<lab1_end; ++lab1, ++lab2)
+   unsigned int *lab1=p_impl->canon_labels, *lab1_end=lab1+n_cols, *lab2=g2.p_impl->canon_labels;
+   for (unsigned int *dst=col_perm.begin(); lab1<lab1_end; ++lab1, ++lab2)
dst[*lab2]=*lab1;

-   lab1_end=p_impl->canon_labels+p_impl->n;
-   for (int *dst=row_perm.begin(); lab1<lab1_end; ++lab1, ++lab2)
+   lab1_end=p_impl->canon_labels+p_impl->src_graph->get_nof_vertices();
+   for (unsigned int *dst=row_perm.begin(); lab1<lab1_end; ++lab1, ++lab2)
dst[*lab2-n_cols]=*lab1-n_cols;

return std::make_pair(row_perm, col_perm);
--- ./apps/graph/src/Makefile.inc.orig	2010-12-12 16:36:28.000000000 -0700
+++ ./apps/graph/src/Makefile.inc	2013-01-10 11:05:54.870160960 -0700
@@ -1,9 +1,7 @@
ifndef ExtensionTop
-  ExternalLibs := nauty
-
-  graph_compare\$O : ExtraCXXFLAGS = -DBIGNAUTY -I\${BuildDir}/external/nauty
+  graph_compare\$O : ExtraCXXFLAGS = -DBLISS_USE_GMP

-  LIBS += \${BuildDir}/external/nauty/libnauty\$A
+  LIBS += -lbliss
endif

# Local Variables:
--- ./apps/graph/rules/comparing.rules.orig	2011-04-20 16:30:42.000000000 -0600
+++ ./apps/graph/rules/comparing.rules	2013-01-10 11:05:09.552104890 -0700
@@ -14,12 +14,12 @@
#-------------------------------------------------------------------------------
#  \$Project: polymake \$\$Id: comparing.rules 10159 2011-04-20 22:30:42Z paffenho \$

-CREDIT nauty
+CREDIT bliss
Computation of automorphism groups of graphs.
-  http://cs.anu.edu.au/~bdm/nauty/
+  http://www.tcs.hut.fi/Software/bliss/

-label nauty
+label bliss

# @category Comparing
# true if //graph1// and //graph2// are isomorphic.
--- ./apps/graph/include/graph_compare.h.orig	2011-03-01 08:46:48.000000000 -0700
+++ ./apps/graph/include/graph_compare.h	2013-01-10 11:05:09.552104890 -0700
@@ -27,18 +27,18 @@

namespace polymake { namespace graph {

-class NautyGraph {
+class BlissGraph {
struct impl;
impl *p_impl;

int n_autom;
-   std::list< Array<int> > autom;
+   std::list< Array<unsigned int> > autom;

static impl *alloc_impl(int n_nodes, bool is_directed);
-   void add_edge(int from, int to);
-   void partition(int at);
-   int* partitions();
-   int* labels();
+   void add_edge(unsigned int from, unsigned int to);
+   void color(unsigned int at, unsigned int color);
+   void color(unsigned int from, unsigned int to, unsigned int color);
+   void partition(unsigned int at);
void finalize(bool gather_automorphisms);

template <typename Matrix>
@@ -70,10 +70,10 @@ class NautyGraph {
}

public:
-   NautyGraph() : p_impl(0) {}
+   BlissGraph() : p_impl(0) {}

template <typename Graph>
-   explicit NautyGraph(const GenericGraph<Graph>& G, bool gather_automorphisms=false)
+   explicit BlissGraph(const GenericGraph<Graph>& G, bool gather_automorphisms=false)
: p_impl(alloc_impl(G.nodes(), G.is_directed))
{
fill(G);
@@ -82,11 +82,11 @@ public:

// non-symmetrical incidence matrix
template <typename Matrix>
-   explicit NautyGraph(const GenericIncidenceMatrix<Matrix>& M,
+   explicit BlissGraph(const GenericIncidenceMatrix<Matrix>& M,
typename pm::disable_if<bool, Matrix::is_symmetric>::type gather_automorphisms=false)
: p_impl(alloc_impl(M.rows()+M.cols(), false))
{
-      int rnode=M.cols();
+      unsigned int rnode=M.cols();
partition(rnode);
for (typename Entire< Rows< Matrix > >::const_iterator r=entire(rows(M));  !r.at_end();  ++r, ++rnode)
for (typename Entire< typename Matrix::row_type >::const_iterator c=entire(*r);  !c.at_end();  ++c) {
@@ -98,20 +98,20 @@ public:

// symmetrical incidence matrix
template <typename Matrix>
-   explicit NautyGraph(const GenericIncidenceMatrix<Matrix>& M,
+   explicit BlissGraph(const GenericIncidenceMatrix<Matrix>& M,
typename pm::enable_if<bool, Matrix::is_symmetric>::type gather_automorphisms=false)
: p_impl(alloc_impl(M.rows(), true))
{
// there can be ones on the diagonal, which correspond loops in the graph;
-      // nauty requires the graph to be declared as directed in this case
+      // bliss requires the graph to be declared as directed in this case
fill(M);
finalize(gather_automorphisms);
}

-   ~NautyGraph();
+   ~BlissGraph();

-   bool operator== (const NautyGraph& g2) const;
-   bool operator!= (const NautyGraph& g2) const { return !operator==(g2); }
+   bool operator== (const BlissGraph& g2) const;
+   bool operator!= (const BlissGraph& g2) const { return !operator==(g2); }

private:
static void incr_count(std::pair<int,int>& p)
@@ -129,16 +129,16 @@ private:

public:
template <typename Graph1, typename Colors1, typename Graph2, typename Colors2>
-   static bool prepare_colored(NautyGraph& NG1, const GenericGraph<Graph1>& G1, const Colors1& colors1,
-                               NautyGraph& NG2, const GenericGraph<Graph2>& G2, const Colors2& colors2);
+   static bool prepare_colored(BlissGraph& NG1, const GenericGraph<Graph1>& G1, const Colors1& colors1,
+                               BlissGraph& NG2, const GenericGraph<Graph2>& G2, const Colors2& colors2);
template <typename Graph, typename Colors>
-   static bool prepare_colored(NautyGraph& NG, const GenericGraph<Graph>& G, const Colors& colors);
+   static bool prepare_colored(BlissGraph& NG, const GenericGraph<Graph>& G, const Colors& colors);

-   Array<int> find_permutation(const NautyGraph& g2) const;
-   std::pair< Array<int>, Array<int> > find_permutations(const NautyGraph& g2, int n_cols) const;
+   Array<unsigned int> find_permutation(const BlissGraph& g2) const;
+   std::pair< Array<unsigned int>, Array<unsigned int> > find_permutations(const BlissGraph& g2, int n_cols) const;

int n_automorphisms() const { return n_autom; }
-   const std::list< Array<int> >& automorphisms() const { return autom; }
+   const std::list< Array<unsigned int> >& automorphisms() const { return autom; }
};

template <typename Graph1, typename Graph2> inline
@@ -147,7 +147,7 @@ bool isomorphic(const GenericGraph<Graph
if (G1.is_directed != G2.is_directed || G1.nodes() != G2.nodes())
return false;
if (G1.nodes()<=1) return true;
-   NautyGraph NG1(G1), NG2(G2);
+   BlissGraph NG1(G1), NG2(G2);
return NG1==NG2;
}

@@ -158,49 +158,49 @@ bool isomorphic(const GenericGraph<Graph
if (G1.is_directed != G2.is_directed || G1.nodes() != G2.nodes())
return false;
if (G1.nodes()<=1) return true;
-   NautyGraph NG1, NG2;
-   return NautyGraph::prepare_colored(NG1, G1, colors1, NG2, G2, colors2) && NG1==NG2;
+   BlissGraph NG1, NG2;
+   return BlissGraph::prepare_colored(NG1, G1, colors1, NG2, G2, colors2) && NG1==NG2;
}

template <typename Graph1, typename Graph2> inline
-Array<int> find_node_permutation(const GenericGraph<Graph1>& G1, const GenericGraph<Graph2>& G2)
+Array<unsigned int> find_node_permutation(const GenericGraph<Graph1>& G1, const GenericGraph<Graph2>& G2)
{
if (G1.is_directed != G2.is_directed)
throw no_match("graphs of different kind");
if (G1.nodes() != G2.nodes())
throw no_match("graphs of different size");
-   NautyGraph NG1(G1), NG2(G2);
+   BlissGraph NG1(G1), NG2(G2);
return NG1.find_permutation(NG2);
}

template <typename Graph1, typename Colors1, typename Graph2, typename Colors2> inline
-Array<int> find_node_permutation(const GenericGraph<Graph1>& G1, const Colors1& colors1,
+Array<unsigned int> find_node_permutation(const GenericGraph<Graph1>& G1, const Colors1& colors1,
const GenericGraph<Graph2>& G2, const Colors2& colors2)
{
if (G1.is_directed != G2.is_directed)
throw no_match("graphs of different kind");
if (G1.nodes() != G2.nodes())
throw no_match("graphs of different size");
-   NautyGraph NG1, NG2;
-   if (NautyGraph::prepare_colored(NG1, G1, colors1, NG2, G2, colors2))
+   BlissGraph NG1, NG2;
+   if (BlissGraph::prepare_colored(NG1, G1, colors1, NG2, G2, colors2))
return NG1.find_permutation(NG2);
else
throw no_match("different colors");
}

template <typename Graph> inline
-Array< Array<int> > automorphisms(const GenericGraph<Graph>& G)
+Array< Array<unsigned int> > automorphisms(const GenericGraph<Graph>& G)
{
-   NautyGraph NG(G, true);
-   return Array< Array<int> >(NG.n_automorphisms(), NG.automorphisms().begin());
+   BlissGraph NG(G, true);
+   return Array< Array<unsigned int> >(NG.n_automorphisms(), NG.automorphisms().begin());
}

template <typename Graph, typename Colors> inline
-Array< Array<int> > automorphisms(const GenericGraph<Graph>& G, const Colors& colors)
+Array< Array<unsigned int> > automorphisms(const GenericGraph<Graph>& G, const Colors& colors)
{
-   NautyGraph NG;
-   NautyGraph::prepare_colored(NG,G,colors);
-   return Array< Array<int> >(NG.n_automorphisms(), NG.automorphisms().begin());
+   BlissGraph NG;
+   BlissGraph::prepare_colored(NG,G,colors);
+   return Array< Array<unsigned int> >(NG.n_automorphisms(), NG.automorphisms().begin());
}

template <typename Matrix1, typename Matrix2> inline
@@ -210,49 +210,49 @@ isomorphic(const GenericIncidenceMatrix<
if (M1.rows() != M2.rows() || M1.cols() != M2.cols())
return false;
if (M1.rows()<=1) return true;
-   NautyGraph NG1(M1), NG2(M2);
+   BlissGraph NG1(M1), NG2(M2);
return NG1==NG2;
}

template <typename Matrix1, typename Matrix2> inline
-typename pm::enable_if< Array<int>, Matrix1::is_symmetric && Matrix2::is_symmetric>::type
+typename pm::enable_if< Array<unsigned int>, Matrix1::is_symmetric && Matrix2::is_symmetric>::type
find_row_permutation(const GenericIncidenceMatrix<Matrix1>& M1, const GenericIncidenceMatrix<Matrix2>& M2)
{
if (M1.rows() != M2.rows())
throw no_match("matrices of different dimensions");
-   NautyGraph NG1(M1), NG2(M2);
+   BlissGraph NG1(M1), NG2(M2);
return NG1.find_permutation(NG2);
}

template <typename Matrix1, typename Matrix2> inline
-typename pm::enable_if< std::pair< Array<int>, Array<int> >, !Matrix1::is_symmetric && !Matrix2::is_symmetric>::type
+typename pm::enable_if< std::pair< Array<unsigned int>, Array<unsigned int> >, !Matrix1::is_symmetric && !Matrix2::is_symmetric>::type
find_row_col_permutation(const GenericIncidenceMatrix<Matrix1>& M1, const GenericIncidenceMatrix<Matrix2>& M2)
{
if (M1.rows() != M2.rows() || M1.cols() != M2.cols())
throw no_match("matrices of different dimensions");
-   NautyGraph NG1(M1), NG2(M2);
+   BlissGraph NG1(M1), NG2(M2);
return NG1.find_permutations(NG2, M1.cols());
}

template <typename Matrix> inline
-typename pm::enable_if< Array< Array<int> >, Matrix::is_symmetric>::type
+typename pm::enable_if< Array< Array<unsigned int> >, Matrix::is_symmetric>::type
automorphisms(const GenericIncidenceMatrix<Matrix>& M)
{
-   NautyGraph NG(M, true);
-   return Array< Array<int> >(NG.n_automorphisms(), NG.automorphisms().begin());
+   BlissGraph NG(M, true);
+   return Array< Array<unsigned int> >(NG.n_automorphisms(), NG.automorphisms().begin());
}

template <typename Matrix>
-typename pm::disable_if< Array< std::pair< Array<int>, Array<int> > >, Matrix::is_symmetric>::type
+typename pm::disable_if< Array< std::pair< Array<unsigned int>, Array<unsigned int> > >, Matrix::is_symmetric>::type
automorphisms(const GenericIncidenceMatrix<Matrix>& M)
{
-   NautyGraph NG(M, true);
-   Array< std::pair< Array<int>, Array<int> > > result(NG.n_automorphisms());
-   std::list< Array<int> >::const_iterator p=NG.automorphisms().begin();
+   BlissGraph NG(M, true);
+   Array< std::pair< Array<unsigned int>, Array<unsigned int> > > result(NG.n_automorphisms());
+   std::list< Array<unsigned int> >::const_iterator p=NG.automorphisms().begin();
const int n_rows=M.rows(), n_cols=M.cols();
sequence rows(n_cols, n_rows), cols(0, n_cols);

-   for (Entire< Array< std::pair< Array<int>, Array<int> > > >::iterator r=entire(result); !r.at_end(); ++r, ++p) {
+   for (Entire< Array< std::pair< Array<unsigned int>, Array<unsigned int> > > >::iterator r=entire(result); !r.at_end(); ++r, ++p) {
r->first.append(n_rows, translate(select(*p,rows), -n_cols).begin());
r->second.append(n_cols, select(*p,cols).begin());
}
@@ -260,45 +260,31 @@ automorphisms(const GenericIncidenceMatr
}

template <typename Graph1, typename Colors1, typename Graph2, typename Colors2>
-bool NautyGraph::prepare_colored(NautyGraph& NG1, const GenericGraph<Graph1>& G1, const Colors1& colors1,
-                                 NautyGraph& NG2, const GenericGraph<Graph2>& G2, const Colors2& colors2)
+bool BlissGraph::prepare_colored(BlissGraph& NG1, const GenericGraph<Graph1>& G1, const Colors1& colors1,
+                                 BlissGraph& NG2, const GenericGraph<Graph2>& G2, const Colors2& colors2)
{
const int n=G1.nodes();
NG1.p_impl=alloc_impl(n, G1.is_directed);
NG2.p_impl=alloc_impl(n, G2.is_directed);

typedef Map<typename pm::identical<typename Colors1::value_type, typename Colors2::value_type>::type,
-      std::pair<int, int> > color_map_type;
+      unsigned int > color_map_type;
color_map_type color_map;
+   unsigned int color_num = 0U;

for (typename Entire<Colors1>::const_iterator c=entire(colors1); !c.at_end(); ++c)
-      incr_count(color_map[*c]);
-
+      if (!color_map.exists(*c))
+         color_map[*c]=color_num++;
for (typename Entire<Colors2>::const_iterator c=entire(colors2); !c.at_end(); ++c)
-      if (--color_map[*c].second < 0)
-         return false;
-
-   int *p1=NG1.partitions(), *l1=NG1.labels(), *l2=NG2.labels();
-   int start=0;
-
-   for (typename color_map_type::iterator cm=color_map.begin(); !cm.at_end(); ++cm) {
-      const int n_of_this_color=cm->second.first;
-      cm->second.second=start;
-      std::fill(p1, p1+n_of_this_color-1, 1);  p1+=n_of_this_color; p1[-1]=0;
-      start+=n_of_this_color;
-   }
-   p1=NG1.partitions();
-
-   std::copy(p1, p1+n, NG2.partitions());
+      if (!color_map.exists(*c))
+         color_map[*c]=color_num++;

for (typename pm::ensure_features<Colors1, pm::cons<pm::end_sensitive, pm::indexed> >::const_iterator
-           c=ensure(colors1, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !c.at_end(); ++c)
-      l1[first_index(color_map[*c])]=c.index();
-
+           c=ensure(colors1, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !c.at_end(); ++c)
+      NG1.color(c.index(), color_map[*c]);
for (typename pm::ensure_features<Colors2, pm::cons<pm::end_sensitive, pm::indexed> >::const_iterator
c=ensure(colors2, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !c.at_end(); ++c)
-      l2[second_index(color_map[*c])]=c.index();
-
+      NG2.color(c.index(), color_map[*c]);

NG1.fill(G1);  NG1.finalize(false);
NG2.fill(G2);  NG2.finalize(false);
@@ -306,31 +292,22 @@ bool NautyGraph::prepare_colored(NautyGr
}

template <typename Graph, typename Colors>
-bool NautyGraph::prepare_colored(NautyGraph& NG, const GenericGraph<Graph>& G, const Colors& colors)
+bool BlissGraph::prepare_colored(BlissGraph& NG, const GenericGraph<Graph>& G, const Colors& colors)
{
const int n=G.nodes();
NG.p_impl=alloc_impl(n, G.is_directed);

-   typedef Map<typename Colors::value_type, int > color_map_type;
+   typedef Map<typename Colors::value_type, unsigned int > color_map_type;
color_map_type color_map;
+   unsigned int color_num = 0U;

for (typename Entire<Colors>::const_iterator c=entire(colors); !c.at_end(); ++c)
-      ++color_map[*c];
-
-
-   int *p=NG.partitions(), *l=NG.labels();
-   int start=0;
-
-   for (typename color_map_type::iterator cm=color_map.begin(); !cm.at_end(); ++cm) {
-      const int n_of_this_color=cm->second;
-      cm->second += start-n_of_this_color;
-      start += n_of_this_color;
-      std::fill(p, p+n_of_this_color-1, 1);  p+=n_of_this_color; p[-1]=0;
-   }
+      if (!color_map.exists(*c))
+         color_map[*c]=color_num++;

for (typename pm::ensure_features<Colors, pm::cons<pm::end_sensitive, pm::indexed> >::const_iterator
c=ensure(colors, (pm::cons<pm::end_sensitive, pm::indexed>*)0).begin(); !c.at_end(); ++c)
-      l[color_map[*c]++]=c.index();
+      NG.color(c.index(), color_map[*c]);

NG.fill(G);  NG.finalize(true);
return true;
--- ./apps/polytope/src/isomorphic_polytopes.cc.orig	2011-04-13 01:51:10.000000000 -0600
+++ ./apps/polytope/src/isomorphic_polytopes.cc	2013-01-10 11:05:09.550105266 -0700
@@ -40,7 +40,7 @@ find_facet_vertex_permutations(perl::Obj
return graph::find_row_col_permutation(M1,M2);
}

-UserFunction4perl("CREDIT nauty\n\n"
+UserFunction4perl("CREDIT bliss\n\n"
"# @category Comparing"
"# Check whether the face lattices of two polytopes are isomorphic."
"# The problem is reduced to graph isomorphism of the vertex-facet incidence graphs."
--- ./apps/polytope/src/lattice_isomorphic_polytopes.cc.orig	2011-09-12 15:56:14.000000000 -0600
+++ ./apps/polytope/src/lattice_isomorphic_polytopes.cc	2013-01-10 11:05:09.543106580 -0700
@@ -88,7 +88,7 @@ Array< Array<int> > lattice_automorphism
}

-UserFunction4perl("CREDIT nauty\n\n"
+UserFunction4perl("CREDIT bliss\n\n"
"# @category Comparing"
"# Tests whether two smooth lattice polytopes are lattice equivalent"
"# by comparing lattice distances between vertices and facets. "
--- ./apps/polytope/src/congruent_polytopes.cc.orig	2011-04-13 01:51:10.000000000 -0600
+++ ./apps/polytope/src/congruent_polytopes.cc	2013-01-10 11:05:09.543106580 -0700
@@ -59,7 +59,7 @@ Scalar congruent(perl::Object p1, perl::
return graph::isomorphic(G1, dist1, G2, dist2) ? min1 : Scalar(0);
}

-UserFunctionTemplate4perl("CREDIT nauty\n\n"
+UserFunctionTemplate4perl("CREDIT bliss\n\n"
"# @category Comparing"
"# Check whether two given polytopes //P1// and //P2// are congruent, i.e. whether"
"# there is an affine isomorphism between them that is induced by a (possibly scaled) orthogonal matrix."
``````