U
    ZÊ¹jó#  ã                   @   s‚   d dl mZmZ d dlmZ d dlmZ d dlmZ e	e
dœdd„Ze
dœd	d
„Ze
dœdd„Ze
dœdd„Zdd„ Zdd„ ZdS )é    )ÚchainÚcombinations)Úgcd)Ú	factorint)Úas_int)ÚfactorsÚreturnc                 C   sT   |   ¡ D ]F}|  ¡ D ]8\}}d}t|ƒD ]"}|| | }|dkr(   dS q(qqdS )z¸ Check whether `n` is a nilpotent number.
    Note that ``factors`` is a prime factorization of `n`.

    This is a low-level helper for ``is_nilpotent_number``, for internal use.
    é   FT)ÚkeysÚitemsÚrange)r   ÚpÚqÚeÚmÚ_© r   ú`/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/combinatorics/group_numbers.pyÚ_is_nilpotent_number   s    r   )r   c                 C   s(   t | ƒ} | dkrtd|  ƒ‚tt| ƒƒS )aj  
    Check whether `n` is a nilpotent number. A number `n` is said to be
    nilpotent if and only if every finite group of order `n` is nilpotent.
    For more information see [1]_.

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import is_nilpotent_number
    >>> from sympy import randprime
    >>> is_nilpotent_number(21)
    False
    >>> is_nilpotent_number(randprime(1, 30)**12)
    True

    References
    ==========

    .. [1] Pakianathan, J., Shankar, K., Nilpotent Numbers,
           The American Mathematical Monthly, 107(7), 631-634.
    .. [2] https://oeis.org/A056867

    r   ú$n must be a positive integer, not %i)r   Ú
ValueErrorr   r   )Únr   r   r   Úis_nilpotent_number   s    r   c                 C   sB   t | ƒ} | dkrtd|  ƒ‚t| ƒ}tdd„ | ¡ D ƒƒo@t|ƒS )a†  
    Check whether `n` is an abelian number. A number `n` is said to be abelian
    if and only if every finite group of order `n` is abelian. For more
    information see [1]_.

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import is_abelian_number
    >>> from sympy import randprime
    >>> is_abelian_number(4)
    True
    >>> is_abelian_number(randprime(1, 2000)**2)
    True
    >>> is_abelian_number(60)
    False

    References
    ==========

    .. [1] Pakianathan, J., Shankar, K., Nilpotent Numbers,
           The American Mathematical Monthly, 107(7), 631-634.
    .. [2] https://oeis.org/A051532

    r   r   c                 s   s   | ]}|d k V  qdS )é   Nr   ©Ú.0r   r   r   r   Ú	<genexpr>V   s     z$is_abelian_number.<locals>.<genexpr>©r   r   r   ÚallÚvaluesr   ©r   r   r   r   r   Úis_abelian_number8   s
    r!   c                 C   sB   t | ƒ} | dkrtd|  ƒ‚t| ƒ}tdd„ | ¡ D ƒƒo@t|ƒS )a  
    Check whether `n` is a cyclic number. A number `n` is said to be cyclic
    if and only if every finite group of order `n` is cyclic. For more
    information see [1]_.

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import is_cyclic_number
    >>> from sympy import randprime
    >>> is_cyclic_number(15)
    True
    >>> is_cyclic_number(randprime(1, 2000)**2)
    False
    >>> is_cyclic_number(4)
    False

    References
    ==========

    .. [1] Pakianathan, J., Shankar, K., Nilpotent Numbers,
           The American Mathematical Monthly, 107(7), 631-634.
    .. [2] https://oeis.org/A003277

    r   r   c                 s   s   | ]}|d kV  qdS ©r	   Nr   r   r   r   r   r   w   s     z#is_cyclic_number.<locals>.<genexpr>r   r    r   r   r   Úis_cyclic_numberY   s
    r#   c                    s¬   ‡fdd„ˆD ƒ}ˆ| ‰ d}t  ‡ fdd„ttˆ ƒd ƒD ƒ¡}|D ]`}t|ƒ}d}ˆ | D ]>‰t‡fdd„||B D ƒƒ}|ˆ| d ˆd  9 }|s^ qžq^||7 }qF|S )	a|   Number of groups of order `n`.
    where `n` is squarefree and its prime factors are ``prime_factors``.
    i.e., ``n == math.prod(prime_factors)``

    Explanation
    ===========

    When `n` is squarefree, the number of groups of order `n` is expressed by

    .. math ::
        \sum_{d \mid n} \prod_p \frac{p^{c(p, d)} - 1}{p - 1}

    where `n=de`, `p` is the prime factor of `e`,
    and `c(p, d)` is the number of prime factors `q` of `d` such that `q \equiv 1 \pmod{p}` [2]_.

    The formula is elegant, but can be improved when implemented as an algorithm.
    Since `n` is assumed to be squarefree, the divisor `d` of `n` can be identified with the power set of prime factors.
    We let `N` be the set of prime factors of `n`.
    `F = \{p \in N : \forall q \in N, q \not\equiv 1 \pmod{p} \}, M = N \setminus F`, we have the following.

    .. math ::
        \sum_{d \in 2^{M}} \prod_{p \in M \setminus d} \frac{p^{c(p, F \cup d)} - 1}{p - 1}

    Practically, many prime factors are expected to be members of `F`, thus reducing computation time.

    Parameters
    ==========

    prime_factors : set
        The set of prime factors of ``n``. where `n` is squarefree.

    Returns
    =======

    int : Number of groups of order ``n``

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import _holder_formula
    >>> _holder_formula({2}) # n = 2
    1
    >>> _holder_formula({2, 3}) # n = 2*3 = 6
    2

    See Also
    ========

    groups_count

    References
    ==========

    .. [1] Otto Holder, Die Gruppen der Ordnungen p^3, pq^2, pqr, p^4,
           Math. Ann. 43 pp. 301-412 (1893).
           http://dx.doi.org/10.1007/BF01443651
    .. [2] John H. Conway, Heiko Dietrich and E.A. O'Brien,
           Counting groups: gnus, moas and other exotica
           The Mathematical Intelligencer 30, 6-15 (2008)
           https://doi.org/10.1007/BF02985731

    c                    s&   h | ]‰ t ‡ fd d„ˆD ƒƒrˆ ’qS )c                 3   s   | ]}|ˆ  d kV  qdS r"   r   ©r   r   ©r   r   r   r   ¹   s     z,_holder_formula.<locals>.<setcomp>.<genexpr>)r   )r   )Úprime_factorsr%   r   Ú	<setcomp>¹   s      z"_holder_formula.<locals>.<setcomp>r   c                 3   s   | ]}t ˆ |ƒV  qd S )N)r   )r   Úr)ÚMr   r   r   ½   s     z"_holder_formula.<locals>.<genexpr>r	   c                    s   g | ]}|ˆ  d kr|‘qS )r	   r   r$   r%   r   r   Ú
