
Xc           @` s  d  d l  m Z m Z m Z d  d l Z d  d l m Z d  d l Z d  d l m Z m	 Z	 d  d l
 m Z d  d l Z d  d l m Z d  d l 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 d  d l m Z d  d l m Z d  d l m  Z! d  d l" m# Z# e j$ Z$ g  e j% j& d  d  D] Z' e( e'  ^ qRZ) d   Z* d   Z+ d   Z, d   Z- d e f d     YZ. d f  d     YZ/ e j0 e. e/    d e f d     YZ1 d e f d     YZ2 d e2 f d      YZ3 d! e2 f d"     YZ4 d# e2 f d$     YZ5 d% e5 f d&     YZ6 d' e5 f d(     YZ7 d) e j8 f d*     YZ9 e9 e j: d+ d, Z; d- e5 f d.     YZ< d S(/   i    (   t   absolute_importt   print_functiont   divisionN(   t   copy(   t	   iteritemst   integer_types(   t   xrange(   t   gof(   t   izip(   t   change_flags(   t   Applyt   Opt   OpenMPOp(   t   scalar(   t   get_scalar_type(   t   pprint(   t   DisconnectedType(   t   NullType(   t   elemwise_cgen(   t
   frozendictt   .i   c         C` s   t  d   d  S(   NsK   Circular dependencies prevent using thishere. import tensor before elemwise(   t	   Exception(   t   data(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   as_tensor_variable   s    c          O` s   t  d   d  S(   NsL   Circular dependencies prevent using this here. import tensor before elemwise(   R   (   t   inputst   kwargs(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt
   TensorType#   s    c          O` s   t  d   d  S(   NsL   Circular dependencies prevent using this here. import tensor before elemwise(   R   (   R   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   TensorVariable(   s    c          O` s   t  d   d  S(   NsL   Circular dependencies prevent using this here. import tensor before elemwise(   R   (   R   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   TensorConstant-   s    t
   DimShufflec           B` st   e  Z d  Z e Z e Z d Z e d  Z d   Z	 d   Z
 d   Z d   Z d	   Z d
   Z d   Z d   Z RS(   sR  
    Allows to reorder the dimensions of a tensor or insert or remove
    broadcastable dimensions.

    In the following examples, 'x' means that we insert a broadcastable
    dimension and a numerical index represents the dimension of the same
    rank in the tensor passed to perform.

    Parameters
    ----------
    input_broadcastable
        The expected broadcastable pattern of the input
    new_order
        A list representing the relationship between the input's
        dimensions and the output's dimensions. Each element of the
        list can either be an index or 'x'. Indices must be encoded
        as python integers, not theano symbolic integers.
    inplace : bool, optional
        If True (default), the output will be a view of the input.

    Note
    ----
    If `j = new_order[i]` is an index, the output's ith dimension
    will be the input's jth dimension.
    If `new_order[i]` is `x`, the output's ith dimension will
    be 1 and Broadcast operations will be allowed to do broadcasting
    over that dimension.

    If `input.broadcastable[i] == False` then `i` must be found in new_order.
    Broadcastable dimensions, on the other hand, can be discarded.

    Note
    ----
    .. code-block:: python

        DimShuffle((False, False, False), ['x', 2, 'x', 0, 1])

    This op will only work on 3d tensors with no broadcastable
    dimensions.  The first dimension will be broadcastable,
    then we will have the third dimension of the input tensor as
    the second of the resulting tensor, etc. If the tensor has
    shape (20, 30, 40), the resulting tensor will have dimensions
    (1, 40, 1, 20, 30). (AxBxC tensor is mapped to 1xCx1xAxB tensor)

    .. code-block:: python

        DimShuffle((True, False), [1])

    This op will only work on 2d tensors with the first dimension
    broadcastable.
    The second dimension of the input tensor will be the first dimension of
    the resulting tensor.
    If the tensor has shape (1, 20), the resulting tensor will have shape
    (20, ).

    Example
    -------
    .. code-block:: python

        DimShuffle((), ['x'])  # make a 0d (scalar) into a 1d vector
        DimShuffle((False, False), [0, 1])  # identity
        DimShuffle((False, False), [1, 0])  # inverts the 1st and 2nd dimensions
        DimShuffle((False,), ['x', 0])  # make a row out of a 1d vector
                                        # (N to 1xN)
        DimShuffle((False,), [0, 'x'])  # make a column out of a 1d vector
                                        # (N to Nx1)
        DimShuffle((False, False, False), [2, 0, 1])  # AxBxC to CxAxB
        DimShuffle((False, False), [0, 'x', 1])  # AxB to Ax1xB
        DimShuffle((False, False), [1, 'x', 0])  # AxB to Bx1xA

    The reordering of the dimensions can be done with the numpy.transpose
    function.
    Adding, subtracting dimensions can be done with reshape.

    t   input_broadcastablet	   new_ordert   inplacec         C` s  t  |  } | |  _ t  |  } | |  _ | t k rB | |  _ n t d   x t |  D] \ } } | d k r[ t | t t	 j
 f  s t d t |  t t |     n  | t |  k r t d | | t |  f   n  | | | d k rt d |   qq[ q[ Wg  |  _ x] t |  D]O \ } } | | k r)| d k r`|  j j |  qxt d | | f   q)q)Wg  | D] } | d k r| ^ q|  _ g  t |  D] \ } } | d k r| ^ q|  _ |  j ri d g d 6|  _ n  d  S(	   NsR   DimShuffle is inplace by default and hence the inplace for DimShuffle must be truet   xs?   DimShuffle indices must be python ints. Got: '%s' of type '%s'.s4   new_order[%d] is %d, but the input only has %d axes.i   sN   The same input dimension may not appear twice in the list of output dimensionss.   You cannot drop a non-broadcastable dimension.i    (   t   tupleR   R   t   TrueR    t
   ValueErrort	   enumeratet
   isinstanceR   t   numpyt   integert	   TypeErrort   strt   typet   lent   dropt   appendt   shufflet   augmentt   view_map(   t   selfR   R   R    t   it   jt   bR!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   __init__   s>    		!	(4	c   	      C` s9  t  |  } t | j j  } | |  j k s t |  t |  j  k rd t d |  j | f   n  xW t |  j |  D]@ \ } } | t k rw | t	 k rw t d |  j | f   qw qw Wn  g  } x> |  j
 D]3 } | d k r | j t  q | j | |  q Wt d | j j d |    } t |  | g | g  S(   NsT   The number of dimensions of the input is incorrect for this op. Expected %s, got %s.sU   The broadcastable pattern of the input is incorrect for this op. Expected %s, got %s.R!   t   dtypet   broadcastable(   R   R"   R+   R8   R   R,   R)   t   zipR#   t   FalseR   R.   R   R7   R
   (	   R2   t   _inputt   inputt   ibt   expectedR5   t   obt   valuet   output(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt	   make_node   s(    c         C` sI   |  j  r' d d j d   |  j D  Sd d j d   |  j D  Sd  S(   Ns   InplaceDimShuffle{%s}t   ,c         s` s   |  ] } t  |  Vq d  S(   N(   R*   (   t   .0R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>   s   s   DimShuffle{%s}c         s` s   |  ] } t  |  Vq d  S(   N(   R*   (   RD   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>   s    (   R    t   joinR   (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   __str__   s    	c   	      C` s   | \ } | \ } | } t  |  t j k rQ t  |  t j k rQ t |   n  | j |  j |  j  } t | j	 t
 |  j    } x! |  j D] } | j | d  q W| j |  } |  j s t j |  } n  t j |  | d <d  S(   Ni   i    (   R+   R'   t   ndarrayt   memmapR)   t	   transposeR/   R-   t   listt   shapeR,   R0   t   insertt   reshapeR    R   t   asarray(	   R2   t   nodet   inpt   outR<   t   storaget   resRK   t   augm(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   perform   s    		*	c         C` sT   | \ } g  |  j  D] } | | ^ q } x! |  j D] } | j | d  q3 W| g S(   Ni   (   R/   R0   RL   (   R2   RO   t   shapest   ishpR3   t   rvalRT   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   infer_shape   s
    	 c         C` s)   d  | k r d  g S|  | t d t    S(   Nt   return_list(   t   Nonet   dictR#   (   R2   R   t   eval_points(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   R_op  s    c         C` s_  | \ } | \ } | d } d   }	 t  |  j  }
 t  |  j  } d t |
  d g } d g } |  j r{ d d g } n	 d g } d	 | g } xp t |  j  D]_ \ } } | d
 k r | d t |  d t |  d g 7} q | d t |  d g 7} q Wd | g } x~ t |  j  D]m \ } } | d
 k rs| d t |  d t |  d t |  d g 7} q!| d t |  d g 7} q!W| d k r| j d t |  d t |  d  n  x> t | d d d  D]& } | j d t d t |    qWd t |  d d d d g } |	 | | | | | |  } | t t	   |  S(    Nt   __view_or_copyc         S` s   d j  |   d S(   Ns   ;
t   ;(   RE   (   t   lst(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt
   statements  s    s   if (PyArray_NDIM(%(input)s) != sD   ){PyErr_SetString(PyExc_NotImplementedError, "input nd"); %(fail)s;}s#   if (%(res)s) {Py_XDECREF(%(res)s);}s*   { PyArrayObject * %(basename)s = %(input)ss"   Py_INCREF((PyObject*)%(basename)s)s   { PyArrayObject * %(basename)s = (PyArrayObject*)PyArray_FromAny((PyObject*)%(input)s, NULL, 0, 0, NPY_ARRAY_ALIGNED|NPY_ARRAY_ENSURECOPY, NULL)s   npy_intp dimensions[%i]R!   s   dimensions[s   ] = PyArray_DIMS(%(basename)s)[t   ]s   ] = 1s   npy_intp strides[%i]s   strides[s*   ] == 1? 0 : PyArray_STRIDES(%(basename)s)[s   ] = 0i    s   if (strides[s   -1] == 0) strides[s)   -1] = PyArray_DESCR(%(basename)s)->elsizei   isP   if (strides[%(i)s] == 0) strides[%(i)s] = strides[%(i)s+1] * dimensions[%(i)s+1]R3   s5   %(res)s = (PyArrayObject*)PyArray_New(&PyArray_Type, s   , dimensions, PyArray_TYPE(%(basename)s), strides, PyArray_DATA(%(basename)s), PyArray_ITEMSIZE(%(basename)s), (NPY_ARRAY_WRITEABLE*PyArray_ISWRITEABLE(%(basename)s)), NULL)s   if (%(res)s == NULL) %(fail)s;s2   PyArray_UpdateFlags(%(res)s, NPY_ARRAY_UPDATE_ALL)s;   
PyArray_SetBaseObject(%(res)s, (PyObject*)%(basename)s);
}(
   R,   R   R   R*   R    R%   R.   R   R\   t   locals(   R2   RO   t   nameRP   RQ   t   subR<   RS   t   basenameRb   t   nd_int   nd_outt   check_input_ndt   clear_outputt   get_baset   shape_statementsR3   t   ot   strides_statementst   close_brackett	   full_code(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   c_code  sP    		
				)7	
c         C` s   d S(   Ni   (   i   (    (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   c_code_cache_versionv  s    c         C` s   | \ } | \ } t  |  } d g t | j j  } x6 t |  j  D]% \ } } | d k rG | | | <qG qG W| d j t j j	 k r | d j
 d t j j  g St | j j |  t t j  |   g Sd  S(   NR!   i    R7   (   R   R,   R+   R8   R%   R   R7   t   theanot   tensort   discrete_dtypest
   zeros_liket   configt   floatXR   t   ElemwiseR   t   identity(   R2   RP   t   gradsR!   t   gzt
   grad_orderR3   t   v(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   grady  s    		(   s   input_broadcastables	   new_orders   inplace(   t   __name__t
   __module__t   __doc__R#   t   _f16_okR:   t   check_inputt	   __props__R6   RB   RF   RU   RY   R^   Rr   Rs   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   6   s   K6				
		n	t   DimShufflePrinterc           B` s   e  Z d    Z d   Z RS(   c         C` s   | d k r7 | d d k r7 d |  j  | d | |  St |  t t | j j   k rk | j j |  St |  t t t | j j    k r d | j j |  Sd d j t	 t
 |   | j j |  f S(	   Ni    R!   s   %si   s   %s.Ts   DimShuffle{%s}(%s)s   , (    (   t   _DimShufflePrinter__pRJ   t   rangeR+   t   ndimt   pprintert   processt   reversedRE   t   mapR*   (   R2   R   t   pstatet   r(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   __p  s    $*c         C` so   | j  d  k r t d   nM t | j  j t  r_ | j  j j } |  j | | | j  j d  St d   d  S(   Ns   Can only print DimShuffle.i    (	   t   ownerR[   R)   R&   t   opR   R   R   R   (   R2   R   R   t   ord(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    (   R   R   R   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s   	Rz   c           B` s   e  Z d  Z d d f Z e e e e d  Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z RS(   s@  
    Generalizes a scalar op to tensors.

    All the inputs must have the same number of dimensions. When the
    Op is performed, for each dimension, each input's size for that
    dimension must be the same. As a special case, it can also be 1
    but only if the input's broadcastable flag is True for that
    dimension. In that case, the tensor is (virtually) replicated
    along that dimension to match the size of the others.

    The dtypes of the outputs mirror those of the scalar Op that is
    being generalized to tensors. In particular, if the calculations
    for an output are done inplace on an input, the output type must
    be the same as the corresponding input type (see the doc of
    scalar.ScalarOp to get help about controlling the output type)

    Parameters
    ----------
    scalar_op
        An instance of a subclass of scalar.ScalarOp which works uniquely
        on scalars.
    inplace_pattern
        A dictionary that maps the index of an output to the
        index of an input so the output is calculated inplace using
        the input's storage. (Just like destroymap, but without the lists.)
    nfunc_spec
        Either None or a tuple of three elements,
        (nfunc_name, nin, nout) such that getattr(numpy, nfunc_name)
        implements this operation, takes nin inputs and nout outputs.
        Note that nin cannot always be inferred from the scalar op's
        own nin field because that value is sometimes 0 (meaning a
        variable number of inputs), whereas the numpy function may
        not have varargs.

    Note
    ----
    | Elemwise(add) represents + on tensors (x + y)
    | Elemwise(add, {0 : 0}) represents the += operation (x += y)
    | Elemwise(add, {0 : 1}) represents += on the second argument (y += x)
    | Elemwise(mul)(rand(10, 5), rand(1, 5)) the second input is completed along the first dimension to match the first input
    | Elemwise(true_div)(rand(10, 5), rand(10, 1)) same but along the second dimension
    | Elemwise(int_div)(rand(1, 5), rand(10, 1)) the output has size (10, 5)
    | Elemwise(log)(rand(3, 4, 5))

    t	   scalar_opt   inplace_patternc         C` s   | d  k r t i   } n  | |  _ | |  _ t |  |  _ t d   |  j j   D  |  _ d  |  _ d  |  _	 | d  k r t
 | d d   } n  | |  _ | r t
 t | d  |  _	 n  t t |   j d |  d  S(   Nc         s` s$   |  ] \ } } | | g f Vq d  S(   N(    (   RD   Rn   R3   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    t
   nfunc_speci    t   openmp(   R[   R   Re   R   R   R\   t   itemst   destroy_mapt   ufunct   nfunct   getattrR   R'   t   superRz   R6   (   R2   R   R   Re   R   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6     s    		"			c         C` s=   t  |  j  } | j d  | j d  | j d d   | S(   NR   R   t   __epydoc_asRoutine(   R   t   __dict__t   popR[   (   R2   t   d(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   __getstate__  s
    c         C` s   t  t |   j |  d  |  _ d  |  _ t |  j  |  _ t |  d d   rh t t	 |  j
 d  |  _ nO d |  j j k  o d k  n r t	 j |  j j |  j j |  j j  |  _ n  d  S(   NR   i    i    (   R   Rz   t   __setstate__R[   R   R   R   R   R   R'   R   R   t   nint
   frompyfunct   implt   nout(   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    		"	c         ` sK  |  j  j g    D]! } t d | j j  j   ^ q   } t g    D] } | j j ^ qD  } g  } xs   D]k } | j j } | | }	 |	 s | j |  ql | j | | j j	 d g |	 t
 t |    |   ql W|   g  t g    D] } | j j	 ^ q   D] }
 t |
  ^ qg | j } |  j } | rxg t |  D]V \ } } xG t | |   | j j	  D]( \ } } | ro| rot d   qoqoWqEWn  g  | j D] } | j j ^ q t    f d   | j   D  r t d g    D] } | j j ^ q | f f   n  t   t |  k s>t   |   f S(   s`   Return the outputs dtype and broadcastable pattern and the
        dimshuffled niputs.

        R7   R!   sI   Operation cannot be done inplace on an input with broadcasted dimensions.c         3` s/   |  ]% \ } }   | j  j  | k Vq d  S(   N(   R+   R7   (   RD   Rn   R3   (   R   t
   out_dtypes(    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>2  s   s:   Cannot do an inplace operation on incompatible data types.(   R   RB   R   R+   R7   t   make_variablet   maxR   R.   R8   RJ   R   R   t   allR   R   R   R$   t   outputst   anyR   R)   R,   t   AssertionError(   R2   t   dim_shuffleR   R3   t   shadowR<   t   target_lengtht   argst   lengtht
   differencet   bcastt   out_broadcastablesR   t
   overwritert   overwrittenR?   R=   Rn   (    (   R   R   s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   get_output_info  sB    	.%
		+
?	"1c         G` sz   t  t t |   } |  j t |  \ } } } g  t | |  D]$ \ } } t d | d |    ^ q@ } t |  | |  S(   s   
        If the inputs have different number of dimensions, their shape
        is left-completed to the greatest number of dimensions with 1s
        using DimShuffle.
        R7   R8   (   RJ   R   R   R   R   R   R   R
   (   R2   R   R   R   R7   R8   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRB   :  s    1c         C` sg   |  j  d  k r\ |  j rN t |  j j    } | j   d |  j t |  f Sd |  j Sn |  j  Sd  S(   Ns   Elemwise{%s}%ss   Elemwise{%s}(   Re   R[   R   RJ   R   t   sortR   R*   (   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF   H  s    	
c         C` s<  |  | t  d t    } g  | D] } d  ^ q } xt |  D] \ } } g  | D] } | j   ^ qQ } t j j |  | | <|  j | |  }	 d  }
 x t t	 | |   D]y \ } \ } } |	 | d  k s&t
 |	 | j t  r q | d  k	 r |
 d  k r|	 | | }
 q&|
 |	 | | }
 q q W|
 | | <q> W| S(   NRZ   (   R\   R#   R[   R%   Rw   Rt   Ru   t	   ones_liket   _bgradR   R&   R+   R   (   R2   R   R]   t   outsR!   RX   t   idxRQ   t   ogradst   bgradst   rop_outt   jdxRP   t
   eval_point(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR^   S  s$    c         C` sR   t  |  j d  r" |  j j |  Sg  | j D]" } g  | j D] } t ^ q< ^ q, S(   Nt   connection_pattern(   t   hasattrR   R   R   R   R#   (   R2   RO   t   iptRA   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   u  s    c         C` s  |  j  | |  } t d   | D  r g  } x t | |  D] \ } } t | j t t f  rr | j |  q> | j   } t	 | j j
  t j j k r | j t j j  } n  t	 | j j
  t j j k s t  | j |  q> W| Sx t |  D] \ } } t | | j t t f  r(q n  g  t | j j  D]* \ }	 }
 |
 r;| d j |	 r;|	 ^ q;} | r t j j j | | d | d t } | | | <q q W| S(   Nc         s` s'   |  ] } | j  j t j j k Vq d  S(   N(   R+   R7   Rt   Ru   t   continuous_dtypes(   RD   RQ   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s   i    t   axist   keepdims(   R   R   R   R&   R+   R   R   R.   Rw   R*   R7   Rt   Ru   R   t   astypeRx   Ry   Rv   R   R%   R8   t   basict   sumR#   (   R2   R   R   R   RX   t   new_rvalt   elemR   R3   R4   R   t   to_sumt   sr(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   L_op|  s.    	
$$c   	      ` s]  t  d d  y d   } t t |      t t |     |  j j    } x) | D]! } | d  k	 s_ t |  j   q_ WWd  QXt | t t f  s t	 d t
 |  j  t
 t |   f   n  t   d j j          f d    g  } xO t |    D]> \ } } | d  k rB| j d   qn  | j  |   qW| S(   Nt   compute_test_valuet   offc         S` s/   t  |  j t t f  r |  St |  j j    S(   N(   R&   R+   R   R   R   R7   (   t   t(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt	   as_scalar  s    s,   %s.grad returned %s instead of list or tuplei    c         ` s   t  |  j t t f  r |  S|   k r9    j |   S|   k rV   j |   S|  j } | d  k r t j j	 t
 j |  j  d |  j j } t d d g   |  St | j i   g  | j D] }  |  ^ q   } | S(   NR7   R!   (    (   R&   R+   R   R   t   indexR   R[   Rt   Ru   t   constantR'   RN   R   R7   R   Rz   R   R   (   R   RO   RS   R   t   new_r(   R   t   ndR   t   scalar_inputst   scalar_ogradst	   transform(    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    	%(   R	   RJ   R   R   R   R[   R   R&   R"   R)   R*   R+   R,   R8   R   R.   (	   R2   R   R   R   t   scalar_igradst   igradt   rett   scalar_igradR   (    (   R   R   R   R   R   R   s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s&    	%(c         C` s  t  | j  d k  r |  j d  k s? |  j j t  | j  k r |  j d  k r | d k r t j |  j j	 t  | j  |  j j
  } |  j j d k r | |  _ q | | j _ n  | j d j } | t j j k r>t |  j t j  r>| j d j t j j k r>t j |  } | | j d | | j
 } | | j _ n  t |  j g  | j D]! }	 t d |	 j j  j   ^ qQg  | j D]! }
 t d |
 j j  j   ^ q | j _ |  j j | j j d  d  |  d  S(   Ni    t   pyi    s   ->R7   (   R,   R   R   R[   R   R   R   R'   R   R   R   t   tagR   R7   Rt   Ru   t   float_dtypesR&   Rv   t   sctype2chart   sigR
   R   R+   R   t	   fake_nodet   prepare_node(   R2   RO   t   storage_mapt   compute_mapR   R   t	   out_dtypet   charR   R<   RA   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s2    +7c         C` s  t  | j  d k r4 t t |   j | | |  n  xt g  t | | j  D]* \ } } t t | j | j	 j
   ^ qM   D]9} t d   | D  d k r~ d t f | k r~ g  } t  |  t  | j  k s t  x t | | j  D] \ } } t  | j  t  | j	 j
  k st  g  } xO t | j | j	 j
  D]5 \ }	 }
 |
 r`| d g 7} q>| t |	  g 7} q>W| j d d j |   q Wd d j |  } t |   q~ q~ Wg  } x{ t g  | D] } | j ^ q  D]W } t d   | D  r(t |  d k st  | j d	  q| j t |   qWt |  } | } i  } |  j rt  |  |  j d k r|  j } |  j d
 } t | j d  r-| j j | d <q-nv |  j r|  j } nX t | j d  s|  j | d  d  d  |  j r	|  j } q$| j j } n | j j } | j } | | |   } | d k rT| g } n  d	 } xCt | | | j  D],\ } } } t | d d  d k rt j  | d | j! } n  | |  j" k r| |  j" | } | | d <| | d	 <n t# | t j$  s| j! | j! k rit j  | | j!  } t j! | j!  j% | j! j% k r\| j& d | j!  } n  | | d	 <n) | j' j( s| j)   | d	 <n
 | | d	 <| d 7} qpWd  S(   Ni    c         s` s   |  ] \ } } | Vq d  S(   N(    (   RD   R   R5   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    i   t   *s   (%s)s   , s!   Dimension mismatch; shapes are %sc         s` s   |  ] } | d  k Vq d S(   i    N(    (   RD   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>1  s    i    i   R   R   R   R7   t    t   object.(*   R,   R   R   Rz   RU   R   R9   RJ   RK   R+   R8   R   R:   R   R*   R.   RE   R$   R   R"   R   R   R   R   R   R   R   R[   R   R   R   R'   RN   R7   R   R&   RG   t   numt   viewt   flagst   owndataR   (   R2   RO   R   t   output_storageR<   t   sinputt   dimst   msgt   msg2R   R5   t   base_exc_strt	   out_shapet   valuest
   ufunc_argst   ufunc_kwargsR   R   t	   variablesR3   t   variableRR   t   odat(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRU     s~    	G.!'%)"					
!
c         C` s   g  } x | j  D] } g  } x t | j j  D] \ } } d  } | rP d } nl xi t | | j  D]U \ }	 }
 t |
 j t j	 j
  r qc n  |
 j j | sc |	 | r |	 | } Pq qc qc W| j |  q/ W| j t |   q W| S(   Ni   (   R   R%   R+   R8   R[   R   R   R&   Rt   R   t   ScalarR.   R"   (   R2   RO   t   i_shapesRX   Rn   t   oshpt   dimR5   t   b_dimRW   R3   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRY     s"    	

c   =      C` s
  t  | j d  s+ |  j | d  d  d  n  | } | } t j j |  } t j j | j  } t |  t |  k s| t	  t
 t t j j t
 t | | j       \ }	 }
 t g  t |	 |  D] \ } } | | k ^ q  s t	  t g  t |
 |  D] \ } } | | k ^ q  s&t	  d } d } t g  t |  j  D]) \ } } | j | | j | g f ^ qE } g  | D] } | j j   d ^ q~} t
 t g  t | j |  D]4 \ } } | | k r| | | j j   d f ^ q   } | r| \ } } } n g  g  g  } } } t
 t g  t | j |  D]$ \ } } | | k r;| | f ^ q;   } | r| \ } } n g  g  } } g  | D]= } g  t | j j  D] \ } } | rd p| ^ q^ q} t | d  } t |  } x7 t t | |   D]  \ } \ } } | | d | <q	Wt j | | |  }  t j | | |  }! t
 t | |   }" d j g  |" D]% \ }# }$ t |$ j  syd	 |# ^ qy }% t |%  d k rd
 }% n  d }& x t | | |  D] \ }' }( }) | d 7} |( | d | <|( | d <|& t j t
 t |   g |) g t | d |(  7}& |& t j | |) | d |% 7}& |& t j t
 t |   g |) g t | d |(  7}& qW| }* xq t | |  D]` \ }' }( | j | |' d  }* | |* } |& d t   7}& | d t   7} | d t   7} qW|  j j | j j  | d g  | D] } d | ^ q7g  | D] } d | ^ qQ|  }+ d t   }, | t
 t |   g t |  }- | t
 |  }. t g  | j D] } | j! d k ^ qpt | j d j   r| rd) g | d d |, f g d g }/ n	 |, g }/ t |/  d k r`d j g  t | t
 |  | t
 |   D] \ }0 }1 d |1 |0 |0 f ^ qa }2 i  }3 x t t |- |.   D] \ } \ }4 }1 x t |4  D]G \ }5 }6 |6 d k r|3 j" |5 d  |3 |5 c d t   | 7<PqqW|3 j" d d  |3 d c d t   | 7<qW|3 j# d d  }7 d t   }8 qt j$ d |- d |. d |/ d | d |  j%  }8 n3 t j& d |- d |* d |. d |, d | d |  j%  }8 t g  | j D] } | j! d k ^ q r
