#NEWLINE# def Rop( f , wrt , eval_points ) : #NEWLINE# #INDENT# '\n    Computes the R operation on `f` wrt to `wrt` evaluated at points given\n    in `eval_points`. Mathematically this stands for the jacobian of `f` wrt\n    to `wrt` right muliplied by the eval points.\n\n    :type f: Variable or list of Variables\n             `f` stands for the output of the computational graph to which you\n             want to apply the R operator\n    :type wrt: Variable or list of `Variables`s\n               variables for which you compute the R operator of the expression\n               described by `f`\n    :type eval_points: Variable or list of Variables\n                       evalutation points for each of the variables in `wrt`\n    :rtype: Variable or list/tuple of Variables depending on type of f\n    :return: symbolic expression such that\n        R_op[i] = sum_j ( d f[i] / d wrt[j]) eval_point[j]\n        where the indices in that expression are magic multidimensional\n        indices that specify both the position within a list and all\n        coordinates of the tensor element in the last.\n        If `wrt` is a list/tuple, then return a list/tuple with the results.\n    ' #NEWLINE# from theano.tensor import as_tensor_variable #NEWLINE# using_list = isinstance ( f , list ) #NEWLINE# using_tuple = isinstance ( f , tuple ) #NEWLINE# if ( not isinstance ( wrt , ( list , tuple ) ) ) : #NEWLINE# #INDENT# wrt = [ wrt ] #NEWLINE# #UNINDENT# if ( not isinstance ( eval_points , ( list , tuple ) ) ) : #NEWLINE# #INDENT# eval_points = [ eval_points ] #NEWLINE# #UNINDENT# if ( not isinstance ( f , ( list , tuple ) ) ) : #NEWLINE# #INDENT# f = [ f ] #NEWLINE# #UNINDENT# assert ( len ( wrt ) == len ( eval_points ) ) #NEWLINE# for pack in enumerate ( zip ( wrt , eval_points ) ) : #NEWLINE# #INDENT# i = pack [ 0 ] #NEWLINE# ( wrt_elem , eval_point ) = pack [ 1 ] #NEWLINE# if ( not isinstance ( wrt_elem , gof . Variable ) ) : #NEWLINE# #INDENT# wrt_elem = as_tensor_variable ( wrt_elem ) #NEWLINE# #UNINDENT# if ( not isinstance ( eval_point , gof . Variable ) ) : #NEWLINE# #INDENT# eval_point = as_tensor_variable ( eval_point ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# if ( wrt_elem . type . ndim != eval_point . type . ndim ) : #NEWLINE# #INDENT# raise ValueError ( ( ( ( ( ( ( 'Element ' + str ( i ) ) + ' of wrt/eval_point have mismatched ' ) + 'dimensionality: ' ) + str ( wrt_elem . type . ndim ) ) + ' versus ' ) + str ( eval_point . type . ndim ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# except AttributeError : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# #UNINDENT# seen_nodes = OrderedDict ( ) #NEWLINE# def _traverse( node ) : #NEWLINE# #INDENT# ' TODO: writeme ' #NEWLINE# if ( node is None ) : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# op = node . op #NEWLINE# inputs = node . inputs #NEWLINE# local_eval_points = [ ] #NEWLINE# for inp in inputs : #NEWLINE# #INDENT# if ( inp in wrt ) : #NEWLINE# #INDENT# local_eval_points . append ( eval_points [ wrt . index ( inp ) ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( inp . owner is None ) : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# local_eval_points . append ( inp . zeros_like ( ) ) #NEWLINE# #UNINDENT# except : #NEWLINE# #INDENT# local_eval_points . append ( None ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( inp . owner in seen_nodes ) : #NEWLINE# #INDENT# local_eval_points . append ( seen_nodes [ inp . owner ] [ inp . owner . outputs . index ( inp ) ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# _traverse ( inp . owner ) #NEWLINE# local_eval_points . append ( seen_nodes [ inp . owner ] [ inp . owner . outputs . index ( inp ) ] ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# same_type_eval_points = [ ] #NEWLINE# for ( x , y ) in zip ( inputs , local_eval_points ) : #NEWLINE# #INDENT# if ( y is not None ) : #NEWLINE# #INDENT# if ( not isinstance ( x , gof . Variable ) ) : #NEWLINE# #INDENT# x = as_tensor_variable ( x ) #NEWLINE# #UNINDENT# if ( not isinstance ( y , gof . Variable ) ) : #NEWLINE# #INDENT# y = as_tensor_variable ( y ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# y = x . type . filter_variable ( y ) #NEWLINE# #UNINDENT# except TypeError : #NEWLINE# #INDENT# y = theano . tensor . cast ( y , x . type . dtype ) #NEWLINE# y = x . type . filter_variable ( y ) #NEWLINE# #UNINDENT# assert ( x . type == y . type ) #NEWLINE# same_type_eval_points . append ( y ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# same_type_eval_points . append ( y ) #NEWLINE# #UNINDENT# #UNINDENT# seen_nodes [ node ] = op . R_op ( node . inputs , same_type_eval_points ) #NEWLINE# #UNINDENT# for out in f : #NEWLINE# #INDENT# _traverse ( out . owner ) #NEWLINE# #UNINDENT# rval = [ ] #NEWLINE# for out in f : #NEWLINE# #INDENT# if ( out in wrt ) : #NEWLINE# #INDENT# rval . append ( eval_points [ wrt . index ( out ) ] ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( seen_nodes [ out . owner ] [ out . owner . outputs . index ( out ) ] is None ) : #NEWLINE# #INDENT# raise ValueError ( 'The function is not differentiable with respect to the provided inputs !' ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# rval . append ( seen_nodes [ out . owner ] [ out . owner . outputs . index ( out ) ] ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# return format_as ( using_list , using_tuple , rval )