a
    RG5d3                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ dd Zdd Zdd Zedd ZeG dd dZedd Zdd ZedddZdS )z'Utilities for algebraic number theory.     )sympify)	factorint)QQ)ZZ)DMRankError)minpoly)IntervalPrinter)public)lambdify)mpc                 C   s   t | tpt| pt| S )z
    Test whether an argument is of an acceptable type to be used as a rational
    number.

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

    Returns ``True`` on any argument of type ``int``, :ref:`ZZ`, or :ref:`QQ`.

    See Also
    ========

    is_int

    )
isinstanceintr   of_typer   c r   ^/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/polys/numberfields/utilities.pyis_rat   s    r   c                 C   s   t | tpt| S )z
    Test whether an argument is of an acceptable type to be used as an integer.

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

    Returns ``True`` on any argument of type ``int`` or :ref:`ZZ`.

    See Also
    ========

    is_rat

    )r   r   r   r   r   r   r   r   is_int)   s    r   c                 C   s   t | }|j|jfS )z
    Given any argument on which :py:func:`~.is_rat` is ``True``, return the
    numerator and denominator of this number.

    See Also
    ========

    is_rat

    )r   	numeratordenominator)r   rr   r   r   get_num_denom>   s    r   c           	      C   s  | d dvrt d| dkr(i ddifS | dkr8i i fS t| }i }i }d}| D ]V\}}|d dkrd||< |d dkr|d7 }|dkr|d d ||< qT|d ||< qTd|v }|s|d dkr|d }|dksJ |dkr|d= n|d |d< |rdnd|d< ||fS )a  
    Extract a fundamental discriminant from an integer *a*.

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

    Given any rational integer *a* that is 0 or 1 mod 4, write $a = d f^2$,
    where $d$ is either 1 or a fundamental discriminant, and return a pair
    of dictionaries ``(D, F)`` giving the prime factorizations of $d$ and $f$
    respectively, in the same format returned by :py:func:`~.factorint`.

    A fundamental discriminant $d$ is different from unity, and is either
    1 mod 4 and squarefree, or is 0 mod 4 and such that $d/4$ is squarefree
    and 2 or 3 mod 4. This is the same as being the discriminant of some
    quadratic field.

    Examples
    ========

    >>> from sympy.polys.numberfields.utilities import extract_fundamental_discriminant
    >>> print(extract_fundamental_discriminant(-432))
    ({3: 1, -1: 1}, {2: 2, 3: 1})

    For comparison:

    >>> from sympy import factorint
    >>> print(factorint(-432))
    {2: 4, 3: 3, -1: 1}

    Parameters
    ==========

    a: int, must be 0 or 1 mod 4

    Returns
    =======

    Pair ``(D, F)``  of dictionaries.

    Raises
    ======

    ValueError
        If *a* is not 0 or 1 mod 4.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*
       (See Prop. 5.1.3)

       )r      zATo extract fundamental discriminant, number must be 0 or 1 mod 4.r   r         )
ValueErrorr   items)	aZ	a_factorsDFZnum_3_mod_4peevene2r   r   r    extract_fundamental_discriminantM   s6    6r&   c                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )AlgIntPowersa  
    Compute the powers of an algebraic integer.

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

    Given an algebraic integer $\theta$ by its monic irreducible polynomial
    ``T`` over :ref:`ZZ`, this class computes representations of arbitrarily
    high powers of $\theta$, as :ref:`ZZ`-linear combinations over
    $\{1, \theta, \ldots, \theta^{n-1}\}$, where $n = \deg(T)$.

    The representations are computed using the linear recurrence relations for
    powers of $\theta$, derived from the polynomial ``T``. See [1], Sec. 4.2.2.

    Optionally, the representations may be reduced with respect to a modulus.

    Examples
    ========

    >>> from sympy import Poly, cyclotomic_poly
    >>> from sympy.polys.numberfields.utilities import AlgIntPowers
    >>> T = Poly(cyclotomic_poly(5))
    >>> zeta_pow = AlgIntPowers(T)
    >>> print(zeta_pow[0])
    [1, 0, 0, 0]
    >>> print(zeta_pow[1])
    [0, 1, 0, 0]
    >>> print(zeta_pow[4])  # doctest: +SKIP
    [-1, -1, -1, -1]
    >>> print(zeta_pow[24])  # doctest: +SKIP
    [-1, -1, -1, -1]

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory.*

    Nc                    sH   | _ | _|  _ fddt|jjD dd g _ j _dS )a-  
        Parameters
        ==========

        T : :py:class:`~.Poly`
            The monic irreducible polynomial over :ref:`ZZ` defining the
            algebraic integer.

        modulus : int, None, optional
            If not ``None``, all representations will be reduced w.r.t. this.

        c                    s   g | ]}|   qS r   r   ).0r   selfr   r   
