U
    ZÊ¹j×Š  ã                   @   sš  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„ deƒZ,G dd„ de,ed�Z-G dd„ de,ƒZ.G dd„ de.ƒZ/G dd„ de.ƒZ0G dd„ de,ƒZ1d)d!d"„Z2G d#d$„ d$e,ƒZ3G d%d&„ d&e3ƒZ4G d'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                   @   s  e Zd ZdZdZdZedd„ ƒZdd„ Ze	dd	„ ƒZ
e	d
d„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zed$ƒd%d&„ ƒZd'd(„ Zed)ƒd*d+„ ƒZd,d-„ Zd.d/„ Zed0ƒd1d2„ ƒZd3d4„ Z d5d6„ Z!d:d8d9„Z"d7S );ÚSeqBasezBase class for sequencesTé   c                 C   s*   z
| j }W n tk
r$   tj}Y nX |S )z[Return start (if possible) else S.Infinity.

        adapted from Set._infimum_key
        )ÚstartÚNotImplementedErrorr   ÚInfinity)Úexprr    © r$   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/series/sequences.pyÚ
_start_key    s
    
zSeqBase._start_keyc                 C   s   t | j|jƒ}|j|jfS )zTReturns start and stop.

        Takes intersection over the two intervals.
        )r   ÚintervalÚinfÚsup)ÚselfÚotherr'   r$   r$   r%   Ú_intersect_interval,   s    zSeqBase._intersect_intervalc                 C   s   t d|  ƒ‚dS )z&Returns the generator for the sequencez(%s).genN©r!   ©r*   r$   r$   r%   Úgen4   s    zSeqBase.genc                 C   s   t d|  ƒ‚dS )z-The interval on which the sequence is definedz(%s).intervalNr-   r.   r$   r$   r%   r'   9   s    zSeqBase.intervalc                 C   s   t d|  ƒ‚dS )ú:The starting point of the sequence. This point is includedz
