Residue

This example describes a system containing two AND gates, \(A\) and \(B\), with a single overlapping input node.

First let’s create the subsystem corresponding to the residue network, with all nodes OFF in the current and previous states.

>>> import pyphi
>>> subsystem = pyphi.examples.residue_subsystem()

Next, we can define the mechanisms of interest. Mechanisms and purviews are represented by tuples of node indices in the network:

>>> A = (0,)
>>> B = (1,)
>>> AB = (0, 1)

And the possible cause purviews that we’re interested in:

>>> CD = (2, 3)
>>> DE = (3, 4)
>>> CDE = (2, 3, 4)

We can then evaluate the cause information for each of the mechanisms over the cause purview \(CDE\).

>>> subsystem.cause_info(A, CDE)
0.333332
>>> subsystem.cause_info(B, CDE)
0.333332
>>> subsystem.cause_info(AB, CDE)
0.5

The composite mechanism \(AB\) has greater cause information than either of the individual mechanisms. This contradicts the idea that \(AB\) should exist minimally in this system.

Instead, we can quantify existence as the irreducible cause information of a mechanism. The MIP of a mechanism is the partition of mechanism and purview which makes the least difference to the cause repertoire (see the documentation for the RepertoireIrreducibilityAnalysis object). The irreducible cause information is the distance between the unpartitioned and partitioned repertoires.

To analyze the irreducibility of the mechanism \(AB\) on the cause side:

>>> mip_AB = subsystem.cause_mip(AB, CDE)

We can then determine what the specific partition is.

>>> mip_AB.partition  # doctest: +NORMALIZE_WHITESPACE
 ∅    A,B
─── ✕ ───
 C    D,E

The indices (0, 1, 2, 3, 4) correspond to nodes \(A, B, C, D, E\) respectively. Thus the MIP is \(\frac{AB}{DE} \times \frac{\varnothing}{C}\), where \(\varnothing\) denotes the empty mechanism.

The partitioned repertoire of the MIP can also be retrieved:

>>> mip_AB.partitioned_repertoire
array([[[[[0.2, 0.2],
          [0.1, 0. ]],
<BLANKLINE>
         [[0.2, 0.2],
          [0.1, 0. ]]]]])

And we can then calculate the irreducible cause information as the difference between partitioned and unpartitioned repertoires.

>>> mip_AB.phi
0.1

One counterintuitive result that merits discussion is that since irreducible cause information is what defines existence, we must also evaluate the irreducible cause information of the mechanisms \(A\) and \(B\).

The mechanism \(A\) over the purview \(CDE\) is completely reducible to \(\frac{A}{CD} \times \frac{\varnothing}{E}\) because \(E\) has no effect on \(A\), so it has zero \(\varphi\).

>>> subsystem.cause_mip(A, CDE).phi
0.0
>>> subsystem.cause_mip(A, CDE).partition  # doctest: +NORMALIZE_WHITESPACE
 ∅     A
─── ✕ ───
 E    C,D

Instead, we should evaluate \(A\) over the purview \(CD\).

>>> mip_A = subsystem.cause_mip(A, CD)

In this case, there is a well-defined MIP

>>> mip_A.partition  # doctest: +NORMALIZE_WHITESPACE
 ∅     A
─── ✕ ───
 C     D

which is \(\frac{\varnothing}{C} \times \frac{A}{D}\). It has partitioned repertoire

>>> mip_A.partitioned_repertoire
array([[[[[0.33333333],
          [0.16666667]],
<BLANKLINE>
         [[0.33333333],
          [0.16666667]]]]])

and irreducible cause information

>>> mip_A.phi
0.166667

A similar result holds for \(B\). Thus the mechanisms \(A\) and \(B\) exist at levels of \(\varphi = \frac{1}{6}\), while the higher-order mechanism \(AB\) exists only as the residual of causes, at a level of \(\varphi = \frac{1}{10}\).