
    wg׊                        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mZ d dlmZ 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mZmZ d dlmZ d dlmZ d dl m!Z!m"Z" d dl#m$Z$m%Z% d dl&m'Z' d dl(m)Z)m*Z*m+Z+  G d de      Z, G d de,e      Z- G d de,      Z. G d de.      Z/ G d de.      Z0 G d de,      Z1d(d!Z2 G d" d#e,      Z3 G d$ d%e3      Z4 G d& d'e3      Z5y ))    )Basic)cacheit)Tuple)call_highest_priority)global_parameters)AppliedUndefexpandMul)Integer)Eq)S	Singleton)ordered)DummySymbolWildsympify)Matrix)lcmfactor)IntervalIntersection)Idx)flattenis_sequenceiterablec                   L   e Zd ZdZdZdZed        Zd Ze	d        Z
e	d        Ze	d        Ze	d	        Ze	d
        Ze	d        Ze	d        Zed        Zd Zd Zd Zd Zd Zd Z ed      d        Zd Z ed      d        Zd Zd Z ed      d        Zd Z d Z!d!d Z"y)"SeqBasezBase class for sequencesT   c                 `    	 | j                   }|S # t        $ r t        j                  }Y |S w xY w)z[Return start (if possible) else S.Infinity.

        adapted from Set._infimum_key
        )startNotImplementedErrorr   Infinity)exprr#   s     [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/series/sequences.py
_start_keyzSeqBase._start_key    s6    	JJE  # 	JJE	s    --c                 r    t        | j                  |j                        }|j                  |j                  fS )zTReturns start and stop.

        Takes intersection over the two intervals.
        )r   intervalinfsup)selfotherr*   s      r'   _intersect_intervalzSeqBase._intersect_interval,   s+    
  u~~>||X\\))    c                     t        d| z        )z&Returns the generator for the sequencez(%s).genr$   r-   s    r'   genzSeqBase.gen4   s     "*t"344r0   c                     t        d| z        )z-The interval on which the sequence is definedz(%s).intervalr2   r3   s    r'   r*   zSeqBase.interval9   s     "/D"899r0   c                     t        d| z        ):The starting point of the sequence. This point is includedz
(%s).startr2   r3   s    r'   r#   zSeqBase.start>   s     ","566r0   c                     t        d| z        )z8The ending point of the sequence. This point is includedz	(%s).stopr2   r3   s    r'   stopzSeqBase.stopC   s     "+"455r0   c                     t        d| z        )zLength of the sequencez(%s).lengthr2   r3   s    r'   lengthzSeqBase.lengthH   s     "-$"677r0   c                      y)z-Returns a tuple of variables that are bounded r=   r3   s    r'   	variableszSeqBase.variablesM   s     r0   c                     | j                   D ch c].  }|j                  j                  | j                        D ]  }| 0 c}}S c c}}w )aG  
        This method returns the symbols in the object, excluding those
        that take on a specific value (i.e. the dummy symbols).

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n, m
        >>> SeqFormula(m*n**2, (n, 0, 5)).free_symbols
        {m}
        )argsfree_symbols
differencer>   )r-   ijs      r'   rA   zSeqBase.free_symbolsR   sF     !II 0qq~~Jt~~.0! 0 0 	1 0s   3Ac                     || j                   k  s|| j                  kD  rt        d|d| j                        | j	                  |      S )z#Returns the coefficient at point ptzIndex z out of bounds )r#   r9   
IndexErrorr*   _eval_coeffr-   pts     r'   coeffzSeqBase.coeffc   s>     

?b499nBNOO##r0   c                 2    t        d| j                  z        )NzhThe _eval_coeff method should be added to%s to return coefficient so it is availablewhen coeff calls it.)r$   funcrH   s     r'   rG   zSeqBase._eval_coeffj   s"    ! #9 %)II#. / 	/r0   c                     | j                   t        j                  u r| j                  }n| j                   }| j                   t        j                  u rd}nd}|||z  z   S )a  Returns the i'th point of a sequence.

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

        If start point is negative infinity, point is returned from the end.
        Assumes the first point to be indexed zero.

        Examples
        =========

        >>> from sympy import oo
        >>> from sympy.series.sequences import SeqPer

        bounded

        >>> SeqPer((1, 2, 3), (-10, 10))._ith_point(0)
        -10
        >>> SeqPer((1, 2, 3), (-10, 10))._ith_point(5)
        -5

        End is at infinity

        >>> SeqPer((1, 2, 3), (0, oo))._ith_point(5)
        5

        Starts at negative infinity

        >>> SeqPer((1, 2, 3), (-oo, 0))._ith_point(5)
        -5
           )r#   r   NegativeInfinityr9   )r-   rC   initialsteps       r'   
_ith_pointzSeqBase._ith_pointp   sT    @ ::+++iiGjjG::+++DD4r0   c                      y)aI  
        Should only be used internally.

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

        self._add(other) returns a new, term-wise added sequence if self
        knows how to add with other, otherwise it returns ``None``.

        ``other`` should only be a sequence object.

        Used within :class:`SeqAdd` class.
        Nr=   r-   r.   s     r'   _addzSeqBase._add        r0   c                      y)aS  
        Should only be used internally.

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

        self._mul(other) returns a new, term-wise multiplied sequence if self
        knows how to multiply with other, otherwise it returns ``None``.

        ``other`` should only be a sequence object.

        Used within :class:`SeqMul` class.
        Nr=   rU   s     r'   _mulzSeqBase._mul   rW   r0   c                     t        | |      S )a  
        Should be used when ``other`` is not a sequence. Should be
        defined to define custom behaviour.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> SeqFormula(n**2).coeff_mul(2)
        SeqFormula(2*n**2, (n, 0, oo))

        Notes
        =====

        '*' defines multiplication of sequences with sequences only.
        r
   rU   s     r'   	coeff_mulzSeqBase.coeff_mul   s    $ 4r0   c                 h    t        |t              st        dt        |      z        t	        | |      S )a4  Returns the term-wise addition of 'self' and 'other'.

        ``other`` should be a sequence.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> SeqFormula(n**2) + SeqFormula(n**3)
        SeqFormula(n**3 + n**2, (n, 0, oo))
        zcannot add sequence and %s
isinstancer    	TypeErrortypeSeqAddrU   s     r'   __add__zSeqBase.__add__   s0     %)84;FGGdE""r0   rb   c                     | |z   S Nr=   rU   s     r'   __radd__zSeqBase.__radd__       e|r0   c                 j    t        |t              st        dt        |      z        t	        | |       S )a7  Returns the term-wise subtraction of ``self`` and ``other``.

        ``other`` should be a sequence.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> SeqFormula(n**2) - (SeqFormula(n))
        SeqFormula(n**2 - n, (n, 0, oo))
        zcannot subtract sequence and %sr]   rU   s     r'   __sub__zSeqBase.__sub__   s2     %)=UKLLdUF##r0   rh   c                     |  |z   S rd   r=   rU   s     r'   __rsub__zSeqBase.__rsub__   s    r0   c                 $    | j                  d      S )zNegates the sequence.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> -SeqFormula(n**2)
        SeqFormula(-n**2, (n, 0, oo))
        rN   )r[   r3   s    r'   __neg__zSeqBase.__neg__   s     ~~b!!r0   c                 h    t        |t              st        dt        |      z        t	        | |      S )a{  Returns the term-wise multiplication of 'self' and 'other'.

        ``other`` should be a sequence. For ``other`` not being a
        sequence see :func:`coeff_mul` method.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> SeqFormula(n**2) * (SeqFormula(n))
        SeqFormula(n**3, (n, 0, oo))
        zcannot multiply sequence and %s)r^   r    r_   r`   SeqMulrU   s     r'   __mul__zSeqBase.__mul__  s0     %)=UKLLdE""r0   ro   c                     | |z  S rd   r=   rU   s     r'   __rmul__zSeqBase.__rmul__  rf   r0   c              #      K   t        | j                        D ]&  }| j                  |      }| j                  |       ( y wrd   )ranger;   rS   rJ   )r-   rC   rI   s      r'   __iter__zSeqBase.__iter__  s:     t{{# 	!A#B**R. 	!s   A Ac                 t   t        |t              r"| j                  |      }| j                  |      S t        |t              rq|j
                  |j                  }}|d}|| j                  }t        |||j                  xs d      D cg c]"  }| j                  | j                  |            $ c}S y c c}w )Nr   rO   )