(%s).startNr-   r.   r$   r$   r%   r    >   s    zSeqBase.startc                 C   s   t d|  ƒ‚dS )z8The ending point of the sequence. This point is includedz	(%s).stopNr-   r.   r$   r$   r%   ÚstopC   s    zSeqBase.stopc                 C   s   t d|  ƒ‚dS )zLength of the sequencez(%s).lengthNr-   r.   r$   r$   r%   ÚlengthH   s    zSeqBase.lengthc                 C   s   dS )z-Returns a tuple of variables that are boundedr$   r$   r.   r$   r$   r%   Ú	variablesM   s    zSeqBase.variablesc                    s   ‡ fd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                    s$   h | ]}|j  ˆ j¡D ]}|’qqS r$   )Úfree_symbolsÚ
differencer3   )Ú.0ÚiÚjr.   r$   r%   Ú	<setcomp>`   s     ÿ  z'SeqBase.free_symbols.<locals>.<setcomp>©Úargsr.   r$   r.   r%   r4   R   s    zSeqBase.free_symbolsc                 C   s0   || j k s|| jkr&td|| jf ƒ‚|  |¡S )z#Returns the coefficient at point ptzIndex %s out of bounds %s)r    r1   Ú
IndexErrorr'   Ú_eval_coeff©r*   Úptr$   r$   r%   Úcoeffc   s    zSeqBase.coeffc                 C   s   t d| j ƒ‚d S )NzhThe _eval_coeff method should be added to%s to return coefficient so it is availablewhen coeff calls it.)r!   Úfuncr>   r$   r$   r%   r=   j   s    ýzSeqBase._eval_coeffc                 C   s<   | j tjkr| j}n| j }| j tjkr,d}nd}|||  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   ÚNegativeInfinityr1   )r*   r7   ÚinitialÚstepr$   r$   r%   Ú
_ith_pointp   s     zSeqBase._ith_pointc                 C   s   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*   r+   r$   r$   r%   Ú_addœ   s    zSeqBase._addc                 C   s   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$   rH   r$   r$   r%   Ú_mul¬   s    zSeqBase._mulc                 C   s
   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	   rH   r$   r$   r%   Ú	coeff_mul¼   s    zSeqBase.coeff_mulc                 C   s$   t |tƒstdt|ƒ ƒ‚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ÚSeqAddrH   r$   r$   r%   Ú__add__Ð   s    
zSeqBase.__add__rQ   c                 C   s   | | S ©Nr$   rH   r$   r$   r%   Ú__radd__á   s    zSeqBase.__radd__c                 C   s&   t |tƒstdt|ƒ ƒ‚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 %srL   rH   r$   r$   r%   Ú__sub__å   s    
zSeqBase.__sub__rT   c                 C   s
   |  | S rR   r$   rH   r$   r$   r%   Ú__rsub__ö   s    zSeqBase.__rsub__c                 C   s
   |   d¡S )zÓNegates the sequence.

        Examples
        ========

        >>> from sympy import SeqFormula
        >>> from sympy.abc import n
        >>> -SeqFormula(n**2)
        SeqFormula(-n**2, (n, 0, oo))
        rB   )rK   r.   r$   r$   r%   Ú__neg__ú   s    zSeqBase.__neg__c                 C   s$   t |tƒstdt|ƒ ƒ‚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)rM   r   rN   rO   ÚSeqMulrH   r$   r$   r%   Ú__mul__  s    
zSeqBase.__mul__rX   c                 C   s   | | S rR   r$   rH   r$   r$   r%   Ú__rmul__  s    zSeqBase.__rmul__c                 c   s*   t | jƒD ]}|  |¡}|  |¡V  q
d S rR   )Úranger2   rG   r@   )r*   r7   r?   r$   r$   r%   Ú__iter__  s    
zSeqBase.__iter__c                    st   t |tƒrˆ  |¡}ˆ  |¡S t |tƒrp|j|j }}|d krBd}|d krPˆ j}‡ fdd„t|||j	phdƒD ƒS d S )Nr   c                    s   g | ]}ˆ   ˆ  |¡¡‘qS r$   )r@   rG   )r6   r7   r.   r$   r%   Ú
<listcomp>,  s     z'SeqBase.__getitem__.<locals>.<listcomp>rC   )
rM   ÚintrG   r@   Úslicer    r1   r2   rZ   rF   )r*   Úindexr    r1   r$   r.   r%   Ú__getitem__"  s    




ÿzSeqBase.__getitem__Nc                    s<  ddl m‰  ‡ fdd„| d|… D ƒ}t|ƒ}|dkr@|d }nt||d ƒ}g }td|d ƒD ]è}d| }	g }
t|ƒD ]}|
 |||| … ¡ qxt|
ƒ}| ¡ dkr`ˆ | t|||	… ƒ¡ƒ}||	krât	|ddd… ƒ} �qJg }
t||| ƒD ]}|
 |||| … ¡ qôt|
ƒ}|| t||	d… ƒkr`t	|ddd… ƒ} �qJq`|dk�rX|S t|ƒ}|dk�rrg dfS ||d  ||d   d||d  ||    }}t|d ƒD ]n}||| ||  7 }t|| d ƒD ]*}||| ||  ||| d   8 }�qØ||| ||d   8 }�q°|ˆ t
|ƒt
|ƒ ƒfS d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                    s   g | ]}ˆ t |ƒƒ‘qS r$   )r   )r6   Útra   r$   r%   r\   R  s     z2SeqBase.find_linear_recurrence.<locals>.<listcomp>Né   rC   rB   )Zsympy.simplifyrb   ÚlenÚminrZ   Úappendr   ZdetZLUsolver   r   )r*   ÚnÚdZgfvarÚxÚlxÚrZcoeffsÚlÚl2ZmlistÚkÚmÚyr7   r8   r$   ra   r%   Úfind_linear_recurrence/  sJ    "


2(zSeqBase.find_linear_recurrence)NN)#Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zis_commutativeZ_op_priorityÚstaticmethodr&   r,   Úpropertyr/   r'   r    r1   r2   r3   r4   r   r@   r=   rG   rI   rJ   rK   rQ   r   rS   rT   rU   rV   rX   rY   r[   r`   rr   r$   r$   r$   r%   r      sP   