<listcomp>       z)AlgIntPowers.__init__.<locals>.<listcomp>N)Tmodulusdegreenreversedreppowers_n_and_up
max_so_far)r*   r.   r/   r   r)   r   __init__   s
    
&zAlgIntPowers.__init__c                 C   s   | j d u r|S || j  S N)r/   )r*   expr   r   r   red   s    zAlgIntPowers.redc                 C   s
   |  |S r7   )r9   )r*   otherr   r   r   __rmod__   s    zAlgIntPowers.__rmod__c              
      s   j }||krd S jjd t|d |d D ]Vd   d   d    g fddtdD   q8|_ d S )Nr   r   c                    s4   g | ],}d    |d   |     qS )r   r   r(   ibr   kr1   r   r*   r   r   r+      s   z3AlgIntPowers.compute_up_through.<locals>.<listcomp>)r5   r1   r4   rangeappend)r*   r#   mr   r>   r   compute_up_through   s    $zAlgIntPowers.compute_up_throughc                    sR   | j } dk rtdn6 |k r6 fddt|D S |   | j |  S d S )Nr   zExponent must be non-negative.c                    s   g | ]}| krd ndqS )r   r   r   r<   r#   r   r   r+      r,   z$AlgIntPowers.get.<locals>.<listcomp>)r1   r   rA   rD   r4   )r*   r#   r1   r   rE   r   get   s    

zAlgIntPowers.getc                 C   s
   |  |S r7   )rF   )r*   itemr   r   r   __getitem__  s    zAlgIntPowers.__getitem__)N)
__name__
__module____qualname____doc__r6   r9   r;   rD   rF   rH   r   r   r   r   r'      s   '

r'   c                 c   s   |}|g|  }||ks(||v s(| |v r6|dd V  | d }|| | krV|d8 }q>||  d8  < t |d | D ]}|||< qtt | D ]}|| dkr qq|d7 }|g|  }qdS )a[  
    Generate coefficients for searching through polynomials.

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

    Lead coeff is always non-negative. Explore all combinations with coeffs
    bounded in absolute value before increasing the bound. Skip the all-zero
    list, and skip any repeats. See examples.

    Examples
    ========

    >>> from sympy.polys.numberfields.utilities import coeff_search
    >>> cs = coeff_search(2, 1)
    >>> C = [next(cs) for i in range(13)]
    >>> print(C)
    [[1, 1], [1, 0], [1, -1], [0, 1], [2, 2], [2, 1], [2, 0], [2, -1], [2, -2],
     [1, 2], [1, -2], [0, 2], [3, 3]]

    Parameters
    ==========

    m : int
        Length of coeff list.
    R : int
        Initial max abs val for coeffs (will increase as search proceeds).

    Returns
    =======

    generator
        Infinite generator of lists of coefficients.

    Nr   r   )rA   )rC   RZR0r   jr=   r   r   r   coeff_search  s    %


