12 #ifndef NETCOMPLEXITY_H 13 #define NETCOMPLEXITY_H 38 using std::insert_iterator;
39 using std::max_element;
40 using std::set_difference;
52 #include "nauty_sizes.h" 65 typedef unsigned int setword;
68 typedef unsigned long setword;
75 typedef unsigned int setword;
79 typedef unsigned long setword;
82 typedef unsigned long long setword;
83 #define SETWORD_LONGLONG 89 const setword MSK64=0xFFFFFFFFFFFFFFFFUL;
90 const setword MSK63C=0x7FFFFFFFFFFFFFFFUL;
91 const setword ALLBITS=MSK64;
92 inline unsigned SETWD(
unsigned pos) {
return pos>>6;}
93 inline unsigned SETBT(
unsigned pos) {
return pos&0x3F;}
94 inline setword BITMASK(
unsigned x) {
return MSK63C >> x;}
96 #ifdef SETWORD_LONGLONG 97 const setword bitt[] = {01000000000000000000000LL,0400000000000000000000LL,
98 0200000000000000000000LL,0100000000000000000000LL,
99 040000000000000000000LL,020000000000000000000LL,
100 010000000000000000000LL,04000000000000000000LL,
101 02000000000000000000LL,01000000000000000000LL,
102 0400000000000000000LL,0200000000000000000LL,
103 0100000000000000000LL,040000000000000000LL,
104 020000000000000000LL,010000000000000000LL,
105 04000000000000000LL,02000000000000000LL,
106 01000000000000000LL,0400000000000000LL,0200000000000000LL,
107 0100000000000000LL,040000000000000LL,020000000000000LL,
108 010000000000000LL,04000000000000LL,02000000000000LL,
109 01000000000000LL,0400000000000LL,0200000000000LL,
110 0100000000000LL,040000000000LL,020000000000LL,010000000000LL,
111 04000000000LL,02000000000LL,01000000000LL,0400000000LL,
112 0200000000LL,0100000000LL,040000000LL,020000000LL,
113 010000000LL,04000000LL,02000000LL,01000000LL,0400000LL,
114 0200000LL,0100000LL,040000LL,020000LL,010000LL,04000LL,
115 02000LL,01000LL,0400LL,0200LL,0100LL,040LL,020LL,010LL,
118 const setword bitt[] = {01000000000000000000000,0400000000000000000000,
119 0200000000000000000000,0100000000000000000000,
120 040000000000000000000,020000000000000000000,
121 010000000000000000000,04000000000000000000,
122 02000000000000000000,01000000000000000000,
123 0400000000000000000,0200000000000000000,
124 0100000000000000000,040000000000000000,020000000000000000,
125 010000000000000000,04000000000000000,02000000000000000,
126 01000000000000000,0400000000000000,0200000000000000,
127 0100000000000000,040000000000000,020000000000000,
128 010000000000000,04000000000000,02000000000000,
129 01000000000000,0400000000000,0200000000000,0100000000000,
130 040000000000,020000000000,010000000000,04000000000,
131 02000000000,01000000000,0400000000,0200000000,0100000000,
132 040000000,020000000,010000000,04000000,02000000,01000000,
133 0400000,0200000,0100000,040000,020000,010000,04000,
134 02000,01000,0400,0200,0100,040,020,010,04,02,01};
137 const setword MSK32=0xFFFFFFFFUL;
138 const setword MSK31C=0x7FFFFFFFUL;
139 const setword ALLBITS=MSK32;
140 inline unsigned SETWD(
unsigned pos) {
return pos>>5;}
141 inline unsigned SETBT(
unsigned pos) {
return pos&0x1F;}
142 inline setword BITMASK(
unsigned x) {
return MSK31C >> x;}
144 const setword bitt[] = {020000000000,010000000000,04000000000,02000000000,
145 01000000000,0400000000,0200000000,0100000000,040000000,
146 020000000,010000000,04000000,02000000,01000000,0400000,
147 0200000,0100000,040000,020000,010000,04000,02000,01000,
148 0400,0200,0100,040,020,010,04,02,01};
152 inline void ADDELEMENT(setword* setadd,
unsigned pos)
153 {setadd[SETWD(pos)] |= bitt[SETBT(pos)];}
155 inline void DELELEMENT(setword *setadd,
unsigned pos)
156 {setadd[SETWD(pos)] &= ~bitt[SETBT(pos)];}
158 inline void FLIPELEMENT(setword *setadd,
unsigned pos)
159 {setadd[SETWD(pos)] ^= bitt[SETBT(pos)];}
161 inline bool ISELEMENT(
const setword *setadd,
unsigned pos)
162 {
return (setadd[SETWD(pos)] & bitt[SETBT(pos)]) != 0;}
164 inline void EMPTYSET(setword *setadd,
unsigned m)
167 for (es = setadd+m; --es >= setadd;) *es=0;
179 void iota(
typename T::iterator p,
const typename T::iterator& end,
typename T::value_type val)
180 {
for (; p!=end; p++, val++) *p=val;}
182 inline void iota(vector<unsigned>::iterator p,
const vector<unsigned>::iterator& end,
unsigned val)
183 {
for (; p!=end; p++, val++) *p=val;}
185 inline void iota(
unsigned* p,
const unsigned * end,
unsigned val)
186 {
for (; p!=end; p++, val++) *p=val;}
196 bitref(setword *a,
unsigned i): addr(a), idx(i) {}
197 operator bool ()
const {
return ISELEMENT(addr,idx);}
198 bitref& operator=(
bool x) {x? ADDELEMENT(addr,idx): DELELEMENT(addr,idx);
return *
this;}
199 bitref& operator=(
const bitref& x) {
return (*
this)=(bool)x;}
200 bool operator==(
const bitref x)
const {
return (
bool)(*this)==(bool)x;}
201 bool operator!=(
const bitref x)
const {
return (
bool)(*this)==(bool)x;}
202 bool operator<(
const bitref x)
const {
return (
bool)(*this)<(bool)x;}
211 const_bitref(
const setword *a,
unsigned i): addr(a), idx(i) {}
212 operator bool ()
const {
return ISELEMENT(addr,idx);}
213 bool operator==(
const bitref x)
const {
return (
bool)(*this)==(bool)x;}
214 bool operator!=(
const bitref x)
const {
return (
bool)(*this)==(bool)x;}
215 bool operator<(
const bitref x)
const {
return (
bool)(*this)<(bool)x;}
223 std::vector<setword> data;
225 unsigned nwords()
const {
return sz? div(sz-1)+1: 0;}
226 unsigned nbytes()
const {
return nwords()*(WORDSIZE>>3);}
227 unsigned div(
unsigned i)
const {
return SETWD(i);}
228 unsigned mod(
unsigned i)
const {
return SETBT(i);}
229 unsigned mod(
int i)
const {
return SETBT(i);}
230 void null_last_bits() {
if (sz) data[nwords()-1]&=~BITMASK(mod(sz-1));}
231 bool last_bits_null()
const {
232 return sz==0 || !(data[nwords()-1]&BITMASK(mod(sz-1)));
241 bitvect(
const bitvect& x): sz(x.sz), data(x.data) {assert(last_bits_null());}
242 bitvect(
unsigned s,
bool x=
false): sz(s), data(nwords(),x?ALLBITS:0) {
245 bitvect(
const vector<T>& x): sz(x.sz), data(nwords()) {
246 for (
unsigned i=0; i<sz; i++) (*
this)[i]=x[i];
247 assert(last_bits_null());
251 assert(x.data.size()==data.size());
252 for (
unsigned i=0; i<x.data.size(); ++i) data[i]|=x.data[i];
253 assert(last_bits_null());
259 assert(x.data.size()==data.size());
260 for (
unsigned i=0; i<x.data.size(); ++i) data[i]&=x.data[i];
261 assert(last_bits_null());
268 assert(x.data.size()==data.size());
269 for (
unsigned i=0; i<x.data.size(); ++i) data[i]^=x.data[i];
281 for (
unsigned i=0; i<data.size(); ++i) data[i]=~data[i];
286 bitvect operator>>(
unsigned offs)
const {
288 for (
unsigned i=0; i<nwords()-1; ++i) {
289 r.data[div(i*WORDSIZE+offs)+1] = data[i]>>mod(offs);
290 r.data[div(i*WORDSIZE+offs)] = data[i]<<mod(-offs);
292 r.data[div((nwords()-1)*WORDSIZE+offs)] = data[nwords()-1]<<mod(-offs);
295 bitvect num(
unsigned start,
unsigned nbits)
const;
296 bool equal(
const bitvect& y,
unsigned len,
unsigned offs)
const;
297 void setrange(
unsigned start,
unsigned end,
bool value);
298 bitref operator[] (
unsigned i) {assert(i<sz);
return bitref(&data[0],i);}
300 unsigned size()
const {
return sz;}
302 void operator++(
int);
306 unsigned popcnt(
unsigned start=0,
int end=-1 )
const;
307 bool operator==(
const bitvect& x)
const 310 for (
unsigned i=0; r&&i<nwords(); i++) r&=x.data[i]==data[i];
313 bool operator!=(
const bitvect& x)
const {
return !((*this)==x);}
314 bool operator<(
const bitvect& x)
const 316 assert(last_bits_null());
319 for (i=0; i<nwords(); i++)
if (!(r&=x.data[i]==data[i]))
break;
320 return !r && (sz<x.sz || (sz==x.sz && data[i]<x.data[i]));
323 for (
unsigned i=0; i<nwords(); data[i++]=::rand());
330 #pragma omit pack ecolab::bitref 331 #pragma omit unpack ecolab::bitref 332 #pragma omit pack ecolab::const_bitref 333 #pragma omit unpack ecolab::const_bitref 342 template <
class T,
class U>
343 void asgRep(T& x,
const U& y)
345 if (x.nodes()!=y.nodes()) x=T(y.nodes());
346 for (
unsigned i=0; i<y.nodes(); ++i)
347 for (
unsigned j=0; j<y.nodes(); ++j)
348 if (i!=j) x(i,j)=y(i,j);
352 template <
class T,
class Graph>
357 x(i->source(),i->target())=
true;
369 e(0, 1), i(e.source()), j(e.target()), rep(&rp)
371 if (end||rep->nodes()<2) {i=rep->nodes(); j=0;}
372 else if (!(*rep)(i,j)) operator++();
375 i(e.source()), j(e.target()) {*
this=x;}
377 {e=x.e; rep=x.rep;
return *
this;}
379 Edge operator*()
const {
return e;}
380 const Edge* operator->()
const {
return &e;}
390 }
while (i<rep->nodes() && !(*rep)(i,j));
393 return e==x.e && rep==x.rep;
396 return !operator==(x);
411 unsigned idx(
unsigned i,
unsigned j)
const {
413 return (j<i)? (nodecnt-1)*i+j: (nodecnt-1)*i+j-1;
417 const_iterator begin()
const {
return const_iterator(*
this,
false);}
418 const_iterator end()
const {
return const_iterator(*
this,
true);}
422 BitRep(
unsigned nodes=0,
unsigned links=0):
423 linklist( nodes * (nodes-1), false), nodecnt(nodes) {
424 assert(links<=linklist.size());
425 linklist.setrange(0,links,
true);
435 const BitRep& operator=(
const NautyRep& x) {asgRep(*
this,x);
return *
this;}
437 {asgRep(*
this,x);
return *
this;}
440 {linklist|=x.linklist;
return *
this;}
443 {linklist&=x.linklist;
return *
this;}
446 {linklist^=x.linklist;
return *
this;}
449 {
BitRep r; r.nodecnt=nodecnt; r.linklist=~linklist;
return r;}
452 linklist|=x.linklist>>nodecnt;
458 bitref operator()(
unsigned i,
unsigned j) {
459 return linklist[
idx(i,j)];}
461 return linklist[
idx(i,j)];}
463 unsigned nodes()
const {
return nodecnt;}
465 unsigned links()
const {
return linklist.popcnt();}
468 bool operator==(
const BitRep& x)
const {
469 return nodecnt==x.nodecnt && linklist==x.linklist;
471 bool operator!=(
const BitRep& x)
const {
return !operator==(x);}
472 bool operator<(
const BitRep& x)
const {
473 return nodecnt<x.nodecnt || (nodecnt==x.nodecnt && linklist<x.linklist);
475 bool contains(
const Edge& e)
const {
return operator()(e.source(),e.target());}
476 void push_back(
const Edge& e) {operator()(e.source(),e.target())=
true;}
477 void clear (
unsigned nodes=0) {
478 nodecnt=nodes; linklist.setrange( 0, nodes * (nodes-1),
false);}
491 const_iterator begin()
const {
return const_iterator(*
this,
false);}
492 const_iterator end()
const {
return const_iterator(*
this,
true);}
494 unsigned m()
const {
return SETWD(nodecnt-1)+1;}
495 unsigned mw()
const {
return WORDSIZE*m();}
500 nodecnt(nodes),linklist( nodes * mw(),
false) {
513 const NautyRep& operator=(
const BitRep& x) {asgRep(*
this,x);
return *
this;}
515 asgRep(*
this,x);
return *
this;}
518 bitref operator()(
unsigned i,
unsigned j) {
519 return linklist[mw()*i+j];}
521 return linklist[mw()*i+j];}
523 unsigned nodes()
const {
return nodecnt;}
525 unsigned links()
const {
return linklist.popcnt();}
528 return nodecnt==x.nodecnt && linklist==x.linklist;
530 bool operator!=(
const NautyRep& x)
const {
return !operator==(x);}
531 bool operator<(
const NautyRep& x)
const {
532 return nodecnt<x.nodecnt || (nodecnt==x.nodecnt && linklist<x.linklist);
535 double lnomega()
const;
539 bool contains(
const Edge& e)
const {
return operator()(e.source(),e.target());}
540 void push_back(
const Edge& e) {operator()(e.source(),e.target())=
true;}
541 void clear (
unsigned nodes=0) {
542 nodecnt=nodes; linklist.setrange( 0, nodes * (nodes-1),
false);}
552 unsigned idx(
unsigned i,
unsigned j)
const {
553 return (j<i)? ((i*(i-1))>>1) + j: ((j*(j-1))>>1)+i;
558 const_iterator begin()
const {
return const_iterator(*
this,
false);}
559 const_iterator end()
const {
return const_iterator(*
this,
true);}
561 operator BitRep()
const {
BitRep r; asgRep(r,*
this);
return r;}
565 linklist( nodes*(nodes-1)/2, false), nodecnt(nodes) {
566 assert(links<=linklist.size());
567 linklist.setrange(0,links,
true);
580 {asgRep(*
this,x);
return *
this;}
582 {asgRep(*
this,x);
return *
this;}
584 bitref operator()(
unsigned i,
unsigned j) {
585 return linklist[
idx(i,j)];}
587 return linklist[
idx(i,j)];}
589 unsigned nodes()
const {
return nodecnt;}
591 unsigned links()
const {
return 2*linklist.popcnt();}
595 return nodecnt==x.nodecnt && linklist==x.linklist;
599 return nodecnt<x.nodecnt || (nodecnt==x.nodecnt && linklist<x.linklist);
601 bool contains(
const Edge& e)
const {
return operator()(e.source(),e.target());}
602 void push_back(
const Edge& e) {operator()(e.source(),e.target())=
true;}
603 void clear (
unsigned nodes=0) {
604 nodecnt=nodes; linklist.setrange( 0, nodes * (nodes-1),
false);}
610 BitRep permute(
const BitRep& x,
const vector<unsigned>& perm);
620 bool do_canonical,
int invMethod=0);
623 double saucy_lnomega(
const DiGraph&);
625 double igraph_lnomega(
const DiGraph& g,
int method);
631 #pragma omit TCL_obj BitRep 632 #pragma omit TCL_obj BiDirectionalBitRep 635 BitRep start_perm(
unsigned nodes,
unsigned links);
636 double lnfactorial(
unsigned x);
637 double lnCombine(
unsigned x,
unsigned y);
639 inline double baseComplexity(
unsigned n,
unsigned l,
bool bidirectional=
false)
641 double ilog2=1/log(2.0);
644 return 2*ceil(log(n+1)*ilog2) + 1 + ceil(log(N)*ilog2) +
645 ilog2 * (bidirectional? lnCombine(N/2,l/2): lnCombine(N,l));
648 inline double complexity(
NautyRep x,
bool bidirectional=
false)
650 double ilog2=1/log(2.0);
665 {
return canonical(canon, static_cast<const Graph&>(g));}
668 {
return canonical(canon, static_cast<const Graph&>(g));}
675 double complexity(
const Graph& g);
677 {
return complexity(static_cast<const Graph&>(g));}
679 double complexity(
const Graph& g);
681 {
return complexity(static_cast<const Graph&>(g));}
683 template <
class G>
double complexity(
const G& g)
689 inline setword bitrange(
unsigned i) {
return i==64? 0: ALLBITS>>i;}
692 inline setword bitrange(
unsigned i) {
return i==32? 0: ALLBITS>>i;}
695 inline bitvect num(
const bitvect& x,
unsigned start,
unsigned nbits)
697 return x.num(start,nbits);
700 inline bitvect bitvect::num(
unsigned start,
unsigned nbits)
const 703 if (start+nbits<WORDSIZE)
704 r.data[0]= (data[0]<<start) & ~bitrange(nbits);
706 for (
unsigned i=0; i<nbits; i++)
707 r[i]=(*
this)[start+i];
712 vector<T> num(
const vector<T>& x,
unsigned start,
unsigned nbits)
713 {
return vector<T>(x.begin()+start,x.begin()+start+nbits);}
715 inline bool equal(
const bitvect& x,
const bitvect& y,
unsigned len,
unsigned offs)
717 return x.equal(y,len,offs);
720 inline bool bitvect::equal(
const bitvect& y,
unsigned len,
unsigned offs)
const 723 if (offs+len>WORDSIZE)
726 for (i=0; r && i<div(len); i++)
727 r&= data[i]==(y.data[div(offs)+i]<<mod(offs)|
728 y.data[div(offs)+i+1]>>(WORDSIZE-mod(offs)));
729 unsigned lastword= (div(offs)+i+1<y.nwords())?
730 y.data[div(offs)+i+1]>>(WORDSIZE-mod(offs)): 0;
731 r&= !(~bitrange(mod(len)) &
732 (data[i] ^ (y.data[div(offs)+i]<<mod(offs)| lastword)));
735 r&= !(~bitrange(len) & (data[0] ^ (y.data[0]<<offs)));
740 bool equal(
const T& x,
const T& y,
unsigned len,
unsigned offs)
744 for (
unsigned i=0; r&&i<len; i++)
750 void setvec(vector<T>& x,
const bitvect& y)
753 for (
unsigned i=0; i<y.size(); i++)
776 #include "netcomplexity.cd" descriptor access to a class's privates
virtual const_iterator begin() const =0
iterator to first edge
Definition: netcomplexity.h:190
An iterator suitable for "duck-typing" with Graph.
Definition: netcomplexity.h:362
unsigned nodes() const
number of nodes this graph has
Definition: netcomplexity.h:523
BiDirectionalBitRep(unsigned nodes=0, unsigned links=0)
Definition: netcomplexity.h:564
iterator over edges
Definition: graph.h:111
NautyRep canonicalise() const
bool next_perm()
next permutation of links - returns false if no further permutations
Definition: netcomplexity.h:467
void ecolab_nauty(const NautyRep &g, NautyRep &canonical, double &lnomega, bool do_canonical, int invMethod=0)
EcoLab interface to Nauty.
virtual unsigned nodes() const =0
number of nodes
bool operator==(const NautyRep &x) const
next permutation of links - returns false if no further permutations
Definition: netcomplexity.h:527
buffer object providing MPI functionality
Definition: classdescMP.h:75
Reference counted smart pointer classes.
double MA(const DiGraph &x)
Medium articulation.
A graph in which each link is bidirectional.
Definition: graph.h:375
unsigned nodes() const
number of nodes this graph has
Definition: netcomplexity.h:589
void asgRepGraph(T &x, const Graph &y)
convert between an EcoLab Graph type and a BitRep type
Definition: netcomplexity.h:353
bool directed() const
true if a bidirectional graph (all edges go both ways)
Definition: graph.h:269
Definition: netcomplexity.h:548
BitRep(unsigned nodes=0, unsigned links=0)
Definition: netcomplexity.h:422
Definition: netcomplexity.h:220
Definition: TCL_obj_stl.h:185
bool next_perm()
next permutation of links - returns false if no further permutations
Definition: netcomplexity.h:593
#define CLASSDESC_ACCESS(type)
add friend statements for each accessor function
Definition: classdesc_access.h:36
unsigned nodes() const
number of nodes this graph has
Definition: netcomplexity.h:463
double lnomega() const
log of the number of bitstrings equivalent to this graph
double canonical(BitRep &canon, const Graph &g)
SuperNOVA automorphism algorithm:
Definition: netcomplexity.h:484
unsigned links() const
number of links this graph has
Definition: netcomplexity.h:465
unsigned links() const
number of links this graph has
Definition: netcomplexity.h:525
serialisation for standard containers
MPI parallel processing library.
Definition: netcomplexity.h:205
_OPENMP
Definition: accessor.h:16
virtual const_iterator end() const =0
iterator beyond last edge
double ODcomplexity(const DiGraph &x)
Offdiagonal complexity.
Definition: netcomplexity.h:406
unsigned links() const
number of links this graph has
Definition: netcomplexity.h:591