t | j d j  r
d  }9 y& |  j j' | | d  | | |  }9 Wn#t( j j j) k
 rV	t g  | j | j D]. }: |: j | j d j k pt |: j  ^ q^ rW	| d }" d! t   }9 d }6 xm t | | | | j  D]Q \ } }$ t |$ j  s	|9 d" t   7}9 |6 d# t   7}6 q|9 d$ t   7}9 qW|  j% r?	|9 d% t* j+ 7}9 n  |9 d& t   7}9 qW	n X|9 d  k	 r
t
 t | | | | j   }" d j g  |" D]% \ }# }$ t |$ j  s	d' |# ^ q	 }; d j g  |" D]% \ }# }$ t |$ j  s	d	 |# ^ q	 }< d( t   }8 q
n  |  |! |& |8 f S(*   NR   t   cR   i   R!   i    s   lv%is    && s   PyArray_ISFORTRAN(%s)t   0t   olvt   lv0t   fortrans   
            if (%(oname)s) {
                Py_XDECREF(%(oname)s);
            }
            %(oname)s = %(iname)s;
            Py_XINCREF(%(oname)s);
            s    #define %(oname)s_i %(iname)s_i
s   #undef %(oname)s_i
t   _scalar_s   %s_isf   
        {
            %(defines)s
            %(task_code)s
            %(undefs)s
        }
        s   %s& %s_i = *%s_iter;
s>   %%(lv%(i)s)s_iter = (%(dtype)s*)(PyArray_DATA(%%(lv%(i)s)s));
t    s   
                {
                  %(defines)s
                  %(init_array)s
                  %(task_decl)s
                  %(task_code)s
                  %(undefs)s
                }
                t   loop_orderst   dtypest
   loop_tasksRf   R   t   init_loop_orderst	   olv_indext
   inner_taskt   _scalar_contig_s   
                    // All output have the same size
                    npy_intp n = PyArray_SIZE(%(z)s);
                    sg   
            dtype_%(x)s * %(x)s_ptr = (dtype_%(x)s*) PyArray_DATA(%(x)s);
                            sN   
            dtype_%(x)s& %(x)s_i = %(x)s_ptr[i];
                            si   
            dtype_%(x)s& %(x)s_i = ((dtype_%(x)s*) PyArray_DATA(%(x)s))[0];
                            s;   #pragma omp parallel for if(n>=%d)
                        s   
                    for(int i=0; i<n; i++){
                        %(index)s
                        %(task_code)s;
                    }
                    s   PyArray_ISCONTIGUOUS(%s)s   
            if((%(cond1)s) || (%(cond2)s)){
                %(contig)s
            }else{
                %(loop)s
            }
            (   R   R   (,   R   R   R   R[   R   t   utilst   uniqR   R,   R   RJ   R9   R   R\   R   R   R   R+   t   dtype_specsR   R%   R8   t   cgent   make_declaret   make_checksRE   R   t
   make_allocR   Rd   R   Rr   R   R   t
   setdefaultt   gett	   make_loopR   t   make_reordered_loopt   c_code_contiguousRt   t   MethodNotDefinedRx   t   openmp_elemwise_minsize(=   R2   RO   t   nodenamet   inamest   onamesRf   t   _inamest   _onamesR   t   iit   iiiR!   t   yt   definest   undefsRn   R3   t   dmapR<   t   idtypesR   t   st   realt   real_outputst   real_onamest   real_odtypest   aliasedt   aliased_outputst   aliased_onamest   orderst   nnestedt   inamet   declt   checkst   zt   arrt   vart   alloc_fortrant   allocRA   t   onamet   odtypeR  t	   task_codet   codeR  R  t   all_codeRe   R7   t	   task_declt   preloopst
   loop_orderR4   R   t
   init_arrayt   loopt   contigt   iot   cond1t   cond2(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   _c_all  s"   6::?&	4	$G(	"	

!
!
			#((	9			+	E
	 	"	"c         C` s   t  d   | j D  sG t  d   | j D  sG t |  j d t  rl t t |   j | | | | |  n  d j	 |  j
 | | | | |   } | S(   Nc         s` s   |  ] } | j  d  k Vq d S(   t   float16N(   R7   (   RD   R3   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    c         s` s   |  ] } | j  d  k Vq d S(   RO  N(   R7   (   RD   Rn   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    t   inner_float16s   
(   R   R   R   R   R   R:   R   Rz   Rr   RE   RN  (   R2   RO   R"  R#  R$  Rf   RC  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRr     s    %$c         C` s
   d d g S(   Ns   <vector>s   <algorithm>(    (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt	   c_headers  s    c         C` s   |  j  j   S(   N(   R   t   c_support_code(   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRR    s    c         C` s   |  j  j | | d  } | S(   NR  (   R   t   c_support_code_apply(   R2   RO   R"  t   support_code(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRS    s    
c         C` s   d g } t  |  j g  | j D]! } t d | j j  j   ^ q g  | j D]! } t d | j j  j   ^ qJ  } | j |  j j	 |   x: | j | j D]( } | j t d | j j  j
    q W| j d |  j f  t |  r t |  Sd Sd  S(   Ni   R7   R   (    (   R
   R   R   R   R+   R7   R   R   R.   t   c_code_cache_version_applyRs   R   R   R"   (   R2   RO   t   versionR<   RA   t   scalar_nodeR3   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRU    s    	+1 
c         C` s)   | j  d j d k o( t | j  d k  S(   ss   
        Return True if we do not want to compile c code
        when doing constant folding of this node.
        i    i    (   R   R   R,   R   (   R2   RO   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   python_constant_folding  s    (   R   R   R   R   R[   R6   R   R   R   RB   RF   R^   R   R   R   R   RU   RY   RN  Rr   RQ  RR  RS  RU  RX  (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRz     s0   /			9			"		3	3	.	o	!	 	
				t   CAReducec           B` s   e  Z d  Z d Z d d  Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z RS(   sQ  
    CAReduce = Commutative Associative Reduce
    Reduces a scalar operation along the specified axis(es).
    (The scalar op should be both commutative and assocative)

    The output will have the same shape as the input minus the reduced
    dimensions. It will contain the variable of accumulating all values
    over the reduced dimensions using the specified scalar op.

    Parameters
    ----------
    scalar_op
        A binary scalar op with only one output.
        It must be commutative and associative.
    axis
        - The dimension along which we want to reduce
        - List of dimensions that we want to reduce
        - If None, all dimensions are reduced

    Note
    ----
    .. code-block:: python

        CAReduce(add)      # sum (ie, acts like the numpy sum operation)
        CAReduce(mul)      # product
        CAReduce(maximum)  # max
        CAReduce(minimum)  # min
        CAReduce(or_)      # any # not lazy
        CAReduce(and_)     # all # not lazy
        CAReduce(xor)      # a bit at 1 tell that there was an odd number of
                           # bit at that position that where 1. 0 it was an
                           # even number ...

    In order to (eventually) optimize memory usage patterns,
    CAReduce makes zero guarantees on the order in which it
    iterates over the dimensions and the elements of the
    array(s). Therefore, to ensure consistent variables, the scalar
    operation represented by the reduction must be both commutative
    and associative (eg add, multiply, maximum, binary or/and/xor - but not
    subtract, divide or power).

    R   R   c         C` s   | j  d k s | j d k r- t d   n  | |  _ | d  k rN | |  _ n t | t t j	 f  ru | f |  _ nt t | t j
  r | j d k r t |  f |  _ n> t t d   | D   |  _ |  j j   t |  j  |  _ |  j |  d  S(   Nii   i   s=   CAReduce only supports binary functions with a single output.i    c         s` s   |  ] } t  |  Vq d  S(   N(   t   int(   RD   t   a(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    (   ii   (   R   R   t   NotImplementedErrorR   R[   R   R&   R   R'   R(   RG   R   RZ  RJ   t   setR   R"   t	   set_ufunc(   R2   R   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6     s    	!c         C` sB  t  | t j j j  r' t j |  _ nt  | t j j j  rN t j	 |  _ n t  | t j j j
  ru t j |  _ n t  | t j j j  r t j |  _ n t  | t j j j  r t d d g k r t j |  _ ni t  | t j j j  r t j |  _ nB t  | t j j j  r#t j |  _ n t j | j d d  |  _ d  S(   Ni   i   i   (   R&   Rt   R   R   t   AddR'   t   addR   t   Mult   multiplyt   Maximumt   maximumt   Minimumt   minimumt   ANDt
   _numpy_vert   bitwise_andt   ORt
   bitwise_ort   XORt   bitwise_xorR   R   (   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR^    s     c         C` s   | S(   N(    (   R2   t   input_dtype(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   _output_dtype7  s    c   
      C` s  t  |  } |  j d  k	 r xc |  j D]U } | | j j k sa | d k  r% t |  | j j k r% t d | | f   q% q% Wn  t  |  } |  j } | d  k r t t t	 | j j
    } n  t d   | D  rxg  } xD |  j D]9 } | d k  r| j | | j j  q | j |  q Wt	 |  t	 |  k sDt  t |  } t |   } | j | j  | | _ n |  } g  t | j j
  D] \ } } | | k r| ^ q} t d |  j | j j  d |    }	 t | | g |	 g  S(   Ni    s0   Not enough dimensions on %s to reduce on axis %sc         s` s   |  ] } | d  k  Vq d S(   i    N(    (   RD   R[  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>H  s    R7   R8   (   R   R   R[   R+   R   t   absR$   RJ   R   R,   R8   R   R.   R   R"   R   R^  R   R%   R   Ro  R7   R
   (
   R2   R<   R   t   axis2R[  R   R3   R!   R8   RA   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRB   :  s:    $	!c         C` s#   t  |  j  } | j d d   | S(   NR   (   R   R   R   R[   (   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   ^  s    c         C` s$   |  j  j |  |  j |  j  d  S(   N(   R   t   updateR^  R   (   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   c  s    c         C` sE   |  j  d  k	 r6 d |  j d j d   |  j  D  f Sd |  j Sd  S(   Ns   Reduce{%s}{%s}s   , c         s` s   |  ] } t  |  Vq d  S(   N(   R*   (   RD   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>j  s    s
   Reduce{%s}(   R   R[   R   RE   (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF   g  s    $c         C` s  | \ } | \ } |  j  } | d  k r? t t | j   } n  | } t t |   } t |  d  r |  j d  k	 r |  j }	 n | j	 d j
 j }	 | rx | D] }
 | j |
 d k r2t |  j d  rt | j  } | |
 =t j t |  d |	 } | j |  j j  qMt d | |
 |  j f   q |  j j | |
 d |	 } q Wt j |  } t j | |  r| j   } n  t j | d | j	 d j
 j | d <n, t j | d t d | j	 d j
 j | d <d  S(   Nt	   acc_dtypei    R{   R7   sX   Input (%s) has zero-size on axis %s, but self.scalar_op (%s) has no attribute 'identity'R   (   R   R[   RJ   R   R   R   t   sortedR   Rs  R   R+   R7   RK   R   R'   t   emptyR"   t   fillR{   R$   R   t   reduceRN   t   may_share_memoryR   Rt   t   _asarrayt   arrayR#   (   R2   RO   RP   RQ   R<   RA   R   R   t	   to_reduceRs  t	   dimensiont   v_shape(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRU   n  s>    				c         C` se   | \ } |  j  } | d  k r" d Sg  t | j d j j  D]" \ } } | | k r< | | ^ q< f S(   Ni    (    (   (    (   R   R[   R%   R   R+   R8   (   R2   RO   RV   t   ishapeR   R3   R5   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRY     s    		#c   &   	   C` s)  | j  d } | j d } | d } | d }	 | j j   d }
 | j j   d } t |  d  r |  j d  k	 r |  j d k r t j j	 j
 d   n  t d | j d j d |  j  } | j   d } n | } |  j } | d  k r
t t t | j j    } n  t |  d k rt j j | | j d j  } | | k r_t t j  |  } n  | j | j d j k s~t  | j j j | j | | | |  Sg  t | j j  D] } | | k r| ^ q} | t |  } t |  } t |  } x: t t | j  |   D]  \ } \ } } | | d | <qWd	 } | | k ryd
 } | j  | |  } | | j! | |  7} n |	 } | t" j# | g |
 g |  7} t" j$ | g |
 g |  } d	 } | d 7} |	 | d | <|	 | d <| t" j# t t |   d g t |  g | g t | d |	  7} | t" j% | g | |  7} | t" j$ t t |   d g t |  g | g t | d |	  7} | | k r`| | d | <| | d <| t" j# t t |   d g t |  g | g t | d |  7} | t" j% | g | |  7} | t" j$ t t |   d g t |  g | g t | d |  7} n  t |  j& d  r|  j& j } n|  j& t j' t j( g k r|  j& t j' k rd } | j j d' k rd } q| j j j) d  rd } qd t* | j j  j+   } n  |  j& t j( k r^d } | j j d( k r?d } q^d t* | j j  j+   } n  | d } d g t | j  d j  } |  j } | d  k rt t t |    } n  x | D] } d | | <qWt* |  d d !} | d t,   7} | d t,   7} n t- d   d t d | d | d |  } d  t d |
 d | d  } |  j& j. t/ |  j& g  | j  d! D]! } t0 d | j j  j1   ^ qpg  | j D]! }  t0 d |  j j  j1   ^ q d  d" | d" | d g d" | g |  }! d# t,   }" | j  d j j rt |  d k rBd) g | | |" f d	 g }# qd* g | | d	 f g d+ g t |  d! d	 |" f d	 g }# n | |" g }# t" j2 | t t |   d g t |  g |
 | g |# |  }$ d	 }% | | k rd$ t d% |	 d& |  }% |% | j3 | |  7}% n  | | | |$ |% f S(,   Ni    i   Rs  RO  s   no c_code for float16R8   R7   s   lv%iR   t   accR  R!   R	  R{   Rd  t   float32t   float64s   -__builtin_inf()t   uintR  t   NPY_MIN_Rf  s   __builtin_inf()t   NPY_MAX_t   failis   int tosum[]={%(pattern_)s};s   
