Download .zip (8kB), or download .tar.bz2 (6kB).

This code is mainly written in Cython.
On Debian, `apt-get install cython3`

should be all you need.
It was originally written in plain Python, and could be converted back
fairly easily if necessary.

Many of the algorithms used scale horribly with the number of nodes in
the GDAG. One useful optimization would be to find a way to enumerate
non-isomorphic GDAGs directly, rather than generating and then removing
isomorphic ones as is currently done in `find_candidates()`

.

## list_interesting.py

To list small irreducibly interesting GDAGs, as shown in Appendix E,
edit the settings in list_interesting.py and then run it.

Each line of output corresponds to a GDAG. The first interesting one is
of size 4:

(['', '', 'AB', 'AC'], 'BCD')

The bit in square brackets describes the underlying DAG:

- The 1st node, A, has no parents
- The 2nd node, B, has no parents
- The 3rd node, C, has parents A and B
- The 4th node, D, has parents A and C

The final part lists the observable nodes B, C, and D, which means that
node A is unobservable.

## count_boring.py

To counts the total number of small GDAGs, and how many we can identify
as having 𝓒 = 𝓘 as shown in Table 1, edit the settings in
count_interesting.py and then run it.

The total number minus the boring number will generally be higher than
the number output by list_interesting.py since no account is taken of
reducibility.

Each line of output corresponds to a size *n*. The first line will be:

(1, 2, 2)

This means: considering GDAGs of size 1,
there are 2 in total (a single node of either type),
and of those 2 are boring (𝓒 = 𝓘).

## Update

Changed xrange() to range() for Python 3 compatibility, and fixed a bug in the detection of disconnected GDAGs (which didn't seem to affect the results).

*Matthew F. Pusey, November 2014 (updated August 2022)*