
    ph                      l    S r SSKrSSKJrJrJrJrJrJ	r	J
r
  SSKJr  SSKJr   " S S5      rS	 rS
 rg)z
Represents the network of interest. This is the primary object of PyPhi and the
context of all |small_phi| and |big_phi| computation.
    N   )cacheconnectivityconvertjsonifyutilsvalidateconfig)
NodeLabels)is_state_by_statec                   "   \ rS rSrSrSS jr\S 5       r\S 5       r	\S 5       r
S r\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       r\S 5       r\R&                  " S5      S 5       rS rS rS rS rS rS rS r\S 5       rSrg)Network   a  A network of nodes.

Represents the network under analysis and holds auxilary data about it.

Args:
    tpm (np.ndarray): The transition probability matrix of the network.

        The TPM can be provided in any of three forms: **state-by-state**,
        **state-by-node**, or **multidimensional state-by-node** form.
        In the state-by-node forms, row indices must follow the
        little-endian convention (see :ref:`little-endian-convention`). In
        state-by-state form, column indices must also follow the
        little-endian convention.

        If the TPM is given in state-by-node form, it can be either
        2-dimensional, so that ``tpm[i]`` gives the probabilities of each
        node being ON if the previous state is encoded by |i| according to
        the little-endian convention, or in multidimensional form, so that
        ``tpm[(0, 0, 1)]`` gives the probabilities of each node being ON if
        the previous state is |N_0 = 0, N_1 = 0, N_2 = 1|.

        The shape of the 2-dimensional form of a state-by-node TPM must be
        ``(s, n)``, and the shape of the multidimensional form of the TPM
        must be ``[2] * n + [n]``, where ``s`` is the number of states and
        ``n`` is the number of nodes in the network.

Keyword Args:
    cm (np.ndarray): A square binary adjacency matrix indicating the
        connections between nodes in the network. ``cm[i][j] == 1`` means
        that node |i| is connected to node |j| (see :ref:`cm-conventions`).
        **If no connectivity matrix is given, PyPhi assumes that every node
        is connected to every node (including itself)**.
    node_labels (tuple[str] or |NodeLabels|): Human-readable labels for
        each node in the network.

Example:
    In a 3-node network, ``the_network.tpm[(0, 0, 1)]`` gives the
    transition probabilities for each node at |t| given that state at |t-1|
    was |N_0 = 0, N_1 = 0, N_2 = 1|.
Nc                 h   U R                  U5      u  U l        U l        U R                  U5      u  U l        U l        [        [        U R                  5      5      U l	        [        X0R                  5      U l        U=(       d    [        R                  " 5       U l        [        R                   " U 5        g N)
_build_tpm_tpm	_tpm_hash	_build_cm_cm_cm_hashtuplerangesize_node_indicesr   _node_labelsr   PurviewCachepurview_cacher	   network)selftpmcmnode_labelsr   s        G/home/james-whalen/.local/lib/python3.13/site-packages/pyphi/network.py__init__Network.__init__<   s}    $(OOC$8!	4>"&.."4$-"5#34&{4F4FG*Be.@.@.B    c                     U R                   $ )zSnp.ndarray: The network's transition probability matrix, in
multidimensional form.
)r   r    s    r$   r!   Network.tpmE   s    
 yyr'   c                 J   [         R                  " U 5      n [        R                  " U [        R
                  S9  [        U 5      (       a  [        R                  " U 5      n O[        R                  " U 5      n [        R                  " U 5        U [        R                  " U 5      4$ )zJValidate the TPM passed by the user and convert to multidimensional
form.
)check_independence)nparrayr	   r!   r
   !VALIDATE_CONDITIONAL_INDEPENDENCEr   r   state_by_state2state_by_nodeto_multidimensionalr   np_immutablenp_hash)r!   s    r$   r   Network._build_tpmL   st    
 hhsmSV-U-UV S!!66s;C--c2C3U]]3'((r'   c                     U R                   $ )znp.ndarray: The network's connectivity matrix.

A square binary adjacency matrix indicating the connections between
nodes in the network.
r   r)   s    r$   r"   
Network.cm_   s     xxr'   c                     Uc-  [         R                  " U R                  U R                  45      nO[         R                  " U5      n[        R
                  " U5        U[        R                  " U5      4$ )z^Convert the passed CM to the proper format, or construct the
unitary CM if none was provided.
)r-   onesr   r.   r   r2   r3   )r    r"   s     r$   r   Network._build_cmh   sS     :$))TYY/0B"B2EMM"%&&r'   c                     U R                   $ )znp.ndarray: Alias for ``cm``.r6   r)   s    r$   connectivity_matrixNetwork.connectivity_matrixv   s     xxr'   c                 B    [         R                  " U R                  5      $ )z:See :func:`pyphi.connectivity.causally_significant_nodes`.)r   causally_significant_nodesr"   r)   s    r$   r?   "Network.causally_significant_nodes{   s     66tww??r'   c                     [        U 5      $ )(int: The number of nodes in the network.)lenr)   s    r$   r   Network.size   s     4yr'   c                      SU R                   -  $ )z2int: The number of possible states of the network.   )r   r)   s    r$   
num_statesNetwork.num_states   s     DII~r'   c                     U R                   $ )zhtuple[int]: The indices of nodes in the network.

