
    ph?                        S r SSKrSSKJrJr  SSKJrJrJrJ	r	J
r
  SSKJr  / SQr " S	 S
\R                  5      rSS jr " S S\R                  5      r " S S\5      r " S S\5      r/ SQr " S S\R                  5      rg)zMechanism-level objects.    N   )cmpfmt   )	Directionconfigconnectivitydistributionutils)WrongDirectionError)phi	direction	mechanismpurview	partition
repertoirepartitioned_repertoirec                       \ rS rSrSr SS j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g) RepertoireIrreducibilityAnalysis   a  An analysis of the irreducibility (|small_phi|) of a mechanism over a
purview, for a given partition, in one temporal direction.

These can be compared with the built-in Python comparison operators (``<``,
``>``, etc.). First, |small_phi| values are compared. Then, if these are
equal up to |PRECISION|, the size of the mechanism is compared (see the
|PICK_SMALLEST_PURVIEW| option in |config|.)
Nc	                     Xl         X l        X0l        X@l        XPl        S n	U	" U5      U l        U	" U5      U l        Xl        g )Nc                 6    U c  g [         R                  " U 5      $ N)nparray)r   s    P/home/james-whalen/.local/lib/python3.13/site-packages/pyphi/models/mechanism.py_repertoire>RepertoireIrreducibilityAnalysis.__init__.<locals>._repertoire$   s    !88J''    )_phi
_direction
_mechanism_purview
_partitionr   _partitioned_repertoire_node_labels)
selfr   r   r   r   r   r   r   node_labelsr   s
             r   __init__)RepertoireIrreducibilityAnalysis.__init__   sG     	###	(
 'z2'23I'J$ (r   c                     U R                   $ )zafloat: This is the difference between the mechanism's unpartitioned
and partitioned repertoires.
)r    r'   s    r   r   $RepertoireIrreducibilityAnalysis.phi/       
 yyr   c                     U R                   $ zDirection: |CAUSE| or |EFFECT|.)r!   r,   s    r   r   *RepertoireIrreducibilityAnalysis.direction6        r   c                     U R                   $ )z,tuple[int]: The mechanism that was analyzed.)r"   r,   s    r   r   *RepertoireIrreducibilityAnalysis.mechanism;   r2   r   c                     U R                   $ )zCtuple[int]: The purview over which the the mechanism was
analyzed.
)r#   r,   s    r   r   (RepertoireIrreducibilityAnalysis.purview@   s    
 }}r   c                     U R                   $ )zKKPartition: The partition of the mechanism-purview pair that was
analyzed.
)r$   r,   s    r   r   *RepertoireIrreducibilityAnalysis.partitionG   s    
 r   c                     U R                   $ )z=np.ndarray: The repertoire of the mechanism over the purview.)r   r,   s    r   r   +RepertoireIrreducibilityAnalysis.repertoireN   s     r   c                     U R                   $ )znp.ndarray: The partitioned repertoire of the mechanism over the
