--- ./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 - -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 +#include #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(n, perm) ); + BlissGraph *g=reinterpret_cast(graph); + g->n_autom++; + g->autom.push_back( Array(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 NautyGraph::add_edge(int from, int to) +void BlissGraph::add_edge(unsigned int from, unsigned int to) { - nauty_set *gv=graph_row(p_impl->src_graph, from, p_impl->m); - ADDELEMENT(gv, to); + if (p_impl->digraph) { + bliss::Digraph *g = reinterpret_cast(p_impl->src_graph); + g->add_edge(from, to); + } else { + bliss::Graph *g = reinterpret_cast(p_impl->src_graph); + g->add_edge(from, to); + } } -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(p_impl->src_graph); + g->change_color(at, color); + } else { + bliss::Graph *g = reinterpret_cast(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(p_impl->src_graph); + for (unsigned int i = from; i < to; i++) + g->change_color(i, color); + } else { + bliss::Graph *g = reinterpret_cast(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 NautyGraph::find_permutation(const NautyGraph& g2) const +Array BlissGraph::find_permutation(const BlissGraph& g2) const { if (*this != g2) throw no_match("not isomorphic"); - Array 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 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, Array > -NautyGraph::find_permutations(const NautyGraph& g2, int n_cols) const +std::pair< Array, Array > +BlissGraph::find_permutations(const BlissGraph& g2, int n_cols) const { if (*this != g2) throw no_match("not isomorphic"); - Array row_perm(p_impl->n-n_cols), col_perm(n_cols); + Array 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(); lab1canon_labels, *lab1_end=lab1+n_cols, *lab2=g2.p_impl->canon_labels; + for (unsigned int *dst=col_perm.begin(); lab1canon_labels+p_impl->n; - for (int *dst=row_perm.begin(); lab1canon_labels+p_impl->src_graph->get_nof_vertices(); + for (unsigned int *dst=row_perm.begin(); lab1 > autom; + std::list< Array > 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 @@ -70,10 +70,10 @@ class NautyGraph { } public: - NautyGraph() : p_impl(0) {} + BlissGraph() : p_impl(0) {} template - explicit NautyGraph(const GenericGraph& G, bool gather_automorphisms=false) + explicit BlissGraph(const GenericGraph& 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 - explicit NautyGraph(const GenericIncidenceMatrix& M, + explicit BlissGraph(const GenericIncidenceMatrix& M, typename pm::disable_if::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 - explicit NautyGraph(const GenericIncidenceMatrix& M, + explicit BlissGraph(const GenericIncidenceMatrix& M, typename pm::enable_if::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& p) @@ -129,16 +129,16 @@ private: public: template - static bool prepare_colored(NautyGraph& NG1, const GenericGraph& G1, const Colors1& colors1, - NautyGraph& NG2, const GenericGraph& G2, const Colors2& colors2); + static bool prepare_colored(BlissGraph& NG1, const GenericGraph& G1, const Colors1& colors1, + BlissGraph& NG2, const GenericGraph& G2, const Colors2& colors2); template - static bool prepare_colored(NautyGraph& NG, const GenericGraph& G, const Colors& colors); + static bool prepare_colored(BlissGraph& NG, const GenericGraph& G, const Colors& colors); - Array find_permutation(const NautyGraph& g2) const; - std::pair< Array, Array > find_permutations(const NautyGraph& g2, int n_cols) const; + Array find_permutation(const BlissGraph& g2) const; + std::pair< Array, Array > find_permutations(const BlissGraph& g2, int n_cols) const; int n_automorphisms() const { return n_autom; } - const std::list< Array >& automorphisms() const { return autom; } + const std::list< Array >& automorphisms() const { return autom; } }; template inline @@ -147,7 +147,7 @@ bool isomorphic(const GenericGraph inline -Array find_node_permutation(const GenericGraph& G1, const GenericGraph& G2) +Array find_node_permutation(const GenericGraph& G1, const GenericGraph& 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 inline -Array find_node_permutation(const GenericGraph& G1, const Colors1& colors1, +Array find_node_permutation(const GenericGraph& G1, const Colors1& colors1, const GenericGraph& 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 inline -Array< Array > automorphisms(const GenericGraph& G) +Array< Array > automorphisms(const GenericGraph& G) { - NautyGraph NG(G, true); - return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); + BlissGraph NG(G, true); + return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); } template inline -Array< Array > automorphisms(const GenericGraph& G, const Colors& colors) +Array< Array > automorphisms(const GenericGraph& G, const Colors& colors) { - NautyGraph NG; - NautyGraph::prepare_colored(NG,G,colors); - return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); + BlissGraph NG; + BlissGraph::prepare_colored(NG,G,colors); + return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); } template 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 inline -typename pm::enable_if< Array, Matrix1::is_symmetric && Matrix2::is_symmetric>::type +typename pm::enable_if< Array, Matrix1::is_symmetric && Matrix2::is_symmetric>::type find_row_permutation(const GenericIncidenceMatrix& M1, const GenericIncidenceMatrix& 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 inline -typename pm::enable_if< std::pair< Array, Array >, !Matrix1::is_symmetric && !Matrix2::is_symmetric>::type +typename pm::enable_if< std::pair< Array, Array >, !Matrix1::is_symmetric && !Matrix2::is_symmetric>::type find_row_col_permutation(const GenericIncidenceMatrix& M1, const GenericIncidenceMatrix& 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 inline -typename pm::enable_if< Array< Array >, Matrix::is_symmetric>::type +typename pm::enable_if< Array< Array >, Matrix::is_symmetric>::type automorphisms(const GenericIncidenceMatrix& M) { - NautyGraph NG(M, true); - return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); + BlissGraph NG(M, true); + return Array< Array >(NG.n_automorphisms(), NG.automorphisms().begin()); } template -typename pm::disable_if< Array< std::pair< Array, Array > >, Matrix::is_symmetric>::type +typename pm::disable_if< Array< std::pair< Array, Array > >, Matrix::is_symmetric>::type automorphisms(const GenericIncidenceMatrix& M) { - NautyGraph NG(M, true); - Array< std::pair< Array, Array > > result(NG.n_automorphisms()); - std::list< Array >::const_iterator p=NG.automorphisms().begin(); + BlissGraph NG(M, true); + Array< std::pair< Array, Array > > result(NG.n_automorphisms()); + std::list< Array >::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, Array > > >::iterator r=entire(result); !r.at_end(); ++r, ++p) { + for (Entire< Array< std::pair< Array, Array > > >::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 -bool NautyGraph::prepare_colored(NautyGraph& NG1, const GenericGraph& G1, const Colors1& colors1, - NautyGraph& NG2, const GenericGraph& G2, const Colors2& colors2) +bool BlissGraph::prepare_colored(BlissGraph& NG1, const GenericGraph& G1, const Colors1& colors1, + BlissGraph& NG2, const GenericGraph& 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::type, - std::pair > color_map_type; + unsigned int > color_map_type; color_map_type color_map; + unsigned int color_num = 0U; for (typename Entire::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::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 >::const_iterator - c=ensure(colors1, (pm::cons*)0).begin(); !c.at_end(); ++c) - l1[first_index(color_map[*c])]=c.index(); - + c=ensure(colors1, (pm::cons*)0).begin(); !c.at_end(); ++c) + NG1.color(c.index(), color_map[*c]); for (typename pm::ensure_features >::const_iterator c=ensure(colors2, (pm::cons*)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 -bool NautyGraph::prepare_colored(NautyGraph& NG, const GenericGraph& G, const Colors& colors) +bool BlissGraph::prepare_colored(BlissGraph& NG, const GenericGraph& G, const Colors& colors) { const int n=G.nodes(); NG.p_impl=alloc_impl(n, G.is_directed); - typedef Map color_map_type; + typedef Map color_map_type; color_map_type color_map; + unsigned int color_num = 0U; for (typename Entire::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 >::const_iterator c=ensure(colors, (pm::cons*)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 > 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."