
    phu                         S r SSKrSSKrSSKrSSKJrJrJrJ	r	J
r
  SSKJr  SSKJrJr  SSKJrJrJrJrJrJr  SSKJr  SS	KJr  SS
KJr  SSKJrJr  SSK	Jr  \R@                  " \!5      r" " S S5      r#g)zGRepresents a candidate system for |small_phi| and |big_phi| evaluation.    N   )	Directioncachedistributionutilsvalidate)repertoire_distance)max_entropy_distributionrepertoire_shape)ConceptMaximallyIrreducibleCauseMaximallyIrreducibleEffectNullCut RepertoireIrreducibilityAnalysis	_null_ria)irreducible_purviews)generate_nodes)mip_partitions)condition_tpmmarginalize_out)time_annotatedc                   R   \ rS rSrSr   S@S jr\S 5       r\R                  S 5       r\S 5       r	\S 5       r
\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS r \!RD                  " S\#RH                  5      S  5       r%\!RD                  " S!\#RH                  5      S" 5       r&\!RD                  " S\#RN                  5      S# 5       r(\!RD                  " S!\#RN                  5      S$ 5       r)S% r*S& r+S' r,S( r-S) r.SAS* jr/SAS+ jr0SAS, jr1S- r2S. r3S/ r4 SAS0 jr5S1 r6S2 r7S3 r8S4 r9S5 r:S6 r;SBS7 jr<\!RD                  " S85      SBS9 j5       r=SBS: jr>SBS; jr?S< r@\S= 5       rA\B  SCS> j5       rCS?rDg)D	Subsystem   a  A set of nodes in a network.

Args:
    network (Network): The network the subsystem belongs to.
    state (tuple[int]): The state of the network.

Keyword Args:
    nodes (tuple[int] or tuple[str]): The nodes of the network which are in
        this subsystem. Nodes can be specified either as indices or as
        labels if the |Network| was passed ``node_labels``. If this is
        ``None`` then the full network will be used.
    cut (Cut): The unidirectional |Cut| to apply to this subsystem.

Attributes:
    network (Network): The network the subsystem belongs to.
    tpm (np.ndarray): The TPM conditioned on the state of the external
        nodes.
    cm (np.ndarray): The connectivity matrix after applying the cut.
    state (tuple[int]): The state of the network.
    node_indices (tuple[int]): The indices of the nodes in the subsystem.
    cut (Cut): The cut that has been applied to this subsystem.
    null_cut (Cut): The cut object representing no cut.
