def __getitem__(self, args): if not isinstance(args, tuple): args = args, # Determine if advanced indexing is needed or not # The logic is already in Subtensor.convert: if it succeeds, # standard indexing is used; if it fails with # AdvancedIndexingError, advanced indexing advanced = False axis = None for i, arg in enumerate(args): try: if arg != numpy.newaxis: theano.tensor.subtensor.Subtensor.convert(arg) except theano.tensor.subtensor.AdvancedIndexingError: if advanced: axis = None break else: advanced = True axis = i if advanced: if (axis is not None and all(a == slice(None) for a in args[:axis]) and all(a == slice(None) for a in args[axis + 1:]) and isinstance(args[axis], ( numpy.ndarray, list, TensorVariable, TensorConstant, theano.tensor.sharedvar.TensorSharedVariable))): return self.take(arg, axis) else: return theano.tensor.subtensor.AdvancedSubtensor()(self, *args) else: if numpy.newaxis in args: # None (aka np.newaxis) in numpy indexing means to add a # broadcastable dimension, which theano traditionally did with # the dimshuffle op. The following code converts numpy-style # indexing on self to traditional [read: implemented] theano # indexing on a dimshuffled view of self. counter = 0 pattern = [] new_args = [] for arg in args: if arg == numpy.newaxis: pattern.append('x') new_args.append(slice(None, None, None)) else: pattern.append(counter) counter += 1 new_args.append(arg) view = self.dimshuffle(pattern) rval = view.__getitem__(tuple(new_args)) return rval else: return theano.tensor.subtensor.Subtensor(args)( self, *theano.tensor.subtensor.Subtensor.collapse(args, lambda entry: isinstance(entry, Variable)))
def __getitem__(self, args): if not isinstance(args, tuple): args = args, # Determine if advanced indexing is needed or not # The logic is already in Subtensor.convert: if it succeeds, # standard indexing is used; if it fails with # AdvancedIndexingError, advanced indexing advanced = False axis = None for i, arg in enumerate(args): try: if arg != numpy.newaxis: theano.tensor.subtensor.Subtensor.convert(arg) except theano.tensor.subtensor.AdvancedIndexingError: if advanced: axis = None break else: advanced = True axis = i if advanced: if (axis is not None and all(a == slice(None) for a in args[:axis]) and all(a == slice(None) for a in args[axis + 1:]) and isinstance(args[axis], ( numpy.ndarray, list, TensorVariable, TensorConstant, theano.tensor.sharedvar.TensorSharedVariable))): return self.take(arg, axis) else: return theano.tensor.subtensor.advanced_subtensor(self, *args) else: if numpy.newaxis in args: # None (aka np.newaxis) in numpy indexing means to add a # broadcastable dimension, which theano traditionally did with # the dimshuffle op. The following code converts numpy-style # indexing on self to traditional [read: implemented] theano # indexing on a dimshuffled view of self. counter = 0 pattern = [] new_args = [] for arg in args: if arg == numpy.newaxis: pattern.append('x') new_args.append(slice(None, None, None)) else: pattern.append(counter) counter += 1 new_args.append(arg) view = self.dimshuffle(pattern) rval = view.__getitem__(tuple(new_args)) return rval else: return theano.tensor.subtensor.Subtensor(args)( self, *theano.tensor.subtensor.Subtensor.collapse(args, lambda entry: isinstance(entry, Variable)))
class T_picklefunction(unittest.TestCase): def test_deepcopy(self): a = T.scalar() # the a is for 'anonymous' (un-named). x, s = T.scalars('xs') f = function([ x, In(a, value=1.0, name='a'), In(s, value=0.0, update=s + a * x, mutable=True) ], s + a * x) try: g = copy.deepcopy(f) except NotImplementedError, e: if e[0].startswith('DebugMode is not picklable'): return else: raise #if they both return, assume that they return equivalent things. #print [(k,id(k)) for k in f.finder.keys()] #print [(k,id(k)) for k in g.finder.keys()] self.assertFalse(g.container[0].storage is f.container[0].storage) self.assertFalse(g.container[1].storage is f.container[1].storage) self.assertFalse(g.container[2].storage is f.container[2].storage) self.assertFalse(x in g.container) self.assertFalse(x in g.value) self.assertTrue(len(f.defaults) == len(g.defaults)) #print 'f.defaults = %s' % (f.defaults, ) #print 'g.defaults = %s' % (g.defaults, ) self.assertTrue( all([ f_req == g_req and f_feed == g_feed and f_val == g_val for ((f_req, f_feed, f_val), (g_req, g_feed, g_val)) in zip(f.defaults, g.defaults) ])) self.assertFalse( g.value[1] is f.value[1]) # should not have been copied self.assertFalse( g.value[2] is f.value[2]) # should have been copied because it is mutable. self.assertFalse( (g.value[2] != f.value[2]).any()) # its contents should be identical self.assertTrue(f(2, 1) == g( 2)) #they should be in sync, default value should be copied. self.assertTrue(f(2, 1) == g( 2)) #they should be in sync, default value should be copied. f(1, 2) # put them out of sync self.assertFalse(f(1, 2) == g(1, 2)) #they should not be equal anymore. g(1, 2) # put them back in sync self.assertTrue(f(3) == g(3)) # They should be in sync again.