purview. This is the product of the repertoires of each part of the
partition.
)r%   r,   s    r   r   7RepertoireIrreducibilityAnalysis.partitioned_repertoireS   s     +++r   c                     U R                   $ )z|NodeLabels| for this system.)r&   r,   s    r   r(   ,RepertoireIrreducibilityAnalysis.node_labels[   s        r   r   c                    [         R                  (       a6  U R                  [        U R                  5      [        U R
                  5      * /$ U R                  [        U R                  5      [        U R
                  5      /$ r   )r   PICK_SMALLEST_PURVIEWr   lenr   r   r,   s    r   order_by)RepertoireIrreducibilityAnalysis.order_byb   sT    ''HHc$..1C4E3EFF#dnn-s4<</@AAr   c                 8    / SQn[         R                  " XU5      $ )N)r   r   r   r   r   )r   
general_eq)r'   otherattrss      r   __eq__'RepertoireIrreducibilityAnalysis.__eq__h   s    ~~d511r   c                 N    [         R                  " U R                  S5      (       + $ )zLA |RepertoireIrreducibilityAnalysis| is ``True`` if it has
|small_phi > 0|.
r   r   eqr   r,   s    r   __bool__)RepertoireIrreducibilityAnalysis.__bool__o   s     88DHHa(((r   c           	          [        U R                  U R                  U R                  U R                  [
        R                  " U R                  5      45      $ r   )hashr   r   r   r   r   np_hashr   r,   s    r   __hash__)RepertoireIrreducibilityAnalysis.__hash__u   s?    TXX^^^^\\]]4??3	5 6 	6r   c                 8    [         R                  " U [        5      $ r   )r   	make_repr_ria_attributesr,   s    r   __repr__)RepertoireIrreducibilityAnalysis.__repr__|   s    }}T?33r   c                 \    S[         R                  " [         R                  " U 5      5      -   $ )Nz#Repertoire irreducibility analysis
)r   indentfmt_riar,   s    r   __str__(RepertoireIrreducibilityAnalysis.__str__   s$    6

3;;t,-. 	/r   c                 L    [          Vs0 s H  o[        X5      _M     sn$ s  snf r   )rV   getattrr'   attrs     r   to_json(RepertoireIrreducibilityAnalysis.to_json   s"    6EFodgd))oFFFs   !)r!   r"   r&   r$   r%   r    r#   r   r   )__name__
__module____qualname____firstlineno____doc__r)   propertyr   r   r   r   r   r   r   r(   unorderable_unless_eqrB   rH   rM   rR   rW   r\   rb   __static_attributes__ r   r   r   r      s     "((               , , ! ! )MB2)64/Gr   r   c           
           [        U UUSUSUS9$ )z6The irreducibility analysis for a reducible mechanism.N)r   r   r   r   r   r   r   )r   )r   r   r   r   r   s        r   	_null_riarn      s&     ,# r   c                       \ rS rSrSrS 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\R$                  rS rS rS rS rS rS rSrg)!MaximallyIrreducibleCauseOrEffect   a;  A maximally irreducible cause or effect (MICE).

These can be compared with the built-in Python comparison operators (``<``,
``>``, etc.). First, |small_phi| values are compared. Then, if these are
equal up to |PRECISION|, the size of the mechanism is compared (see the
|PICK_SMALLEST_PURVIEW| option in |config|.)
c                     Xl         g r   _ria)r'   rias     r   r)   *MaximallyIrreducibleCauseOrEffect.__init__   s    	r   c                 .    U R                   R                  $ )zYfloat: The difference between the mechanism's unpartitioned and
partitioned repertoires.
)rt   r   r,   s    r   r   %MaximallyIrreducibleCauseOrEffect.phi   s    
 yy}}r   c                 .    U R                   R                  $ r0   rt   r   r,   s    r   r   +MaximallyIrreducibleCauseOrEffect.direction        yy"""r   c                 .    U R                   R                  $ )z9list[int]: The mechanism for which the MICE is evaluated.)rt   r   r,   s    r   r   +MaximallyIrreducibleCauseOrEffect.mechanism   r|   r   c                 .    U R                   R                  $ )zKlist[int]: The purview over which this mechanism's |small_phi| is
maximal.
)rt   r   r,   s    r   r   )MaximallyIrreducibleCauseOrEffect.purview   s    
 yy   r   c                 .    U R                   R                  $ )zYKPartition: The partition that makes the least difference to the
mechanism's repertoire.
)rt   r   r,   s    r   mip%MaximallyIrreducibleCauseOrEffect.mip   s    
 yy"""r   c                 .    U R                   R                  $ )zLnp.ndarray: The unpartitioned repertoire of the mechanism over the
purview.
)rt   r   r,   s    r   r   ,MaximallyIrreducibleCauseOrEffect.repertoire   s    
 yy###r   c                 .    U R                   R                  $ )zJnp.ndarray: The partitioned repertoire of the mechanism over the
purview.
)rt   r   r,   s    r   r   8MaximallyIrreducibleCauseOrEffect.partitioned_repertoire   s    
 yy///r   c                     U R                   $ )zRRepertoireIrreducibilityAnalysis: The irreducibility analysis for
