
    Ed                        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          Z5d S ))    )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                      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"dS )"SeqBasezBase class for sequencesT   c                 j    	 | j         }n)# t          t          t          f$ r t          j        }Y nw xY w|S )z[Return start (if possible) else S.Infinity.

        adapted from Set._infimum_key
        )startNotImplementedErrorAttributeError
ValueErrorr   Infinity)exprr#   s     6lib/python3.11/site-packages/sympy/series/sequences.py
_start_keyzSeqBase._start_key    sG    	JEE#
, 	 	 	JEEE	 s   
 #00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.gen5   s     "*t"3444r2   c                 &    t          d| z            )z-The interval on which the sequence is definedz(%s).intervalr4   r5   s    r)   r,   zSeqBase.interval:   s     "/D"8999r2   c                 &    t          d| z            ):The starting point of the sequence. This point is includedz
(%s).startr4   r5   s    r)   r#   zSeqBase.start?   s     ","5666r2   c                 &    t          d| z            )z8The ending point of the sequence. This point is includedz	(%s).stopr4   r5   s    r)   stopzSeqBase.stopD   s     "+"4555r2   c                 &    t          d| z            )zLength of the sequencez(%s).lengthr4   r5   s    r)   lengthzSeqBase.lengthI   s     "-$"6777r2   c                     dS )z-Returns a tuple of variables that are bounded r?   r5   s    r)   	variableszSeqBase.variablesN   s	     rr2   c                 *      fd j         D             S )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}
        c                 X    h | ]&}|j                             j                  D ]}|'S r?   )free_symbols
differencer@   ).0ijr/   s      r)   	<setcomp>z'SeqBase.free_symbols.<locals>.<setcomp>a   sI     0 0 0qq~Jt~..0 0! 0 0 0 0r2   argsr5   s   `r)   rC   zSeqBase.free_symbolsS   s/    0 0 0 0DI 0 0 0 	1r2   c                     || j         k     s|| j        k    rt          d|d| j                  |                     |          S )z#Returns the coefficient at point ptzIndex z out of bounds )r#   r;   
IndexErrorr,   _eval_coeffr/   pts     r)   coeffzSeqBase.coeffd   sR     
? 	Pb49n 	P*BBBNOOO###r2   c                 0    t          d| j        z            )NzhThe _eval_coeff method should be added to%s to return coefficient so it is availablewhen coeff calls it.)r$   funcrN   s     r)   rM   zSeqBase._eval_coeffk   s%    ! #9 %)I#. / / 	/r2   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   NegativeInfinityr;   )r/   rF   initialsteps       r)   
_ith_pointzSeqBase._ith_pointq   sT    @ :++ 	!iGGjG:++ 	DDD4r2   c                     dS )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/   r0   s     r)   _addzSeqBase._add   	     tr2   c                     dS )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?   r[   s     r)   _mulzSeqBase._mul   r]   r2   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
   r[   s     r)   	coeff_mulzSeqBase.coeff_mul   s    $ 4r2   c                     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SeqAddr[   s     r)   __add__zSeqBase.__add__   sA     %)) 	H84;;FGGGdE"""r2   rh   c                     | |z   S Nr?   r[   s     r)   __radd__zSeqBase.__radd__       e|r2   c                     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 %src   r[   s     r)   __sub__zSeqBase.__sub__   sC     %)) 	M=UKLLLdUF###r2   rn   c                     |  |z   S rj   r?   r[   s     r)   __rsub__zSeqBase.__rsub__   s    r2   c                 ,    |                      d          S )zNegates the sequence.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> -SeqFormula(n**2)
        SeqFormula(-n**2, (n, 0, oo))
        rT   )ra   r5   s    r)   __neg__zSeqBase.__neg__   s     ~~b!!!r2   c                     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)rd   r    re   rf   SeqMulr[   s     r)   __mul__zSeqBase.__mul__  sA     %)) 	M=UKLLLdE"""r2   ru   c                     | |z  S rj   r?   r[   s     r)   __rmul__zSeqBase.__rmul__  rl   r2   c              #      K   t          | j                  D ].}|                     |          }|                     |          V  /d S rj   )ranger=   rY   rP   )r/   rF   rO   s      r)   __iter__zSeqBase.__iter__  sS      t{## 	! 	!A##B**R..    	! 	!r2   c                 .    t          |t                    r*                     |          }                     |          S t          |t                    r?|j        |j        }}|d}| j        } fdt          |||j	        pd          D             S d S )Nr   c                 `    g | ]*}                                         |                    +S r?   )rP   rY   )rE   rF   r/   s     r)   