r^   intrS   rJ   slicer#   r9   r;   rs   rR   )r-   indexr#   r9   rC   s        r'   __getitem__zSeqBase.__getitem__"  s    eS!OOE*E::e$$u%++uzz4E}|{{%uzzQ79qDJJtq12 9 9 &9s   
'B5Nc           
         ddl m} | d| D cg c]  } |t        |             }}t        |      }||dz  }nt	        ||dz        }g }	t        d|dz         D ]  }
d|
z  }g }t        |
      D ]  }|j                  ||||
z            t        |      }|j                         dk7  sP ||j                  t        ||
|                   }||k(  rt        |ddd         }	 nag }t        |
||
z
        D ]  }|j                  ||||
z            t        |      }||z  t        ||d       k(  st        |ddd         }	 n ||	S t        |	      }
|
dk(  rg dfS ||
dz
     ||
dz
  z  z  d|	|
dz
     ||
z  z  z
  }}t        |
dz
        D ]Q  }|||   ||z  z  z  }t        |
|z
  dz
        D ]  }||	|   ||   z  |||z   dz   z  z  z  } ||	|   ||dz   z  z  z  }S |	 |t        |      t        |      z        fS c c}w )a  
        Finds the shortest linear recurrence that satisfies the first n
        terms of sequence of order `\leq` ``n/2`` if possible.
        If ``d`` is specified, find shortest linear recurrence of order
        `\leq` min(d, n/2) if possible.
        Returns list of coefficients ``[b(1), b(2), ...]`` corresponding to the
        recurrence relation ``x(n) = b(1)*x(n-1) + b(2)*x(n-2) + ...``
        Returns ``[]`` if no recurrence is found.
        If gfvar is specified, also returns ordinary generating function as a
        function of gfvar.

        Examples
        ========

        >>> from sympy import sequence, sqrt, oo, lucas
        >>> from sympy.abc import n, x, y
        >>> sequence(n**2).find_linear_recurrence(10, 2)
        []
        >>> sequence(n**2).find_linear_recurrence(10)
        [3, -3, 1]
        >>> sequence(2**n).find_linear_recurrence(10)
        [2]
        >>> sequence(23*n**4+91*n**2).find_linear_recurrence(10)
        [5, -10, 10, -5, 1]
        >>> sequence(sqrt(5)*(((1 + sqrt(5))/2)**n - (-(1 + sqrt(5))/2)**(-n))/5).find_linear_recurrence(10)
        [1, 1]
        >>> sequence(x+y*(-2)**(-n), (n, 0, oo)).find_linear_recurrence(30)
        [1/2, 1/2]
        >>> sequence(3*5**n + 12).find_linear_recurrence(20,gfvar=x)
        ([6, -5], 3*(5 - 21*x)/((x - 1)*(5*x - 1)))
        >>> sequence(lucas(n)).find_linear_recurrence(15,gfvar=x)
        ([1, 1], (x - 2)/(x**2 + x - 1))
        r   )simplifyN   rO   rN   )sympy.simplifyr{   r	   lenminrs   appendr   detLUsolver   r   )r-   ndgfvarr{   txlxrcoeffsll2mlistkmyrC   rD   s                     r'   find_linear_recurrencezSeqBase.find_linear_recurrence/  sd   D 	,*.r(3QXfQi 33V9AAAb!eAq!A# 	A1BE1X 'Qq1X&'uAuuw!|QYYva"g788$QttW-FqA +ALL1QqS*+5MQ3&23.($QttW-F#	$ =MFAAv4x1veacl*AqsE1H0D,D1qs 0A1eQh&A"1Q3q5\ ;VAYqt^EAaCEN::;51Q3<//A	0
 xq	&)(;<<<M 4s   H)NN)#__name__
