#NEWLINE# def jacobian( expression , wrt , consider_constant = None , disconnected_inputs = 'raise' ) : #NEWLINE# #INDENT# "\n    :type expression: Vector (1-dimensional) Variable\n    :type wrt: Variable or list of Variables\n\n    :param consider_constant: a list of expressions not to backpropagate\n        through\n\n    :type disconnected_inputs: string\n    :param disconnected_inputs: Defines the behaviour if some of the variables\n        in ``wrt`` are not part of the computational graph computing ``cost``\n        (or if all links are non-differentiable). The possible values are:\n        - 'ignore': considers that the gradient on these parameters is zero.\n        - 'warn': consider the gradient zero, and print a warning.\n        - 'raise': raise an exception.\n\n    :return: either a instance of Variable or list/tuple of Variables\n            (depending upon `wrt`) repesenting the jacobian of `expression`\n            with respect to (elements of) `wrt`. If an element of `wrt` is not\n            differentiable with respect to the output, then a zero\n            variable is returned. The return value is of same type\n            as `wrt`: a list/tuple or TensorVariable in all cases.\n    " #NEWLINE# from theano.tensor import arange #NEWLINE# assert isinstance ( expression , Variable ) , 'tensor.jacobian expects a Variable as `expression`' #NEWLINE# assert ( expression . ndim < 2 ) , 'tensor.jacobian expects a 1 dimensional variable as `expression`. If not use flatten to make it a vector' #NEWLINE# using_list = isinstance ( wrt , list ) #NEWLINE# using_tuple = isinstance ( wrt , tuple ) #NEWLINE# if isinstance ( wrt , ( list , tuple ) ) : #NEWLINE# #INDENT# wrt = list ( wrt ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# wrt = [ wrt ] #NEWLINE# #UNINDENT# if ( expression . ndim == 0 ) : #NEWLINE# #INDENT# return format_as ( using_list , using_tuple , grad ( expression , wrt , consider_constant = consider_constant , disconnected_inputs = disconnected_inputs ) ) #NEWLINE# #UNINDENT# def inner_function( * args ) : #NEWLINE# #INDENT# idx = args [ 0 ] #NEWLINE# expr = args [ 1 ] #NEWLINE# rvals = [ ] #NEWLINE# for inp in args [ 2 : ] : #NEWLINE# #INDENT# rval = grad ( expr [ idx ] , inp , consider_constant = consider_constant , disconnected_inputs = disconnected_inputs ) #NEWLINE# rvals . append ( rval ) #NEWLINE# #UNINDENT# return rvals #NEWLINE# #UNINDENT# ( jacobs , updates ) = theano . scan ( inner_function , sequences = arange ( expression . shape [ 0 ] ) , non_sequences = ( [ expression ] + wrt ) ) #NEWLINE# assert ( not updates ) , 'Scan has returned a list of updates. This should not happen! Report this to theano-users (also include the script that generated the error)' #NEWLINE# return format_as ( using_list , using_tuple , jacobs )