<listcomp>Â   s      z#_holder_formula.<locals>.<listcomp>)r   Úfrom_iterabler   ÚlenÚset)r&   ÚFÚsZpowersetZpsÚprodÚcr   )r)   r   r&   r   Ú_holder_formulaz   s    ?$
r2   c                 C   s  t | ƒ} | dkrtd|  ƒ‚t| ƒ}t|ƒdk�rJt| ¡ ƒd \}}|dkr|dddddddd	d
ddg}|t|ƒk r||| S |dkr°ddddddddddg
}|t|ƒk r°|| S |dkr¼|S |dkrÈdS |dkrÔdS |dk�r
dd|  dt|d dƒ  t|d dƒ S |dk�rbd|d  d|  d dt|d dƒ  dt|d dƒ  dt|d dƒ  S |dk�rJ|dk�rzdS d|d  d|d   d|d   d|d   d |  d! d|d  d|  d" t|d dƒ  |d d#|  d$ t|d dƒ  d| d% t|d dƒ  dt|d dƒ  dt|d d&ƒ  t|d d'ƒ S td(d)„ | ¡ D ƒƒ�r´dddddddddd*dddd+d+ddd,ddd*ddd-dd.œ}| |k�r¬||  S td/ƒ‚t|ƒdk�rüt| 	¡ ƒ\}}||k�ræ|| }}|| dk�rødS dS t
t| 	¡ ƒƒS )0až   Number of groups of order `n`.
    In [1]_, ``gnu(n)`` is given, so we follow this notation here as well.

    Parameters
    ==========

    n : Integer
        ``n`` is a positive integer

    Returns
    =======

    int : ``gnu(n)``

    Raises
    ======

    ValueError
        Number of groups of order ``n`` is unknown or not implemented.
        For example, gnu(`2^{11}`) is not yet known.
        On the other hand, gnu(12) is known to be 5,
        but this has not yet been implemented in this function.

    Examples
    ========

    >>> from sympy.combinatorics.group_numbers import groups_count
    >>> groups_count(3) # There is only one cyclic group of order 3
    1
    >>> # There are two groups of order 10: the cyclic group and the dihedral group
    >>> groups_count(10)
    2

    See Also
    ========

    is_cyclic_number
        `n` is cyclic iff gnu(n) = 1

    References
    ==========

    .. [1] John H. Conway, Heiko Dietrich and E.A. O'Brien,
           Counting groups: gnus, moas and other exotica
           The Mathematical Intelligencer 30, 6-15 (2008)
           https://doi.org/10.1007/BF02985731
    .. [2] https://oeis.org/A000001

    r   r   r	   é   é   é   é3   i  i	  iÛ  i!  l   yLZ. r   é   éC   iø  i^$  imM l   ¥NÙC é   é=   é   é'   iX  é   é   é   iù…  é   é,   éª   iÃ  i—	  i#  é   é‡   é   é   é	   c                 s   s   | ]}|d kV  qdS r"   r   r   r   r   r   r     s     zgroups_count.<locals>.<genexpr>é4   é   é2   é
   )r@   é   é   r=   é   é$   é(   rA   é-   é0   rJ   rH   é6   é8   é<   é?   éD   éH   éK   éL   éP   éT   éX   éZ   é\   z9Number of groups of order n is unknown or not implemented)r   r   r   r,   Úlistr   r   Úanyr   r
   r2   r-   )r   r   r   r   ZA000679ZA090091Zsmallr   r   r   r   Úgroups_countÊ   s’    2
,
ÿÿÿ

:$ÿ ÿþþþþ             þ


rb   N)Ú	itertoolsr   r   Zsympy.external.gmpyr   Zsympy.ntheory.factor_r   Zsympy.utilities.miscr   ÚdictÚboolr   r   r!   r#   r2   rb   r   r   r   r   Ú<module>   s   !!P