Ë
    ~\;jö  ã                   óÄ   — d Z ddlmZ ddlZddlmZ g d¢ZdZ ej                  g d¢«      Z
 eee
«      D � �ci c]  \  } }| |“Œ
 c}} Zdd	„Zd
„ Zd„ Zd„ Zdd„Zyc c}} w )z:
Contains helper functions for opt_einsum testing scripts
é    )ÚOrderedDictNé   )Ú
get_symbol)Úbuild_viewsÚcompute_size_by_dictÚfind_contractionÚ
flop_countÚabcdefghijklmopqABC)é   é   é   é   r   r   r   é   r   r   r   r   r   é   r   r   r   r   r   c                 óò   — |€t         }g }| j                  d«      d   j                  d«      }|D ]?  }|D �cg c]  }||   ‘Œ	 }}|j                  t        j                  j
                  |Ž «       ŒA |S c c}w )a¨  
    Builds random numpy arrays for testing.

    Parameters
    ----------
    string : list of str
        List of tensor strings to build
    dimension_dict : dictionary
        Dictionary of index _sizes

    Returns
    -------
    ret : list of np.ndarry's
        The resulting views.

    Examples
    --------
    >>> view = build_views(['abbc'], {'a': 2, 'b':3, 'c':5})
    >>> view[0].shape
    (2, 3, 3, 5)

    z->r   Ú,)Ú_default_dim_dictÚsplitÚappendÚnpÚrandomÚrand)ÚstringÚdimension_dictÚviewsÚtermsÚtermÚxÚdimss          ú[G:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\opt_einsum/helpers.pyr   r      sz   € ð0 ÐÜ*ˆà€EØ�L‰L˜Ó˜qÑ!×'Ñ'¨Ó,€EÛˆÙ+/Ó0©4 a�˜qÓ!¨4ˆÐ0Ø�‰”R—Y‘Y—^‘^ TÐ*Õ+ð ð €Lùò 1s   ·A4c                 ó(   — d}| D ]
  }|||   z  }Œ |S )a   
    Computes the product of the elements in indices based on the dictionary
    idx_dict.

    Parameters
    ----------
    indices : iterable
        Indices to base the product on.
    idx_dict : dictionary
        Dictionary of index _sizes

    Returns
    -------
    ret : int
        The resulting product.

    Examples
    --------
    >>> compute_size_by_dict('abbc', {'a': 2, 'b':3, 'c':5})
    90

    r   © )ÚindicesÚidx_dictÚretÚis       r    r   r   5   s&   € ð. €CÛˆØˆx˜‰{Ñ‰ð à€Jó    c                 óÊ   ‡— t        |«      Šˆfd„t        | d¬«      D «       }t        j                  |Ž } |j                  ‰Ž }||z  }||z
  }‰j	                  |«       |‰||fS )a  
    Finds the contraction for a given set of input and output sets.

    Parameters
    ----------
    positions : iterable
        Integer positions of terms used in the contraction.
    input_sets : list
        List of sets that represent the lhs side of the einsum subscript
    output_set : set
        Set that represents the rhs side of the overall einsum subscript

    Returns
    -------
    new_result : set
        The indices of the resulting contraction
    remaining : list
        List of sets that have not been contracted, the new set is appended to
        the end of this list
    idx_removed : set
        Indices removed from the entire contraction
    idx_contraction : set
        The indices used in the current contraction

    Examples
    --------

    # A simple dot product test case
    >>> pos = (0, 1)
    >>> isets = [set('ab'), set('bc')]
    >>> oset = set('ac')
    >>> find_contraction(pos, isets, oset)
    ({'a', 'c'}, [{'a', 'c'}], {'b'}, {'a', 'b', 'c'})

    # A more complex case with additional terms in the contraction
    >>> pos = (0, 2)
    >>> isets = [set('abd'), set('ac'), set('bdc')]
    >>> oset = set('ac')
    >>> find_contraction(pos, isets, oset)
    ({'a', 'c'}, [{'a', 'c'}, {'a', 'c'}], {'b', 'd'}, {'a', 'b', 'c', 'd'})
    c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­w©N)Úpop)Ú.0r&   Ú	remainings     €r    Ú	<genexpr>z#find_contraction.<locals>.<genexpr>~   s   øè ø€ ÐHÑ(G 1ˆi�m‰m˜A×Ñ(Gùs   ƒT)Úreverse)ÚlistÚsortedÚsetÚunionr   )	Ú	positionsÚ