,


r   c                   @   s8   e Zd ZdZedd„ ƒZedd„ ƒZdd„ Zd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                 C   s   t jS rR   )r   ÚEmptySetr.   r$   r$   r%   r'   �  s    zEmptySequence.intervalc                 C   s   t jS rR   )r   ZZeror.   r$   r$   r%   r2   “  s    zEmptySequence.lengthc                 C   s   | S )ú"See docstring of SeqBase.coeff_mulr$   )r*   r@   r$   r$   r%   rK   —  s    zEmptySequence.coeff_mulc                 C   s   t g ƒS rR   )Úiterr.   r$   r$   r%   r[   ›  s    zEmptySequence.__iter__N)	rs   rt   ru   rv   rx   r'   r2   rK   r[   r$   r$   r$   r%   ry   z  s   

ry   )Ú	metaclassc                   @   sX   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	ed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                 C   s
   | j d S ©Nr   r:   r.   r$   r$   r%   r/   ¹  s    zSeqExpr.genc                 C   s   t | jd d | jd d ƒS )NrC   rd   )r   r;   r.   r$   r$   r%   r'   ½  s    zSeqExpr.intervalc                 C   s   | j jS rR   ©r'   r(   r.   r$   r$   r%   r    Á  s    zSeqExpr.startc                 C   s   | j jS rR   ©r'   r)   r.   r$   r$   r%   r1   Å  s    zSeqExpr.stopc                 C   s   | j | j d S ©NrC   ©r1   r    r.   r$   r$   r%   r2   É  s    zSeqExpr.lengthc                 C   s   | j d d fS )NrC   r   r:   r.   r$   r$   r%   r3   Í  s    zSeqExpr.variablesN)rs   rt   ru   rv   rx   r/   r'   r    r1   r2   r3   r$   r$   r$   r%   r~   Ÿ  s   




r~   c                   @   sR   e Zd ZdZddd„Zedd„ ƒZedd„ ƒZd	d
„ Zdd„ Z	dd„ Z
d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                 C   s$  t |ƒ}dd„ }d\}}}|d kr8||ƒdtj  }}}t|tƒrvt|ƒdkrZ|\}}}nt|ƒdkrv||ƒ}|\}}t|ttfƒr”|d ks”|d kr¤t	dt
|ƒ ƒ‚|tjkrÀ|tjkrÀt	dƒ‚t |||fƒ}t|tƒrêt tt|ƒƒƒ}nt	d	| ƒ‚t|d
 |d ƒtjk�rtjS t | ||¡S )Nc                 S   s(   | j }t| j ƒdkr| ¡ S tdƒS d S )NrC   ro   )r4   re   Úpopr   )Ú
periodicalÚfreer$   r$   r%   Ú_find_x  s    zSeqPer.__new__.<locals>._find_x©NNNr   é   rd   úInvalid limits given: %sz/Both the start and end valuecannot be unboundedz6invalid period %s should be something like e.g (1, 2) rC   )r   r   r"   r   r   re   rM   r   r   Ú
ValueErrorÚstrrD   Útupler   r   rz   ry   r   Ú__new__)Úclsr†   Úlimitsrˆ   rj   r    r1   r$   r$   r%   r�     s0    


ÿzSeqPer.__new__c                 C   s
   t | jƒS rR   )re   r/   r.   r$   r$   r%   Úperiod+  s    zSeqPer.periodc                 C   s   | j S rR   ©r/   r.   r$   r$   r%   r†   /  s    zSeqPer.periodicalc                 C   sF   | j tjkr| j| | j }n|| j  | j }| j|  | jd |¡S r   )r    r   rD   r1   r’   r†   Úsubsr3   )r*   r?   Úidxr$   r$   r%   r=   3  s    zSeqPer._eval_coeffc                 C   s�   t |tƒrŒ| j| j }}|j|j }}t||ƒ}g }t|ƒD ]*}|||  }	|||  }
