At several points during the IIT analysis, ties may arise when integrated information values of objects (partitions, purviews, subsystems) are compared. See the following papers:
Krohn S, Ostwald D.Computing integrated information.Neuroscience of Consciousness. 2017; 2017(nix017).Moon K.Exclusion and Underdetermined Qualia.Entropy. 2019; 21(4):405.Hanson JR, Walker SI.On the Non-uniqueness Problem in Integrated Information Theory.bioRxiv. 2021;2021.04.07.438793.
This documentation is solely meant to describe how the software deals with ties. Future work is required to resolve the role of ties in the IIT formalism.
Currently, only one of the tied objects is returned (selected as described below).
An exception is the actual causation computation, which returns all tied actual causes and effects.
In general, when searching for a minimal or maximal value, the first one encountered is selected as the output and used in further analysis (see additional selection criteria below).
This arbitrary selection process was chosen for computational simplicity. It also ensures that the same purviews are selected in the intact and cut subsystem, if the purviews are not affected by the system cut. This is important because causal distinctions unaffected by the system cut should not contribute to \(\Phi\).
As a consequence, the object selected may depend on the speed at which it was
computed when performing parallel computations. This applies to tied system cuts
PARALLEL_CUT_EVALUATION is set to
and to subsystems if
is set to
True and subsystems of the same size are tied for
pyphi.compute.network.major_complex() (note that
pyphi.compute.network.complexes() returns the list of all complexes within
a system). However, ties in partitions and subsystems do not have further
effects on other quantities in the computation.
Mechanism purviews are always evaluated in the same order. In principle, ties in
the \(\varphi\) values across multiple possible purivews propagate to the
Under most choices of settings, including the default IIT 3.0 configuration, the
\(\Phi\) value of a subsystem depends on the particular purviews of its
mechanisms, not just their \(\varphi\) value (except if
USE_SMALL_PHI_DIFFERENCE_FOR_CES_DISTANCE is set
In case of purview ties, the cause-effect structure and \(\Phi\) value for a given subsystem are not necessarily unique.
Our expectation is that the resulting value is representative. The variance of
possible \(\Phi\) values will depend on the specific system under consideration
and the particular config settings for performing the
systems with symmetric inputs and outputs are generally more prone to ties than
probabilistic systems. The EMD measure used in the default IIT 3.0 settings
is also particularly prone to ties in \(\varphi\) across purviews. Moreover,
due to the numerical optimization algorithm of the EMD measure, the
has to be set to a relatively low value (default is 6 decimal places; see
PRECISION). Other difference measures allow for significantly higher
MaximallyIrreducibleEffect objects can be compared using the built-in Python comparison
>, etc.) First, \(\varphi\) values are compared. If
these are equal up to
PRECISION, the size of the purview is compared. If
PICK_SMALLEST_PURVIEW is set to
True, the partition with the smallest
purview is returned; otherwise the largest purview is returned. By default, this
is set to
False (which of these should be used depends on the choice of
PARTITION_TYPE for \(\varphi\) computations; the
default configuration settings correspond to the IIT 3.0 formalism).
SystemIrreducibilityAnalysis objects are compared this way as well. First, \(\Phi\) values are
compared. If these are equal up to
PRECISION, then the largest subsystem is
pyphi.compute.complexes() function computes all complexes
with \(\Phi\) > 0 and can be used to inspect ties in \(\Phi\) across
All remaining ties between objects of the same size are resolved in an arbitrary
but stable manner by chosing the first one encountered. That is, if there is no
unique largest (or smallest, depending on configuration) purview with maximal
\(\varphi\), the returned purview is the first one as ordered by
pyphi.subsystem.Subsystem.potential_purviews() (lexicographical by node index).
Similarly, if there is no unique largest subsystem with maximal \(\Phi\), then
the returned subsystem is the first one as ordered by
pyphi.compute.possible_complexes() (also lexicographical by node
Below we list all instances in which ties may occur.
Comparing mechanism partitions¶
The first instance of ties can arise when finding the partition with the minimum \(\varphi\) value (MIP) for a given purview. After computing each partition’s \(\varphi\) value, it is compared to the previously minimal \(\varphi\). If less, the MIP will be updated. Therefore, the first of all minimal \(\varphi\) found will be selected.
subsystem.py, line 610:
if phi < mip.phi: mip = _mip(phi, partition, partitioned_repertoire)
This is performed for both causes and effects.
After computing the minimum information partition, we take the
all potential purviews. In the case of a tie, Python’s builtin
function returns the first maximal element.
subsystem.py, line 703:
if not purviews: max_mip = _null_ria(direction, mechanism, ()) else: max_mip = max( self.find_mip(direction, mechanism, purview) for purview in purviews )
This is performed for both causes and effects.
Comparing system partitions¶
Next we find the system partition with minimal \(\Phi\).
Assuming we don’t short-circuit (i.e., find a
SystemIrreducibilityAnalysis with \(\Phi\) = 0), each
new SIA is compared with the previous minimum. Again the returned minimum is the
first one, as ordered by
compute/subsystem.py, line 191:
def process_result(self, new_sia, min_sia): """Check if the new SIA has smaller |big_phi| than the standing result. """ if new_sia.phi == 0: self.done = True # Short-circuit return new_sia elif abs(new_sia.phi) < abs(min_sia.phi): return new_sia return min_sia
Comparing candidate systems¶
Finally, a search is performed for the candidate system with maximal \(\Phi\).
We compare the candidate systems with the builtin
max(), returning the first
one, as ordered by
compute/network.py, line 149:
result = complexes(network, state) if result: result = max(result)
This is then the major complex of the network.