__module____qualname____doc__is_commutative_op_prioritystaticmethodr(   r/   propertyr4   r*   r#   r9   r;   r>   rA   r   rJ   rG   rS   rV   rY   r[   rb   r   re   rh   rj   rl   ro   rq   rt   ry   r   r=   r0   r'   r    r       sO   "NL	 	* 5 5 : : 7 7 6 6 8 8   1 1  $ $/* X   (#" 9% &$" 9% &"#$ 9% &!
9I=r0   r    c                   <    e Zd ZdZed        Zed        Zd Zd Zy)EmptySequencea  Represents an empty sequence.

    The empty sequence is also available as a singleton as
    ``S.EmptySequence``.

    Examples
    ========

    >>> from sympy import EmptySequence, SeqPer
    >>> from sympy.abc import x
    >>> EmptySequence
    EmptySequence
    >>> SeqPer((1, 2), (x, 0, 10)) + EmptySequence
    SeqPer((1, 2), (x, 0, 10))
    >>> SeqPer((1, 2)) * EmptySequence
    EmptySequence
    >>> EmptySequence.coeff_mul(-1)
    EmptySequence
    c                 "    t         j                  S rd   )r   EmptySetr3   s    r'   r*   zEmptySequence.interval  s    zzr0   c                 "    t         j                  S rd   )r   Zeror3   s    r'   r;   zEmptySequence.length  s    vvr0   c                     | S )"See docstring of SeqBase.coeff_mulr=   )r-   rJ   s     r'   r[   zEmptySequence.coeff_mul  s    r0   c                     t        g       S rd   )iterr3   s    r'   rt   zEmptySequence.__iter__  s    Bxr0   N)	r   r   r   r   r   r*   r;   r[   rt   r=   r0   r'   r   r   z  s9    (    r0   r   )	metaclassc                   p    e Zd ZdZed        Zed        Zed        Zed        Zed        Z	ed        Z
y)	SeqExpra  Sequence expression class.

    Various sequences should inherit from this class.

    Examples
    ========

    >>> from sympy.series.sequences import SeqExpr
    >>> from sympy.abc import x
    >>> from sympy import Tuple
    >>> s = SeqExpr(Tuple(1, 2, 3), Tuple(x, 0, 10))
    >>> s.gen
    (1, 2, 3)
    >>> s.interval
    Interval(0, 10)
    >>> s.length
    11

    See Also
    ========

    sympy.series.sequences.SeqPer
    sympy.series.sequences.SeqFormula
    c                      | j                   d   S Nr   r@   r3   s    r'   r4   zSeqExpr.gen  s    yy|r0   c                 Z    t        | j                  d   d   | j                  d   d         S )NrO   r|   )r   r@   r3   s    r'   r*   zSeqExpr.interval  s'    		!Q1a99r0   c                 .    | j                   j                  S rd   r*   r+   r3   s    r'   r#   zSeqExpr.start      }}   r0   c                 .    | j                   j                  S rd   r*   r,   r3   s    r'   r9   zSeqExpr.stop  r   r0   c                 :    | j                   | j                  z
  dz   S NrO   r9   r#   r3   s    r'   r;   zSeqExpr.length      yy4::%))r0   c                 (    | j                   d   d   fS )NrO   r   r   r3   s    r'   r>   zSeqExpr.variables  s    		!Q!!r0   N)r   r   r   r   r   r4   r*   r#   r9   r;   r>   r=   r0   r'   r   r     s    2   : : ! ! ! ! * * " "r0   r   c                   P    e Zd ZdZd