| |	|
 ¡ q<|  |¡\}}t|| jd ||fƒS dS ©zSee docstring of SeqBase._addr   N©	rM   r„   r†   r’   r   rZ   rg   r,   r3   ©r*   r+   Zper1Zlper1Zper2Zlper2Z
per_lengthZnew_perrj   Zele1Zele2r    r1   r$   r$   r%   rI   :  s    

zSeqPer._addc                 C   s�   t |tƒrŒ| j| j }}|j|j }}t||ƒ}g }t|ƒD ]*}|||  }	|||  }
| |	|
 ¡ q<|  |¡\}}t|| jd ||fƒS dS ©zSee docstring of SeqBase._mulr   Nr—   r˜   r$   r$   r%   rJ   K  s    

zSeqPer._mulc                    s,   t ˆ ƒ‰ ‡ fdd„| jD ƒ}t|| jd ƒS )r{   c                    s   g | ]}|ˆ  ‘qS r$   r$   ©r6   rj   ©r@   r$   r%   r\   _  s     z$SeqPer.coeff_mul.<locals>.<listcomp>rC   )r   r†   r„   r;   )r*   r@   Zperr$   r›   r%   rK   \  s    zSeqPer.coeff_mul)N)rs   rt   ru   rv   r�   rx   r’   r†   r=   rI   rJ   rK   r$   r$   r$   r%   r„   Ò  s   0
(

r„   c                   @   sN   e Zd ZdZddd„Zedd„ ƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
d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                 C   sú   t |ƒ}dd„ }d\}}}|d kr8||ƒdtj  }}}t|tƒrvt|ƒdkrZ|\}}}nt|ƒdkrv||ƒ}|\}}t|ttfƒr”|d ks”|d kr¤t	dt
|ƒ ƒ‚|tjkrÀ|tjkrÀt	dƒ‚t |||fƒ}t|d	 |d ƒtjkrìtjS t | ||¡S )
Nc                 S   s6   | j }t|ƒdkr| ¡ S |s&tdƒS td|  ƒ‚d S )NrC   ro   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)))r4   re   r…   r   rŒ   )Úformular‡   r$   r$   r%   rˆ   �  s    ýÿz#SeqFormula.__new__.<locals>._find_xr‰   r   rŠ   rd   r‹   z0Both the start and end value cannot be unboundedrC   )r   r   r"   r   r   re   rM   r   r   rŒ   r�   rD   r   rz   ry   r   r�   )r�   r�   r‘   rˆ   rj   r    r1   r$   r$   r%   r�   Œ  s&    

zSeqFormula.__new__c                 C   s   | j S rR   r“   r.   r$   r$   r%   r�   ³  s    zSeqFormula.formulac                 C   s   | j d }| j ||¡S r   )r3   r�   r”   )r*   r?   ri   r$   r$   r%   r=   ·  s    
zSeqFormula._eval_coeffc           	      C   s`   t |tƒr\| j| jd  }}|j|jd  }}|| ||¡ }|  |¡\}}t||||fƒS dS r–   ©rM   rœ   r�   r3   r”   r,   ©	r*   r+   Zform1Zv1Zform2Zv2r�   r    r1   r$   r$   r%   rI   »  s    
zSeqFormula._addc           	      C   s`   t |tƒr\| j| jd  }}|j|jd  }}|| ||¡ }|  |¡\}}t||||fƒS dS r™   rž   rŸ   r$   r$   r%   rJ   Ä  s    
zSeqFormula._mulc                 C   s"   t |ƒ}| j| }t|| jd ƒS )r{   rC   )r   r�   rœ   r;   )r*   r@   r�   r$   r$   r%   rK   Í  s    
zSeqFormula.coeff_mulc                 O   s   t t| jf|ž|Ž| jd ƒS r‚   )rœ   r   r�   r;   )r*   r;   Úkwargsr$   r$   r%   r   Ó  s    zSeqFormula.expand)N)rs   rt   ru   rv   r�   rx   r�   r=   rI   rJ   rK   r   r$   r$   r$   r%   rœ   c  s   (
'
		rœ   c                   @   s–   e Zd ZdZddd„Zedd„ ƒZedd	„ ƒZed
d„ ƒZedd„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zd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                    s^  t |tƒstd |¡ƒ‚t |tƒr(|js6td |¡ƒ‚|j|fkrJtdƒ‚|j‰td|fd�}d}| 	ˆ¡}|D ]f}	t
|	jƒdkrŠtdƒ‚|	jd  || ¡| }
|
 ¡ r¸|
