a
    RG5d}'                     @  s   d dl mZ d dlmZ d dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dlmZ dd	d
dZddd	ddZdd Zdd Zdd ZdS )    )annotations)factor_terms)IntegerRational)S)Dummy)_sympify)as_intlist)returnc                 C  s  t | }tdd | D r|jr2t|ddS |jrHt|j|jdS |jrp|j	t
ju rp|jjrptdd|jS |jrt|jdkr|jd jr|jd jr|jd jjr|jd j	t
ju r|j\} }td| j|j| jS |  \}}|jr|jrt||S |jr(t|jdkr(|j\} }n
t
j} |}| jrt
j}|jrdt|jdkrd|j\}}n|jrxtd}|}|jr|jr|j	t
ju r|jjr|j}t| |||S td| dS )a  Return the continued fraction representation of a Rational or
    quadratic irrational.

    Examples
    ========

    >>> from sympy.ntheory.continued_fraction import continued_fraction
    >>> from sympy import sqrt
    >>> continued_fraction((1 + 2*sqrt(3))/5)
    [0, 1, [8, 3, 34, 3]]

    See Also
    ========
    continued_fraction_periodic, continued_fraction_reduce, continued_fraction_convergents
    c                 s  s   | ]}|j V  qd S N)is_Rational).0i r   \/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/ntheory/continued_fraction.py	<genexpr>       z%continued_fraction.<locals>.<genexpr>   r      z4expecting a rational or quadratic irrational, not %sN)r   allatoms
is_Integercontinued_fraction_periodicr   pqis_Powexpr   Halfbaseis_Mullenargsexpandas_numer_denomis_AddZeroNaNr   
ValueError)aebr   dbccr   r   r   continued_fraction
   s\    




r/   r   c                 C  s  ddl m}m} ttt| |||g\} }}}|dk rBtd| |dkrRtd|sZd}||}|jrttt	| ||  |S |dk r|  | |   } }}| ||  | }|dk r|| }| | }	t
d|	 }
|
d  |d 8  < |
S ||d 9 }||9 }|| d  | r:||d 9 }||9 }| |9 } ||9 }g }i }| |f|vrt||| |f< || | |  |d | |  } || d  | }qB|| |f }|d| ||d g S )	aR  
    Find the periodic continued fraction expansion of a quadratic irrational.

    Compute the continued fraction expansion of a rational or a
    quadratic irrational number, i.e. `\frac{p + s\sqrt{d}}{q}`, where
    `p`, `q \ne 0` and `d \ge 0` are integers.

    Returns the continued fraction representation (canonical form) as
    a list of integers, optionally ending (for quadratic irrationals)
    with list of integers representing the repeating digits.

    Parameters
    ==========

    p : int
        the rational part of the number's numerator
    q : int
        the denominator of the number
    d : int, optional
        the irrational part (discriminator) of the number's numerator
    s : int, optional
        the coefficient of the irrational part

    Examples
    ========

    >>> from sympy.ntheory.continued_fraction import continued_fraction_periodic
    >>> continued_fraction_periodic(3, 2, 7)
    [2, [1, 4, 1, 1]]

    Golden ratio has the simplest continued fraction expansion:

    >>> continued_fraction_periodic(1, 2, 5)
    [[1]]

    If the discriminator is zero or a perfect square then the number will be a
    rational number:

    >>> continued_fraction_periodic(4, 3, 0)
    [1, 3]
    >>> continued_fraction_periodic(4, 3, 49)
    [3, 1, 2]

    See Also
    ========

    continued_fraction_iterator, continued_fraction_reduce

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Periodic_continued_fraction
    .. [2] K. Rosen. Elementary Number theory and its applications.
           Addison-Wesley, 3 Sub edition, pages 379-381, January 1992.

    r   )sqrtfloorz(expected non-negative for `d` but got %szThe denominator cannot be 0.r   r   N)sympy.functionsr0   r1   r
   mapr	   r(   r   continued_fraction_iteratorr   r/   r!   append)r   r   r,   sr0   r1   sdnwfZone_ftermspqr   r   r   r   r   K   sH    9