dZed        Zed        Zd Zd Z	d Z
d	 Zy)SeqPera  
    Represents a periodic sequence.

    The elements are repeated after a given period.

    Examples
    ========

    >>> from sympy import SeqPer, oo
    >>> from sympy.abc import k

    >>> s = SeqPer((1, 2, 3), (0, 5))
    >>> s.periodical
    (1, 2, 3)
    >>> s.period
    3

    For value at a particular point

    >>> s.coeff(3)
    1

    supports slicing

    >>> s[:]
    [1, 2, 3, 1, 2, 3]

    iterable

    >>> list(s)
    [1, 2, 3, 1, 2, 3]

    sequence starts from negative infinity

    >>> SeqPer((1, 2, 3), (-oo, 0))[0:6]
    [1, 2, 3, 1, 2, 3]

    Periodic formulas

    >>> SeqPer((k, k**2, k**3), (k, 0, oo))[0:6]
    [0, 1, 8, 3, 16, 125]

    See Also
    ========

    sympy.series.sequences.SeqFormula
    Nc                    t        |      }d }d\  }}}| ||      dt        j                  }}}t        |t              r0t        |      dk(  r|\  }}}nt        |      dk(  r ||      }|\  }}t        |t        t        f      r||t        dt        |      z        |t        j                  u r|t        j                  u rt        d      t        |||f      }t        |t              rt        t        t        |                  }nt        d|z        t        |d	   |d         t        j                  u rt        j                   S t#        j$                  | ||      S )
Nc                     | j                   }t        | j                         dk(  r|j                         S t        d      S )NrO   r   )rA   r~   popr   )
periodicalfrees     r'   _find_xzSeqPer.__new__.<locals>._find_x  s6    **D:**+q0xxz!Sz!r0   NNNr      r|   Invalid limits given: %sz/Both the start and end valuecannot be unboundedz6invalid period %s should be something like e.g (1, 2) rO   )r   r   r%   r   r   r~   r^   r   r   
ValueErrorstrrP   tupler   r   r   r   r   __new__)clsr   limitsr   r   r#   r9   s          r'   r   zSeqPer.__new__  sT   Z(
	" *5$>$Z0!QZZduAvu%6{a!'5$V!J'$t!fc]+u}7#f+EFFA&&&41::+=  "7 8 8 !UD)*z5) wz':!;<J 02<= > > F1Ivay)QZZ7??"}}S*f55r0   c                 ,    t        | j                        S rd   )r~   r4   r3   s    r'   periodzSeqPer.period+  s    488}r0   c                     | j                   S rd   r4   r3   s    r'   r   zSeqPer.periodical/      xxr0   c                    | j                   t        j                  u r| j                  |z
  | j                  z  }n|| j                   z
  | j                  z  }| j
                  |   j                  | j                  d   |      S r   )r#   r   rP   r9   r   r   subsr>   )r-   rI   idxs      r'   rG   zSeqPer._eval_coeff3  se    ::+++99r>T[[0C

?dkk1Cs#(():B??r0   c                 h   t        |t              r| j                  | j                  }}|j                  |j                  }}t	        ||      }g }t        |      D ]&  }|||z     }	|||z     }
|j                  |	|
z          ( | j                  |      \  }}t        || j                  d   ||f      S yzSee docstring of SeqBase._addr   N	r^   r   r   r   r   rs   r   r/   r>   r-   r.   per1lper1per2lper2
per_lengthnew_perr   ele1ele2r#   r9   s                r'   rV   zSeqPer._add:      eV$//4;;%D**ELL%DUE*JG:& ,AIAItd{+,
 2259KE4'DNN1$5ud#CDD %r0   c                 h   t        |t              r| j                  | j                  }}|j                  |j                  }}t	        ||      }g }t        |      D ]&  }|||z     }	|||z     }