Nc	                 .   [         R                  " U5        Xl        UR                  U l        U R                  R	                  U5      U l        [         R                  " X R                  R                  5        [        U5      U l	        Uc:  [        [        UR
                  5      [        U R
                  5      -
  5      U l        OXl        [        U R                  R                  U R                  U R                  5      U l        Ub  UO[        U R
                  U R                  5      U l        U R                  R!                  UR"                  5      U l        [$        R&                  " X5      U l        U=(       d    [$        R*                  " 5       U l        U=(       d    [$        R*                  " 5       U l        [1        U R                  U R"                  U R                  U R
                  U R                  5      U l        [         R4                  " U 5        g N)r   
is_networknetworknode_labelscoerce_to_indicesnode_indicesstate_lengthsizetuplestatesetexternal_indicesr   tpmr   cut	apply_cutcmr   	MICECache_mice_cache	DictCache_single_node_repertoire_cache_repertoire_cacher   nodes	subsystem)	selfr   r%   r1   r)   
mice_cacherepertoire_cachesingle_node_repertoire_cache_external_indicess	            I/home/james-whalen/.local/lib/python3.13/site-packages/pyphi/subsystem.py__init__Subsystem.__init__4   s    	G$".. !,,>>uEe\\%6%67 5\
 $$)G(()C0A0A,BB%DD! %6! !LLd33TZZA ?C !2!2D4D4DE 	 (($$WZZ0 !??4< )=EOO,= 	*!1!FU__5F#HHdggtzz4+<+<d>N>NP
 	4     c                     U R                   $ )z+tuple[Node]: The nodes in this |Subsystem|.)_nodesr3   s    r8   r1   Subsystem.nodesg   s     {{r;   c                 r    Xl         U R                    Vs0 s H  o"R                  U_M     snU l        gs  snf )zORemap indices to nodes whenever nodes are changed, e.g. in the
`macro` module.
N)r=   index_index2node)r3   valuenodes      r8   r1   r?   l   s.     9=EJJ,EEs   4c                 X    [         R                  " U R                  U R                  5      $ )ztuple[int]: The state of the subsystem.

``proper_state[i]`` gives the state of the |ith| node **in the
subsystem**. Note that this is **not** the state of ``nodes[i]``.
)r   state_ofr!   r%   r>   s    r8   proper_stateSubsystem.proper_stateu   s     ~~d//<<r;   c                     U R                   $ )z%np.ndarray: Alias for |Subsystem.cm|.)r+   r>   s    r8   connectivity_matrixSubsystem.connectivity_matrix~   s     wwr;   c                 ,    [        U R                  5      $ )z*int: The number of nodes in the subsystem.lenr!   r>   s    r8   r#   Subsystem.size   s     4$$%%r;   c                 8    U R                   R                  (       + $ )z9bool: ``True`` if this Subsystem has a cut applied to it.)r)   is_nullr>   s    r8   is_cutSubsystem.is_cut   s     88####r;   c                     U R                   $ )ztuple[int]: The nodes of this subsystem to cut for |big_phi|
computations.

This was added to support ``MacroSubsystem``, which cuts indices other
than ``node_indices``.

Yields:
    tuple[int]
)r!   r>   s    r8   cut_indicesSubsystem.cut_indices   s        r;   c                 6    U R                   R                  5       $ )z=list[tuple[int]]: The mechanisms that are cut in this system.)r)   all_cut_mechanismsr>   s    r8   cut_mechanismsSubsystem.cut_mechanisms   s     xx**,,r;   c                     U R                   $ )zF``NodeLabels``: Labels for the nodes of this system that will be
cut.
)r   r>   s    r8   cut_node_labelsSubsystem.cut_node_labels   s    
 r;   c                 4    U R                   R                  S   $ )z$int: The number of nodes in the TPM.)r(   shaper>   s    r8   tpm_sizeSubsystem.tpm_size   s     xx~~b!!r;   c                     U R                   R                  5       U R                  R                  5       U R                  R                  5       S.$ )z#Report repertoire cache statistics.)single_node_repertoire
repertoiremice)r/   infor0   r-   r>   s    r8   
cache_infoSubsystem.cache_info   sD     2277900557$$))+	
 	
