
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 Z d  d l	 Z	 d  d l
 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 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! m" Z" m# Z# m$ Z$ d  d l% m& Z& d  d l' m( Z( m) Z) m* Z* m+ Z+ d  d l m, Z, e, j- rd  d l. Z d  d l/ m0 Z0 n  e j1 d  Z2 e3 a4 d e5 f d     YZ6 d   Z7 e8 d  Z9 d   Z: d e f d     YZ; d f  d     YZ< e j= e; e<    e8 e8 d  Z> e8 e8 e8 d  Z? d e f d     YZ@ d    ZA d! e f d"     YZB eB   ZC d# e f d$     YZD eD   ZE eD d% eF  ZG d&   ZH d'   ZI d( e f d)     YZJ eJ   ZK d* e f d+     YZL eL   ZM eL d% eF  ZN e3 d, d-  ZO d S(.   i    (   t   absolute_importt   print_functiont   divisionN(   t   dedent(   t   integer_types(   t   xrange(   t   izip(   t   DisconnectedType(   t   gof(   t   Applyt   hashtypet   Opt   Typet   MethodNotDefined(   t   pprint(   t   scalar(   t   alloc(   t   addbroadcastt   clipt   get_scalar_constant_valuet
   TensorTypet   NotScalarConstantError(   t
   DimShuffle(   t	   NoneConstt	   SliceTypet	   NoneTypeTt
   make_slice(   t   config(   t   inplace_increments   theano.tensor.subtensort   AdvancedIndexingErrorc           B` s   e  Z d  Z d   Z RS(   sG   
    Raised when Subtensor is asked to perform advanced indexing.

    c         G` s   t  j |  |  d  S(   N(   t	   TypeErrort   __init__(   t   selft   args(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   )   s    (   t   __name__t
   __module__t   __doc__R   (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   #   s   c         ` s"     f d     t  t   |    S(   sO   
    Convert python litterals to theano constants in subtensor arguments.

    c         ` s}   |  d  k r |  St |  t  rJ t   |  j    |  j    |  j   St |  t t j f  ru t	 j
 t	 j |   S|  Sd  S(   N(   t   Nonet
   isinstancet   slicet   startt   stopt   stepR   t   numpyt   integert   scalt   ScalarConstantt   int64(   t   a(   t   conv(    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR1   6   s    (   t   tuplet   map(   R!   (    (   R1   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   make_constant1   s    c         ` s   t  |   d } | d k r& t |  St t t |  d        f d     t t   |   } | r} | t    S| Sd S(   s   
    Given a list of inputs to the subtensor and its idx_list reorders
    the inputs according to the idx list to get the right values.

    If get_counts=True, instead returns the number of inputs consumed
    during this process.

    i   i    c         ` s^   t  |  t j  r  j   St  |  t  rV t   |  j    |  j    |  j   S|  Sd  S(   N(   R&   R   R   t   popR'   R(   R)   R*   (   t   entry(   t   convertt   indices(    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR7   W   s    
N(   t   lenR2   t   listt   reversedR3   (   t   inputst   idx_listt	   get_countt   nt   cdata(    (   R7   R8   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   get_idx_listD   s    
	c         ` s  d d l  m  m } m } m } t |  t  rcd   } | |  j  \ } } | |  j  \ } }	 | |  j	  \ }
 } | |  \ } } |
 d	 k r d }
 t } n  |
 d k r| d	 k p | d k p | o | o | d k  o | | d k } | d	 k p(| | t j g k p(|	 o(| o(| | k } | r| rMt d | d  d f S|	 r| d k rt d  | | |  | |  d  d f S| | }  | | d   | | d  d |   | | |  | |   } t d | d  d f S| r| r2| d k r2t  | | |  | |  | d  d f S| | }  | | d   | | d  d |   | | |  | |   } t | | d  d f Sn  | r|
 d k st  |
 d k rd   } |
 } d } q(d   } |
 } d } n9 | |
 d       f d   } t |
  } | |
  } | | d d  } | d |  } | d	 k r_| } nk  | | d  | | |  }  | | d  | d d  |  }  | | |  | | d |  |  } | d	 k s| t j k r| } nU  | | d  | | |  }  | | d  d |  }  | | |  | |  } | | d |  } | | d | d }  | | d  d |  } | | d | d }  | | d  | d |  } | | |  }  | | d  d |  }  | | d  d |  }  | | |  | |  } | } |
 d k rJ| } t | | |  | f St | | |  d f Sn; t j j |   }  | | d  | | |  } | d f Sd	 S(
   sf  
    Given a slice [start:stop:step] transform it into a canonical form
    that respects the conventions imposed by python and numpy.

    In a canonical form a slice is represented by a canonical form slice,
    in which 0 <= start <= stop <= length and step > 0, and a flag which says
    if the resulting set of numbers needs to be reversed or not.

    i    (   t   switcht   ltt   get   sgnc         S` sR   y t  |   } t } Wn/ t j j k
 rG t j j |   } t } n X| | f S(   N(   R   t   Truet   theanot   tensorR   t   extract_constantt   False(   t   xt
   x_constantt   is_constant(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   analyzet   s    

i   c         S` s   | S(   N(    (   R0   t   b(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   switch_neg_step   s    c         S` s   |  S(   N(    (   R0   RO   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRP      s    ic         ` s      |  |  S(   N(    (   R0   RO   (   t   is_step_negRB   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRP      s    N(   t   theano.tensorRB   RC   RD   RE   R&   R'   R(   R)   R*   R%   RF   t   syst   maxsizet   AssertionErrort   absRG   RH   RI   (   t   theslicet   lengthRC   RD   RE   RN   R(   t   is_start_constantR)   t   is_stop_constantR*   t   is_step_constantt   is_length_constantt
   is_start_0t   is_stop_lengtht   stop_plus_lent   start_plus_lenRP   t   abs_stept   sgn_stept   defstartt   defstopt   nw_stopt	   slice_lent	   neg_startt   nw_startt   nw_stept   reverset   value(    (   RQ   RB   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   get_canonical_form_sliceg   s    
"			!

					$		t	   Subtensorc           B` s/  e  Z d  Z d Z d Z d Z d Z e Z i d g d 6Z	 e
 Z d Z e d    Z e e
 d   Z e e e
 d  Z d	   Z e d
    Z d   Z d   Z d   Z d   Z d   Z d   Z e d    Z d   Z e d    Z e d d d   Z e d    Z d   Z d   Z  d   Z! RS(   s1  
    Return a subtensor view.

    The inputs array is the tensor x, followed by scalar integer types.
    TODO: WRITEME: how are the scalar integer variables formatted?

    This class uses a relatively complex internal representation of the inputs
    to remember how the input tensor x should be sliced.

    idx_list: instance variable TODO: WRITEME: is this a list or a tuple?
                                        (old docstring gives two conflicting
                                        descriptions)
              elements are either integers, theano scalar types, or slices.
              one element per "explicitly named dimension"
                TODO: WRITEME: what is an "explicitly named dimension" ?

              if integer:
                  indexes into the inputs array
              if slice:
                  start/stop/step members of each slice are integer indices
                  into the inputs array or None
                  integer indices be actual integers or theano scalar types

    Note that the idx_list defines the Op, so two Subtensor instances are
    considered to be different Ops if they have different idx_list fields.
    This means that the entries in it are theano Types, not theano Variables.

    @todo: add support for advanced tensor indexing (in Subtensor_dx too).

    s   The index list is longer (size %d) than the number of dimensions of the tensor(namely %d). You are asking for a dimension of the tensor that does not exist! You might need to use dimshuffle to add extra dimension to your tensor.s   nested slicing is not supporteds)   Invalid index type or slice for Subtensori    R=   c         ` s:   g       f d    x |  D] }  |  q" W S(   s4  
        Parameters
        ----------
        idxs : a list of indices or slices.
        cond : a callable that returns a bool

        Returns
        -------
        list
            idxs, with the slices flattened out into a list.
            If cond is true for an entry, does not flatten it.

        c         ` sY     |   r  j  |   n9 t |  t  rU  |  j   |  j   |  j  n  d  S(   N(   t   appendR&   R'   R(   R)   R*   (   R6   (   t   condt   helpert   ret(    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRp   ;  s    (    (   t   idxsRo   t   idx(    (   Ro   Rp   Rq   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   collapse*  s
    c         C` s  t  j t  j t  j g } t  j t  j t  j t  j g } t j	 j
 t j	 j t j	 j t j	 j g } t j	 j t j	 j t j	 j t j	 j g } t |  t j  r |  j | k s |  j | k r t d   n  t |  t j  r |  j | k r |  j St |  t j  r|  | k r|  St |  t j  r\|  j | k r\t j |  j j  r\t  j |  j j  St |  t j  r|  | k rt j |  j  rt  j |  j  S| r`t |  t  r`|  j } |  j } |  j  } | d k	 rt" j# | t$  }	 n d }	 | d k	 r#| t% j& k r#t" j# | t$  }
 n d }
 | d k	 rJt" j# | t$  } n d } t |	 |
 |  St |  t' t j( f  rt d   n t) t" j* |    d S(   sd  
        Change references to Variables into references to Types.

        The "idx_list" field is unique to each Subtensor instance.
        It is not unique to each Apply node, so it should not refer to
        specific Variables.
        TODO: WRITEME: This method also accepts "entry" already being a Type;
            when would that happen?

        s   Expected an integersA   Python scalar in idx_list.Please report this error to theano-dev.N(+   R-   t   float64t   float32t   float16R/   t   int32t   int16t   int8RG   RH   t   lscalart   iscalart   wscalart   bscalart   fscalart   dscalart   cscalart   zscalarR&   R   t   Variablet   typeR   R   R+   t   allt   broadcastablet   get_scalar_typet   dtypeR'   R(   R)   R*   R%   Rm   R7   RJ   RS   RT   R   R,   R   t   e_indextype(   R6   t   slice_okt   invalid_scal_typest
   scal_typest   tensor_typest   invalid_tensor_typesR0   RO   t   ct   slice_at   slice_bt   slice_c(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR7   H  sN    !			c         ` s=   t  | |  j  }      f d    t t  |   S(   si  
        Return the idx_list with constant inputs replaced by their
        python scalar equivalent.
        May raise `theano.tensor.NotScalarConstantError` if the idx contains
        non-constant entries.

        If allow_partial is True, then entries that are not constant will
        stay as their input variable rather than raising an exception.

        None entries are always left as-is.

        Parameters
        ----------
        only_process_constants
            If True, we only attempt to obtain the value of an index/slice if
            it's directly constant and don't try to dig through dimshuffles,
            fills, allocs, and other to figure out its value.

        Examples
        --------
        Example usage where v, a are appropriately typed theano variables :
        >>> b = a[v, 1:3]
        >>> b.owner.op.idx_list
        (Scalar(int64), slice(Scalar(int64), Scalar(int64), None))
        >>> b.owner.op.get_constant_idx(b.owner.inputs, allow_partial=True)
        [v, slice(1, 3, None)]
        >>> b.owner.op.get_constant_idx(b.owner.inputs)
        NotScalarConstantError: v

        c         ` s   |  d  k r d  St |  t  rJ t  |  j   |  j   |  j   Sy t |  d  d  SWn$ t j j	 k
 r   r |  S  n Xd  S(   Nt   only_process_constantst   elemwise(
   R%   R&   R'   R(   R)   R*   R   RG   RH   R   (   t   val(   t   allow_partialR1   R   R   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR1     s    (   RA   R=   R:   R3   (   R    R<   R   R   R   t   real_idx(    (   R   R1   R   R   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   get_constant_idx  s     c         C` s   t  t |  j |   |  _ d  S(   N(   R2   R3   R7   R=   (   R    R=   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` sE   t  |  t j  r4 t  |  j t  r4 t j j |   St j	 |   Sd  S(   N(
   R&   R   R   R   R   RG   RH   t   scalar_from_tensorR-   t	   as_scalar(   R0   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   my_as_scalar  s    $c         ` s  t  j j |  } t   f d   | D  } t   j  } t |  | j j k r t	 t
 j t |  | j j f  } t | _ |  n  t
 j | d    } t |  t |  k r t d | |   n  xH t | |  D]7 \ } } | j | k r t d | j | f   q q W  j d
 | d t t d	 d	 d	  g | j j t |  } g  }	 xt t | | j j   D] \ }
 \ } } t | t  r{| r]| j } y t |  } Wn t k
 rn X| d	 k s| d k r]| j } | d	 k rd } n  | j d	 k sDt | j t t j t j f  rZ| j | k rZ|	 j  t  q{qZq]n  |	 j  t!  q{q{Wt" j#   | f | t  j j d | j j$ d |	  g  S(   s   
        Parameters
        ----------
        x
            The tensor to take a subtensor of.
        inputs
            A list of theano Scalars.

        c         3` s   |  ] }   j  |  Vq d  S(   N(   R   (   t   .0R0   (   R    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pys	   <genexpr>  s    c         S` s   t  |  t j  S(   N(   R&   R   R   (   R6   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   <lambda>  s   s4   Not enough inputs to fill in the Subtensor template.s7   Wrong type for Subtensor template. Expected %s, got %s.R   i    R   R   N(   N(%   RG   RH   t   as_tensor_variableR2   R:   R=   R9   R   t   ndimt
   ValueErrorRm   t	   e_invalidRF   t   subtensor_invalidRt   t
   IndexErrorR   R   R   R%   R'   t	   enumerateR   R&   R(   R   R   R)   R   R+   R,   t   ndarrayRn   RJ   R   R	   R   (   R    RK   R<   R=   t	   exceptiont   input_typest   inputt   expected_typet   paddedR   t   it   pt   bcR(   (    (   R    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt	   make_node  sZ    
				*.				
c         C` sd   | \ } | d } t  | |  j  } t |  d k rD | d } n  t j | j |   | d <d  S(   Ni    i   (   RA   R=   R9   R+   t   asarrayt   __getitem__(   R    t   nodeR<   t   out_t   outRK   R@   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   perform  s    	
c         C` s  | d } t  |  | j d j k s, t  g  } t t | j |  j   } | t d  d  d   g t  |  t  |  j  } d } x t	 | |  D] \ } }	 t
 | t  r | j d k r| j d  t j g k r| j d  k s | j d k r| j |	  na t | |	  d }
 |
 j d k r8|
 j |
 j } n |
 j |
 j d |
 j d } | j |  | d 7} q q W| | j d j k st  t  |  | j d j k st  | g S(   Ni    i   (   Ni    (   R9   R<   R   RU   R:   RA   R=   R'   R%   R   R&   R(   R)   RS   RT   R*   Rn   Rl   t   outputs(   R    R   t   shapest   xshpt   outshpt   actual_idx_listR   R   Rs   t   xlt   cnfRX   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   infer_shape  s.    
"-"c         C` s   | \ } | d } | d } | j  t j j k rP | j   j t j j  } n! t |  j	  | j   | |  } | g t
     g t |  S(   Ni    i   (   R   RG   RH   t   discrete_dtypest
   zeros_liket   astypeR   t   floatXt   IncSubtensorR=   R   R9   (   R    R<   t   gradst   gzRK   t   restt   first(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   grad7  s    	

c         C` s8   t  g g } x% | j d D] } | j t g  q W| S(   Ni   (   RF   R<   Rn   RJ   (   R    R   t   rvalt   ipt(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   connection_patternF  s    c         C` sn   g  } xO |  j  D]D } t | t  rG | | j | j | j f g 7} q | | g 7} q Wt |  } t |  S(   N(   R=   R&   R'   R(   R)   R*   R2   t   hash(   R    t   msgR6   R=   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   __hash__O  s    "c         C` se   g  } xO |  j  |  j |  j g D]5 } | d  k rA | j d  q | j t |   q Wd j |  S(   Nt    t   :(   R(   R)   R*   R%   Rn   t   strt   join(   R6   R   RK   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   str_from_slice`  s    c         C` sr   g  } xL |  j  D]A } t | t  r> | j |  j |   q | j t |   q Wd |  j j d j |  f S(   Ns   %s{%s}s   , (	   R=   R&   R'   Rn   R   R   t	   __class__R"   R   (   R    R8   R6   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   __str__j  s    c           C` s   i d d 6d d 6S(   sN   
        Returns a dictionary of default arguments to helper_c_code.

        t   PyArrayt   c_prefixi   t   strides_mul(    (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   default_helper_c_code_argss  s    
c	      
   ` s  t  j   }	 | d k r% |	 d } n  | d k r> |	 d } n  | d }
 g   g   t j d   d d g   f d     f d     f d   	  f d	    d          	 f	 d
   x | D] }  |  q W   t   k st      t   |  j d j k sDt |  j d j   t   } 	   } d t	   } | d k r{d } n   rd d j
 g   D] } t |  ^ q d } n d } d j
   }  d  \ } | \ } | rd t	   } n d } | d t	   7} | S(   s   
        The parameters c_prefix are there to allow reusing this
        function on PyArray and CudaNdarray object.

        This fct take as input the x.

        R   R   t   faili   i    c         ` s     d c |  7<d  S(   Ni    (    (   t   amt(   t   pos(    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   inc_spec_pos  s    c         ` s     d c |  7<d  S(   Ni   (    (   R   (   R   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   inc_input_pos  s    c           ` s     d S(   Ni    (    (    (   R   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   spec_pos  s    c           ` s     d S(   Ni   (    (    (   R   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt	   input_pos  s    c         ` s  t  |  t j t f  r[  j d    |  f   d  | d k r j d  qn+t  |  t  r  j d        f   d   d  | d k r j d  qn |  d  k r j d      f   d  | d k r j d  qny | d k rtt  |  t  rt |  j | d   |  j	 | d   |  j
 | d   j d  n d st |    d  S(   Ns   subtensor_spec[%i] = %i;i   i    s   subtensor_spec[%i] = %s;(   R&   R+   R,   R   Rn   R   R%   R'   R(   R)   R*   RU   (   R6   t   depth(	   t	   NONE_CODER   R   t	   init_cmdst
   init_entryR   R<   t   is_sliceR   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s8    	
	

	
s0   npy_intp subtensor_spec[%(len_subtensor_spec)s];s!   npy_intp * subtensor_spec = NULL;s   int is_slice[] = {t   ,s   };s   int* is_slice = NULL;s   
s   
        // Argument of the view
        npy_intp xview_dims[%(view_ndim)s];
        npy_intp xview_strides[%(view_ndim)s];

        sw   
        // Argument of the view
        npy_intp* xview_dims = NULL;
        npy_intp* xview_strides = NULL;

        s  
        // One more argument of the view
        npy_intp xview_offset = 0;

        // The subtensor is created by iterating over the dimensions
        // and updating stride, shape, and data pointers

        %(is_slice_init)s
        %(subensor_spec)s
        %(subtensor_init)s;
        int spec_pos = 0; //position in subtensor_spec
        int inner_ii = 0; // the current dimension of zview
        int outer_ii = 0; // current dimension of z


        for (; outer_ii < %(len_is_slice)s; ++outer_ii)
        {
            if (is_slice[outer_ii])
            {
                npy_intp length = %(c_prefix)s_DIMS(%(x)s)[outer_ii];
                npy_intp slicelength;
                npy_intp start = subtensor_spec[spec_pos+0];
                npy_intp stop  = subtensor_spec[spec_pos+1];
                npy_intp step  = subtensor_spec[spec_pos+2];
                if (step == %(NONE_CODE)s) step = 1;

                npy_intp defstart = step < 0 ? length-1 : 0;
                npy_intp defstop = step < 0 ? -1 : length;

                // logic adapted from
                // PySlice_GetIndicesEx in python source
                if (!step)
                {
                    PyErr_Format(PyExc_ValueError,
                                 "slice step cannot be zero");
                    %(fail)s;
                }

                if (start == %(NONE_CODE)s)
                {
                    start = defstart;
                }
                else
                {
                    if (start < 0) start += length;
                    if (start < 0) start = (step < 0) ? -1 : 0;
                    if (start >= length)
                        start = (step < 0) ? length - 1 : length;
                }

                if (stop == %(NONE_CODE)s)
                {
                    stop = defstop;
                }
                else
                {
                    if (stop < 0) stop += length;
                    if (stop < 0) stop = (step < 0) ? -1 : 0;
                    if (stop >= length)
                        stop = (step < 0) ? length - 1 : length;
                }

                if ((step < 0 && stop >= start)
                    || (step > 0 && start >= stop)) {
                    slicelength = 0;
                }
                else if (step < 0) {
                    slicelength = (stop-start+1)/step+1;
                }
                else {
                    slicelength = (stop-start-1)/step+1;
                }

                if (0){
                    fprintf(stdout, "start %%zi\n", start);
                    fprintf(stdout, "stop %%zi\n", stop);
                    fprintf(stdout, "step %%zi\n", step);
                    fprintf(stdout, "length %%zi\n", length);
                    fprintf(stdout, "slicelength %%zi\n", slicelength);
                }

                assert (slicelength <= length);

                xview_offset += (npy_intp)%(c_prefix)s_STRIDES(%(x)s)[outer_ii]
                    * start * %(strides_mul)s;
                xview_dims[inner_ii] = slicelength;
                xview_strides[inner_ii] = (npy_intp)%(c_prefix)s_STRIDES(%(x)s)[outer_ii] * step;

                inner_ii += 1;
                spec_pos += 3;
            }
            else // tuple coord `outer_ii` is an int
            {
                int idx = subtensor_spec[spec_pos];
                if (idx < 0) idx += %(c_prefix)s_DIMS(%(x)s)[outer_ii];
                if (idx >= 0)
                {
                    if (idx < %(c_prefix)s_DIMS(%(x)s)[outer_ii])
                    {
                        xview_offset += (npy_intp)%(c_prefix)s_STRIDES(%(x)s)[outer_ii] * idx *
                               %(strides_mul)s;
                    }
                    else
                    {
                        PyErr_Format(PyExc_IndexError,"index out of bounds");
                        %(fail)s;
                    }
                }
                else
                {
                    PyErr_Format(PyExc_IndexError,"index out of bounds");
                    %(fail)s;
                }

                spec_pos += 1;
            }
        }
        assert (inner_ii <= %(view_ndim)s);
        while (inner_ii < %(view_ndim)s)
        {
            assert (outer_ii < %(c_prefix)s_NDIM(%(x)s));
            xview_dims[inner_ii] = %(c_prefix)s_DIMS(%(x)s)[outer_ii];
            xview_strides[inner_ii] = %(c_prefix)s_STRIDES(%(x)s)[outer_ii];

            inner_ii += 1;
            outer_ii += 1;
        }
        N(   Rm   R   R%   RS   RT   R9   RU   R<   R   t   localsR   R   (   R   t   nameR<   R   t   subR=   t	   view_ndimR   R   t   default_argsR   R6   t   len_is_slicet   len_subtensor_spect   subensor_spect   st   is_slice_initt   subtensor_initRK   t   zR   (    (
   R   R   R   R   R   R   R<   R   R   R   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   helper_c_code}  sH    
*$2		3	c           C` s   d S(   Ni	   (   i	   (    (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   helper_c_code_cache_versions  s    c         C` s   t  | j d j t j j  s+ t    n  | d } | \ } | j d j } | j d j }	 | d }
 d } d t	   } |  j
 | | | | | |  j |	  } d t	   } d t	   } | | d | | | d S(	   Ni    R   s   PyArrayObject * xview = NULL;s   
        if (PyArray_NDIM(%(x)s) != %(ndim)s){
            PyErr_SetString(PyExc_ValueError,
                                     "Expected %(ndim)s dimensions input"
                                        );
            %(fail)s
        }
        sy  
        //TODO: give this Op a second output so that this view can be cached
        //TODO: alternatively, fix the memory leak on failure
        Py_INCREF(PyArray_DESCR(%(x)s));
        xview = (PyArrayObject*)PyArray_NewFromDescr(
                &PyArray_Type,
                PyArray_DESCR(%(x)s),
                %(view_ndim)s,
                xview_dims,
                xview_strides,
                PyArray_BYTES(%(x)s) + xview_offset,
                PyArray_FLAGS(%(x)s),
                NULL);
        assert (PyArray_NDIM(xview) == %(view_ndim)s);
        if (!xview)
        {
            %(fail)s;
        }
        s   
        Py_XDECREF(%(z)s);
        Py_INCREF(py_%(x)s);
        PyArray_SetBaseObject(xview, py_%(x)s);
        assert(py_%(x)s == (PyObject*)%(x)s);
        %(z)s = xview;
        t   {t   }(   R&   R<   R   RG   RH   R   t   NotImplementedErrorR   R   R   R   R=   (   R    R   R   R<   R   R   RK   R   R   R   R   t   declt	   checkNDimt	   get_xviewt
   build_viewt   finish_view(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   c_codew  s    
	
	c         C` s,   |  j    } t |  d k r" d Sd | f S(   Ni    i   (    (   R   R9   (   R    t   hv(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   c_code_cache_version  s    c         C` s8   | d d  k r d  g S|  | d | d t d t   S(   Ni    i   t   return_list(   R%   t   dictRF   (   R    R<   t   eval_points(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   R_op  s    (   s   idx_listN("   R"   R#   R$   R   t
   e_subsliceR   t   debugRJ   t   check_inputt   view_mapRF   t   _f16_okt	   __props__t   staticmethodRt   R7   R   R   R   R   R   R   R   R   R   R   R   R   R%   R   R   R   R   R  (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRm      s@   B6	
	?	
					
		
	6	t   SubtensorPrinterc           B` s   e  Z d    Z RS(   c         C` s	  | j  d  k r t d   nt | j  j t  r| j  j j } t | j  j  } | j	 d  } g  } t
 | d d   } z+d | _ x| D]} t | t  r | j t |   q t | t j  r | j | j j | j	     q t | t  r | j d  k s| j d k r#d }	 n	 | j }	 | j d  k sM| j t j k rVd }
 n	 | j }
 | j d  k rwd } n d | j } | j d |	 |
 | f  q q WWd  | | _ Xz" d | _ | j j | |  } Wd  | | _ Xd	 | d
 j |  f St d   d  S(   Ns   Can only print Subtensor.i    t
   precedenceiR   s   :%ss   %s:%s%si  s   %s[%s]s   , (   t   ownerR%   R   R&   t   opRm   R=   R:   R<   R5   t   getattrR
  R   Rn   R   R-   t   Scalart   pprintert   processR'   R(   R)   RS   RT   R*   R   (   R    t   rt   pstateRr   R<   R   t   sidxst   old_precedenceR6   t   msg1t   msg2t   msg3R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    sB    	"		!			%
	
(   R"   R#   R  (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR	    s   c         C` s   t  |  | | d t d | S(   s  
    Return x with the given subtensor overwritten by y.

    Parameters
    ----------
    x
        Symbolic variable for the lvalue of = operation.
    y
        Symbolic variable for the rvalue of = operation.
    tolerate_inplace_aliasing
        See inc_subtensor for documentation.

    Examples
    --------
    To replicate the numpy expression "r[10:] = 5", type

    >>> r = ivector()
    >>> new_r = set_subtensor(r[10:], 5)

    t   set_instead_of_inct   tolerate_inplace_aliasing(   t   inc_subtensorRF   (   RK   t   yt   inplaceR  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   set_subtensor  s    c      	   C` s  t  j j |   }  t  j j |  } | j |  j k rU t d |  j | j f   n  |  j | j } xH t | j  D]7 } |  j | | ru | j | ru t | |  } qu qu W|  j s t d   n  t	 |  j j
 t  rL| r d d g g } n g  } t |  j j
 j | | d | } |  j j d }	 |  j j d }
 | |	 | |
  St	 |  j j
 t  r|  j j d }	 |  j j d } t | d | } | |	 | |  St	 |  j j
 t  r|  j j d }	 |  j j d } t | d | } | |	 | |  St	 |  j j
 t  r|  j j d } |  j j
 j } d g |  j } xG t |  D]9 \ } } | d k rK| | d k rK| | | | <qKqKWt j j rd g | t t | j   } | | k rt j d d	 d
 qn  t | | j |  d | d | d | } | j |  j j
 j  St	 |  j j
 t  j j  r|  j j d } | j d k rt | g  t |  j  D] } |  j  | ^ qi } | j! | j   } n | } t j j r| j d k rt" | j  d k rt j d d	 d
 qn  t | | d | d | d | } | St d   d S(   s9  
    Return x with the given subtensor incremented by y.

    Parameters
    ----------
    x
        The symbolic result of a Subtensor operation.
    y
        The amount by which to increment the subtensor in question.
    inplace
        Don't use. Theano will do it when possible.
    set_instead_of_inc
        If True, do a set_subtensor instead.
    tolerate_inplace_aliasing:
        Allow x and y to be views of a single underlying array even while
        working inplace. For correct results, x and y must not be overlapping
        views; if they overlap, the result of this Op will generally be
        incorrect. This value has no effect if inplace=False.

    Examples
    --------
    To replicate the numpy expression "r[10:] += 5", type

    >>> r = ivector()
    >>> new_r = inc_subtensor(r[10:], 5)

    sK   Trying to increment a %d-dimensional subtensor with a %d-dimensional value.s-   x must be the result of a subtensor operationi    i   t   destroyhandler_tolerate_aliasedR  RK   s]  Although your current code is fine, please note that earlier versions prior to 0.7 (or this development version) may have yielded an incorrect result in this `inc_subtensor` or `set_subtensor` operation. To remove this warning, you can either set the `warn.inc_set_subtensor1` config option to `False`, or `warn.ignore_bug_before` to at least "0.7".t
   stackleveli   R  R  N(#   RG   RH   R   R   R   R   R   R   R  R&   R  Rm   R   R=   R<   t   AdvancedSubtensor1t   AdvancedIncSubtensor1t   AdvancedSubtensort   AdvancedIncSubtensorR   t	   new_orderR   R   t   warnt   inc_set_subtensor1R:   t   ranget   warningsR  t
   dimshufflet   ReshapeR   t   shapet   reshapet   sum(   RK   R  R  R  R  t
   dim_offsett   dimR  t   the_opt   real_xt   real_idxargst   ilistt   inner_xt   x_ordert   y_orderR   t   vt   prev_y_ordert   inner_incsubtensort
   expanded_yt   flattened_y(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    s     						 	2$	R   c           B` s   e  Z d  Z e Z d Z e e 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 d   Z d   Z d   Z d   Z d   Z RS(   s,  
    Increment a subtensor.

    This is like numpy's

        x[i,j,k] += y

    It is used internally to implement the gradient on SubTensor.

    Parameters
    ----------
    set_instead_of_inc
        If True set the subtensor to the value instead of incrementing it by
        that value.

    R=   R  R  c         C` sq   | d  k r g  } n  t t t j |   |  _ | |  _ | rU i d g d 6|  _ n  t |  |  _ | |  _	 d  S(   Ni    (
   R%   R:   R3   Rm   R7   R=   R  t   destroy_mapR  R  (   R    R=   R  R  R  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    		c         C` s   g  } xO |  j  D]D } t | t  rG | | j | j | j f g 7} q | | g 7} q Wt |  } t |   t |  At |  j	  At |  j
  AS(   N(   R=   R&   R'   R(   R)   R*   R2   R
   R   R  R  (   R    R   R6   R=   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    " c         C` s   g  } xL |  j  D]A } t | t  r> | j t j |   q | j t |   q W|  j rg d } n d } |  j s | d 7} n
 | d 7} d |  j	 j
 | d j |  f S(   Nt   InplaceR   t   Inct   Sets	   %s{%s;%s}s   , (   R=   R&   R'   Rn   Rm   R   R   R  R  R   R"   R   (   R    R8   R6   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    			
	c   	      G` s{  t  t j j | | g  \ } } | j | j k rR t d | j | j f   n  t t  t j |   } t	 |  j
  } t |  | j j k r t t j t |  | j j f  } t | _ |  n  t j | d    } t |  t |  k r
t d | |   n  xH t | |  D]7 \ } } | j | k rt d | j | f   qqWt j |  | | f | | j   g  S(   s   
        Parameters
        ----------
        x
            The tensor to increment.
        y
            The value to increment by.
        inputs: TODO WRITEME

        sK   Trying to increment a %d-dimensional subtensor with a %d-dimensional value.c         S` s   t  |  t j  S(   N(   R&   R   R   (   R6   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    s4   Not enough inputs to fill in the Subtensor template.s7   Wrong type for Subtensor template. Expected %s, got %s.(   R3   RG   RH   R   R   R   R2   Rm   R   R:   R=   R9   R   R   RF   R   Rt   R   R   R   R   R	   (	   R    RK   R  R<   R=   R   R   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s8    !				c         C` s   d S(   Ns   PyArrayObject * zview = NULL;(    (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt	   decl_view(  s    c   	      ` s  | \ } | d  \ } } t  t | d       f d     t t   |  j   } t |  d k rx | d } n  |  j s | j   } n  | j |  } | j	 r |  j
 s | | 7} q| j | |  n0 |  j
 s | j | | |  n | j | |  | | d <d  S(   Ni   c         ` s   t  |  t j  r`  j   } t j d k  r\ t |  } | | k rX t d |   n  | S| St  |  t  r t   |  j	    |  j
    |  j   S|  Sd  S(   Ni   i   s:   Invalid value for indexing: %s. That value may be too big.(   i   i   (   R&   R   R   R5   RS   t   version_infot   intR   R'   R(   R)   R*   (   R6   R   t   rval_(   R7   R8   (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR7   0  s    i   i    (   R:   R;   R2   R3   R=   R9   R  t   copyR   R+  R  t   __setitem__(	   R    R   R<   R   R   RK   R  R@   t   sub_x(    (   R7   R8   s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   +  s$    					c         C` s  |  j  |  |  j r d } n d } | d } | d } | \ }	 |  j rT d }
 n d }
 | d } | j d j t j g  |  j D] } t | t	  ^ q  } |  j
 |  } d t   } |  j   } t j d | d | d | d  | d d	 | d
 | d |  j d | |  } |  j |	 |  } d t   } |  j d |  } |  j | | |  } d t   } |  j   | | | | d S(   Ni   i    R   s9  
        if (%(inplace)s)
        {
            if (%(x)s != %(z)s)
            {
                Py_XDECREF(%(z)s);
                Py_INCREF(%(x)s);
                %(z)s = %(x)s;
            }
        }
        else
        {
            Py_XDECREF(%(z)s);
            %(z)s = %(copy_of_x)s;
        }
        R   R   R<   i   R   R   R=   R   s   
        //TODO: give this Op a second output so that this view can be cached
        //TODO: alternatively, fix the memory leak on failure
        %(alloc_zview)s;
        if (!zview)
        {
            %(fail)s;
        }
        t   zviews  
        if (%(op_is_set)s)
        {
            if (%(copy_into)s) // does broadcasting
            {
                Py_DECREF(zview);
                %(fail)s;
            }
        }
        else
        {
            %(add_to_zview)s
        }
        s   Py_DECREF(zview);(   t   do_type_checkingR  R  R<   R   R+   R-  R=   R&   R'   t	   copy_of_xR   t   get_helper_c_code_argsRm   R   t   make_view_arrayt	   copy_intot   add_to_zviewR@  (   R    R   R   R<   R   R   R  RK   R  R   t	   op_is_setR   Rs   R   RI  t   copy_input_if_necessaryt   helper_argst	   get_zviewt   alloc_zviewR   RL  RM  t   make_modification(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   Y  sB    			

			
	'			
c         C` s/   t  | j d j t j j  s+ t    n  d S(   sw   
        Should raise NotImplementedError if c_code does not support
        the types involved in this node.

        i    N(   R&   R<   R   RG   RH   R   R   (   R    R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRH    s    c         C` s$   t  j   } | r d | f Sd Sd  S(   Ni   (    (   Rm   R   (   R    R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    
c         C` s   d t    S(   sQ  
        Parameters
        ----------
        x
            A string giving the name of a C variable pointing to an array.

        Returns
        -------
        object
            C code expression to make a copy of x.

        Base class uses PyArrayObject *, subclasses may override for
        different types of arrays.

        sa   (PyArrayObject*)PyArray_FromAny(py_%(x)s, NULL, 0, 0,
                NPY_ARRAY_ENSURECOPY, NULL)(   R   (   R    RK   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRI    s    c         C` s   d t    S(   sH  
        Parameters
        ----------
        x
            A string identifying an array to be viewed.
        view_ndim
            A string specifying the number of dimensions to have in the view.

        This doesn't need to actually set up the view with the right indexing;
        we'll do that manually later.

        s  Py_INCREF(PyArray_DESCR(%(x)s));
        zview = (PyArrayObject*)PyArray_NewFromDescr(
                &PyArray_Type,
                PyArray_DESCR(%(x)s),
                %(view_ndim)s,
                xview_dims, //PyArray_DIMS(%(x)s),
                xview_strides, //PyArray_STRIDES(%(x)s),
                PyArray_BYTES(%(x)s) + xview_offset, //PyArray_DATA(%(x)s),
                PyArray_FLAGS(%(x)s),
                NULL);
        (   R   (   R    RK   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRK    s    c         C` s
   t  j   S(   sM   
        Return a dictionary of arguments to pass to helper_c_code.

        (   Rm   R   (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRJ    s    c         C` s   d t    S(   s0  
        Parameters
        ----------
        view : string
            C code expression for an array.
        source : string
            C code expression for an array.

        Returns
        -------
        object
            C code expression to copy source into view, and 0 on success.

        s&   PyArray_CopyInto(%(view)s, %(source)s)(   R   (   R    t   viewt   source(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRL  	  s    c         C` s   d t    S(   sa   
        Return C code to add x to zview. Should DECREF zview if the
        add fails.

        s  
            PyArrayObject * add_rval = (PyArrayObject*)PyNumber_InPlaceAdd(
                    (PyObject*)zview, py_%(x)s);
            if (add_rval)
            {
                assert (PyArray_Check((PyObject*)add_rval));
                assert (PyArray_DATA(add_rval) == PyArray_DATA(zview));
                Py_DECREF(add_rval);
            }
            else
            {
                Py_DECREF(zview);
                %(fail)s;
            }(   R   (   R    R   RK   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRM    s    c         C` s   | d g S(   Ni    (    (   R    R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   0  s    c         C` sO   | d d  k s  | d d  k r' d  g S|  | d | d | d t d t   S(   Ni    i   i   R   (   R%   R   RF   (   R    R<   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR  3  s     c         C` s>   t  g t  g g } x% | j d D] } | j t g  q  W| S(   Ni   (   RF   R<   Rn   RJ   (   R    R   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   ;  s    c   	      C` s@  | \ } | d  \ } } | d } | j  t j j k r | j d t j j  } | j  t j j k r | j d t j j  } q| j   } n | j  t j j k r t d   nl |  j	 r t
 t d |  j  | |  t j j |   } n | } t d |  j  | |  } t | |  } | | g t     g t |  S(   Ni   R   s   No support for complex grad yetR=   (   R   RG   RH   R   R   R   R   t   complex_dtypesR   R  R  Rm   R=   t   _sum_grad_over_bcasted_dimsR   R9   (	   R    R<   R   t   g_outputRK   R  R=   t   gxt   gy(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   D  s$    	
	(   s   idx_lists   inplaces   set_instead_of_incN(   R"   R#   R$   RJ   R  R  R%   R   R   R   R   R@  R   R   RH  R   RI  RK  RJ  RL  RM  R   R  R   R   (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s,   			,		.	c	
										c         C` s  | j  |  j  k r| j |  j } t f | |  j  } t | j   t |  k  sW t  g  } x t | j  D]| } | j  | t k r | | t k r | j |  qm | j  | t k r | | t k r qm | j  | | | k sm t  qm W| j d | d t  } | j |  j k r}| j |  j k s/t  x' t |  D] } | j  | s<t  q<W| j t	 t
 | | j     } n  | j  |  j  k st  n  | S(   s   
    Sum of gx over dimensions to reproduce x.broadcastable.

    This is useful to sum gradients over certain dimensions when
    x has been broadcasted, and we need to sum the gradient contributions
    over all duplications.

    t   axist   keepdims(   R   R   RF   R-  RU   R   RJ   Rn   R)  R:   R'  (   RK   RY  t   x_dim_addedt   x_broadt   axis_to_sumR   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRW  _  s(    	!#!$R   c           B` sw   e  Z d  Z d Z e Z e d  Z d   Z d   Z	 d   Z
 d   Z d   Z d   Z d   Z d	   Z d
   Z RS(   sB   
    Implement x[ilist] where ilist is a vector of integers.

    c         C` s   | |  _  d  S(   N(   t   sparse_grad(   R    R`  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` s   t  j j |  } t  j j |  } | j j t  j j k rK t d   n  | j j d k rl t d   n  | j j d k r t d   n  | j d f | j d } t	 |  | | g t
 d | j d |    g  S(   Ns   index must be integersi   s   index must be vectori    s   cannot index into a scalarR   R   (   RG   RH   R   R   R   t   integer_dtypesR   R   R   R	   R   (   R    RK   R3  t   x_t   ilist_t   bcast(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c   	      C` s   | \ } } | \ } | d d  k	 rY | d j t |  f | j d k rY | d } n d  } | j t j k r t j | d t j } t j | j t j  s t j	 | | k  r t
 d |   q n  | } n  | j | d d d | | d <d  S(   Ni    i   R   sQ   index contains values that are bigger than the maximum array size on this system.R[  R   (   R%   R+  R9   R   R+   t   intpRG   t   _asarrayt   can_castt   anyR   t   take(	   R    R   t   inpR   RK   R   R   t   ot   i_(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    	7	c         C` s8   t  g g } x% | j d D] } | j t g  q W| S(   Ni   (   RF   R<   Rn   RJ   (   R    R   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` s   | \ } } | \ } t  |  d k s- t  |  j r | j j d k rg t d t | j j    n  t d  k r d d  l	 j
 a n  t j | | |  g } n t | j   | |  g } | t     g t  |  d S(   Ni   sY   AdvancedSubtensor1: you can't take the sparse grad from a tensor with ndim != 2. ndim is i    i   (   R9   RU   R`  R   R   R   R   t   sparse_module_refR%   t   theano.sparset   sparset   construct_sparse_from_listt   advanced_inc_subtensor1R   R   (   R    R<   R   RK   R3  R   t   rval1(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    		c         C` s2   | d d  k r d  g S|  j | d | d  j S(   Ni    i   (   R%   R   R   (   R    R<   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    s    c         C` s   | \ } } | | d g S(   Ni   (    (   R    R   t   ishapesRK   R3  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` s
   t  d  S(   Nse                   #ifndef MIN_LONG
                #define MIN_LONG NPY_MIN_LONG
                #endif(   R   (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   c_support_code  s    c   
      C` s[   |  j  t k	 r' t d t |     n  | d | d } } | d } | d }	 d t   S(   Ns:   c_code defined for AdvancedSubtensor1, not for child classi    i   R   s)  
            PyArrayObject *indices;
            int i_type = PyArray_TYPE(%(i_name)s);
            if (i_type != NPY_INTP) {
                // Cast %(i_name)s to NPY_INTP (expected by PyArray_TakeFrom),
                // if all values fit.
                if (!PyArray_CanCastSafely(i_type, NPY_INTP) &&
                    PyArray_SIZE(%(i_name)s) > 0) {
                    npy_int64 min_val, max_val;
                    PyObject* py_min_val = PyArray_Min(%(i_name)s, NPY_MAXDIMS,
                                                       NULL);
                    if (py_min_val == NULL) {
                        %(fail)s;
                    }
                    min_val = PyLong_AsLongLong(py_min_val);
                    Py_DECREF(py_min_val);
                    if (min_val == -1 && PyErr_Occurred()) {
                        %(fail)s;
                    }
                    PyObject* py_max_val = PyArray_Max(%(i_name)s, NPY_MAXDIMS,
                                                       NULL);
                    if (py_max_val == NULL) {
                        %(fail)s;
                    }
                    max_val = PyLong_AsLongLong(py_max_val);
                    Py_DECREF(py_max_val);
                    if (max_val == -1 && PyErr_Occurred()) {
                        %(fail)s;
                    }
                    if (min_val < NPY_MIN_INTP || max_val > NPY_MAX_INTP) {
                        PyErr_SetString(PyExc_IndexError,
                                     "Index contains values "
                                     "that are bigger than the maximum array "
                                     "size on this system.");
                        %(fail)s;
                    }
                }
                indices = (PyArrayObject*) PyArray_Cast(%(i_name)s, NPY_INTP);
                if (indices == NULL) {
                    %(fail)s;
                }
            }
            else {
                 indices = %(i_name)s;
                 Py_INCREF(indices);
            }
            if (%(output_name)s != NULL) {
                npy_intp nd, i, *shape;
                nd = PyArray_NDIM(%(a_name)s) + PyArray_NDIM(indices) - 1;
                if (PyArray_NDIM(%(output_name)s) != nd) {
                    Py_CLEAR(%(output_name)s);
                }
                else {
                    shape = PyArray_DIMS(%(output_name)s);
                    for (i = 0; i < PyArray_NDIM(indices); i++) {
                        if (shape[i] != PyArray_DIMS(indices)[i]) {
                            Py_CLEAR(%(output_name)s);
                            break;
                        }
                    }
                    if (%(output_name)s != NULL) {
                        for (; i < nd; i++) {
                            if (shape[i] != PyArray_DIMS(%(a_name)s)[
                                                i-PyArray_NDIM(indices)+1]) {
                                Py_CLEAR(%(output_name)s);
                                break;
                            }
                        }
                    }
                }
            }
            %(output_name)s = (PyArrayObject*)PyArray_TakeFrom(
                        %(a_name)s, (PyObject*)indices, 0, %(output_name)s, NPY_RAISE);
            Py_DECREF(indices);
            if (%(output_name)s == NULL) %(fail)s;
        (   R   R   R   R   R   (
   R    R   R   t   input_namest   output_namesR   t   a_namet   i_namet   output_nameR   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    

Lc         C` s   d S(   Ni    i   i   (   i    i   i   (    (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   A  s    (    (   R"   R#   R$   R  RF   R  RJ   R   R   R   R   R   R  R   Rt  R   R   (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s   								UR!  c           B` s   e  Z d  Z d Z 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 RS(   sI   
    Increments a subtensor using advanced slicing (list of index).

    R  R  c         C` s2   | |  _  | |  _ | r. i d g d 6|  _ n  d  S(   Ni    (   R  R  R<  (   R    R  R  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   O  s    		c         C` s   |  j  d t d |  j  S(   NR  R  (   R   RF   R  (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   clone_inplaceU  s    	c         C` sJ   |  j  r d } n d } |  j r. | d 7} n
 | d 7} |  j j d | S(   NR  t
   no_inplaces   ,sets   ,incs   {%s}(   R  R  R   R"   (   R    R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   Z  s    			
c         C` s  t  j j |  } t  j j |  } t  j j |  } | j j t  j j k r] t d   n  | j j d k r~ t d   n  | j j d k r t d   n  | j j | j j k r |  j r d } n d } t d | | j j | j j f   n  t	 |  | | | g | j   g  S(	   Ns   index must be integersi   s   index must be vectori    s   cannot index into a scalart   sett	   incrementsQ   cannot %s x subtensor with ndim=%s by y with ndim=%s to x subtensor with ndim=%s (
   RG   RH   R   R   R   Ra  R   R   R  R	   (   R    RK   R  R3  Rb  t   y_Rc  t   opname(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   f  s"    		"c         C` s   d t    S(   sP  
        Parameters
        ----------
        x : string
            Gives the name of a C variable pointing to an array.

        Returns
        -------
        object
            C code expression to make a copy of x.

        Base class uses PyArrayObject *, subclasses may override for
        different types of arrays.

        sa   (PyArrayObject*)PyArray_FromAny(py_%(x)s, NULL, 0, 0,
                NPY_ARRAY_ENSURECOPY, NULL)(   R   (   R    RK   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRI  }  s    c         C` s   d d l  m } |   S(   Ni    (   t   compile_cutils_code(   t   theano.gof.cutilsR  (   R    R  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRt    s    c         C` s   g  t  j j d  d  D] } t |  ^ q } t | d d g k   rP t  n  | \ } }	 }
 | d } | d } d |  j } |  j r d } n d } |  j |  } d t	   S(   Nt   .i   i   i   i    R   sa  
        PyObject* rval = NULL;
        if (%(inplace)s)
        {
            if (%(x)s != %(out)s)
            {
                Py_XDECREF(%(out)s);
                Py_INCREF(%(x)s);
                %(out)s = %(x)s;
            }
        }
        else
        {
            Py_XDECREF(%(out)s);
            %(out)s = %(copy_of_x)s;
        }
        PyObject *arglist = Py_BuildValue("OOOi",%(out)s, %(idx)s, %(y)s, %(inc_or_set)d);
        rval = inplace_increment(NULL, arglist);
        Py_XDECREF(arglist);
        if (rval == NULL) {
            %(fail)s;
        }
        Py_XDECREF(rval);
        (
   R+   t   __version__t   splitRB  t   boolR   R  R  RI  R   (   R    R   R   Ru  Rv  R   R?   t	   numpy_verRK   R  Rs   R   R   t
   inc_or_setR  RI  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    /	

		c         C` s   d S(   Ni   (   i   (    (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c   	      C` s   | \ } } } | \ } |  j  s0 | j   } n  |  j rF | | | <n+ t j rX t } n	 |  j } | | | |  | | d <d  S(   Ni    (   R  RD  R  R   t   cxxR   t   inplace_increment1d_slow(	   R    R   Rj  R   RK   R  Rs   R   R}  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    						c         C` s   | j  | j  k s t  | j  | j  k r t |  d k rj | d } xt | D] } | | c | 7<qM Wq t |  t |  k s t  d } xP | D]$ } | | c | | 7<| d 7} q Wn! x | D] } | | c | 7<q Wd  S(   Ni   i    (   R   RU   R9   (   R    RK   Rs   R  t   y_0R   t   j(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    s    
c         C` s   | \ } } } | g S(   N(    (   R    R   Rs  RK   R  R3  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` s9   d  | d  k r d  g S|  j | d | d | d  j S(   Ni   i    i   (   R%   R   R   (   R    R<   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    s    c         C` s   t  g t  g t g g } | S(   N(   RF   RJ   (   R    R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c   	      C` s  | \ } | \ } } } | j  t j j k r | j d t j j  } | j  t j j k ru | j d t j j  } q | j   } nl | j  t j j k r t d   nH |  j	 r t
 | | j   |  } n | } t | |  } t | |  } | | g t     g S(   NR   s   No support for complex grad yet(   R   RG   RH   R   R   R   R   RV  R   R  t   advanced_set_subtensor1t   advanced_subtensor1RW  R   (	   R    R<   R   RX  RK   R  R=   RY  RZ  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR      s$    			(   s   inplaces   set_instead_of_inc(   R"   R#   R$   R  RJ   R   Rz  R   R   RI  Rt  R   R   R   R  R   R  R   R   (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR!  G  s    						'						R  c         C` s   |  d  k r t j   St |  t  r/ t |   St |  t j  rW t |  j t	  rW |  St |  t j  r t |  j t
  r |  St j j |   }  |  j j t j j k r t d   n  |  S(   Ns   index must be integers(   R%   R   t   cloneR&   R'   R   R   R   R   R   R   RG   RH   R   R   Ra  R   (   Rs   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   as_index_variable  s    

$$c         C` sw   d   } t  t | |   } g  |  j D] } d | ^ q( } t j |  | j } t  g  | D] } | d k ^ q^  S(   s   
    This function is only used to determine the broadcast pattern for
    AdvancedSubtensor output variable.

    For this, we make a fake ndarray and a fake idx and call use ask numpy
    the output. From this, we find the output broadcast pattern.

    c         S` s   t  |  t j  rI t |  j  d k r9 t d |    qI |  j d }  n  t j |   r\ d  St  |  j	 t
  r{ t d  d   St j d |  j t  S(   Ni   sD   It is ambiguous which output of a multi-output Op has to be fetched.i    i   (   i   (   R&   R   R	   R9   R   R   R   t   equalsR%   R   R   R'   R+   t   zerosR   RB  (   R7  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   replace_slice6  s    i   i   (   R2   R3   R   R+   t   emptyR+  (   R0   Rs   R  t   newidxR   t	   fakeshapet   retshapeR/  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   adv_index_broadcastable_pattern,  s
    
	 R"  c           B` sJ   e  Z d  Z d Z d   Z d   Z d   Z d   Z d   Z d   Z	 RS(   s<   
    Return a subtensor copy, using advanced indexing.

    c         G` sn   t  j j |  } t t t |   } t | |  } t j |  | f | t  j j d | j	 j
 d |  g  S(   NR   R   (   RG   RH   R   R2   R3   R  R  R   R	   R   R   (   R    RK   t   indexRd  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   Y  s    	
c         C` s2   | d d  k r d  g S|  j | d | d  j S(   Ni    i   (   R%   R   R   (   R    R<   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR  c  s    c         C` s   t  |  d k r | \ } } } t  |  d k r | d  k	 r t  |  d k r | d  k	 r t  |  d k r | j d j d  k r | g S| g Sq n  t j j j d   d  S(   Ni   i   i   s   case not implemented(   R9   R%   R<   R  RG   RH   t   basict
   ShapeError(   R    R   Rs  R   t   ind1shpt   ind2shp(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   h  s    c         C` s(   | \ } | d j  | d  | d <d  S(   Ni    i   (   R   (   R    R   R<   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR   y  s    	c         C` s8   t  g g } x% | j d D] } | j t g  q W| S(   Ni   (   RF   R<   Rn   RJ   (   R    R   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` sS   | \ } | d } | d } t  t j j |  | |  g t     g t |  S(   Ni    i   (   t   advanced_inc_subtensorRG   RH   R   R   R9   (   R    R<   R   R   RK   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    	

	(    (
   R"   R#   R$   R  R   R  R   R   R   R   (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR"  N  s   	
				R#  c           B` sb   e  Z d  Z d Z e e d  Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z RS(   s9   
    Increments a subtensor using advanced indexing.
    R  R  c         C` sC   | |  _  | |  _ t | t  s' t  |  j  r? t d   n  d  S(   Ns'   In place computation is not implemented(   R  R  R&   R  RU   R   (   R    R  R  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s
    			c         C` s1   d |  j  j d t |  j  d t |  j  f S(   Ns
   %s{%s, %s}s   inplace=s    set_instead_of_inc=(   R   R"   R   R  R  (   R    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         G` s   t  j j |  } t  j j |  } g  } xE | D]= } t | t t f  ra t  j j |  } n  | j |  q1 Wt j |  | | f t |  t  j j d | j	 j
 d | j	 j  g  S(   NR   R   (   RG   RH   R   R&   R:   R2   Rn   R   R	   R   R   R   (   R    RK   R  R<   t
   new_inputsRj  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    	c         C` s   | \ } |  j  s) | d j   | d <n | d | d <|  j rY | d | d | d <n: t j r t | d t | d  | d  n t d   d  S(   Ni    i   i   s   Could not import inplace_increment, so advanced indexing is disabled. Please make sure that you have a working C++ compiler and that config.cxx is correctly set.(   R  RD  R  R   R  R   R2   R   (   R    R   R<   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    				%c         C` s   | d g S(   Ni    (    (   R    R   Rs  (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c         C` s>   t  g t  g g } x% | j d D] } | j t g  q  W| S(   Ni   (   RF   R<   Rn   RJ   (   R    R   R   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s    c   
      C` s"  | d  \ } } | d } | \ } | j  t j j k r | j d t j j  } | j  t j j k r | j d t j j  } q | j   } nl | j  t j j k r t d   nH |  j	 r t
 | | j   |  } n | } t | |  } t | |  } | | g g  | D] }	 t     ^ qS(   Ni   R   s   No support for complex grad yet(   R   RG   RH   R   R   R   R   RV  R   R  t   advanced_set_subtensort   advanced_subtensorRW  R   (
   R    t   inptt   output_gradientsRK   R  Rr   t   outgradRY  RZ  t   _(    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR     s(    
				c         C` s9   d  | d  k r d  g S|  j | d | d | d  j S(   Ni   i    i   (   R%   R   R   (   R    R<   R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR    s    (   s   inplaces   set_instead_of_inc(   R"   R#   R$   R  RJ   R   R   R   R   R   R   R   R  (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyR#    s   
							t   raisec         C` s  t  j j |   }  t  j j |  } | j d k r0| d k r_ t | d |  j | d  } n  | d k r | |  j | } n  | d  k r t |  j   |  S| d k r t |  |  S| d k  r | |  j 7} n  | d k s t	  t
 t |  j   } | | d <d | | <t |  j |  |  j |  Sn  | d  k rQ| j } | j } n | d k rt  j j | j |  j | d g  } nL | d k  r| |  j 7} n  t  j j |  j |  | j |  j | d g  } |  j | j d } t |  | j   | |  j | |  S(   Ni   R   i    t   wrap(   RG   RH   R   R   R   R+  R%   R  t   flattenRU   R:   R'  R)  t   concatenateRi  R,  (   R0   R8   R[  t   modet   shuffleR+  R   (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyRi    s>     

		 	'(P   t
   __future__R    R   R   RS   t   textwrapR   R(  t   loggingR+   t   sixR   t	   six.movesR   RG   t   theano.compatR   t   theano.gradientR   R   t
   theano.gofR	   R
   R   R   R   t   theano.printingR   R   R-   t   theano.tensor.basicR   R   R   R   R   R   t   theano.tensor.elemwiseR   t   theano.tensor.type_otherR   R   R   R   R   R  R  t   cutils_ext.cutils_extR   t	   getLoggert   _loggerR%   Rm  R   R   R4   RJ   RA   Rl   Rm   R	  t   assignR  R  R   RW  R   R  R!  Rq  RF   R  R  R  R"  R  R#  R  R  Ri  (    (    (    s7   /tmp/pip-build-X4mzal/theano/theano/tensor/subtensor.pyt   <module>   sj   (("		#	  0 	+				"@	h	