input_setsÚ
output_setÚinputsÚidx_contractÚ
idx_remainÚ
new_resultÚidx_removedr-   s	           @r    r   r   R   sr   ø€ ôV �ZÓ €IÛH¬¨yÀ$Õ(GÓH€FÜ—9‘9˜fÐ%€LØ!�×!Ñ! 9Ð-€Jà˜lÑ*€JØ *Ñ,€KØ×Ñ�ZÔ à�y +¨|Ð;Ð;r'   c                 óP   — t        | |«      }t        d|dz
  «      }|r|dz  }||z  S )aš  
    Computes the number of FLOPS in the contraction.

    Parameters
    ----------
    idx_contraction : iterable
        The indices involved in the contraction
    inner : bool
        Does this contraction require an inner product?
    num_terms : int
        The number of terms in a contraction
    size_dictionary : dict
        The size of each of the indices in idx_contraction

    Returns
    -------
    flop_count : int
        The total number of FLOPS required for the contraction.

    Examples
    --------

    >>> flop_count('abc', False, 1, {'a': 2, 'b':3, 'c':5})
    90

    >>> flop_count('abc', True, 2, {'a': 2, 'b':3, 'c':5})
    270

    r   )r   Úmax)Úidx_contractionÚinnerÚ	num_termsÚsize_dictionaryÚoverall_sizeÚ	op_factors         r    r	   r	   ‰   s7   € ô> (¨¸ÓI€LÜ�A�y 1‘}Ó%€IÙØ�Q‰ˆ	à˜)Ñ#Ð#r'   c                 óö  ‡‡‡‡‡— |�t         j                  j                  |«       | |z  dz  ‰z   }t        | «      D �	cg c]  }	d‘Œ }
}	g Št	        ˆˆfd„t        |«      D «       «      Šˆˆˆfd„}t        t         j                  j                  t         |«       «      «      «      D ]t  \  }}|| k  r|
|xx   |z  cc<   Œt         j                  j                  d| «      }||
|   v r(t         j                  j                  d| «      }||
|   v rŒ(|
|xx   |z  cc<   Œv |rSt        |«      }t         j                  j                  ‰‰dz   «      ‰|<   t        | «      D ]  }|
|xx   |z  cc<   Œ ‰|z  Šdj                  t         j                  j                  ‰«      «      Šdj                  dj                  |
«      ‰«      }|
D �cg c]  }t        ˆfd	„|D «       «      ‘Œ }}||f}|r|‰fz  }|S c c}	w c c}w )
a³  Generate a random contraction and shapes.

    Parameters
    ----------
    n : int
        Number of array arguments.
    reg : int
        'Regularity' of the contraction graph. This essentially determines how
        many indices each tensor shares with others on average.
    n_out : int, optional
        Number of output indices (i.e. the number of non-contracted indices).
        Defaults to 0, i.e., a contraction resulting in a scalar.
    d_min : int, optional
        Minimum dimension size.
    d_max : int, optional
        Maximum dimension size.
    seed: int, optional
        If not None, seed numpy's random generator with this.
    global_dim : bool, optional
        Add a global, 'broadcast', dimension to every operand.
    return_size_dict : bool, optional
        Return the mapping of indices to sizes.

    Returns
    -------
    eq : str
        The equation string.
    shapes : list[tuple[int]]
        The array shapes.
    size_dict : dict[str, int]
        The dict of index sizes, only returned if ``return_size_dict=True``.

    Examples
    --------
    >>> eq, shapes = rand_equation(n=10, reg=4, n_out=5, seed=42)
    >>> eq
    'oyeqn,tmaq,skpo,vg,hxui,n,fwxmr,hitplcj,kudlgfv,rywjsb->cebda'

    >>> shapes
    [(9, 5, 4, 5, 4),
     (4, 4, 8, 5),
     (9, 4, 6, 9),
     (6, 6),
     (6, 9, 7, 8),
     (4,),
     (9, 3, 9, 4, 9),
     (6, 8, 4, 6, 8, 6, 3),
     (4, 7, 8, 8, 6, 9, 6),
     (9, 5, 3, 3, 9, 5)]
    r   Ú c              3   óz   •K  — | ]2  }t        |«      t        j                  j                  ‰‰d z   «      f–— Œ4 y­w)r   N)r   r   r   Úrandint)r,   r&   Úd_maxÚd_mins     €€r    r.   z rand_equation.<locals>.<genexpr>ì   s3   øè ø€ ÐjÑZiÐUVœZ¨›]¬B¯I©I×,=Ñ,=¸eÀUÈQÁYÓ,OÔPÑZiùó   ƒ8;c               3   óz   •K  — t        ‰«      D ](  \  } }| ‰k  r‰j                  |«       |–— Œ!|–— |–— Œ* y ­wr*   )Ú	enumerater   )r&   ÚixÚn_outÚoutputÚ	size_dicts     €€€r    Úgenzrand_equation.<locals>.genï   s>   øè ø€ Ü˜yÖ)‰EˆAˆrà�5ŠyØ—‘˜bÔ!Ø“ð ’Ø“ñ *ùrJ   r   r   z{}->{}r   c              3   ó(   •K  — | ]	  }‰|   –— Œ y ­wr*   r"   )r,   rM   rP   s     €r    r.   z rand_equation.<locals>.<genexpr>  s   øè ø€ Ð/©B b�I˜b•M©Bùs   ƒ)r   r   ÚseedÚranger   rL   Úpermutationr0   rG   r   ÚjoinÚformatÚtuple)ÚnÚregrN   rI   rH   rS   Ú