r;   c                     U R                   R                  5         U R                  R                  5         U R                  R                  5         g)z%Clear the mice and repertoire caches.N)r/   clearr0   r-   r>   s    r8   clear_cachesSubsystem.clear_caches   s8    **002$$& r;   c                 `    SSR                  [        [        U R                  5      5      -   S-   $ )Nz
Subsystem(z, ))joinmapreprr1   r>   s    r8   __repr__Subsystem.__repr__   s&    diiD$**(=>>DDr;   c                     [        U 5      $ r   )rr   r>   s    r8   __str__Subsystem.__str__   s    Dzr;   c                 ,    [        U R                  5      $ )zDReturn ``False`` if the Subsystem has no nodes, ``True``
otherwise.
)boolr1   r>   s    r8   __bool__Subsystem.__bool__   s     DJJr;   c                 D   [        U[        5      (       d  g[        U R                  5      [        UR                  5      :H  =(       aY    U R                  UR                  :H  =(       a9    U R
                  UR
                  :H  =(       a    U R                  UR                  :H  $ )zReturn whether this Subsystem is equal to the other object.

Two Subsystems are equal if their sets of nodes, networks, and cuts are
equal.
F)
isinstancer   r&   r!   r%   r   r)   r3   others     r8   __eq__Subsystem.__eq__   sz     %++ !!"c%*<*<&== "JJ%++%"LLEMM)" HH		!		
r;   c                 .    U R                  U5      (       + $ r   )r   r~   s     r8   __ne__Subsystem.__ne__   s    ;;u%%%r;   c                 X    [        U R                  5      [        UR                  5      :  $ )z=Return whether this subsystem has fewer nodes than the other.rN   r1   r~   s     r8   __lt__Subsystem.__lt__       4::U[[!111r;   c                 X    [        U R                  5      [        UR                  5      :  $ )z<Return whether this subsystem has more nodes than the other.r   r~   s     r8   __gt__Subsystem.__gt__   r   r;   c                 X    [        U R                  5      [        UR                  5      :*  $ r   r   r~   s     r8   __le__Subsystem.__le__       4::#ekk"222r;   c                 X    [        U R                  5      [        UR                  5      :  $ r   r   r~   s     r8   __ge__Subsystem.__ge__   r   r;   c                 ,    [        U R                  5      $ )z-Return the number of nodes in this Subsystem.rM   r>   s    r8   __len__Subsystem.__len__   s    4$$%%r;   c                 p    [        U R                  U R                  U R                  U R                  45      $ r   )hashr   r!   r%   r)   r>   s    r8   __hash__Subsystem.__hash__   s(    T\\4#4#4djj$((KLLr;   c                 `    U R                   U R                  U R                  U R                  S.$ )z*Return a JSON-serializable representation.)r   r%   r1   r)   )r   r%   r!   r)   r>   s    r8   to_jsonSubsystem.to_json   s,     ||ZZ&&88	
 	
r;   c                 j    [        U R                  U R                  U R                  XR                  S9$ )zReturn a cut version of this |Subsystem|.

Args:
    cut (Cut): The cut to apply to this |Subsystem|.