this mechanism.
rs   r,   s    r   ru   %MaximallyIrreducibleCauseOrEffect.ria   r.   r   c                 2    [         R                  " U S/5      $ Nru   )r   rU   r,   s    r   rW   *MaximallyIrreducibleCauseOrEffect.__repr__   s    }}TE7++r   c                     SR                  [        U R                  5      R                  5       5      [        R
                  " [        R                  " U R                  SS95      -   $ )NzMaximally-irreducible {}
T)r   )formatstrr   lowerr   rZ   r[   ru   r,   s    r   r\   )MaximallyIrreducibleCauseOrEffect.__str__   sG    (//DNN0C0I0I0KLJJs{{488678	
r   c                 6    U R                   R                  5       $ r   )ru   rB   r,   s    r   rB   *MaximallyIrreducibleCauseOrEffect.order_by   s    xx  ""r   c                 4    U R                   UR                   :H  $ r   ru   r'   rF   s     r   rH   (MaximallyIrreducibleCauseOrEffect.__eq__   s    xx599$$r   c                 ,    [        U R                  5      $ r   )rP   rt   r,   s    r   rR   *MaximallyIrreducibleCauseOrEffect.__hash__   s    DIIr   c                     SU R                   0$ r   r   r,   s    r   rb   )MaximallyIrreducibleCauseOrEffect.to_json   s    txx  r   c                     U R                   R                  U R                  U R                  5      u  p#[        R
                  " UR                  R                  X#5      $ )u  Identify connections that “matter” to this concept.

For a |MIC|, the important connections are those which connect the
purview to the mechanism; for a |MIE| they are the connections from the
mechanism to the purview.

Returns an |N x N| matrix, where `N` is the number of nodes in this
corresponding subsystem, that identifies connections that “matter” to
this MICE:

``direction == Direction.CAUSE``:
    ``relevant_connections[i,j]`` is ``1`` if node ``i`` is in the
    cause purview and node ``j`` is in the mechanism (and ``0``
    otherwise).

``direction == Direction.EFFECT``:
    ``relevant_connections[i,j]`` is ``1`` if node ``i`` is in the
    mechanism and node ``j`` is in the effect purview (and ``0``
    otherwise).

Args:
    subsystem (Subsystem): The |Subsystem| of this MICE.

Returns:
    np.ndarray: A |N x N| matrix of connections, where |N| is the size
    of the network.

Raises:
    ValueError: If ``direction`` is invalid.
)r   orderr   r   r	   relevant_connectionsnetworksize)r'   	subsystem_fromtos       r   _relevant_connections7MaximallyIrreducibleCauseOrEffect._relevant_connections   sH    > NN((F	001B1B1G1G16< 	<r   c                 
   UR                   R                  U R                  5      =(       dX    [        R                  " U R                  U5      UR                   R                  UR                  R                  5      -  S:H  5      $ )zReturn ``True`` if this MICE is affected by the subsystem's cut.

The cut affects the MICE if it either splits the MICE's mechanism
or splits the connections between the purview and mechanism.
r   )	cutsplits_mechanismr   r   anyr   
cut_matrixr   r   )r'   r   s     r   damaged_by_cut0MaximallyIrreducibleCauseOrEffect.damaged_by_cut  sm     ..t~~> Nt11)< }}//	0A0A0F0FGHKLM N	Or   rs   N)rd   re   rf   rg   rh   r)   ri   r   r   r   r   r   r   r   ru   rW   r\   r   rj   rB   rH   rR   rb   r   r   rk   rl   r   r   rp   rp      s       # # # # ! ! # # $ $ 0 0  ,
 	)>> #%!!<JOr   rp   c                   <   ^  \ rS rSrSrU 4S jr\S 5       rSrU =r	$ )MaximallyIrreducibleCausei   a0  A maximally irreducible cause (MIC).