jr¸|
dk sÆtd	 |	¡ƒ‚|
 |krp|
 }qp|sîd
d„ t|ƒD ƒ}t
|ƒ|k�rtdƒ‚t|ƒ}tˆ ƒ‰ tdd„ |D ƒŽ }t | ||||ˆ ¡}‡ ‡fd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 symbolro   )Úexcluder   rC   z)Recurrence should be in a single variablezDRecurrence should have constant, negative, integer shifts (found {})c                 S   s   g | ]}t d  |¡ƒ‘qS )zc_{})r   Úformat)r6   ro   r$   r$   r%   r\   G  s     z(RecursiveSeq.__new__.<locals>.<listcomp>z)Number of initial terms must equal degreec                 s   s   | ]}t |ƒV  qd S rR   r   rš   r$   r$   r%   Ú	<genexpr>O  s     z'RecursiveSeq.__new__.<locals>.<genexpr>c                    s   i | ]\}}ˆˆ | ƒ|“qS r$   r$   )r6   ro   Úinit©r    rq   r$   r%   Ú
<dictcomp>S  s     
 z(RecursiveSeq.__new__.<locals>.<dictcomp>)rM   r   rN   r£   r   Z	is_symbolr;   rA   r   Úfindre   ÚmatchZis_constantÚ
is_integerrZ   rŒ   r   r   r   r�   Ú	enumerateÚcacheÚdegree)r�   Ú
recurrenceÚynrh   rE   r    ro   r­   Zprev_ysZprev_yÚshiftÚseqr$   r¦   r%   r�   #  sF    
ÿÿ
þ
zRecursiveSeq.__new__c                 C   s
   | j d S ©zEquation defining recurrence.r   r:   r.   r$   r$   r%   Ú_recurrenceX  s    zRecursiveSeq._recurrencec                 C   s   t | j| jd ƒS r²   )r   r¯   r;   r.   r$   r$   r%   r®   ]  s    zRecursiveSeq.recurrencec                 C   s
   | j d S )z*Applied function representing the nth termrC   r:   r.   r$   r$   r%   r¯   b  s    zRecursiveSeq.ync                 C   s   | j jS )z3Undefined function for the nth term of the sequence)r¯   rA   r.   r$   r$   r%   rq   g  s    zRecursiveSeq.yc                 C   s
   | j d S )zSequence index symbolrd   r:   r.   r$   r$   r%   rh   l  s    zRecursiveSeq.nc                 C   s
   | j d S )z"The initial values of the sequencerŠ   r:   r.   r$   r$   r%   rE   q  s    zRecursiveSeq.initialc                 C   s
   | j d S )r0   é   r:   r.   r$   r$   r%   r    v  s    zRecursiveSeq.startc                 C   s   t jS )z&The ending point of the sequence. (oo))r   r"   r.   r$   r$   r%   r1   {  s    zRecursiveSeq.stopc                 C   s   | j tjfS )z&Interval on which sequence is defined.)r    r   r"   r.   r$   r$   r%   r'   €  s    zRecursiveSeq.intervalc                 C   sŒ   || j  t| jƒk r$| j|  |¡ S tt| jƒ|d ƒD ]<}| j | }| j | j|i¡}| | j¡}|| j|  |¡< q8| j|  | j | ¡ S r‚   )r    re   r¬   rq   rZ   r³   Zxreplacerh   )r*   r_   ÚcurrentZ	seq_indexZcurrent_recurrenceZnew_termr$   r$   r%   r=   …  s    