|j                  |	|
z         ( | j                  |      \  }}t        || j                  d   ||f      S yzSee docstring of SeqBase._mulr   Nr   r   s                r'   rY   zSeqPer._mulK  r   r0   c                     t        |      }| j                  D cg c]  }||z  	 }}t        || j                  d         S c c}w r   rO   )r   r   r   r@   )r-   rJ   r   pers       r'   r[   zSeqPer.coeff_mul\  s@    "&//2Qq5y22c499Q<(( 3s   Ard   )r   r   r   r   r   r   r   r   rG   rV   rY   r[   r=   r0   r'   r   r     sM    .`&6P    @E"E")r0   r   c                   F    e Zd ZdZd
dZed        Zd Zd Zd Z	d Z
d	 Zy)
SeqFormulaaf  
    Represents sequence based on a formula.

    Elements are generated using a formula.

    Examples
    ========

    >>> from sympy import SeqFormula, oo, Symbol
    >>> n = Symbol('n')
    >>> s = SeqFormula(n**2, (n, 0, 5))
    >>> s.formula
    n**2

    For value at a particular point

    >>> s.coeff(3)
    9

    supports slicing

    >>> s[:]
    [0, 1, 4, 9, 16, 25]

    iterable

    >>> list(s)
    [0, 1, 4, 9, 16, 25]

    sequence starts from negative infinity

    >>> SeqFormula(n**2, (-oo, 0))[0:6]
    [0, 1, 4, 9, 16, 25]

    See Also
    ========

    sympy.series.sequences.SeqPer
    Nc                 P   t        |      }d }d\  }}}| ||      dt        j                  }}}t        |t              r0t        |      dk(  r|\  }}}nt        |      dk(  r ||      }|\  }}t        |t        t        f      r||t        dt        |      z        |t        j                  u r|t        j                  u rt        d      t        |||f      }t        |d   |d         t        j                  u rt        j                  S t        j                   | ||      S )	Nc                     | j                   }t        |      dk(  r|j                         S |st        d      S t	        d| z        )NrO   r   z specify dummy variables for %s. If the formula contains more than one free symbol, a dummy variable should be supplied explicitly e.g., SeqFormula(m*n**2, (n, 0, 5)))rA   r~   r   r   r   )formular   s     r'   r   z#SeqFormula.__new__.<locals>._find_x  sN    ''D4yA~xxz!Sz! O  r0   r   r   r   r|   r   z0Both the start and end value cannot be unboundedrO   )r   r   r%   r   r   r~   r^   r   r   r   r   rP   r   r   r   r   r   )r   r   r   r   r   r#   r9   s          r'   r   zSeqFormula.__new__  s   '"	 *5$>$W-q!**duAvu%6{a!'5$V!G$$t!fc]+u}7#f+EFFA&&&41::+=  "7 8 8!UD)*F1Ivay)QZZ7??"}}S'622r0   c                     | j                   S rd   r   r3   s    r'   r   zSeqFormula.formula  r   r0   c                 X    | j                   d   }| j                  j                  ||      S r   )r>   r   r   )r-   rI   r   s      r'   rG   zSeqFormula._eval_coeff  s'    NN1||  B''r0   c                     t        |t              rn| j                  | j                  d   }}|j                  |j                  d   }}||j	                  ||      z   }| j                  |      \  }}t        ||||f      S yr   r^   r   r   r>   r   r/   	r-   r.   form1v1form2v2r   r#   r9   s	            r'   rV   zSeqFormula._add  z    eZ(dnnQ&72Euq'92EejjR00G2259KE4gE4'899 )r0   c                     t        |t              rn| j                  | j                  d   }}|j                  |j                  d   }}||j	                  ||      z  }| j                  |      \  }}t        ||||f      S yr   r   r   s	            r'   rY   zSeqFormula._mul  r   r0   c                 h    t        |      }| j                  |z  }t        || j                  d         S r   )r   r   r   r@   )r-   rJ   r   s      r'   r[   zSeqFormula.coeff_mul  s.    ,,&'499Q<00r0   c                 b    t        t        | j                  g|i || j                  d         S r   )r   r	   r   r@   )r-   r@   kwargss      r'   r	   zSeqFormula.expand  s*    &???1NNr0   rd   )r   r   r   r   r   r   r   rG   rV   rY   r[   r	   r=   r0   r'   r   r   c  s<    &P%3N  (::1Or0   r   c                       e Zd ZdZddZed        Zed        Zed        Zed        Z	ed        Z
ed	        Zed
        Zed        Zed        Zd Zd Zy)RecursiveSeqa  
    A finite degree recursive sequence.

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

    That is, a sequence a(n) that depends on a fixed, finite number of its
    previous values. The general form is

        a(n) = f(a(n - 1), a(n - 2), ..., a(n - d))

    for some fixed, positive integer d, where f is some function defined by a
    SymPy expression.

    Parameters
    ==========

    recurrence : SymPy expression defining recurrence
        This is *not* an equality, only the expression that the nth term is
        equal to. For example, if :code:`a(n) = f(a(n - 1), ..., a(n - d))`,
        then the expression should be :code:`f(a(n - 1), ..., a(n - d))`.

    yn : applied undefined function
        Represents the nth term of the sequence as e.g. :code:`y(n)` where
        :code:`y` is an undefined function and `n` is the sequence index.

    n : symbolic argument
        The name of the variable that the recurrence is in, e.g., :code:`n` if
        the recurrence function is :code:`y(n)`.

    initial : iterable with length equal to the degree of the recurrence
        The initial values of the recurrence.

    start : start value of sequence (inclusive)

    Examples
    ========

    >>> from sympy import Function, symbols
    >>> from sympy.series.sequences import RecursiveSeq
    >>> y = Function("y")
    >>> n = symbols("n")
    >>> fib = RecursiveSeq(y(n - 1) + y(n - 2), y(n), n, [0, 1])

    >>> fib.coeff(3) # Value at a particular point
    2

    >>> fib[:6] # supports slicing
    [0, 1, 1, 2, 3, 5]

    >>> fib.recurrence # inspect recurrence
    Eq(y(n), y(n - 2) + y(n - 1))

    >>> fib.degree # automatically determine degree
    2

    >>> for x in zip(range(10), fib): # supports iteration
    ...     print(x)
    (0, 0)
    (1, 1)
    (2, 1)
    (3, 2)
    (4, 3)
    (5, 5)
    (6, 8)
    (7, 13)
    (8, 21)
    (9, 34)

    See Also
    ========

    sympy.series.sequences.SeqFormula

    Nc                    t        |t              st        dj                  |            t        |t              r|j
                  st        dj                  |            |j                  |fk7  rt        d      |j                  }t        d|f      }d}|j                  |      }	|	D ]  }
