
    ph                     p    S r SSKrSSKJr  S rS rS rS rS	 rS
 r	S r
S rSS jr\" 0 SS9S 5       rg)z7
Functions for manipulating probability distributions.
    N   )cachec                 :    U R                  5       nUS:X  a  U $ X-  $ )zNormalize a distribution.

Args:
    a (np.ndarray): The array to normalize.

Returns:
    np.ndarray: ``a`` normalized so that the sum of its entries is 1.
r   )sum)asum_as     L/home/james-whalen/.local/lib/python3.13/site-packages/pyphi/distribution.py	normalizer
      s#     EEGEz9    c                 d    SU -  n[         R                  " U5      U-  R                  S/U -  5      $ )a@  
Return the uniform distribution for a set of binary nodes, indexed by state
(so there is one dimension per node, the size of which is the number of
possible states for that node).

Args:
    nodes (np.ndarray): A set of indices of binary nodes.

Returns:
    np.ndarray: The uniform distribution over the set of nodes.
   )nponesreshape)number_of_nodesnumber_of_statess     r	   uniform_distributionr      s<     O+ GG$%%gqcO&;<=r   c                 t    [        S5      /U R                  -  nSX!'   U [        U5         R                  5       $ )z5Return the marginal probability that the node is OFF.Nr   )slicendimtupler   
repertoire
node_indexindexs      r	   marginal_zeror   2   s6    4[MJOO+EEeEl#''))r   c                 t   ^ [        U4S j[        U R                  5       5       5      nU R                  USS9$ )z)Get the marginal distribution for a node.c              3   6   >#    U  H  oT:w  d  M
  Uv   M     g 7f)N ).0ir   s     r	   	<genexpr>marginal.<locals>.<genexpr><   s     G3J!!3s   		T)keepdims)r   ranger   r   r   s    ` r	   marginalr&   :   s/    GU:??3GGE>>%$>//r   c                     [        U R                  5       Vs/ s H  n[        X5      PM     nnUS   nUSS  H  nX4-  nM	     [        R                  " X5      $ s  snf )z,Check whether the repertoire is independent.r   r   N)r%   r   r&   r   array_equal)r   r!   	marginalsjointms        r	   independentr,   A   s_    27
2HI2HQ*(2HII aLEqr]	  >>*,, Js   Ac                 T    U c  g[        S [        U R                  5       5       5      $ )zThe purview of the repertoire.

Args:
    repertoire (np.ndarray): A repertoire

Returns:
    tuple[int]: The purview that the repertoire was computed over.
Nc              3   :   #    U  H  u  pUS :X  d  M  Uv   M     g7f)r   Nr   )r    r!   dims      r	   r"   purview.<locals>.<genexpr>]   s     I!<vqq!<s   	)r   	enumerateshaper   s    r	   purviewr4   Q   s)     I:+;+;!<IIIr   c                 *    [        [        U 5      5      $ )zReturn the size of the purview of the repertoire.

Args:
    repertoire (np.ndarray): A repertoire

Returns:
    int: The size of purview that the repertoire was computed over.
)lenr4   r3   s    r	   purview_sizer7   `   s     wz"##r   c                 R    [        U5       Vs/ s H  o"U ;   a  SOSPM     sn$ s  snf )a  Return the shape a repertoire.

Args:
    purview (tuple[int]): The purview over which the repertoire is
        computed.
    N (int): The number of elements in the system.

Returns:
    list[int]: The shape of the repertoire. Purview nodes have two
    dimensions and non-purview nodes are collapsed to a unitary dimension.

Example:
    >>> purview = (0, 2)
    >>> N = 3
    >>> repertoire_shape(purview, N)
    [2, 1, 2]
r   r   )r%   )r4   Nr!   s      r	   repertoire_shaper:   l   s)    & /4Ah7hgA1$h777s   $c                 Z    U c  gU(       a  SOSnU R                  5       R                  US9$ )aS  Flatten a repertoire, removing empty dimensions.

By default, the flattened repertoire is returned in little-endian order.

Args:
    repertoire (np.ndarray or None): A repertoire.

Keyword Args:
    big_endian (boolean): If ``True``, flatten the repertoire in big-endian
        order.

Returns:
    np.ndarray: The flattened repertoire.
NCF)order)squeezeravel)r   
big_endianr>   s      r	   flattenrB      s5     C3E %%E%22r   )r   maxmemc                 \    [         R                  " [        X5      5      nX"R                  -  $ )a  Return the maximum entropy distribution over a set of nodes.

This is different from the network's uniform distribution because nodes
outside ``node_indices`` are fixed and treated as if they have only 1
state.

Args:
    node_indices (tuple[int]): The set of node indices over which to take
        the distribution.
    number_of_nodes (int): The total number of nodes in the network.

Returns:
    np.ndarray: The maximum entropy distribution over the set of nodes.
)r   r   r:   size)node_indicesr   distributions      r	   max_entropy_distributionrH      s'      77+LJKL++++r   )F)__doc__numpyr   r   r
   r   r   r&   r,   r4   r7   r:   rB   rH   r   r   r	   <module>rK      s[   
   =(*0- J	$8,30 R, ,r   