These can be compared with the built-in Python comparison operators (``<``,
``>``, etc.). First, |small_phi| values are compared. Then, if these are
equal up to |PRECISION|, the size of the mechanism is compared (see the
|PICK_SMALLEST_PURVIEW| option in |config|.)
c                 v   > UR                   [        R                  :w  a  [        S5      e[        TU ]  U5        g )Nz<A MIC must be initialized with a RIA in the cause direction.)r   r   CAUSEr   superr)   r'   ru   	__class__s     r   r)   "MaximallyIrreducibleCause.__init__)  s5    ==IOO+% '@ A Ar   c                 .    U R                   R                  $ )zDirection: |CAUSE|.rz   r,   s    r   r   #MaximallyIrreducibleCause.direction/  r|   r   rl   
rd   re   rf   rg   rh   r)   ri   r   rk   __classcell__r   s   @r   r   r      !     # #r   r   c                   <   ^  \ rS rSrSrU 4S jr\S 5       rSrU =r	$ )MaximallyIrreducibleEffecti5  a1  A maximally irreducible effect (MIE).

These can be compared with the built-in Python comparison operators (``<``,
``>``, etc.). First, |small_phi| values are compared. Then, if these are
equal up to |PRECISION|, the size of the mechanism is compared (see the
|PICK_SMALLEST_PURVIEW| option in |config|.)
c                 v   > UR                   [        R                  :w  a  [        S5      e[        TU ]  U5        g )Nz=A MIE must be initialized with a RIA in the effect direction.)r   r   EFFECTr   r   r)   r   s     r   r)   #MaximallyIrreducibleEffect.__init__>  s7    ==I,,,% 'A B Br   c                 .    U R                   R                  $ )zDirection: |EFFECT|.rz   r,   s    r   r   $MaximallyIrreducibleEffect.directionD  r|   r   rl   r   r   s   @r   r   r   5  r   r   r   )r   r   causeeffectr   c                       \ rS rSrSr  SS jrS rS 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S jrSS jrS rS rS r\S 5       rSrg)ConceptiQ  a  The maximally irreducible cause and effect specified by a mechanism.

These can be compared with the built-in Python comparison operators (``<``,
``>``, etc.). First, |small_phi| values are compared. Then, if these are
equal up to |PRECISION|, the size of the mechanism is compared.

Attributes:
    mechanism (tuple[int]): The mechanism that the concept consists of.
    cause (MaximallyIrreducibleCause): The |MIC| representing the
        maximally-irreducible cause of this concept.
    effect (MaximallyIrreducibleEffect): The |MIE| representing the
        maximally-irreducible effect of this concept.
    subsystem (Subsystem): This concept's parent subsystem.
    time (float): The number of seconds it took to calculate.
Nc                 b    Xl         X l        X0l        XPl        X@l        UR
                  U l        g r   )r   r   r   timer   r(   )r'   r   r   r   r   r   s         r   r)   Concept.__init__b  s)    "
	"$00r   c                 8    [         R                  " U [        5      $ r   )r   rU   _concept_attributesr,   s    r   rW   Concept.__repr__k  s    }}T#677r   c                 .    [         R                  " U 5      $ r   )r   fmt_conceptr,   s    r   r\   Concept.__str__n  s    t$$r   c                 j    [        U R                  R                  U R                  R                  5      $ )zqfloat: The size of the concept.

