ó
¡¼™\c           @  sf   d  d l  m Z m Z d  d l m Z d  d l m Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ	 d S(	   iÿÿÿÿ(   t   print_functiont   division(   t   ExprWithLimits(   t   St   ReorderErrorc           B  s   e  Z d  Z d „  Z RS(   sC   
    Exception raised when trying to reorder dependent limits.
    c         C  s$   t  t |  ƒ j d | | f ƒ d  S(   Ns   %s could not be reordered: %s.(   t   superR   t   __init__(   t   selft   exprt   msg(    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyR   
   s    (   t   __name__t
   __module__t   __doc__R   (    (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyR      s   t   ExprWithIntLimitsc           B  s/   e  Z d d  „ Z d „  Z d „  Z d „  Z RS(   c   
      C  s¥  | d k r | } n  g  } xH|  j D]=} | d | k rU| j | ƒ } | j ƒ  d k rk t d ƒ ‚ n  | j | ƒ } | j t j ƒ } | j r$| t j k rÕ | j	 | | | d | | | d | f ƒ qR| t j
 k r| j	 | | | d | | | d | f ƒ qRt d ƒ ‚ qb| j	 | | | d | | | d | f ƒ q% | j	 | ƒ q% W|  j j | | | | ƒ }	 |	 j | | ƒ }	 |  j |	 | Œ S(   s\  
        Change index of a Sum or Product.

        Perform a linear transformation `x \mapsto a x + b` on the index variable
        `x`. For `a` the only values allowed are `\pm 1`. A new variable to be used
        after the change of index can also be specified.

        Usage
        =====

        ``change_index(expr, var, trafo, newvar=None)`` where ``var`` specifies the
        index variable `x` to transform. The transformation ``trafo`` must be linear
        and given in terms of ``var``. If the optional argument ``newvar`` is
        provided then ``var`` gets replaced by ``newvar`` in the final expression.

        Examples
        ========

        >>> from sympy import Sum, Product, simplify
        >>> from sympy.abc import x, y, a, b, c, d, u, v, i, j, k, l

        >>> S = Sum(x, (x, a, b))
        >>> S.doit()
        -a**2/2 + a/2 + b**2/2 + b/2

        >>> Sn = S.change_index(x, x + 1, y)
        >>> Sn
        Sum(y - 1, (y, a + 1, b + 1))
        >>> Sn.doit()
        -a**2/2 + a/2 + b**2/2 + b/2

        >>> Sn = S.change_index(x, -x, y)
        >>> Sn
        Sum(-y, (y, -b, -a))
        >>> Sn.doit()
        -a**2/2 + a/2 + b**2/2 + b/2

        >>> Sn = S.change_index(x, x+u)
        >>> Sn
        Sum(-u + x, (x, a + u, b + u))
        >>> Sn.doit()
        -a**2/2 - a*u + a/2 + b**2/2 + b*u + b/2 - u*(-a + b + 1) + u
        >>> simplify(Sn.doit())
        -a**2/2 + a/2 + b**2/2 + b/2

        >>> Sn = S.change_index(x, -x - u, y)
        >>> Sn
        Sum(-u - y, (y, -b - u, -a - u))
        >>> Sn.doit()
        -a**2/2 - a*u + a/2 + b**2/2 + b*u + b/2 - u*(-a + b + 1) + u
        >>> simplify(Sn.doit())
        -a**2/2 + a/2 + b**2/2 + b/2

        >>> P = Product(i*j**2, (i, a, b), (j, c, d))
        >>> P
        Product(i*j**2, (i, a, b), (j, c, d))
        >>> P2 = P.change_index(i, i+3, k)
        >>> P2
        Product(j**2*(k - 3), (k, a + 3, b + 3), (j, c, d))
        >>> P3 = P2.change_index(j, -j, l)
        >>> P3
        Product(l**2*(k - 3), (k, a + 3, b + 3), (l, -d, -c))

        When dealing with symbols only, we can make a
        general linear transformation:

        >>> Sn = S.change_index(x, u*x+v, y)
        >>> Sn
        Sum((-v + y)/u, (y, b*u + v, a*u + v))
        >>> Sn.doit()
        -v*(a*u - b*u + 1)/u + (a**2*u**2/2 + a*u*v + a*u/2 - b**2*u**2/2 - b*u*v + b*u/2 + v)/u
        >>> simplify(Sn.doit())
        a**2*u/2 + a/2 - b**2*u/2 + b/2

        However, the last result can be inconsistent with usual
        summation where the index increment is always 1. This is
        obvious as we get back the original value only for ``u``
        equal +1 or -1.

        See Also
        ========

        sympy.concrete.simplification.index,
        sympy.concrete.simplification.reorder_limit,
        sympy.concrete.simplification.reorder,
        sympy.concrete.simplification.reverse_order
        i    i   s"   Index transformation is not lineari   s>   Linear transformation results in non-linear summation stepsizeN(   t   Nonet   limitst   as_polyt   degreet
   ValueErrort   coeff_monomialR   t   Onet	   is_numbert   appendt   NegativeOnet   functiont   subst   func(
   R   t   vart   trafot   newvarR   t   limitt   pt   alphat   betaR   (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyt   change_index   s*    X		111c         C  sX   g  |  j  D] } | d ^ q
 } | j | ƒ d k rG t |  d ƒ ‚ n | j | ƒ Sd S(   s÷  
        Return the index of a dummy variable in the list of limits.

        Usage
        =====

        ``index(expr, x)``  returns the index of the dummy variable ``x`` in the
        limits of ``expr``. Note that we start counting with 0 at the inner-most
        limits tuple.

        Examples
        ========

        >>> from sympy.abc import x, y, a, b, c, d
        >>> from sympy import Sum, Product
        >>> Sum(x*y, (x, a, b), (y, c, d)).index(x)
        0
        >>> Sum(x*y, (x, a, b), (y, c, d)).index(y)
        1
        >>> Product(x*y, (x, a, b), (y, c, d)).index(x)
        0
        >>> Product(x*y, (x, a, b), (y, c, d)).index(y)
        1

        See Also
        ========

        reorder_limit, reorder, reverse_order
        i    i   s0   Number of instances of variable not equal to oneN(   R   t   countR   t   index(   R   t   xR   t	   variables(    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyR$   …   s     c         G  s·   |  } xª | D]¢ } t  | ƒ d k r7 t | d ƒ ‚ n  | d } | d } t | d t ƒ st |  j | d ƒ } n  t | d t ƒ s |  j | d ƒ } n  | j | | ƒ } q W| S(   s‰  
        Reorder limits in a expression containing a Sum or a Product.

        Usage
        =====

        ``expr.reorder(*arg)`` reorders the limits in the expression ``expr``
        according to the list of tuples given by ``arg``. These tuples can
        contain numerical indices or index variable names or involve both.

        Examples
        ========

        >>> from sympy import Sum, Product
        >>> from sympy.abc import x, y, z, a, b, c, d, e, f

        >>> Sum(x*y, (x, a, b), (y, c, d)).reorder((x, y))
        Sum(x*y, (y, c, d), (x, a, b))

        >>> Sum(x*y*z, (x, a, b), (y, c, d), (z, e, f)).reorder((x, y), (x, z), (y, z))
        Sum(x*y*z, (z, e, f), (y, c, d), (x, a, b))

        >>> P = Product(x*y*z, (x, a, b), (y, c, d), (z, e, f))
        >>> P.reorder((x, y), (x, z), (y, z))
        Product(x*y*z, (z, e, f), (y, c, d), (x, a, b))

        We can also select the index variables by counting them, starting
        with the inner-most one:

        >>> Sum(x**2, (x, a, b), (x, c, d)).reorder((0, 1))
        Sum(x**2, (x, c, d), (x, a, b))

        And of course we can mix both schemes:

        >>> Sum(x*y, (x, a, b), (y, c, d)).reorder((y, x))
        Sum(x*y, (y, c, d), (x, a, b))
        >>> Sum(x*y, (x, a, b), (y, c, d)).reorder((y, 0))
        Sum(x*y, (y, c, d), (x, a, b))

        See Also
        ========

        reorder_limit, index, reverse_order
        i   s   Invalid number of argumentsi    i   (   t   lenR   t
   isinstancet   intR$   t   reorder_limit(   R   t   argt   new_exprt   rt   index1t   index2(    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyt   reorderª   s    -

c   	      C  sa  d „  |  j  Dƒ } |  j  | } |  j  | } t t | d j ƒ j | ƒ ƒ d k rNt t | d j ƒ j | ƒ ƒ d k rNt t | d j ƒ j | ƒ ƒ d k rNt t | d j ƒ j | ƒ ƒ d k rNg  } xb t |  j  ƒ D]Q \ } } | | k r| j | ƒ qã | | k r'| j | ƒ qã | j | ƒ qã Wt |  ƒ |  j | Œ St	 |  d ƒ ‚ d S(   sÌ  
        Interchange two limit tuples of a Sum or Product expression.

        Usage
        =====

        ``expr.reorder_limit(x, y)`` interchanges two limit tuples. The
        arguments ``x`` and ``y`` are integers corresponding to the index
        variables of the two limits which are to be interchanged. The
        expression ``expr`` has to be either a Sum or a Product.

        Examples
        ========

        >>> from sympy.abc import x, y, z, a, b, c, d, e, f
        >>> from sympy import Sum, Product

        >>> Sum(x*y*z, (x, a, b), (y, c, d), (z, e, f)).reorder_limit(0, 2)
        Sum(x*y*z, (z, e, f), (y, c, d), (x, a, b))
        >>> Sum(x**2, (x, a, b), (x, c, d)).reorder_limit(1, 0)
        Sum(x**2, (x, c, d), (x, a, b))

        >>> Product(x*y*z, (x, a, b), (y, c, d), (z, e, f)).reorder_limit(0, 2)
        Product(x*y*z, (z, e, f), (y, c, d), (x, a, b))

        See Also
        ========

        index, reorder, reverse_order
        c         S  s   h  |  ] } | d  ’ q S(   i    (    (   t   .0R   (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pys	   <setcomp>	  s   	 i   i    i   s.   could not interchange the two limits specifiedN(
   R   R'   t   sett   free_symbolst   intersectiont	   enumerateR   t   typeR   R   (	   R   R%   t   yR   t   limit_xt   limit_yR   t   iR   (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyR*   ê   s     ((((N(   R
   R   R   R"   R$   R0   R*   (    (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyR      s   v	%	@N(
   t
   __future__R    R   t   sympy.concrete.expr_with_limitsR   t   sympy.core.singletonR   t   NotImplementedErrorR   R   (    (    (    sA   lib/python2.7/site-packages/sympy/concrete/expr_with_intlimits.pyt   <module>   s   