Returns:
    Subsystem: The cut subsystem.
)r)   r4   )r   r   r%   r!   r-   )r3   r)   s     r8   r*   Subsystem.apply_cut   s.     tzz43D3D -=-=? 	?r;   c                    ^  [        U5      [        T R                  5      -
  (       a  [        S5      e[        U 4S jU 5       5      $ )zReturn |Nodes| for these indices.

Args:
    indices (tuple[int]): The indices in question.

Returns:
    tuple[Node]: The |Node| objects corresponding to these indices.

Raises:
    ValueError: If requested indices are not in the subsystem.
z6`indices` must be a subset of the Subsystem's indices.c              3   B   >#    U  H  nTR                   U   v   M     g 7fr   )rB   ).0nr3   s     r8   	<genexpr>*Subsystem.indices2nodes.<locals>.<genexpr>  s     :'QT%%a('s   )r&   r!   
ValueErrorr$   )r3   indicess   ` r8   indices2nodesSubsystem.indices2nodes  s?     w<#d//00HJ J:':::r;   r/   c                     U R                   U   nUR                  SUR                  4   n[        UR                  U-
  U5      $ )N.)rB   r(   r%   r   inputs)r3   mechanism_node_indexpurviewmechanism_noder(   s        r8   _single_node_cause_repertoire'Subsystem._single_node_cause_repertoire  sL     ))*>?   n&:&:!:;  5 5 ?#FFr;   r0   c                    U(       d  [         R                  " S/5      $ U(       d  [        X R                  5      $ [	        U5      n[         R
                  " [        X R                  5      5      nU[        R                  " [         R                  U Vs/ s H  nU R                  XB5      PM     sn5      -  n[        R                  " U5      $ s  snf )a  Return the cause repertoire of a mechanism over a purview.

Args:
    mechanism (tuple[int]): The mechanism for which to calculate the
        cause repertoire.
    purview (tuple[int]): The purview over which to calculate the
        cause repertoire.

Returns:
    np.ndarray: The cause repertoire of the mechanism over the purview.

.. note::
    The returned repertoire is a distribution over purview node states,
    not the states of the whole network.
      ?)nparrayr
   ra   	frozensetonesr   	functoolsreducemultiplyr   r   	normalize)r3   	mechanismr   jointms        r8   cause_repertoireSubsystem.cause_repertoire!  s    & 88SE?" +G]]CC G$ (--@A 	!!KK#,.#,a <<QH#,.
 	
 %%e,,.s   Cc                    U R                   U   nUR                  U-  n[        UR                  X@R                  5      nUR                  U-
  n[        Xe5      nUR                  [        UR                  /U R                  5      5      $ r   )
rB   r   r   r(   r%   r   reshaper   rA   ra   )r3   r   purview_node_indexpurview_nodemechanism_inputsr(   nonmechanism_inputss          r8   _single_node_effect_repertoire(Subsystem._single_node_effect_repertoireM  s     ''(:;(//);L,,.>

K+22Y>17{{+\-?-?,@,0MM; < 	<r;   c                 @   U(       d  [         R                  " S/5      $ [        U5      n[         R                  " [	        X R
                  5      5      nU[        R                  " [         R                  U Vs/ s H  nU R                  X5      PM     sn5      -  $ s  snf )a  Return the effect repertoire of a mechanism over a purview.

Args:
    mechanism (tuple[int]): The mechanism for which to calculate the
        effect repertoire.
    purview (tuple[int]): The purview over which to calculate the
        effect repertoire.

Returns:
    np.ndarray: The effect repertoire of the mechanism over the
    purview.

.. note::
    The returned repertoire is a distribution over purview node states,
    not the states of the whole network.
r   )
r   r   r   r   r   ra   r   r   r   r   )r3   r   r   r   ps        r8   effect_repertoireSubsystem.effect_repertoire[  s    ( 88SE?" i(	 (--@A y''KK#*,#*a ==iK#*,
 
 	
,s   7Bc                     U[         R                  :X  a  U R                  X#5      $ U[         R                  :X  a  U R	                  X#5      $ [
        R                  " U5      $ )a  Return the cause or effect repertoire based on a direction.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The mechanism for which to calculate the
        repertoire.
    purview (tuple[int]): The purview over which to calculate the
        repertoire.

Returns:
    np.ndarray: The cause or effect repertoire of the mechanism over
    the purview.

Raises:
    ValueError: If ``direction`` is invalid.
)r   CAUSEr   EFFECTr   r   	direction)r3   r   r   r   s       r8   re   Subsystem.repertoire~  sQ    " 	'((<<)***)))==!!),,r;   c                 (    U R                  USU5      $ )z@Return the unconstrained cause/effect repertoire over a purview. re   )r3   r   r   s      r8   unconstrained_repertoire"Subsystem.unconstrained_repertoire  s    y"g66r;   c                 B    U R                  [        R                  U5      $ )z}Return the unconstrained cause repertoire for a purview.

This is just the cause repertoire in the absence of any mechanism.
)r   r   r   r3   r   s     r8   unconstrained_cause_repertoire(Subsystem.unconstrained_cause_repertoire  s    
 ,,Y__gFFr;   c                 B    U R                  [        R                  U5      $ )zReturn the unconstrained effect repertoire for a purview.

This is just the effect repertoire in the absence of any mechanism.
)r   r   r   r   s     r8   unconstrained_effect_repertoire)Subsystem.unconstrained_effect_repertoire  s    
 ,,Y-=-=wGGr;   c                     U Vs/ s H)  nU R                  XR                  UR                  5      PM+     nn[        R                  " [
        R                  U5      $ s  snf )z>Compute the repertoire of a partitioned mechanism and purview.)re   r   r   r   r   r   r   )r3   r   	partitionpartrepertoiress        r8   partitioned_repertoire Subsystem.partitioned_repertoire  sU     "
! OOI~~t||D! 	 
 [99	
s   0Ac                 >   Uc  g[         R                  " U5      nUc  U R                  n[        U5      R	                  U5      (       d  [        S5      e[        [        U5      [        U5      -
  5      nU R                  X5      nX&-  n[         R                  " U5      $ )a)  Distribute an effect repertoire over a larger purview.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    repertoire (np.ndarray): The repertoire to expand.

Keyword Args:
    new_purview (tuple[int]): The new purview to expand the repertoire
        over. If ``None`` (the default), the new purview is the entire
        network.

Returns:
    np.ndarray: A distribution over the new purview, where probability
    is spread out over the new nodes.

Raises:
    ValueError: If the expanded purview doesn't contain the original
        purview.
Nz/Expanded purview must contain original purview.)	r   r   r!   r&   issubsetr   r$   r   r   )r3   r   re   new_purviewr   non_purview_indicesucexpanded_repertoires           r8   expand_repertoireSubsystem.expand_repertoire  s    ( &&z2++K7|$$[11NOO $C$4s7|$CD**9J )o%%&9::r;   c                 D    U R                  [        R                  UU5      $ )zKAlias for |expand_repertoire()| with ``direction`` set to |CAUSE|.
        )r   r   r   r3   re   r   s      r8   expand_cause_repertoire!Subsystem.expand_cause_repertoire  s"     %%iooz&13 	3r;   c                 D    U R                  [        R                  UU5      $ )zLAlias for |expand_repertoire()| with ``direction`` set to |EFFECT|.
        )r   r   r   r   s      r8   expand_effect_repertoire"Subsystem.expand_effect_repertoire  s$     %%i&6&6
&13 	3r;   c                 t    [        [        R                  U R                  X5      U R	                  U5      5      $ )z<Return the cause information for a mechanism over a purview.)r	   r   r   r   r   r3   r   r   s      r8   
cause_infoSubsystem.cause_info  s2    "OO!!)5//8
 	
r;   c                 t    [        [        R                  U R                  X5      U R	                  U5      5      $ )z=Return the effect information for a mechanism over a purview.)r	   r   r   r   r   r   s      r8   effect_infoSubsystem.effect_info  s4    """96009
 	
r;   c                 V    [        U R                  X5      U R                  X5      5      $ )z~Return the cause-effect information for a mechanism over a purview.

This is the minimum of the cause and effect information.
)minr   r   r   s      r8   cause_effect_infoSubsystem.cause_effect_info  s*    
 4??96##I79 	9r;   c                 n    Uc  U R                  XU5      nU R                  UU5      n[        XU5      nXv4$ )a-  Return the |small_phi| of a mechanism over a purview for the given
partition.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The nodes in the mechanism.
    purview (tuple[int]): The nodes in the purview.
    partition (Bipartition): The partition to evaluate.

Keyword Args:
    repertoire (np.array): The unpartitioned repertoire.
        If not supplied, it will be computed.

Returns:
    tuple[int, np.ndarray]: The distance between the unpartitioned and
    partitioned repertoires, and the partitioned repertoire.
)re   r   r	   )r3   r   r   r   r   re   r   phis           r8   evaluate_partitionSubsystem.evaluate_partition  sN    & wGJ!%!<!<Y=F"H "#9; ,,r;   c           	        ^ ^^^^	 T(       d  [        TTT5      $ T R                  TTT5      m	UUUU	U 4S jnT[        R                  :X  a(  [        R
                  " T	S:H  5      (       a
  U" SSS5      $ [        TTT[        S5      S9n[        TTT R                  5       HC  nT R                  TTTUT	S9u  pxUS:X  a  U" SXh5      s  $ XuR                  :  d  M:  U" XvU5      nME     U$ )a}  Return the minimum information partition for a mechanism over a
purview.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The nodes in the mechanism.
    purview (tuple[int]): The nodes in the purview.

Returns:
    RepertoireIrreducibilityAnalysis: The irreducibility analysis for
    the mininum-information partition in one temporal direction.
c                 8   > [        U TTTUTUTR                  S9$ )N)r   r   r   r   r   re   r   r   )r   r   )r   r   r   r   r   r   re   r3   s      r8   _mip Subsystem.find_mip.<locals>._mip1  s0     4###%'= ,,	 	r;   r   Ninf)r   r   g        )r   re   r   r   r   allfloatr   r   r   r   )
r3   r   r   r   r  mipr   r   r   re   s
   ````     @r8   find_mipSubsystem.find_mip  s     Y	7;; __Y	7C
	 	  (zQ''4&&	9g5<H'	7D<L<LMI +/*A*A9gy% +B +''C
 axCCC WW}3+AB N 
r;   c                 B    U R                  [        R                  X5      $ )zqReturn the irreducibility analysis for the cause MIP.

Alias for |find_mip()| with ``direction`` set to |CAUSE|.
)r	  r   r   r   s      r8   	cause_mipSubsystem.cause_mipX  s    
 }}Y__iAAr;   c                 B    U R                  [        R                  X5      $ )zsReturn the irreducibility analysis for the effect MIP.

Alias for |find_mip()| with ``direction`` set to |EFFECT|.
)r	  r   r   r   s      r8   
effect_mipSubsystem.effect_mip_  s    
 }}Y--yBBr;   c                 N    U R                  X5      nU(       a  UR                  $ S$ )zReturn the |small_phi| of the cause MIP.

This is the distance between the unpartitioned cause repertoire and the
MIP cause repertoire.
r   )r  r   r3   r   r   r  s       r8   phi_cause_mipSubsystem.phi_cause_mipf  s#     nnY0sww$1$r;   c                 N    U R                  X5      nU(       a  UR                  $ S$ )zReturn the |small_phi| of the effect MIP.

This is the distance between the unpartitioned effect repertoire and
the MIP cause repertoire.
r   )r  r   r  s       r8   phi_effect_mipSubsystem.phi_effect_mipo  s#     ooi1sww$1$r;   c                 V    [        U R                  X5      U R                  X5      5      $ )z5Return the |small_phi| of a mechanism over a purview.)r   r  r  r   s      r8   r   Subsystem.phix  s*    4%%i9&&y:< 	<r;   c                     USL aX  U R                   R                  X5      nU Vs/ s H0  n[        U5      R                  U R                  5      (       d  M.  UPM2     nn[        U R                  XU5      $ s  snf )a&  Return all purviews that could belong to the |MIC|/|MIE|.

Filters out trivially-reducible purviews.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The mechanism of interest.

Keyword Args:
    purviews (tuple[int]): Optional subset of purviews of interest.
F)r   potential_purviewsr&   r   r!   r   r+   )r3   r   r   purviewsr   s        r8   r  Subsystem.potential_purviews  sp     u||66yLH/7 ExGw<001B1BC  xH E $DGGY8LLEs   -A5A5r-   c                 .  ^ ^^ T R                  TTU5      nU(       d  [        TTS5      nO[        UUU 4S jU 5       5      nT[        R                  :X  a  [        U5      $ T[        R                  :X  a  [        U5      $ [        R                  " T5      $ )a  Return the |MIC| or |MIE| for a mechanism.

Args:
    direction (Direction): :|CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The mechanism to be tested for
        irreducibility.

Keyword Args:
    purviews (tuple[int]): Optionally restrict the possible purviews
        to a subset of the subsystem. This may be useful for _e.g._
        finding only concepts that are "about" a certain subset of
        nodes.

Returns:
    MaximallyIrreducibleCauseOrEffect: The |MIC| or |MIE|.
r   c              3   J   >#    U  H  nTR                  TTU5      v   M     g 7fr   )r	  )r   r   r   r   r3   s     r8   r   &Subsystem.find_mice.<locals>.<genexpr>  s(      3)1g --	9gFF)1s    #)
r  r   maxr   r   r   r   r   r   r   )r3   r   r   r  max_mips   ```  r8   	find_miceSubsystem.find_mice  s    $ **9iJ	9b9G 3)13 3G 	',W55)***-g66!!),,r;   c                 >    U R                  [        R                  XS9$ )zxReturn the mechanism's maximally-irreducible cause (|MIC|).

Alias for |find_mice()| with ``direction`` set to |CAUSE|.
r  )r#  r   r   r3   r   r  s      r8   micSubsystem.mic  s    
 ~~iooy~LLr;   c                 >    U R                  [        R                  XS9$ )zzReturn the mechanism's maximally-irreducible effect (|MIE|).

Alias for |find_mice()| with ``direction`` set to |EFFECT|.
r&  )r#  r   r   r'  s      r8   mieSubsystem.mie  s    
 ~~i..	~MMr;   c                 ~    [        U R                  U5      R                  U R                  U5      R                  5      $ )zqReturn the |small_phi_max| of a mechanism.

This is the maximum of |small_phi| taken over all possible purviews.
)r   r(  r   r+  )r3   r   s     r8   phi_maxSubsystem.phi_max  s/    
 488I&**DHHY,?,C,CDDr;   c                     U R                  SS5      nU R                  SS5      n[        [        [        R
                  SSU5      5      n[        [        [        R                  SSU5      5      n[        SUUU S9$ )zReturn the null concept of this subsystem.

The null concept is a point in concept space identified with
the unconstrained cause and effect repertoire of this subsystem.
r   r   causeeffectr2   )	r   r   r   r   r   r   r   r   r   )r3   r   r   r2  r3  s        r8   null_conceptSubsystem.null_concept  s      00R8 222r: *ioor2/?@B ,i&&B0ABD "$!%' 	'r;   c                     [         R                  SU5        U(       d!  [         R                  S5        U R                  $ U R                  X=(       d    US9nU R	                  X=(       d    US9n[         R                  SU5        [        XUU S9$ )a  Return the concept specified by a mechanism within this subsytem.

Args:
    mechanism (tuple[int]): The candidate set of nodes.

Keyword Args:
    purviews (tuple[tuple[int]]): Restrict the possible purviews to
        those in this list.
    cause_purviews (tuple[tuple[int]]): Restrict the possible cause
        purviews to those in this list. Takes precedence over
        ``purviews``.
    effect_purviews (tuple[tuple[int]]): Restrict the possible effect
        purviews to those in this list. Takes precedence over
        ``purviews``.

Returns:
    Concept: The pair of maximally irreducible cause/effect repertoires
    that constitute the concept specified by the given mechanism.
zComputing concept %s...z%Empty concept; returning null conceptr&  zFound concept %sr1  )logdebugr4  r(  r+  r   )r3   r   r  cause_purviewseffect_purviewsr2  r3  s          r8   conceptSubsystem.concept  s    , 			+Y7 II=>$$$ .HJ )/J(L		$i0
 !%' 	'r;   )rB   r-   r=   r0   r/   r+   r)   r'   r   r!   r   r1   r%   r(   )NNNNNNr   )F)FFF)E__name__
__module____qualname____firstlineno____doc__r9   propertyr1   setterrG   rJ   r#   rR   rU   rY   r\   ra   rh   rl   rs   rv   rz   r   r   r   r   r   r   r   r   r   r*   r   r   methodr   r   r   r   r   r   r   re   r   r   r   r   r   r   r   r   r   r   r   r	  r  r  r  r  r   r  r#  r(  r+  r.  r4  r   r;  __static_attributes__r   r;   r8   r   r      s   0 IMEI#'1!f   \\F F = =   & & $ $ 
! 
! - -     " "
!E 
 &2233&M

?;$ \\19??CG DG \\%y7(- 8(-V \\193C3CD< E< \\%y'7'78 
 9 
D-07GH:&;P33

9 '+-<9vBC%%<M. \\- - !->MNE ' '0 @E %(' ('r;   r   )$rA  r   loggingnumpyr    r   r   r   r   r   distancer	   r
   r   modelsr   r   r   r   r   r   r   r   rD   r   r   r   r(   r   r   r   	getLoggerr=  r7  r   r   r;   r8   <module>rL     sY   
 N    = = ) DB B *   % / !!v' v'r;   