This is the minimum of the |small_phi| values of the concept's |MIC|
and |MIE|.
)minr   r   r   r,   s    r   r   Concept.phiq  s!     4::>>4;;??33r   c                 0    [        U R                  SS5      $ )ztuple[int]: The cause purview.r   Nr_   r   r,   s    r   cause_purviewConcept.cause_purviewz  s     tzz9d33r   c                 0    [        U R                  SS5      $ )ztuple[int]: The effect purview.r   Nr_   r   r,   s    r   effect_purviewConcept.effect_purview  s     t{{It44r   c                 0    [        U R                  SS5      $ )z!np.ndarray: The cause repertoire.r   Nr   r,   s    r   cause_repertoireConcept.cause_repertoire  s     tzz<66r   c                 0    [        U R                  SS5      $ )z"np.ndarray: The effect repertoire.r   Nr   r,   s    r   effect_repertoireConcept.effect_repertoire  s     t{{L$77r   c                 l    [         R                  " U R                  U R                  R                  5      $ )z(tuple(int): The state of this mechanism.)r   state_ofr   r   stater,   s    r   mechanism_stateConcept.mechanism_state  s#     ~~dnndnn.B.BCCr   r   c                 D    U R                   [        U R                  5      /$ r   )r   rA   r   r,   s    r   rB   Concept.order_by  s    #dnn-..r   c                    U R                   UR                   :H  =(       a    U R                  UR                  :H  =(       a    U R                  UR                  :H  =(       a    U R                  UR                  :H  =(       ae    U R                  UR                  :H  =(       aE    U R                  U5      =(       a-    U R                  R                  UR                  R                  :H  $ r   )r   r   r   r   r   eq_repertoiresr   r   r   s     r   rH   Concept.__eq__  s    EII% B%//1B$$(=(==B ""e&9&99B ##u';';;	B
 ##E*B &&%//*A*AA	Cr   c                 ,   [        U R                  U R                  U R                  U R                  U R
                  [        R                  " U R                  5      [        R                  " U R                  5      U R                  R                  45      $ r   )rP   r   r   r   r   r   r   rQ   r   r   r   r   r,   s    r   rR   Concept.__hash__  sm    TXX^^))''((]]4#8#89]]4#9#9:^^++- . 	.r   c                 N    [         R                  " U R                  S5      (       + $ )z)A concept is ``True`` if |small_phi > 0|.r   rK   r,   s    r   rM   Concept.__bool__  s    88DHHa(((r   c                     [         R                  " U R                  UR                  5      =(       a+    [         R                  " U R                  UR                  5      $ )a  Return whether this concept has the same repertoires as another.

.. warning::
    This only checks if the cause and effect repertoires are equal as
    arrays; mechanisms, purviews, or even the nodes that the mechanism
    and purview indices refer to, might be different.
)r   array_equalr   r   r   s     r   r   Concept.eq_repertoires  sD     NN400%2H2HI LNN41153J3JK	Mr   c                     U R                   UR                   :H  =(       a1    U R                  UR                  :H  =(       a    U R                  U5      $ )zVReturn whether this concept is equal to another in the context of
an EMD calculation.
)r   r   r   r   s     r   emd_eqConcept.emd_eq  sA     EII% +%//1+##E*	,r   c                 b    U R                   R                  U R                  R                  U5      $ z$See |Subsystem.expand_repertoire()|.)r   expand_cause_repertoirer   r   r'   new_purviews     r   r   Concept.expand_cause_repertoire  s(    ~~55JJ!!;0 	0r   c                 b    U R                   R                  U R                  R                  U5      $ r   )r   expand_effect_repertoirer   r   r   s     r   r    Concept.expand_effect_repertoire  s(    ~~66KK""K1 	1r   c                 t    U R                   R                  U R                  R                  R                  5      $ r   )r   r   r   ru   r   r,   s    r   #expand_partitioned_cause_repertoire+Concept.expand_partitioned_cause_repertoire  s*    ~~55JJNN113 	3r   c                 t    U R                   R                  U R                  R                  R                  5      $ r   )r   r   r   ru   r   r,   s    r   $expand_partitioned_effect_repertoire,Concept.expand_partitioned_effect_repertoire  s*    ~~66KKOO224 	4r   c                 V    [         S/-    Vs0 s H  nU[        X5      _M     sn$ s  snf )z*Return a JSON-serializable representation.r   )r   r_   r`   s     r   rb   Concept.to_json  s:     ,vh6
6 '$%%6
 	
 
s   &c                     US	 U " S0 UD6$ )Nr   rl   rl   )clsdcts     r   	from_jsonConcept.from_json  s    JzSzr   )r   r   r   r(   r   r   )NNNNNr   )rd   re   rf   rg   rh   r)   rW   r\   ri   r   r   r   r   r   r   rj   rB   rH   rR   rM   r   r   r   r   r   r  rb   classmethodr  rk   rl   r   r   r   r   Q  s      ;?&*18% 4 4 4 4 5 5 7 7 8 8 D D )M/C.)
M,0
1
3
4

  r   r   )Ng        )rh   numpyr    r   r   r   r   r	   r
   r   
exceptionsr   rV   	Orderabler   rn   rp   r   r   r   r   rl   r   r   <module>r     s   
    C C ,;sGs}} sGl"EO EOP# A #*#!B #. K 
Rcmm Rr   