ó
¡¼™\c           @  sÆ   d  Z  d d l m Z m Z d d l m Z m Z m Z d d l m	 Z	 d d l
 m Z m Z d d l m Z d „  Z d e f d	 „  ƒ  YZ d
 „  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s   Recurrence Operatorsiÿÿÿÿ(   t   print_functiont   division(   t   symbolst   Symbolt   S(   t   sstr(   t   ranget   string_types(   t   sympifyc         C  s   t  |  | ƒ } | | j f S(   s9  
    Returns an Algebra of Recurrence Operators and the operator for
    shifting i.e. the `Sn` operator.
    The first argument needs to be the base polynomial ring for the algebra
    and the second argument must be a generator which can be either a
    noncommutative Symbol or a string.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy import symbols
    >>> from sympy.holonomic.recurrence import RecurrenceOperators
    >>> n = symbols('n', integer=True)
    >>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n), 'Sn')
    (   t   RecurrenceOperatorAlgebrat   shift_operator(   t   baset	   generatort   ring(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   RecurrenceOperators   s    R	   c           B  s/   e  Z d  Z d „  Z d „  Z e Z d „  Z RS(   sì  
    A Recurrence Operator Algebra is a set of noncommutative polynomials
    in intermediate `Sn` and coefficients in a base ring A. It follows the
    commutation rule:
    Sn * a(n) = a(n + 1) * Sn

    This class represents a Recurrence Operator Algebra and serves as the parent ring
    for Recurrence Operators.

    Examples
    ========

    >>> from sympy.polys.domains import ZZ
    >>> from sympy import symbols
    >>> from sympy.holonomic.recurrence import RecurrenceOperators
    >>> n = symbols('n', integer=True)
    >>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n), 'Sn')
    >>> R
    Univariate Recurrence Operator Algebra in intermediate Sn over the base ring
    ZZ[n]

    See Also
    ========

    RecurrenceOperator
    c         C  s‘   | |  _  t | j | j g |  ƒ |  _ | d  k rK t d d t ƒ|  _ nB t	 | t
 ƒ rr t | d t ƒ|  _ n t	 | t ƒ r | |  _ n  d  S(   Nt   Snt   commutative(   R   t   RecurrenceOperatort   zerot   oneR
   t   NoneR   t   Falset
   gen_symbolt
   isinstanceR   R   (   t   selfR   R   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __init__=   s    	c         C  s(   d t  |  j ƒ d |  j j ƒ  } | S(   Ns7   Univariate Recurrence Operator Algebra in intermediate s    over the base ring (   R   R   R   t   __str__(   R   t   string(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   L   s    c         C  s0   |  j  | j  k r( |  j | j k r( t St Sd  S(   N(   R   R   t   TrueR   (   R   t   other(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __eq__U   s    $(   t   __name__t
   __module__t   __doc__R   R   t   __repr__R   (    (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR	   !   s
   		c         C  s“   t  |  ƒ t  | ƒ k rU g  t |  | ƒ D] \ } } | | ^ q( | t  |  ƒ } n: g  t |  | ƒ D] \ } } | | ^ qe |  t  | ƒ } | S(   N(   t   lent   zip(   t   list1t   list2t   at   bt   sol(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt
   _add_lists\   s    =:R   c           B  sq   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z e Z d „  Z	 d „  Z
 d „  Z d	 „  Z e Z d
 „  Z RS(   st  
    The Recurrence Operators are defined by a list of polynomials
    in the base ring and the parent ring of the Operator.

    Takes a list of polynomials for each power of Sn and the
    parent ring which must be an instance of RecurrenceOperatorAlgebra.

    A Recurrence Operator can be created easily using
    the operator `Sn`. See examples below.

    Examples
    ========

    >>> from sympy.holonomic.recurrence import RecurrenceOperator, RecurrenceOperators
    >>> from sympy.polys.domains import ZZ, QQ
    >>> from sympy import symbols
    >>> n = symbols('n', integer=True)
    >>> R, Sn = RecurrenceOperators(ZZ.old_poly_ring(n),'Sn')

    >>> RecurrenceOperator([0, 1, n**2], R)
    (1)Sn + (n**2)Sn**2

    >>> Sn*n
    (n + 1)Sn

    >>> n*Sn*n + 1 - Sn**2*n
    (1) + (n**2 + n)Sn + (-n - 2)Sn**2

    See Also
    ========

    DifferentialOperatorAlgebra
    i   c         C  sÀ   | |  _  t | t ƒ r¦ x t | ƒ D]q \ } } t | t ƒ rb |  j  j j t | ƒ ƒ | | <q% t | |  j  j j ƒ s% |  j  j j | ƒ | | <q% q% W| |  _	 n  t
 |  j	 ƒ d |  _ d  S(   Ni   (   t   parentR   t   listt	   enumeratet   intR   t
   from_sympyR   t   dtypet
   listofpolyR#   t   order(   R   t   list_of_polyR+   t   it   j(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   ‰   s    	" c           sõ   |  j  } |  j j ‰  t | t ƒ si t | |  j j j ƒ s] |  j j j t | ƒ ƒ g } qr | g } n	 | j  } d „  } | | d | ƒ } ‡  f d †  } xE t d t	 | ƒ ƒ D]. } | | ƒ } t
 | | | | | ƒ ƒ } q³ Wt | |  j ƒ S(   sŸ   
        Multiplies two Operators and returns another
        RecurrenceOperator instance using the commutation rule
        Sn * a(n) = a(n + 1) * Sn
        c         S  sJ   t  | t ƒ r; g  } x | D] } | j | |  ƒ q W| S|  | g Sd  S(   N(   R   R,   t   append(   R(   t   listofotherR)   R4   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   _mul_dmp_diffop®   s    i    c           s¼   ˆ  j  g } t |  t ƒ rx xš |  D]O } ˆ  j | ƒ j ˆ  j d ˆ  j d t d ƒ ƒ } | j ˆ  j | ƒ ƒ q" Wn@ |  j ˆ  j d ˆ  j d t d ƒ ƒ } | j ˆ  j | ƒ ƒ | S(   Ni    i   (	   R   R   R,   t   to_sympyt   subst   gensR   R6   R/   (   R(   R)   R4   R5   (   R   (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt
   _mul_Sni_bº   s    3*i   (   R1   R+   R   R   R   R0   R/   R   R   R#   R*   (   R   R   t
   listofselfR7   R8   R)   R<   R4   (    (   R   s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __mul__š   s    	!			 c         C  sœ   t  | t ƒ s˜ t  | t ƒ r- t | ƒ } n  t  | |  j j j ƒ s] |  j j j | ƒ } n  g  } x" |  j D] } | j	 | | ƒ qm Wt | |  j ƒ Sd  S(   N(
   R   R   R.   R   R+   R   R0   R/   R1   R6   (   R   R   R)   R5   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __rmul__Ð   s    c         C  sØ   t  | t ƒ r4 t |  j | j ƒ } t | |  j ƒ St  | t ƒ rR t | ƒ } n  |  j } t  | |  j j j ƒ sŽ |  j j j	 | ƒ g } n	 | g } g  } | j
 | d | d ƒ | | d 7} t | |  j ƒ Sd  S(   Ni    i   (   R   R   R*   R1   R+   R.   R   R   R0   R/   R6   (   R   R   R)   t	   list_selft
   list_other(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __add__ß   s    		c         C  s   |  d | S(   Niÿÿÿÿ(    (   R   R   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __sub__ö   s    c         C  s   d |  | S(   Niÿÿÿÿ(    (   R   R   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __rsub__ù   s    c         C  sü   | d k r |  S| d k r8 t  |  j j j g |  j ƒ S|  j |  j j j k r¬ g  } x- t d | ƒ D] } | j |  j j j ƒ qf W| j |  j j j ƒ t  | |  j ƒ S| d d k rÒ |  | d } | |  S| d d k rø |  | d } | | Sd  S(   Ni   i    i   (	   R   R+   R   R   R1   R
   R   R6   R   (   R   t   nR)   R4   t	   powreduce(    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   __pow__ü   s     c         C  sØ   |  j  } d } xÂ t | ƒ D]´ \ } } | |  j j j k rC q n  | d k rm | d t | ƒ d 7} q n  | r€ | d 7} n  | d k rª | d t | ƒ d 7} q n  | d t | ƒ d d t | ƒ 7} q W| S(	   Nt    i    t   (t   )s    + i   s   )Sns   Sn**(   R1   R-   R+   R   R   R   (   R   R1   t	   print_strR4   R5   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR     s    	*c         C  sŽ   t  | t ƒ r> |  j | j k r7 |  j | j k r7 t St SnL |  j d | k r† x. |  j d D] } | |  j j j k	 r_ t Sq_ Wt St Sd  S(   Ni    i   (   R   R   R1   R+   R   R   R   R   (   R   R   R4   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   +  s    $(   R   R    R!   t   _op_priorityR   R>   R?   RB   t   __radd__RC   RD   RG   R   R"   R   (    (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   d   s   !		6						t   HolonomicSequencec           B  s2   e  Z d  Z g  d „ Z d „  Z e Z d „  Z RS(   sõ   
    A Holonomic Sequence is a type of sequence satisfying a linear homogeneous
    recurrence relation with Polynomial coefficients. Alternatively, A sequence
    is Holonomic if and only if its generating function is a Holonomic Function.
    c         C  st   | |  _  t | t ƒ s' | g |  _ n	 | |  _ t |  j ƒ d k rQ t |  _ n	 t |  _ | j j	 j
 d |  _ d  S(   Ni    (   t
   recurrenceR   R,   t   u0R#   R   t   _have_init_condR   R+   R   R;   RE   (   R   RO   RP   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   B  s    			c         C  s‹   d |  j  j ƒ  t |  j ƒ f } |  j s/ | Sd } d } x; |  j D]0 } | d t | ƒ t | ƒ f 7} | d 7} qE W| | } | Sd  S(   Ns   HolonomicSequence(%s, %s)RH   i    s   , u(%s) = %si   (   RO   R"   R   RE   RQ   RP   (   R   t   str_solt   cond_strt   seq_strR4   R)   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR"   O  s    "	 
c         C  si   |  j  | j  k ra |  j | j k rZ |  j rS | j rS |  j | j k rL t St Sq^ t Sqe t Sn t Sd  S(   N(   RO   RE   RQ   RP   R   R   (   R   R   (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyR   _  s    (   R   R    R!   R   R"   R   R   (    (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyRN   ;  s
   	N(   R!   t
   __future__R    R   t   sympyR   R   R   t   sympy.printingR   t   sympy.core.compatibilityR   R   t   sympy.core.sympifyR   R   t   objectR	   R*   R   RN   (    (    (    s9   lib/python2.7/site-packages/sympy/holonomic/recurrence.pyt   <module>   s   	;	×