zRecursiveSeq._eval_coeffc                 c   s    | j }|  |¡V  |d7 }qd S r‚   )r    r=   )r*   r_   r$   r$   r%   r[   ”  s    zRecursiveSeq.__iter__)Nr   )rs   rt   ru   rv   r�   rx   r³   r®   r¯   rq   rh   rE   r    r1   r'   r=   r[   r$   r$   r$   r%   r¡   Ö  s,   L
5








r¡   Nc                 C   s*   t | ƒ} t| tƒrt| |ƒS t| |ƒS d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
    N)r   r   r   r„   rœ   )r±   r‘   r$   r$   r%   Úsequence›  s    

r¶   c                   @   sX   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	ed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                 C   s   t dd„ | jD ƒƒS )zjGenerator for the sequence.

        returns a tuple of generators of all the argument sequences.
        c                 s   s   | ]}|j V  qd S rR   r“   ©r6   Úar$   r$   r%   r¤   á  s     z SeqExprOp.gen.<locals>.<genexpr>)rŽ   r;   r.   r$   r$   r%   r/   Û  s    zSeqExprOp.genc                 C   s   t dd„ | jD ƒŽ S )zeSequence is defined on the intersection
        of all the intervals of respective sequences
        c                 s   s   | ]}|j V  qd S rR   ©r'   r¸   r$   r$   r%   r¤   è  s     z%SeqExprOp.interval.<locals>.<genexpr>)r   r;   r.   r$   r$   r%   r'   ã  s    zSeqExprOp.intervalc                 C   s   | j jS rR   r€   r.   r$   r$   r%   r    ê  s    zSeqExprOp.startc                 C   s   | j jS rR   r�   r.   r$   r$   r%   r1   î  s    zSeqExprOp.stopc                 C   s   t tdd„ | jD ƒƒƒS )z%Cumulative of all the bound variablesc                 S   s   g | ]
}|j ‘qS r$   )r3   r¸   r$   r$   r%   r\   õ  s     z'SeqExprOp.variables.<locals>.<listcomp>)rŽ   r   r;   r.   r$   r$   r%   r3   ò  s    zSeqExprOp.variablesc                 C   s   | j | j d S r‚   rƒ   r.   r$   r$   r%   r2   ÷  s    zSeqExprOp.lengthN)rs   rt   ru   rv   rx   r/   r'   r    r1   r3   r2   r$   r$   r$   r%   r·   Â  s   




