o
    oh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   v/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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ri i fS t| }i }i }d}| D ]+\}}|d dkrOd||< |d dkrB|d7 }|dkrN|d d ||< q*|d ||< q*d|v }|sb|d dkr|d }|dkslJ |dkrt|d= n|d |d< |r~d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)	a	a_factorsDFnum_3_mod_4peevene2r   r   r    extract_fundamental_discriminantM   s8   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                    sJ   | _ | _|  _ fddt|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>   s    z)AlgIntPowers.__init__.<locals>.<listcomp>N)	Tmodulusdegreenreversedrepto_listpowers_n_and_up
max_so_far)r,   r/   r0   r   r+   r   __init__   s
   
(zAlgIntPowers.__init__c                 C   s   | j d u r|S || j  S N)r0   )r,   expr   r   r   red   s   zAlgIntPowers.redc                 C   
   |  |S r9   )r;   )r,   otherr   r   r   __rmod__      
zAlgIntPowers.__rmod__c              
      s   j }||kr	d S jjd t|d |d D ]+d   d   d    g fddtdD   q|_ d S )Nr   r   c                    s4   g | ]}d    |d   |     qS )r   r   r*   ibr   kr2   r   r,   r   r   r-      s    (z3AlgIntPowers.compute_up_through.<locals>.<listcomp>)r7   r2   r6   rangeappend)r,   r%   mr   rB   r   compute_up_through   s   $
zAlgIntPowers.compute_up_throughc                    sL   | j } dk rtd |k r fddt|D S |   | j |  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-      s    z$AlgIntPowers.get.<locals>.<listcomp>)r2   r   rE   rH   r6   )r,   r%   r2   r   rI   r   get   s   
zAlgIntPowers.getc                 C   r<   r9   )rJ   )r,   itemr   r   r   __getitem__  r?   zAlgIntPowers.__getitem__r9   )
__name__
__module____qualname____doc__r8   r;   r>   rH   rJ   rL   r   r   r   r   r)      s    
'
r)   c                 c   s    |}|g|  }	 ||ks||v s| |v r|dd V  | d }|| | kr3|d8 }|| | ks(||  d8  < t |d | D ]}|||< qBt | D ]
}|| dkrW n
qM|d7 }|g|  }q	)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.

    TNr   r   )rE   )rG   RR0r   jrA   r   r   r   coeff_search  s(   %


rT   c                 C   sj   | j \}}| | || j}| \}}|d| tt|kr%t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domainrreftuplerE   r   inv)Mr2   r   MaugrQ   pivotsABr   r   r   supplement_a_subspace=  s   
Cra   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}}z(|sQ| } |D ]\}}	|| j
krG| j|	krGd} nq5t j	d	9  _	|r0W |t_	n|t_	w |d
uri|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   rC   refine_root)
algrg   rh   funcpolyrl   rm   doner   rC   r   r   r   isolate  s4   '
rs   )NF)rP   sympy.core.sympifyr   sympy.ntheory.factor_r   !sympy.polys.domains.rationalfieldr   sympy.polys.domains.integerringr   sympy.polys.matrices.exceptionsr    sympy.polys.numberfields.minpolyr   sympy.printing.lambdareprr   sympy.utilities.decoratorr	   sympy.utilities.lambdifyr
   rb   r   r   r   r   r(   r)   rT   ra   rs   r   r   r   r   <module>   s.    
X^
7W