global_dimÚreturn_size_dictÚnum_indsÚ_r7   rQ   r&   rM   ÚwhereÚgdimÚeqÚopÚshapesr%   rO   rP   s     ```               @@r    Úrand_equationrd   °   sÕ  ü€ ðh ÐÜ
�	‰	�‰�tÔð �3‰w˜!‰|˜eÑ#€HÜ œ(Ó#™(�QŠb˜(€FÐ#Ø€FäÔjÔZ_Ð`hÔZiÓjÓj€Iö	ô œ2Ÿ9™9×0Ñ0´±c³e³Ó=Ö>‰ˆˆ2àˆqŠ5Ø�1‹I˜‰OŒIô —I‘I×%Ñ% a¨Ó+ˆEØ˜˜u™Ñ%ÜŸ	™	×)Ñ)¨!¨QÓ/�ð ˜˜u™Ò%ð �5‹M˜RÑŒMð ?ñ Ü˜(Ó#ˆÜŸ)™)×+Ñ+¨E°5¸1±9Ó=ˆ	�$‰Ü�q–ˆAØ�1‹I˜ÑŒIð à�$‰ˆð �W‰W”R—Y‘Y×*Ñ*¨6Ó2Ó3€FØ	�‰˜Ÿ™ &Ó)¨6Ó	2€Bñ ;AÓA¹&°BŒeÓ/©BÓ/Õ/¸&€FÐAàˆvˆ,€CáØ�	ˆ}Ñˆà€Jùòe $ùòV Bs   ¿	G1ÇG6r*   )r   r   é	   NFF)Ú__doc__Úcollectionsr   Únumpyr   Úparserr   Ú__all__Ú_valid_charsÚarrayÚ_sizesÚzipr   r   r   r   r	   rd   )ÚcÚss   00r    Ú<module>rq      sz   ðñõ $ã å â
S€à$€Ø	ˆ�‰ÒKÓ	L€Ù&)¨,¸Ô&?Ô@Ñ&?™d˜a �Q˜‘TÐ&?Ò@Ð ó òFò:4<òn$$ôNkùóC As   ¹A