t        |
j                        dk7  rt        d      |
j                  d   j                  ||z         |   }|j                         r|j                  r|dk  st        d	j                  |
            | |kD  s| } |s0t        |      D cg c]  }t        d
j                  |             }}t        |      |k7  rt!        d      t#        |      }t%        |      }t'        d |D         }t	        j(                  | |||||      }t+        |      D ci c]  \  }} |||z         | c}}|_        ||_        |S c c}w c c}}w )NzErecurrence sequence must be an applied undefined function, found `{}`z0recurrence variable must be a symbol, found `{}`z)recurrence sequence does not match symbolr   )excluder   rO   z)Recurrence should be in a single variablezDRecurrence should have constant, negative, integer shifts (found {})zc_{}z)Number of initial terms must equal degreec              3   2   K   | ]  }t        |        y wrd   r   ).0r   s     r'   	<genexpr>z'RecursiveSeq.__new__.<locals>.<genexpr>O  s     6'!*6s   )r^   r   r_   formatr   	is_symbolr@   rL   r   findr~   matchis_constant
is_integerrs   r   r   r   r   r   r   	enumeratecachedegree)r   
recurrenceynr   rQ   r#   r   r   r  prev_ysprev_yshiftseqinits                 r'   r   zRecursiveSeq.__new__#  s   "l+ ++16":7 7 !U#1;; ++16!96 6 77qd?GHHGGqd# //!$ 	 F6;;1$ KLLKKN((Q/2E%%'E,<,< !..4fVn> > v	  8=fF1uV]]1-.FGFw<6!HII6g67mmCRGUC7@7IJGAtQuqy\4'J	

 G Ks   !G<Hc                      | j                   d   S zEquation defining recurrence.r   r   r3   s    r'   _recurrencezRecursiveSeq._recurrenceX       yy|r0   c                 H    t        | j                  | j                  d         S r  )r   r  r@   r3   s    r'   r  zRecursiveSeq.recurrence]  s     $''499Q<((r0   c                      | j                   d   S )z*Applied function representing the nth termrO   r   r3   s    r'   r  zRecursiveSeq.ynb  r  r0   c                 .    | j                   j                  S )z3Undefined function for the nth term of the sequence)r  rL   r3   s    r'   r   zRecursiveSeq.yg  s     ww||r0   c                      | j                   d   S )zSequence index symbolr|   r   r3   s    r'   r   zRecursiveSeq.nl  r  r0   c                      | j                   d   S )z"The initial values of the sequencer   r   r3   s    r'   rQ   zRecursiveSeq.initialq  r  r0   c                      | j                   d   S )r7      r   r3   s    r'   r#   zRecursiveSeq.startv  r  r0   c                 "    t         j                  S )z&The ending point of the sequence. (oo))r   r%   r3   s    r'   r9   zRecursiveSeq.stop{  s     zzr0   c                 :    | j                   t        j                  fS )z&Interval on which sequence is defined.)r#   r   r%   r3   s    r'   r*   zRecursiveSeq.interval  s     

AJJ''r0   c                 
   || j                   z
  t        | j                        k  r| j                  | j                  |         S t	        t        | j                        |dz         D ]q  }| j                   |z   }| j
                  j                  | j                  |i      }|j                  | j                        }|| j                  | j                  |      <   s | j                  | j                  | j                   z            S r   )r#   r~   r  r   rs   r  xreplacer   )r-   rx   current	seq_indexcurrent_recurrencenew_terms         r'   rG   zRecursiveSeq._eval_coeff  s    4::DJJ/::dffUm,,S_eai8 	5G 

W,I!%!1!1!:!:DFFI;N!O)224::>H,4DJJtvvi()	5 zz$&&g!5677r0   c              #   V   K   | j                   }	 | j                  |       |dz  }wr   )r#   rG   )r-   rx   s     r'   rt   zRecursiveSeq.__iter__  s1     

""5))QJE s   ')r   )r   r   r   r   r   r   r  r  r  r   r   rQ   r#   r9   r*   rG   rt   r=   r0   r'   r   r     s    JX3j   ) )             ( (8r0   r   Nc                 h    t        |       } t        | t              rt        | |      S t	        | |      S )a  
    Returns appropriate sequence object.

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

    If ``seq`` is a SymPy sequence, returns :class:`SeqPer` object
    otherwise returns :class:`SeqFormula` object.

    Examples
    ========

    >>> from sympy import sequence
    >>> from sympy.abc import n
    >>> sequence(n**2, (n, 0, 5))
    SeqFormula(n**2, (n, 0, 5))
    >>> sequence((1, 2, 3), (n, 0, 5))
    SeqPer((1, 2, 3), (n, 0, 5))

    See Also
    ========

    sympy.series.sequences.SeqPer
    sympy.series.sequences.SeqFormula
    )r   r   r   r   r   )r  r   s     r'   sequencer    s1    4 #,C3c6""#v&&r0   c                   p    e Zd ZdZed        Zed        Zed        Zed        Zed        Z	ed        Z