<listcomp>z'SeqBase.__getitem__.<locals>.<listcomp>-  s=     9 9 9qDJJtq1122 9 9 9r2   rU   )
rd   intrY   rP   slicer#   r;   r=   ry   rX   )r/   indexr#   r;   s   `   r)   __getitem__zSeqBase.__getitem__#  s    eS!! 
	9OOE**E::e$$$u%% 	9+uz4E  #{9 9 9 9%uzQ779 9 9 9	9 	9r2   Nc           
         ddl m fd| d|         D             }t          |          }||dz  }nt          ||dz            }g }t	          d|dz             D ]5}d|z  }	g }
t	          |          D ]"}|
                    ||||z                       #t          |
          }|                                dk    r |                    t          |||	                                       }||	k    rt          |ddd                   } ng }
t	          |||z
            D ]"}|
                    ||||z                       #t          |
          }||z  t          ||	d                   k    rt          |ddd                   } n7||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 ]_}|||         ||z  z  z  }t	          ||z
  dz
            D ]"}|||         ||         z  |||z   dz   z  z  z  }#|||         ||dz   z  z  z  }`| t          |          t          |          z            fS )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   )simplifyc                 @    g | ]} t          |                    S r?   )r	   )rE   tr   s     r)   r}   z2SeqBase.find_linear_recurrence.<locals>.<listcomp>S  s)    333QXXfQii  333r2   N   rU   rT   )sympy.simplifyr   lenminry   appendr   detLUsolver   r   )r/   ndgfvarxlxrcoeffsll2mlistkmyrF   rG   r   s                   @r)   find_linear_recurrencezSeqBase.find_linear_recurrence0  s   D 	,+++++3333$rr(333VV 	AAAAb!eAq!A# 	 	A1BE1XX ' 'Qq1uX&&&&uAuuww!| HQYYva"g77888 $QtttW--FEqA + +ALL1QqS5****5MMQ3&233..( $QtttW--FE 	=MFAAv 	=4x1veacl*AqsE1H0D,D1qs 0 0A1eQh&A"1Q3q5\\ ; ;VAYqt^EAaCEN::51Q3<//AAxxq		&))(;<<<<r2   )NN)#__name__
__module____qualname____doc__is_commutative_op_prioritystaticmethodr*   r1   propertyr6   r,   r#   r;   r=   r@   rC   r   rP   rM   rY   r\   r_   ra   rh   r   rk   rn   rp   rr   ru   rw   rz   r   r   r?   r2   r)   r    r       sY       ""NL
 
 \
* * * 5 5 X5 : : X: 7 7 X7 6 6 X6 8 8 X8   X 1 1 X1  $ $ W$/ / /*  *  * X           (# # #" 9%%  &%$ $ $" 9%%  &%" " "# # #$ 9%%  &%! ! !
9 9 9I= I= I= I= I= I=r2   r    c                   J    e Zd ZdZed             Zed             Zd Zd ZdS )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 rj   )r   EmptySetr5   s    r)   r,   zEmptySequence.interval  s
    zr2   c                     t           j        S rj   )r   Zeror5   s    r)   r=   zEmptySequence.length  s	    vr2   c                     | S )"See docstring of SeqBase.coeff_mulr?   )r/   rP   s     r)   ra   zEmptySequence.coeff_mul  s    r2   c                      t          g           S rj   )iterr5   s    r)   rz   zEmptySequence.__iter__  s    Bxxr2   N)	r   r   r   r   r   r,   r=   ra   rz   r?   r2   r)   r   r   {  sr         (   X   X      r2   r   )	metaclassc                       e Zd ZdZed             Zed             Zed             Zed             Zed             Z	ed             Z
dS )	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   rI   r5   s    r)   r6   zSeqExpr.gen  s    y|r2   c                 f    t          | j        d         d         | j        d         d                   S )NrU   r   )r   rJ   r5   s    r)   r,   zSeqExpr.interval  s&    	!Q1a999r2   c                     | j         j        S rj   r,   r-   r5   s    r)   r#   zSeqExpr.start      }  r2   c                     | j         j        S rj   r,   r.   r5   s    r)   r;   zSeqExpr.stop  r   r2   c                 &    | j         | j        z
  dz   S NrU   r;   r#   r5   s    r)   r=   zSeqExpr.length      y4:%))r2   c                 *    | j         d         d         fS )NrU   r   rI   r5   s    r)   r@   zSeqExpr.variables  s    	!Q!!r2   N)r   r   r   r   r   r6   r,   r#   r;   r=   r@   r?   r2   r)   r   r     s         2   X : : X: ! ! X! ! ! X! * * X* " " X" " "r2   r   c                   ^    e Zd ZdZd
dZed             Zed             Zd Zd Z	d Z
d	 ZdS )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                    r=t          |          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|                                S t          d          S )NrU   r   )rC   r   popr   )
periodicalfrees     r)   _find_xzSeqPer.__new__.<locals>._find_x  s<    *D:*++q0 "xxzz!Szz!r2   NNNr      r   Invalid limits given: %sz/Both the start and end valuecannot be unboundedz6invalid period %s should be something like e.g (1, 2) rU   )r   r   r'   r   r   r   rd   r   r   r&   strrV   tupler   r   r   r   r   __new__)clsr   limitsr   r   r#   r;   s          r)   r   zSeqPer.__new__  s   Z((
	" 	" 	" *5$ 	@$WZ00!QZduAvu%% 	%6{{a %!'5$$V! %GJ''$t!fc]++ 	Gu 	G 	G7#f++EFFFA&& 	841:+= 	8  "7 8 8 8 !UD)**z5)) 	> wz':':!;!;<<JJ 02<= > > > F1Ivay))QZ7 	#?"}S*f555r2   c                 *    t          | j                  S rj   )r   r6   r5   s    r)   periodzSeqPer.period,  s    48}}r2   c                     | j         S rj   r6   r5   s    r)   r   zSeqPer.periodical0  	    xr2   c                     | j         t          j        u r| j        |z
  | j        z  }n|| j         z
  | j        z  }| j        |                             | j        d         |          S r   )r#   r   rV   r;   r   r   subsr@   )r/   rO   idxs      r)   rM   zSeqPer._eval_coeff4  s^    :++ 	29r>T[0CC
?dk1Cs#(():B???r2   c                 x   t          |t                    r| j        | j        }}|j        |j        }}t	          ||          }g }t          |          D ]0}|||z           }	|||z           }
|                    |	|
z              1|                     |          \  }}t          || j        d         ||f          S dS zSee docstring of SeqBase._addr   N	rd   r   r   r   r   ry   r   r1   r@   r/   r0   per1lper1per2lper2
per_lengthnew_perr   ele1ele2r#   r;   s                r)   r\   zSeqPer._add;      eV$$ 	E/4;%D*EL%DUE**JG:&& , ,AIAItd{++++22599KE4'DN1$5ud#CDDD	E 	Er2   c                 x   t          |t                    r| j        | j        }}|j        |j        }}t	          ||          }g }t          |          D ]0}|||z           }	|||z           }
|                    |	|
z             1|                     |          \  }}t          || j        d         ||f          S dS zSee docstring of SeqBase._mulr   Nr   r   s                r)   r_   zSeqPer._mulL  r   r2   c                 ~    t                    fd| j        D             }t          || j        d                   S )r   c                     g | ]}|z  S r?   r?   )rE   r   rP   s     r)   r}   z$SeqPer.coeff_mul.<locals>.<listcomp>`  s    222Qq5y222r2   rU   )r   r   r   rJ   )r/   rP   pers    ` r)   ra   zSeqPer.coeff_mul]  s?    2222$/222c49Q<(((r2   rj   )r   r   r   r   r   r   r   r   rM   r\   r_   ra   r?   r2   r)   r   r     s        . .`&6 &6 &6 &6P   X   X@ @ @E E E"E E E") ) ) ) )r2   r   c                   N    e Zd ZdZd
dZed             Zd Zd Zd Z	d Z
d	 ZdS )
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                    t          |          }d }d\  }}}| ||          dt          j        }}}t          |t                    r=t          |          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|                                S |st          d          S t	          d| z            )NrU   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)))rC   r   r   r   r&   )formular   s     r)   r   z#SeqFormula.__new__.<locals>._find_x  s`    'D4yyA~ 	xxzz! Szz! O   r2   r   r   r   r   r   z0Both the start and end value cannot be unboundedrU   )r   r   r'   r   r   r   rd   r   r   r&   r   rV   r   r   r   r   r   )r   r   r   r   r   r#   r;   s          r)   r   zSeqFormula.__new__  sp   '""	 	 	 *5$ 	=$WW--q!*duAvu%% 	%6{{a %!'5$$V! %GG$$$t!fc]++ 	Gu 	G 	G7#f++EFFFA&& 	841:+= 	8  "7 8 8 8!UD)**F1Ivay))QZ7 	#?"}S'6222r2   c                     | j         S rj   r   r5   s    r)   r   zSeqFormula.formula  r   r2   c                 R    | j         d         }| j                            ||          S r   )r@   r   r   )r/   rO   r   s      r)   rM   zSeqFormula._eval_coeff  s&    N1|  B'''r2   c                    t          |t                    rl| j        | j        d         }}|j        |j        d         }}||                    ||          z   }|                     |          \  }}t          ||||f          S dS r   rd   r   r   r@   r   r1   	r/   r0   form1v1form2v2r   r#   r;   s	            r)   r\   zSeqFormula._add      eZ(( 	:dnQ&72Euq'92EejjR000G22599KE4gE4'8999	: 	:r2   c                    t          |t                    rl| j        | j        d         }}|j        |j        d         }}||                    ||          z  }|                     |          \  }}t          ||||f          S dS r   r   r   s	            r)   r_   zSeqFormula._mul  r   r2   c                 j    t          |          }| j        |z  }t          || j        d                   S )r   rU   )r   r   r   rJ   )r/   rP   r   s      r)   ra   zSeqFormula.coeff_mul  s/    ,&'49Q<000r2   c                 ^    t          t          | j        g|R i || j        d                   S r   )r   r	   r   rJ   )r/   rJ   kwargss      r)   r	   zSeqFormula.expand  s2    &??????1NNNr2   rj   )r   r   r   r   r   r   r   rM   r\   r_   ra   r	   r?   r2   r)   r   r   d  s        & &P%3 %3 %3 %3N   X( ( (: : :: : :1 1 1O O O O Or2   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dS )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

    Nr   c                 ,   t          |t                    s"t          d                    |                    t          |t                    r|j        s"t          d                    |                    |j        |fk    rt          d          |j        t          d|f          }d}|	                              }|D ]}	t          |	j                  dk    rt          d          |	j        d                             ||z             |         }
|
                                r|
j        r|
dk     s"t          d	                    |	                    |
 |k    r|
 }|sd
 t          |          D             }t          |          |k    rt          d          t!          |          }t#                    t%          d |D              }t	          j        | ||||          }fdt)          |          D             |_        ||_        |S )NzErecurrence sequence must be an applied undefined function, found `{}`z0recurrence variable must be a symbol, found `{}`z)recurrence sequence does not match symbolr   )excluder   rU   z)Recurrence should be in a single variablezDRecurrence should have constant, negative, integer shifts (found {})c                 R    g | ]$}t          d                     |                    %S )zc_{})r   format)rE   r   s     r)   r}   z(RecursiveSeq.__new__.<locals>.<listcomp>H  s,    FFF1uV]]1--..FFFr2   z)Number of initial terms must equal degreec              3   4   K   | ]}t          |          V  d S rj   r   )rE   r   s     r)   	<genexpr>z'RecursiveSeq.__new__.<locals>.<genexpr>P  s(      66'!**666666r2   c                 4    i | ]\  }} |z             |S r?   r?   )rE   r   initr#   r   s      r)   
<dictcomp>z(RecursiveSeq.__new__.<locals>.<dictcomp>T  s+    JJJGAtQQuqy\\4JJJr2   )rd   r   re   r   r   	is_symbolrJ   rR   r   findr   matchis_constant
is_integerry   r&   r   r   r   r   	enumeratecachedegree)r   
recurrenceynr   rW   r#   r   r  prev_ysprev_yshiftseqr   s        `      @r)   r   zRecursiveSeq.__new__$  sF   "l++ 	7 ++16"::7 7 7 !U## 	61; 	6 ++16!996 6 6 7qd? 	IGHHHGqd### //!$$ 	  	 F6;1$ M KLLLKN((Q//2E%%'' >E,< > > !..4fVnn> > > v   	GFFfFFFGw<<6! 	JHIII66g6667mCRGUCCJJJJJy7I7IJJJ	

r2   c                     | j         d         S zEquation defining recurrence.r   rI   r5   s    r)   _recurrencezRecursiveSeq._recurrenceY       y|r2   c                 B    t          | j        | j        d                   S r  )r   r  rJ   r5   s    r)   r  zRecursiveSeq.recurrence^  s     $'49Q<(((r2   c                     | j         d         S )z*Applied function representing the nth termrU   rI   r5   s    r)   r  zRecursiveSeq.ync  r  r2   c                     | j         j        S )z3Undefined function for the nth term of the sequence)r  rR   r5   s    r)   r   zRecursiveSeq.yh  s     w|r2   c                     | j         d         S )zSequence index symbolr   rI   r5   s    r)   r   zRecursiveSeq.nm  r  r2   c                     | j         d         S )z"The initial values of the sequencer   rI   r5   s    r)   rW   zRecursiveSeq.initialr  r  r2   c                     | j         d         S )r9      rI   r5   s    r)   r#   zRecursiveSeq.startw  r  r2   c                     t           j        S )z&The ending point of the sequence. (oo))r   r'   r5   s    r)   r;   zRecursiveSeq.stop|  s     zr2   c                 (    | j         t          j        fS )z&Interval on which sequence is defined.)r#   r   r'   r5   s    r)   r,   zRecursiveSeq.interval  s     
AJ''r2   c                    || j         z
  t          | j                  k     r | j        |                     |                   S t	          t          | j                  |dz             D ]d}| j         |z   }| j                            | j        |i          }|                    | j                  }|| j        |                     |          <   e| j        |                     | j         |z                      S r   )r#   r   r  r   ry   r  xreplacer   )r/   r   current	seq_indexcurrent_recurrencenew_terms         r)   rM   zRecursiveSeq._eval_coeff  s    4:DJ/ 	-:dffUmm,,S__eai88 	5 	5G 
W,I!%!1!:!:DFI;N!O!O)224:>>H,4DJtvvi(())z$&&g!56677r2   c              #   P   K   | j         }	 |                     |          V  |dz  })NTrU   )r#   rM   )r/   r   s     r)   rz   zRecursiveSeq.__iter__  s:      
	""5)))))QJE	r2   r   )r   r   r   r   r   r   r  r  r  r   r   rW   r#   r;   r,   rM   rz   r?   r2   r)   r   r     sG       J JX3 3 3 3j   X ) ) X)   X   X   X   X   X   X ( ( X(8 8 8    r2   r   Nc                     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(    sA    4 #,,C3 'c6"""#v&&&r2   c                       e Zd ZdZed             Zed             Zed             Zed             Zed             Z	ed             Z
dS )		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   $   K   | ]}|j         V  d S rj   r   rE   as     r)   r  z SeqExprOp.gen.<locals>.<genexpr>  s$      ..qQU......r2   )r   rJ   r5   s    r)   r6   zSeqExprOp.gen  s#     ..DI......r2   c                 2    t          d | j        D              S )zeSequence is defined on the intersection
        of all the intervals of respective sequences
        c              3   $   K   | ]}|j         V  d S rj   r,   r-  s     r)   r  z%SeqExprOp.interval.<locals>.<genexpr>  s$      <<Qaj<<<<<<r2   )r   rJ   r5   s    r)   r,   zSeqExprOp.interval  s     
 <<$)<<<==r2   c                     | j         j        S rj   r   r5   s    r)   r#   zSeqExprOp.start  r   r2   c                     | j         j        S rj   r   r5   s    r)   r;   zSeqExprOp.stop  r   r2   c                 X    t          t          d | j        D                                 S )z%Cumulative of all the bound variablesc                     g | ]	}|j         
S r?   )r@   r-  s     r)   r}   z'SeqExprOp.variables.<locals>.<listcomp>  s    ===aak===r2   )r   r   rJ   r5   s    r)   r@   zSeqExprOp.variables  s+     W==49===>>???r2   c                 &    | j         | j        z
  dz   S r   r   r5   s    r)   r=   zSeqExprOp.length  r   r2   N)r   r   r   r   r   r6   r,   r#   r;   r@   r=   r?   r2   r)   r*  r*    s         0 / / X/ > > X> ! ! X! ! ! X! @ @ X@ * * X* * *r2   r*  c                   4    e Zd ZdZd Zed             Zd ZdS )rg   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                    |                     dt          j                  }t          |          }fd |          }d |D             }|st          j        S t          d |D              t          j        u rt          j        S |rt          	                    |          S t          t          |t          j                            }t          j        | g|R  S )Nevaluatec                    t          | t                    r;t          | 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)rd   r    rg   summaprJ   r   re   arg_flattens    r)   r@  z SeqAdd.__new__.<locals>._flatten!  s    #w'' !c6** !s8SX66;;;5L}} 33x--r222 6 7 7 7r2   c                 .    g | ]}|t           j        u|S r?   )r   r   r-  s     r)   r}   z"SeqAdd.__new__.<locals>.<listcomp>-  s$    <<<a1AO#;<<<<r2   c              3   $   K   | ]}|j         V  d S rj   r1  r-  s     r)   r  z!SeqAdd.__new__.<locals>.<genexpr>3  $      33!*333333r2   )getr   r9  listr   r   r   r   rg   reducer   r    r*   r   r   r   rJ   r   r9  r@  s       @r)   r   zSeqAdd.__new__  s    ::j*;*DEE Dzz		7 		7 		7 		7 		7 x~~<<4<<<  	#?"33d3334
B 	#?"  	'==&&&GD'"45566}S(4((((r2   c                 n   d}|rxt          |           D ]f\  }d}t          |           D ]I\  }||k    r                              }|&fd| D             }|                    |            nJ|r|}  ng|xt          |           dk    r|                                 S t          | d          S )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``

        TFNc                      g | ]
}|fv|S r?   r?   rE   r.  sr   s     r)   r}   z!SeqAdd.reduce.<locals>.<listcomp>V  &    #G#G#G!qA#GA#G#G#Gr2   rU   r9  )r
  r\   r   r   r   rg   rJ   new_argsid1id2new_seqrK  r   s        @@r)   rF  zSeqAdd.reduce>  s     	#D//  Q 'oo 	 	FCcz ! ffQiiG  #G#G#G#G#Gt#G#G#G 000  #DE  	" t99> 	088::$////r2   c                 D    t          fd| j        D                       S )z9adds up the coefficients of all the sequences at point ptc              3   B   K   | ]}|                               V  d S rj   )rP   )rE   r.  rO   s     r)   r  z%SeqAdd._eval_coeff.<locals>.<genexpr>d  s-      2211772;;222222r2   )r<  rJ   rN   s    `r)   rM   zSeqAdd._eval_coeffb  s(    2222	222222r2   Nr   r   r   r   r   r   rF  rM   r?   r2   r)   rg   rg     sY         8") ") ")H !0 !0 \!0F3 3 3 3 3r2   rg   c                   4    e Zd ZdZd Zed             Zd ZdS )rt   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                    |                     dt          j                  }t          |          }fd |          }|st          j        S t          d |D              t          j        u rt          j        S |rt          	                    |          S t          t          |t          j                            }t          j        | g|R  S )Nr9  c                    t          | t                    r;t          | t                    r#t          t	          | j                  g           S | gS t          |           rt          t	          |           g           S t          d          r;  )rd   r    rt   r<  r=  rJ   r   re   r>  s    r)   r@  z SeqMul.__new__.<locals>._flatten  s    #w'' 3c6** !s8SX66;;;5L# 33x--r222 6 7 7 7r2   c              3   $   K   | ]}|j         V  d S rj   r1  r-  s     r)   r  z!SeqMul.__new__.<locals>.<genexpr>  rC  r2   )rD  r   r9  rE  r   r   r   r   rt   rF  r   r    r*   r   r   rG  s       @r)   r   zSeqMul.__new__  s    ::j*;*DEE Dzz		7 		7 		7 		7 		7 x~~  	#?"33d3334
B 	#?"  	'==&&&GD'"45566}S(4((((r2   c                 n   d}|rxt          |           D ]f\  }d}t          |           D ]I\  }||k    r                              }|&fd| D             }|                    |            nJ|r|}  ng|xt          |           dk    r|                                 S t          | d          S )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``

        TFNc                      g | ]
}|fv|S r?   r?   rJ  s     r)   r}   z!SeqMul.reduce.<locals>.<listcomp>  rL  r2   rU   rM  )r
  r_   r   r   r   rt   rN  s        @@r)   rF  zSeqMul.reduce  s      	#D//  Q 'oo 	 	FCcz ! ffQiiG  #G#G#G#G#Gt#G#G#G 000  #DE  	" t99> 	088::$////r2   c                 N    d}| j         D ]}||                    |          z  }|S )z<multiplies the coefficients of all the sequences at point ptrU   )rJ   rP   )r/   rO   valr.  s       r)   rM   zSeqMul._eval_coeff  s3     	 	A1772;;CC
r2   NrU  r?   r2   r)   rt   rt   g  sZ           D )  )  )D $0 $0 \$0L    r2   rt   rj   )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*  rg   rt   r?   r2   r)   <module>rp     s[   " " " " " " $ $ $ $ $ $ ' ' ' ' ' ' 7 7 7 7 7 7 3 3 3 3 3 3 4 4 4 4 4 4 4 4       & & & & & & $ $ $ $ $ $ - - - - - - - - & & & & & & 1 1 1 1 1 1 1 1 1 1 & & & & & & ! ! ! ! ! ! # # # # # # # # 2 2 2 2 2 2 2 2 $ $ $ $ $ $ D D D D D D D D D D_= _= _= _= _=e _= _= _=B" " " " "Gy " " " "J0" 0" 0" 0" 0"g 0" 0" 0"fN) N) N) N) N)W N) N) N)bqO qO qO qO qO qO qO qOfB B B B B7 B B BJ' ' ' 'N7* 7* 7* 7* 7* 7* 7* 7*tg3 g3 g3 g3 g3Y g3 g3 g3Tq q q q qY q q q q qr2   