r   c                   s   ddl m} g  td fdd}tj}t|| D ]}q8 rtd}|t |g | |}|  |d }||	 }n|}|j
rt|}|jr|jd dkr|j|j }|S )a2  
    Reduce a continued fraction to a rational or quadratic irrational.

    Compute the rational or quadratic irrational number from its
    terminating or periodic continued fraction expansion.  The
    continued fraction expansion (cf) should be supplied as a
    terminating iterator supplying the terms of the expansion.  For
    terminating continued fractions, this is equivalent to
    ``list(continued_fraction_convergents(cf))[-1]``, only a little more
    efficient.  If the expansion has a repeating part, a list of the
    repeating terms should be returned as the last element from the
    iterator.  This is the format returned by
    continued_fraction_periodic.

    For quadratic irrationals, returns the largest solution found,
    which is generally the one sought, if the fraction is in canonical
    form (all terms positive except possibly the first).

    Examples
    ========

    >>> from sympy.ntheory.continued_fraction import continued_fraction_reduce
    >>> continued_fraction_reduce([1, 2, 3, 4, 5])
    225/157
    >>> continued_fraction_reduce([-2, 1, 9, 7, 1, 2])
    -256/233
    >>> continued_fraction_reduce([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8]).n(10)
    2.718281835
    >>> continued_fraction_reduce([1, 4, 2, [3, 1]])
    (sqrt(21) + 287)/238
    >>> continued_fraction_reduce([[1]])
    (1 + sqrt(5))/2
    >>> from sympy.ntheory.continued_fraction import continued_fraction_periodic
    >>> continued_fraction_reduce(continued_fraction_periodic(8, 5, 13))
    (sqrt(13) + 8)/5

    See Also
    ========

    continued_fraction_periodic

    r   )solvexc                 3  s2   | D ](}t |tr& | V   q.|V  qd S r   )
isinstancer
   extend)cfnxtperiodr?   r   r   	untillist   s    

z,continued_fraction_reduce.<locals>.untillistyr2   )Zsympy.solversr>   r   r   r&   continued_fraction_convergentscontinued_fraction_reducesortsubsradsimpr%   r   r    r"   func)rB   r>   rF   r)   rG   ZsolnsZpurervr   rD   r   rI      s&    +rI   c                 c  s6   ddl m} || }|V  | |8 } | s(q2d|  } qdS )a  
    Return continued fraction expansion of x as iterator.

    Examples
    ========

    >>> from sympy import Rational, pi
    >>> from sympy.ntheory.continued_fraction import continued_fraction_iterator

    >>> list(continued_fraction_iterator(Rational(3, 8)))
    [0, 2, 1, 2]
    >>> list(continued_fraction_iterator(Rational(-3, 8)))
    [-1, 1, 1, 1, 2]

    >>> for i, v in enumerate(continued_fraction_iterator(pi)):
    ...     if i > 7:
    ...         break
    ...     print(v)
    3
    7
    15
    1
    292
    1
    1
    1

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Continued_fraction

    r   )r1   r   N)r3   r1   )r?   r1   r   r   r   r   r5     s    "r5   c                 c  sb   t jt j }}t jt j }}| D ]<}|| | || |  }}|| }}|| }}|| V  q dS )av  
    Return an iterator over the convergents of a continued fraction (cf).

    The parameter should be an iterable returning successive
    partial quotients of the continued fraction, such as might be
    returned by continued_fraction_iterator.  In computing the
    convergents, the continued fraction need not be strictly in
    canonical form (all integers, all but the first positive).
    Rational and negative elements may be present in the expansion.

    Examples
    ========

    >>> from sympy.core import pi
    >>> from sympy import S
    >>> from sympy.ntheory.continued_fraction import             continued_fraction_convergents, continued_fraction_iterator

    >>> list(continued_fraction_convergents([0, 2, 1, 2]))
    [0, 1/2, 1/3, 3/8]

    >>> list(continued_fraction_convergents([1, S('1/2'), -7, S('1/4')]))
    [1, 3, 19/5, 7]

    >>> it = continued_fraction_convergents(continued_fraction_iterator(pi))
    >>> for n in range(7):
    ...     print(next(it))
    3
    22/7
    333/106
    355/113
    103993/33102
    104348/33215
    208341/66317

    See Also
    ========

    continued_fraction_iterator

    N)r   r&   One)rB   Zp_2Zq_2Zp_1Zq_1r)   r   r   r   r   r   rH   /  s    *

rH   N)r   r   )
__future__r   Zsympy.core.exprtoolsr   sympy.core.numbersr   r   sympy.core.singletonr   sympy.core.symbolr   sympy.core.sympifyr   sympy.utilities.miscr	   r/   r   rI   r5   rH   r   r   r   r   <module>   s   AmK,