This is equivalent to ``tuple(range(network.size))``.
)r   r)   s    r$   node_indicesNetwork.node_indices   s     !!!r'   c                     U R                   $ )z/tuple[str]: The labels of nodes in the network.)r   r)   s    r$   r#   Network.node_labels   s        r'   r   c                 p    [         R                  " U R                  5      n[        U R                  XU5      $ )a6  All purviews which are not clearly reducible for mechanism.

Args:
    direction (Direction): |CAUSE| or |EFFECT|.
    mechanism (tuple[int]): The mechanism which all purviews are
        checked for reducibility over.

Returns:
    list[tuple[int]]: All purviews which are irreducible over
    ``mechanism``.
)r   powersetr   irreducible_purviewsr"   )r    	direction	mechanismall_purviewss       r$   potential_purviewsNetwork.potential_purviews   s0     ~~d&8&89#DGGY$02 	2r'   c                 4    U R                   R                  S   $ )rB   )r!   shaper)   s    r$   __len__Network.__len__   s    xx~~b!!r'   c                 N    SR                  U R                  U R                  5      $ )NzNetwork({}, cm={}))formatr!   r"   r)   s    r$   __repr__Network.__repr__   s    #**488TWW==r'   c                 "    U R                  5       $ r   )r]   r)   s    r$   __str__Network.__str__   s    }}r'   c                     [        U[        5      =(       a]    [        R                  " U R                  UR                  5      =(       a+    [        R                  " U R
                  UR
                  5      $ )zkReturn whether this network equals the other object.

Networks are equal if they have the same TPM and CM.
)
isinstancer   r-   array_equalr!   r"   r    others     r$   __eq__Network.__eq__   sI     ug& .NN488UYY/.NN477EHH-	
r'   c                 .    U R                  U5      (       + $ r   )rg   re   s     r$   __ne__Network.__ne__   s    ;;u%%%r'   c                 D    [        U R                  U R                  45      $ r   )hashr   r   r)   s    r$   __hash__Network.__hash__   s    T^^T]]344r'   c                 `    U R                   U R                  U R                  U R                  S.$ )z*Return a JSON-serializable representation.r!   r"   r   r#   rq   r)   s    r$   to_jsonNetwork.to_json   s,     88''II++	
 	
r'   c                     US	 [        S0 UD6$ )z@Return a |Network| object from a JSON dictionary representation.r    )r   )cls	json_dicts     r$   	from_jsonNetwork.from_json   s     f###r'   )r   r   r   r   r   r   r   )NNN)__name__
__module____qualname____firstlineno____doc__r%   propertyr!   staticmethodr   r"   r   r<   r?   r   rG   rJ   r#   r   methodrT   rY   r]   r`   rg   rj   rn   rr   classmethodrx   __static_attributes__ru   r'   r$   r   r      s   'T   ) )$  '   @ @  
   " " ! ! \\/"2 #2 ">	
&5
 $ $r'   r   c                 d   ^ ^^ U UU4S jnU Vs/ s H  oT" U5      (       a  M  UPM     sn$ s  snf )a  Return all purviews which are irreducible for the mechanism.

Args:
    cm (np.ndarray): An |N x N| connectivity matrix.
    direction (Direction): |CAUSE| or |EFFECT|.
    purviews (list[tuple[int]]): The purviews to check.
    mechanism (tuple[int]): The mechanism in question.

Returns:
    list[tuple[int]]: All purviews in ``purviews`` which are not reducible
    over ``mechanism``.

Raises:
    ValueError: If ``direction`` is invalid.
c                 Z   > TR                  TU 5      u  p[        R                  " TX5      $ )z2Return ``True`` if purview is trivially reducible.)orderr   block_reducible)purview_fromtor"   rQ   rR   s      r$   	reducible'irreducible_purviews.<locals>.reducible   s(    OOIw7	++B::r'   ru   )r"   rQ   rR   purviewsr   r   s   ```   r$   rP   rP      s)     ;
 $,F89W3EG8FFFs   --c                 z    [        U 5       n[        R                  " U5      sSSS5        $ ! , (       d  f       g= f)zConvert a JSON network to a PyPhi network.

Args:
    filename (str): A path to a JSON file representing a network.

Returns:
   Network: The corresponding PyPhi network object.
N)openr   load)filenamefs     r$   rx   rx      s"     
h1||A 
s   ,
:)r~   numpyr-    r   r   r   r   r   r	   r
   labelsr   r!   r   r   rP   rx   ru   r'   r$   <module>r      s6   

  L L L  "B$ B$JG0
r'   