y)		SeqExprOpa  
    Base class for operations on sequences.

    Examples
    ========

    >>> from sympy.series.sequences import SeqExprOp, sequence
    >>> from sympy.abc import n
    >>> s1 = sequence(n**2, (n, 0, 10))
    >>> s2 = sequence((1, 2, 3), (n, 5, 10))
    >>> s = SeqExprOp(s1, s2)
    >>> s.gen
    (n**2, (1, 2, 3))
    >>> s.interval
    Interval(5, 10)
    >>> s.length
    6

    See Also
    ========

    sympy.series.sequences.SeqAdd
    sympy.series.sequences.SeqMul
    c                 :    t        d | j                  D              S )zjGenerator for the sequence.

        returns a tuple of generators of all the argument sequences.
        c              3   4   K   | ]  }|j                     y wrd   r   r   as     r'   r   z SeqExprOp.gen.<locals>.<genexpr>  s     .qQUU.   )r   r@   r3   s    r'   r4   zSeqExprOp.gen  s     .DII...r0   c                 4    t        d | j                  D         S )zeSequence is defined on the intersection
        of all the intervals of respective sequences
        c              3   4   K   | ]  }|j                     y wrd   r*   r$  s     r'   r   z%SeqExprOp.interval.<locals>.<genexpr>  s     <Qajj<r&  )r   r@   r3   s    r'   r*   zSeqExprOp.interval  s    
 <$))<==r0   c                 .    | j                   j                  S rd   r   r3   s    r'   r#   zSeqExprOp.start  r   r0   c                 .    | j                   j                  S rd   r   r3   s    r'   r9   zSeqExprOp.stop  r   r0   c                 x    t        t        | j                  D cg c]  }|j                   c}            S c c}w )z%Cumulative of all the bound variables)r   r   r@   r>   )r-   r%  s     r'   r>   zSeqExprOp.variables  s*     W499=aakk=>??=s   7c                 :    | j                   | j                  z
  dz   S r   r   r3   s    r'   r;   zSeqExprOp.length  r   r0   N)r   r   r   r   r   r4   r*   r#   r9   r>   r;   r=   r0   r'   r!  r!    s    0 / / > > ! ! ! ! @ @ * *r0   r!  c                   ,    e Zd ZdZd Zed        Zd Zy)ra   a  Represents term-wise addition of sequences.

    Rules:
        * The interval on which sequence is defined is the intersection
          of respective intervals of sequences.
        * Anything + :class:`EmptySequence` remains unchanged.
        * Other rules are defined in ``_add`` methods of sequence classes.

    Examples
    ========

    >>> from sympy import EmptySequence, oo, SeqAdd, SeqPer, SeqFormula
    >>> from sympy.abc import n
    >>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), EmptySequence)
    SeqPer((1, 2), (n, 0, oo))
    >>> SeqAdd(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
    EmptySequence
    >>> SeqAdd(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2, (n, 0, oo)))
    SeqAdd(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
    >>> SeqAdd(SeqFormula(n**3), SeqFormula(n**2))
    SeqFormula(n**3 + n**2, (n, 0, oo))

    See Also
    ========

    sympy.series.sequences.SeqMul
    c                    |j                  dt        j                        }t        |      }fd |      }|D cg c]  }|t        j
                  us| }}|st        j
                  S t        d |D         t        j                  u rt        j
                  S |rt        j                  |      S t        t        |t        j                              }t        j                  | g| S c c}w )Nevaluatec                     t        | t              r3t        | t              r t        t	        | j
                        g       S | gS t        |       rt        t	        |       g       S t        d      Nz2Input must be Sequences or  iterables of Sequences)r^   r    ra   summapr@   r   r_   arg_flattens    r'   r7  z SeqAdd.__new__.<locals>._flatten   sc    #w'c6*s8SXX6;;5L}3x-r22 6 7 7r0   c              3   4   K   | ]  }|j                     y wrd   r)  r$  s     r'   r   z!SeqAdd.__new__.<locals>.<genexpr>2       3!**3r&  )getr   r0  listr   r   r   r   ra   reducer   r    r(   r   r   )r   r@   r   r0  r%  r7  s        @r'   r   zSeqAdd.__new__  s    ::j*;*D*DE Dz		7 ~<a1AOO#;<< ??"3d34