rO   c                 C   sj   | j \}}| | || j}| \}}|d| tt|krJtd|dd|df }| }|S )ax  
    Extend a basis for a subspace to a basis for the whole space.

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

    Given an $n \times r$ matrix *M* of rank $r$ (so $r \leq n$), this function
    computes an invertible $n \times n$ matrix $B$ such that the first $r$
    columns of $B$ equal *M*.

    This operation can be interpreted as a way of extending a basis for a
    subspace, to give a basis for the whole space.

    To be precise, suppose you have an $n$-dimensional vector space $V$, with
    basis $\{v_1, v_2, \ldots, v_n\}$, and an $r$-dimensional subspace $W$ of
    $V$, spanned by a basis $\{w_1, w_2, \ldots, w_r\}$, where the $w_j$ are
    given as linear combinations of the $v_i$. If the columns of *M* represent
    the $w_j$ as such linear combinations, then the columns of the matrix $B$
    computed by this function give a new basis $\{u_1, u_2, \ldots, u_n\}$ for
    $V$, again relative to the $\{v_i\}$ basis, and such that $u_j = w_j$
    for $1 \leq j \leq r$.

    Examples
    ========

    Note: The function works in terms of columns, so in these examples we
    print matrix transposes in order to make the columns easier to inspect.

    >>> from sympy.polys.matrices import DM
    >>> from sympy import QQ, FF
    >>> from sympy.polys.numberfields.utilities import supplement_a_subspace
    >>> M = DM([[1, 7, 0], [2, 3, 4]], QQ).transpose()
    >>> print(supplement_a_subspace(M).to_Matrix().transpose())
    Matrix([[1, 7, 0], [2, 3, 4], [1, 0, 0]])

    >>> M2 = M.convert_to(FF(7))
    >>> print(M2.to_Matrix().transpose())
    Matrix([[1, 0, 0], [2, 3, -3]])
    >>> print(supplement_a_subspace(M2).to_Matrix().transpose())
    Matrix([[1, 0, 0], [2, 3, -3], [0, 1, 0]])

    Parameters
    ==========

    M : :py:class:`~.DomainMatrix`
        The columns give the basis for the subspace.

    Returns
    =======

    :py:class:`~.DomainMatrix`
        This matrix is invertible and its first $r$ columns equal *M*.

    Raises
    ======

    DMRankError
        If *M* was not of maximal rank.

    References
    ==========

    .. [1] Cohen, H. *A Course in Computational Algebraic Number Theory*
       (See Sec. 2.3.2.)

    NzM was not of maximal rank)	shapehstackeyedomainZrreftuplerA   r   inv)Mr1   r   ZMaugrM   ZpivotsABr   r   r   supplement_a_subspace=  s    C
rY   NFc           
      C   s   t | } | jr| | fS | js$tdtd| dt d}t| dd}|jdd}tj	d }}zN|s| } |D ]$\}}	|| j
krj| j|	krjd} q\qjt j	d	9  _	q\W |t_	n|t_	0 |d
ur|j||	||d\}}	||	fS )a  
    Find a rational isolating interval for a real algebraic number.

    Examples
    ========

    >>> from sympy import isolate, sqrt, Rational
    >>> print(isolate(sqrt(2)))  # doctest: +SKIP
    (1, 2)
    >>> print(isolate(sqrt(2), eps=Rational(1, 100)))
    (24/17, 17/12)

    Parameters
    ==========

    alg : str, int, :py:class:`~.Expr`
        The algebraic number to be isolated. Must be a real number, to use this
        particular function. However, see also :py:meth:`.Poly.intervals`,
        which isolates complex roots when you pass ``all=True``.
    eps : positive element of :ref:`QQ`, None, optional (default=None)
        Precision to be passed to :py:meth:`.Poly.refine_root`
    fast : boolean, optional (default=False)
        Say whether fast refinement procedure should be used.
        (Will be passed to :py:meth:`.Poly.refine_root`.)

    Returns
    =======

    Pair of rational numbers defining an isolating interval for the given
    algebraic number.

    See Also
    ========

    .Poly.intervals

    z+complex algebraic numbers are not supportedr   mpmath)modulesprinterT)polys)sqfFr   N)epsfast)r   is_Rationalis_realNotImplementedErrorr
   r   r   	intervalsr   dpsr   r?   refine_root)
algr_   r`   funcpolyrd   re   doner   r?   r   r   r   isolate  s.    'rk   )NF)rL   sympy.core.sympifyr   sympy.ntheory.factor_r   Z!sympy.polys.domains.rationalfieldr   Zsympy.polys.domains.integerringr   Zsympy.polys.matrices.exceptionsr    sympy.polys.numberfields.minpolyr   sympy.printing.lambdareprr   sympy.utilities.decoratorr	   Zsympy.utilities.lambdifyr
   rZ   r   r   r   r   r&   r'   rO   rY   rk   r   r   r   r   <module>   s,   
X^
7W