for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
  if(PyArray_DIMS(%(iname)s)[i]==0 && tosum[i]){
    PyErr_Format(PyExc_ValueError,
         "Input of CAReduce{%(scal_name)s} has zero-size on axis %%d",i);
    %(fail)s;
  }
}
                   s3   The CAReduce.scalar_op must have an identity field.sB   %(dtype)s& %(name)s_i = *%(name)s_iter;
%(name)s_i = %(identity)s;Re   s(   %(dtype)s& %(name)s_i = *%(name)s_iter;
i   s   %s_isS   
        {
            %(task1_decl)s
            %(task1_code)s
        }
        sA   
            PyArray_CopyInto(%(oname)s, %(aname)s);
            R@  t   aname(   s   float32R  (   s   float32R  (   R   R   (   R   R   (   R   R   (4   R   R   R+   R  R   Rs  R[   Rt   R   R  R   R   R8   R   RJ   R   R,   Ru   t   castR7   Rz   R   R{   R   R   R   RN  R   R   R\   R%   R   t	   c_declaret   c_initR  R  R  R  R   Rd  Rf  t
   startswithR*   t   upperRd   R)   Rr   R
   R   R   t   make_loop_careducet	   c_cleanup(&   R2   RO   Re   R#  R$  Rf   R<   RA   R8  R@  t   idtypeRA  t   acc_typet   adtypeR   R=  R3   t   order1t   orderR7  R9  R  R:  R?  R{   t	   scal_nameR  t   patternt   pattern_t
   task0_declt
   task1_declt   ivt   ovt
   task1_codet   code1RD  RI  t   end(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRN    s    

	!"1+

	#	#
	#	#			
				/.
	 ,&c         C` s(   d j  |  j | | | | |   } | S(   Ns   
(   RE   RN  (   R2   RO   Re   R#  R$  Rf   RC  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRr   Q  s    $c         C` s
   d d g S(   Ns   <vector>s   <algorithm>(    (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRQ  U  s    c         C` s   d g } t  |  j g  | j D]! } t d | j j  j   ^ q g  | j D]! } t d | j j  j   ^ qJ  } | j |  j j	 |   x: | j | j D]( } | j t d | j j  j
    q Wt |  r t |  Sd Sd  S(   Ni   R7   (    (   R
   R   R   R   R+   R7   R   R   R.   RU  Rs   R   R"   (   R2   RO   RV  R<   RA   RW  R3   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRU  Y  s    	+1 
(   s	   scalar_ops   axisN(   R   R   R   R   R[   R6   R^  Ro  RB   R   R   RF   RU   RY   RN  Rr   RQ  RU  (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRY    s   *			$				/					t   Allc           B` sD   e  Z d  Z d Z d d  Z d   Z d   Z d   Z d   Z	 RS(	   s\    Applies `logical and` to all the values of a tensor along the
    specified axis(es).

    R   c         C` s   t  j |  t j |  d  S(   N(   RY  R6   R   t   and_(   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6   u  s    c         C` s   d S(   Nt   bool(    (   R2   R  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRo  x  s    c         C` s4   |  j  d  k r d Sd d j t t |  j    Sd  S(   NR  s   All{%s}s   , (   R   R[   RE   R   R*   (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF   {  s    c         C` sO   t  |  } | j d k r3 t j j | d  } n  t t |   j |  } | S(   NR  i    (   R   R7   Rt   Ru   t   neqR   R  RB   (   R2   R<   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRB     s
    c         C` s   | \ } | j  t j j  g S(   N(   Rw   Rt   Rx   Ry   (   R2   RP   R|   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    	(   s   axisN(
   R   R   R   R   R[   R6   Ro  RF   RB   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR  n  s   			t   Anyc           B` sD   e  Z d  Z d Z d d  Z d   Z d   Z d   Z d   Z	 RS(	   s[    Applies `bitwise or` to all the values of a tensor along the
    specified axis(es).

    R   c         C` s   t  j |  t j |  d  S(   N(   RY  R6   R   t   or_(   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6     s    c         C` s   d S(   NR  (    (   R2   R  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRo    s    c         C` s4   |  j  d  k r d Sd d j t t |  j    Sd  S(   NR  s   Any{%s}s   , (   R   R[   RE   R   R*   (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF     s    c         C` sO   t  |  } | j d k r3 t j j | d  } n  t t |   j |  } | S(   NR  i    (   R   R7   Rt   Ru   R  R   R  RB   (   R2   R<   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRB     s
    c         C` s   | \ } | j  t j j  g S(   N(   Rw   Rt   Rx   Ry   (   R2   RP   R|   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    	(   s   axisN(
   R   R   R   R   R[   R6   Ro  RF   RB   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR    s   			t   CAReduceDtypec           B` sS   e  Z d  Z d Z d d d d  Z d   Z d   Z d   Z d	   Z	 d
   Z
 RS(   sQ  
    Reduces a scalar operation along the specified axis(es).

    This subclass of CAReduce accepts an additional "dtype" parameter,
    that specifies which dtype the output should be.

    It also accepts an optional "acc_dtype", which specify the dtype that
    will be used for the accumulation.

    So, the accumulation will be done into a tensor of dtype "acc_dtype",
    then it will be casted into "dtype" and returned.

    If no dtype is provided, one will be inferred so as not to lose
    too much precision.

    Parameters
    ----------
    scalar_op
        A binary scalar op with only one output.
        It must be commutative and associative.

    axis
        * the dimension along which we want to reduce
        * list of dimensions that we want to reduce
        * if None, all dimensions are reduced

    dtype
        The dtype of the returned tensor. If None, then we use the default
        dtype which is the same as the input tensor's dtype except when:

        * the input dtype is a signed integer of precision < 64 bit, in which
          case we use int64
        * the input dtype is an unsigned integer of precision < 64 bit, in
          which case we use uint64

        This default dtype does _not_ depend on the value of "acc_dtype".
        This behavior is similar in spirit to that of numpy (except numpy
        uses the default machine integer while we always use 64 bit
        integers to avoid platform-dependent behavior).

    acc_dtype
        The dtype of the internal accumulator.
        If None (default), we use the dtype in the list below,
        or the input dtype if its precision is higher:

        * for int dtypes, we use at least int64;
        * for uint dtypes, we use at least uint64;
        * for float dtypes, we use at least float64;
        * for complex dtypes, we use at least complex128.

    R   R   R7   Rs  c         C` s,   t  j |  | d | | |  _ | |  _ d  S(   NR   (   RY  R6   R7   Rs  (   R2   R   R   R7   Rs  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6     s    	c         C` sP   t  t |   j |  t |  d  s1 d |  _ n  t |  d  sL d  |  _ n  d  S(   NR7   t   OLDRs  (   R   R  R   R   R7   R[   Rs  (   R2   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s
    c         C` s   |  j  } | d k rL t d d d d d d d d d d d d	  j | |  S| d  k r t d
 d d d d d d d d d	 d d	 d d	  j | |  S| Sd  S(   NR  t   int8t   int32t   int16t   int64t   uint8t   uint32t   uint16t   uint64R  (   R7   R\   R  R[   (   R2   R  R7   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRo    s&    	c         C` s   |  j  } | d  k rd t d d d d d d d d d d d d d	 d d
 d d d d d  
j | |  S| t j j k r | t j j k r | St j	 | |  } | | k r t
 d |  | | | | f   n  | Sd  S(   NR  R  R  R  R  R  R  R  R  RO  R  R  t	   complex64t
   complex128s  Cannot build %s node with input dtype %s and acc_dtype %s, as precision would be lost. To correct this error, you can:
  - not specify acc_dtype, or
  - use an acc_dtype at least as precise as %s.
  - specify "dtype" instead of "acc_dtype", so the reduction will be precise, but the result will be casted into "dtype" at the end.
If you are expecting the precision loss, you can use tensor.cast(..., dtype="%s"), on your input.(   Rs  R[   R\   R  Rt   Ru   R   Rv   R   t   upcastR)   (   R2   R  Rs  t   upcasted_dtype(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt
   _acc_dtype  s,    	
c         C` s   t  |  } |  j | j  } |  j | j  } | d  k	 sB t  | d  k	 sT t  | |  j k r{ | |  j k r{ |  } n. t |   } | j |  j	  | | _ | | _ | j d  k	 s t  t
 j | |  S(   N(   R   Ro  R7   R  R[   R   Rs  R   R^  R   RY  RB   (   R2   R<   R7   Rs  R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRB   1  s    			c         C` s   |  j  j } |  j  j d k r1 d |  j f } n  d } |  j d  k	 ro d j d   |  j D  } d | } n  d | | t |  j  f S(   NR  s   ReduceDtype{%s}R   s   , c         s` s   |  ] } t  |  Vq d  S(   N(   R*   (   RD   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>L  s    s   axis=[%s], s   %s{%sacc_dtype=%s}(   t	   __class__R   R   R   R[   RE   R*   Rs  (   R2   Re   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF   F  s    (   s	   scalar_ops   axiss   dtypes	   acc_dtypeN(   R   R   R   R   R[   R6   R   Ro  R  RB   RF   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR    s   3			$	t   Sumc           B` sA   e  Z d  Z d Z d	 d	 d	 d  Z d   Z d   Z d   Z RS(
   s
  
    Sums all the values of a tensor along the specified axis(es).

    Equivalent to `CAReduceDtype(scalar.add, axis=axis, dtype=dtype)`,
    with the difference that this defines the gradient of sum wrt its
    tensor input.

    Parameters
    ----------
    axis
        Axis(es) along which the tensor should be summed
        (use None to sum over all axes, and a list or tuple to sum along more
        than one axis).

    dtype
        The dtype of the internal accumulator and returned
        tensor. If None, then we use the default dtype which is the same as the
        input tensor's dtype except when:
        - the input dtype is a signed integer of precision < 64 bit, in
        which case we use int64
        - the input dtype is an unsigned integer of precision < 64 bit, in
        which case we use uint64
        This value does not depend on the value of "acc_dtype".

    acc_dtype
        The dtype of the internal accumulator.
        If None (default), we use the dtype in the list below,
        or the input dtype if its precision is higher:
        - for int dtypes, we use at least int64;
        - for uint dtypes, we use at least uint64;
        - for float dtypes, we use at least float64;
        - for complex dtypes, we use at least complex128.

    R   R7   Rs  c      	   C` s)   t  j |  t j d | d | d | d  S(   NR   R7   Rs  (   R  R6   R   R`  (   R2   R   R7   Rs  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6   {  s    c         C` sd   |  j  j } d } |  j d  k	 rJ d j d   |  j D  } d | } n  d | | t |  j  f S(   NR   s   , c         s` s   |  ] } t  |  Vq d  S(   N(   R*   (   RD   R!   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pys	   <genexpr>  s    s   axis=[%s], s   %s{%sacc_dtype=%s}(   R  R   R   R[   RE   R*   Rs  (   R2   Re   R   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRF     s    c         C` s/  | \ } | d j  t j j k r; | j d t j j  g S| \ } t |  } |  j } | d  k r t
 t | j j   } n  | d k r | f Sg  } d } xS t | j j  D]? \ }	 }
 |	 | k r | j d  q | j |  | d 7} q Wt | j j |  } t t j  | | |   } | g S(   Ni    R7   R!   i   (    (   R7   Rt   Ru   R   Rw   Rx   Ry   R   R   R[   RJ   R   R+   R   R%   R8   R.   R   Rz   R   t   second(   R2   RP   RQ   R|   R!   R}   R   t   new_dimsR3   R4   t   _t   ds_opt   gx(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s(    			c         C` s)   d  | k r d  g S|  | t d t    S(   NRZ   (   R[   R\   R#   (   R2   R   R]   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR^     s    (   s   axiss   dtypes	   acc_dtypeN(	   R   R   R   R   R[   R6   RF   R   R^   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR  U  s   "		t   Prodc           B` sD   e  Z d  Z d Z d	 d	 d	 e d  Z d   Z d   Z d   Z	 RS(
   s   
    Multiplies all the values of a tensor along the specified axis(es).

    Equivalent to `CAReduce(scalar.prod, axis = axis)`, with the
    difference that this defines the gradient of prod wrt its tensor
    input.

    R   R7   Rs  c      	   C` s2   t  j |  t j d | d | d | | |  _ d  S(   NR   R7   Rs  (   R  R6   R   t   mult   no_zeros_in_input(   R2   R   R7   Rs  R  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6     s    c         C` s2   t  t |   j |  d | k r. t |  _ n  d  S(   NR  (   R   R  R   R:   R  (   R2   t   dct(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     s    c         C` s?  | \ } | \ } | d j  t j j k s@ |  j t j j k rY | j d t j j  g St |  } |  j	 } | d k r t t | j j   } n  | d k r | f Sg  } d } xS t | j j  D]? \ }	 }
 |	 | k r | j d  q | j |  | d 7} q W|  |  j |  } | j |  } | | | } |  j rL| g St j } | j | d  } | j | d |  j	 } | j | d  j |  } | | } | j | d  } | | } | | } t d |  j	  |  } | j |  } | j | d  j |  } | j | | | j | | d  |  } | g Sd S(	   sy  
        The grad of this Op could be very easy, if it is was not for the case
        where zeros are present in a given "group" (ie. elements reduced
        together to form the product).

        If no zeros are found in the elements of the product, then the
        partial derivative of the product relative to one of the elements
        (one of the inputs) is simply the product of the other elements.
        That's easy to see from the chain rule.

        Now the trick (with no zeros) is to take the overall product, then
        for every original element, the partial derivative is given by
        this product divided by the element itself (which equals the product
        of the other terms). This is easy to do by broadcasting the original
        product.

        (Note that we also need to broadcast-multiply by the
        "incoming gradient", ie. the gradient of the cost relative to the
        output/product).

        With zeros, things get more complicated. For a given group, we have 3
        cases:

        * No zeros in the group. Use previous trick.
        * If only one zero is present, then the gradient for that element is
            non-zero, but is zero for all others.
        * If more than one zero is present, then all the derivatives are zero.

        For the last two cases (with 1 or more zeros), we can't use the
        division trick, as this gives divisions by 0.

        Implementing that case-by-case logic is not as trivial, so a bunch of
        hacks are piled down here to do it. Notably, for the "only one zero"
        case, there's a special Op that computes the product of the elements
        in the group, minus the zero (see ProdWithoutZero). The trick is then
        to use the division trick for groups with no zero, to use the
        ProdWithoutZeros op where there's only one zero, and to output a
        derivative of zero for any element part of a group with more than
        one zero.

        I do this by first counting the number of zeros in each group (see
        the "T.eq()" bits), then taking this or that behavior (see T.switch)
        based on the result of this count.

        i    R7   R!   i   g        R   N(    (   R7   Rt   Ru   Rv   Rs  Rw   Rx   Ry   R   R   R[   RJ   R   R+   R   R%   R8   R.   t
   dimshuffleR  t   eqR   R  t   ProdWithoutZerost   switch(   R2   RP   RQ   R|   t   prod_inR}   R   R  R3   R4   R  t   prod_outt   grad_case_without_zerost   Tt   where_zerost   sum_where_zerost   groups_with_single_zerot   where_single_zerot   where_gz_not_zerot    where_to_take_prod_without_zerost   prod_without_zeros_int   prod_without_zerost   groups_without_zerost
   final_grad(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR     sT    .						


		c         C` s   d S(   Ni   (   i   (    (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRs   =  s    (   s   axiss   dtypes	   acc_dtypeN(
   R   R   R   R   R[   R:   R6   R   R   Rs   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR    s   			zt   MulWithoutZerosc           B` s5   e  Z d  Z e Z e Z d   Z d   Z d   Z RS(   g        c         C` s(   | d k r | S| d k r  | S| | S(   Ni    (    (   R2   R!   R)  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   L  s
    c   	      C` s$   | \ } } | \ } d d t    S(   Ns"   %(z)s = ((%(x)s == 0) ? (%(y)s) : s/   ((%(y)s == 0) ? (%(x)s) : ((%(y)s)*(%(x)s))) );(   Rd   (	   R2   RO   Re   RP   RQ   Rf   R!   R)  R;  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRr   S  s
    	c         C` s   d S(   Ni   (   i   (    (   R2   (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyRs   Z  s    (	   R   R   R{   R#   t   commutativet   associativeR   Rr   Rs   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR  A  s   		Re   t   mul_without_zerosR  c           B` s)   e  Z d Z d d d d  Z d   Z RS(   R   R7   Rs  c      	   C` s&   t  j |  t d | d | d | d  S(   NR   R7   Rs  (   R  R6   R  (   R2   R   R7   Rs  (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR6   e  s    c         C` s+   | \ } t  j j |  d | d  } | g S(   Ni    s   2nd derivatives of `product(a)` is not currently supported.If `a` is guarenteed to contains no zeros, use `product(a, no_zeros_in_input=True)`.(   Rt   t   gradientt   grad_not_implemented(   R2   RP   R|   R[  t   a_grad(    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR   i  s
    				(   s   axiss   dtypes	   acc_dtypeN(   R   R   R   R[   R6   R   (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyR  a  s   (=   t
   __future__R    R   R   t   sysR   R'   t   sixR   R   t	   six.movesR   Rt   R   t   theano.compatR   t   theano.configparserR	   t
   theano.gofR
   R   R   R   t   theano.scalarR   t   theano.printingR   t   theano.gradientR   t   theano.gof.null_typeR   t   theano.tensorR   R  t   theano.misc.frozendictR   Rx   t   __version__t   splitt   nRZ  Rh  R   R   R   R   R   R   t   assignRz   RY  R  R  R  R  R  t   BinaryScalarOpR  t
   upcast_outR  R  (    (    (    s6   /tmp/pip-build-X4mzal/theano/theano/tensor/elemwise.pyt   <module>   sT   	/					 V   5 W	