B??" ==&&GD'"4"456}}S(4(( =s   C-C-c                 P   d}|rst        |       D ]b  \  }}d}t        |       D ]G  \  }}||k(  r|j                  |      }| | D cg c]  }|||fvs
| }}|j                  |        n |s`|}  n |rst        |       dk(  r| j	                         S t        | d      S c c}w )a  Simplify :class:`SeqAdd` using known rules.

        Iterates through all pairs and ask the constituent
        sequences if they can simplify themselves with any other constituent.

        Notes
        =====

        adapted from ``Union.reduce``

        TFrO   r0  )r   rV   r   r~   r   ra   r@   new_argsid1sid2r   new_seqr%  s           r'   r<  zSeqAdd.reduce=  s     #D/ Q 'o 	FCcz ffQiG */3#G!qAA#G#G 0	 #D " t9>88:$// $H   B#B#c                 @    t        fd| j                  D              S )z9adds up the coefficients of all the sequences at point ptc              3   @   K   | ]  }|j                          y wrd   )rJ   )r   r%  rI   s     r'   r   z%SeqAdd._eval_coeff.<locals>.<genexpr>c  s     211772;2s   )r3  r@   rH   s    `r'   rG   zSeqAdd._eval_coeffa  s    2		222r0   Nr   r   r   r   r   r   r<  rG   r=   r0   r'   ra   ra     s'    8")H !0 !0F3r0   ra   c                   ,    e Zd ZdZd Zed        Zd Zy)rn   a'  Represents term-wise multiplication of sequences.

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

    Handles multiplication of sequences only. For multiplication
    with other objects see :func:`SeqBase.coeff_mul`.

    Rules:
        * The interval on which sequence is defined is the intersection
          of respective intervals of sequences.
        * Anything \* :class:`EmptySequence` returns :class:`EmptySequence`.
        * Other rules are defined in ``_mul`` methods of sequence classes.

    Examples
    ========

    >>> from sympy import EmptySequence, oo, SeqMul, SeqPer, SeqFormula
    >>> from sympy.abc import n
    >>> SeqMul(SeqPer((1, 2), (n, 0, oo)), EmptySequence)
    EmptySequence
    >>> SeqMul(SeqPer((1, 2), (n, 0, 5)), SeqPer((1, 2), (n, 6, 10)))
    EmptySequence
    >>> SeqMul(SeqPer((1, 2), (n, 0, oo)), SeqFormula(n**2))
    SeqMul(SeqFormula(n**2, (n, 0, oo)), SeqPer((1, 2), (n, 0, oo)))
    >>> SeqMul(SeqFormula(n**3), SeqFormula(n**2))
    SeqFormula(n**5, (n, 0, oo))

    See Also
    ========

    sympy.series.sequences.SeqAdd
    c                    |j                  dt        j                        }t        |      }fd |      }|st        j
                  S t        d |D         t        j                  u rt        j
                  S |rt        j                  |      S t        t        |t        j                              }t        j                  | g| S )Nr0  c                     t        | t              r3t        | t              r t        t	        | j
                        g       S | gS t        |       rt        t	        |       g       S t        d      r2  )r^   r    rn   r3  r4  r@   r   r_   r5  s    r'   r7  z SeqMul.__new__.<locals>._flatten  sc    #w'c6*s8SXX6;;5L#3x-r22 6 7 7r0   c              3   4   K   | ]  }|j                     y wrd   r)  r$  s     r'   r   z!SeqMul.__new__.<locals>.<genexpr>  r9  r&  )r:  r   r0  r;  r   r   r   r   rn   r<  r   r    r(   r   r   )r   r@   r   r0  r7  s       @r'   r   zSeqMul.__new__  s    ::j*;*D*DE Dz		7 ~ ??"3d34

B??" ==&&GD'"4"456}}S(4((r0   c                 P   d}|rst        |       D ]b  \  }}d}t        |       D ]G  \  }}||k(  r|j                  |      }| | D cg c]  }|||fvs
| }}|j                  |        n |s`|}  n |rst        |       dk(  r| j	                         S t        | d      S c c}w )a.  Simplify a :class:`SeqMul` using known rules.

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

        Iterates through all pairs and ask the constituent
        sequences if they can simplify themselves with any other constituent.

        Notes
        =====

        adapted from ``Union.reduce``

        TFrO   r>  )r   rY   r   r~   r   rn   r?  s           r'   r<  zSeqMul.reduce  s      #D/ Q 'o 	FCcz ffQiG */3#G!qAA#G#G 0	 #D " t9>88:$// $HrE  c                 T    d}| j                   D ]  }||j                  |      z  } |S )z<multiplies the coefficients of all the sequences at point ptrO   )r@   rJ   )r-   rI   valr%  s       r'   rG   zSeqMul._eval_coeff  s1     	A1772;C	
r0   NrH  r=   r0   r'   rn   rn   f  s(     D )D $0 $0Lr0   rn   rd   )6sympy.core.basicr   sympy.core.cacher   sympy.core.containersr   sympy.core.decoratorsr   sympy.core.parametersr   sympy.core.functionr   r	   sympy.core.mulr   sympy.core.numbersr   sympy.core.relationalr   sympy.core.singletonr   r   sympy.core.sortingr   sympy.core.symbolr   r   r   sympy.core.sympifyr   sympy.matricesr   sympy.polysr   r   sympy.sets.setsr   r   sympy.tensor.indexedr   sympy.utilities.iterablesr   r   r   r    r   r   r   r   r   r  r!  ra   rn   r=   r0   r'   <module>rb     s    " $ ' 7 3 4  & $ - & 1 1 & ! # 2 $ D D^=e ^=@"Gy "J0"g 0"fN)W N)bqO qOfB7 BJ'N7* 7*tg3Y g3TqY qr0   