r·   c                   @   s,   e Zd ZdZdd„ Zedd„ ƒZdd„ ZdS )	rP   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                    sŽ   |  dtj¡}t|ƒ}‡ fdd„‰ ˆ |ƒ}dd„ |D ƒ}|sBtjS tdd„ |D ƒŽ tjkr`tjS |rnt 	|¡S tt
|tjƒƒ}tj| f|žŽ S )NÚevaluatec                    sP   t | tƒr,t | tƒr&ttˆ | jƒg ƒS | gS t| ƒrDttˆ | ƒg ƒS tdƒ‚d S ©Nz2Input must be Sequences or  iterables of Sequences)rM   r   rP   ÚsumÚmapr;   r   rN   ©Úarg©Ú_flattenr$   r%   rÂ      s    

z SeqAdd.__new__.<locals>._flattenc                 S   s   g | ]}|t jk	r|‘qS r$   )r   ry   r¸   r$   r$   r%   r\   ,  s     
 z"SeqAdd.__new__.<locals>.<listcomp>c                 s   s   | ]}|j V  qd S rR   rº   r¸   r$   r$   r%   r¤   2  s     z!SeqAdd.__new__.<locals>.<genexpr>)Úgetr   r»   Úlistr   ry   r   rz   rP   Úreducer   r   r&   r   r�   ©r�   r;   r    r»   r$   rÁ   r%   r�     s    

zSeqAdd.__new__c                    s    d}|r|t | ƒD ]h\}‰ d}t | ƒD ]F\}‰||kr6q$ˆ  ˆ¡}|dk	r$‡ ‡fdd„| D ƒ}| |¡  qlq$|r|}  qqqt| ƒdkr�|  ¡ S t| dd�S 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                    s   g | ]}|ˆ ˆfkr|‘qS r$   r$   r¸   ©Úsrc   r$   r%   r\   U  s      z!SeqAdd.reduce.<locals>.<listcomp>rC   ©r»   )r«   rI   rg   re   r…   rP   ©r;   Únew_argsZid1Zid2Znew_seqr$   rÇ   r%   rÅ   =  s$    

zSeqAdd.reducec                    s   t ‡ fdd„| jD ƒƒS )z9adds up the coefficients of all the sequences at point ptc                 3   s   | ]}|  ˆ ¡V  qd S rR   r›   r¸   ©r?   r$   r%   r¤   c  s     z%SeqAdd._eval_coeff.<locals>.<genexpr>)r½   r;   r>   r$   rÌ   r%   r=   a  s    zSeqAdd._eval_coeffN©rs   rt   ru   rv   r�   rw   rÅ   r=   r$   r$   r$   r%   rP   ü  s
   $
#rP   c                   @   s,   e Zd ZdZdd„ Zedd„ ƒZdd„ ZdS )	rW   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                    s€   |  dtj¡}t|ƒ}‡ fdd„‰ ˆ |ƒ}|s4tjS tdd„ |D ƒŽ tjkrRtjS |r`t 	|¡S tt
|tjƒƒ}tj| f|žŽ S )Nr»   c                    sR   t | tƒr.t | tƒr&ttˆ | jƒg ƒS | gS nt| ƒrFttˆ | ƒg ƒS tdƒ‚d S r¼   )rM   r   rW   r½   r¾   r;   r   rN   r¿   rÁ   r$   r%   rÂ   �  s    

z SeqMul.__new__.<locals>._flattenc                 s   s   | ]}|j V  qd S rR   rº   r¸   r$   r$   r%   r¤      s     z!SeqMul.__new__.<locals>.<genexpr>)rÃ   r   r»   rÄ   r   ry   r   rz   rW   rÅ   r   r   r&   r   r�   rÆ   r$   rÁ   r%   r�   ‰  s    

zSeqMul.__new__c                    s    d}|r|t | ƒD ]h\}‰ d}t | ƒD ]F\}‰||kr6q$ˆ  ˆ¡}|dk	r$‡ ‡fdd„| D ƒ}| |¡  qlq$|r|}  qqqt| ƒdkr�|  ¡ S t| dd�S 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                    s   g | ]}|ˆ ˆfkr|‘qS r$   r$   r¸   rÇ   r$   r%   r\   Æ  s      z!SeqMul.reduce.<locals>.<listcomp>rC   rÉ   )r«   rJ   rg   re   r…   rW   rÊ   r$   rÇ   r%   rÅ   «  s$    

zSeqMul.reducec                 C   s"   d}| j D ]}|| |¡9 }q
|S )z<multiplies the coefficients of all the sequences at point ptrC   )r;   r@   )r*   r?   Úvalr¹   r$   r$   r%   r=   Ò  s    
zSeqMul._eval_coeffNrÍ   r$   r$   r$   r%   rW   f  s
   ""
&rW   )N)6Zsympy.core.basicr   Zsympy.core.cacher   Zsympy.core.containersr   Zsympy.core.decoratorsr   Zsympy.core.parametersr   Zsympy.core.functionr   r   Zsympy.core.mulr
   Zsympy.core.numbersr   Zsympy.core.relationalr   Zsympy.core.singletonr   r   Zsympy.core.sortingr   Zsympy.core.symbolr   r   r   Zsympy.core.sympifyr   Zsympy.matricesr   Zsympy.polysr   r   Zsympy.sets.setsr   r   Zsympy.tensor.indexedr   Zsympy.utilities.iterablesr   r   r   r   ry   r~   r„   rœ   r¡   r¶   r·   rP   rW   r$   r$   r$   r%   Ú<module>   s>     b%3 s F
':j