def before_run(self, run_namespace=None, level=0): # execute code to initalize the data structures if self._prepare_codeobj is None: self._prepare_codeobj = create_runner_codeobj( self.group, '', # no code, 'spatialneuron_prepare', name=self.name + '_spatialneuron_prepare', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level + 1) self._prepare_codeobj() # Raise a warning if the slow pure numpy version is used # For simplicity, we check which CodeObject class the _prepare_codeobj # is using, this will be the same as the main state updater from brian2.codegen.runtime.numpy_rt.numpy_rt import NumpyCodeObject if isinstance(self._prepare_codeobj, NumpyCodeObject): # If numpy is used, raise a warning if scipy is not present try: import scipy except ImportError: logger.warn( ('SpatialNeuron will use numpy to do the numerical ' 'integration -- this will be very slow. Either ' 'switch to a different code generation target ' '(e.g. weave or cython) or install scipy.'), once=True) CodeRunner.before_run(self, run_namespace, level=level + 1)
def before_run(self, run_namespace): # execute code to initalize the data structures if self._prepare_codeobj is None: self._prepare_codeobj = create_runner_codeobj(self.group, '', # no code, 'spatialneuron_prepare', name=self.name+'_spatialneuron_prepare', check_units=False, additional_variables=self.variables, run_namespace=run_namespace) self._prepare_codeobj() # Raise a warning if the slow pure numpy version is used # For simplicity, we check which CodeObject class the _prepare_codeobj # is using, this will be the same as the main state updater from brian2.codegen.runtime.numpy_rt.numpy_rt import NumpyCodeObject if isinstance(self._prepare_codeobj, NumpyCodeObject): # If numpy is used, raise a warning if scipy is not present try: import scipy except ImportError: logger.info(('SpatialNeuron will use numpy to do the numerical ' 'integration -- this will be very slow. Either ' 'switch to a different code generation target ' '(e.g. weave or cython) or install scipy.'), once=True) CodeRunner.before_run(self, run_namespace)
def before_run(self, run_namespace=None, level=0): # execute code to initalize the data structures if self._prepare_codeobj is None: self._prepare_codeobj = create_runner_codeobj(self.group, '', # no code, 'spatialneuron_prepare', name=self.name+'_spatialneuron_prepare', check_units=False, additional_variables=self.variables, run_namespace=run_namespace, level=level+1) self._prepare_codeobj() CodeRunner.before_run(self, run_namespace, level=level + 1)
def pre_run(self, namespace): # Some dummy code so that code generation takes care of the indexing # and subexpressions code = ['_to_record_%s = %s' % (v, v) for v in self.record_variables] code += ['_recorded_%s = _recorded_%s' % (v, v) for v in self.record_variables] code = '\n'.join(code) self.codeobj = create_runner_codeobj(self.source, code, 'statemonitor', name=self.name, additional_variables=self.variables, additional_namespace=namespace, template_kwds={'_variable_names': self.record_variables}, check_units=False)
def __getitem__(self, index): ''' Returns synaptic indices for `index`, which can be a tuple of indices (including arrays and slices), a single index or a string. ''' if (not isinstance(index, (tuple, basestring)) and isinstance(index, (int, np.ndarray, slice, collections.Sequence))): index = (index, slice(None), slice(None)) if isinstance(index, tuple): if len(index) == 2: # two indices (pre- and postsynaptic cell) index = (index[0], index[1], slice(None)) elif len(index) > 3: raise IndexError('Need 1, 2 or 3 indices, got %d.' % len(index)) I, J, K = index pre_synapses = find_synapses(I, self.pre_synaptic, self.synaptic_pre) post_synapses = find_synapses(J, self.post_synaptic, self.synaptic_post) matching_synapses = np.intersect1d(pre_synapses, post_synapses, assume_unique=True) if K == slice(None): return matching_synapses elif isinstance(K, (int, slice)): test_k = slice_to_test(K) else: raise NotImplementedError(('Indexing synapses with arrays not' 'implemented yet')) pre_neurons = self.synaptic_pre[pre_synapses] post_neurons = self.synaptic_post[post_synapses] synapse_numbers = _synapse_numbers(pre_neurons, post_neurons) return np.intersect1d(matching_synapses, np.flatnonzero(test_k(synapse_numbers)), assume_unique=True) elif isinstance(index, basestring): # interpret the string expression identifiers = get_identifiers(index) variables = dict(self.variables) if 'k' in identifiers: synapse_numbers = _synapse_numbers(self.synaptic_pre[:], self.synaptic_post[:]) variables['k'] = ArrayVariable('k', Unit(1), synapse_numbers) namespace = get_local_namespace(1) additional_namespace = ('implicit-namespace', namespace) abstract_code = '_cond = ' + index codeobj = create_runner_codeobj(self.synapses, abstract_code, 'state_variable_indexing', additional_variables=variables, additional_namespace=additional_namespace, ) result = codeobj() return result else: raise IndexError('Unsupported index type {itype}'.format(itype=type(index)))
def _add_synapses(self, sources, targets, n, p, condition=None, level=0): if condition is None: sources = np.atleast_1d(sources) targets = np.atleast_1d(targets) n = np.atleast_1d(n) p = np.atleast_1d(p) if not len(p) == 1 or p != 1: use_connections = np.random.rand(len(sources)) < p sources = sources[use_connections] targets = targets[use_connections] n = n[use_connections] sources = sources.repeat(n) targets = targets.repeat(n) new_synapses = len(sources) old_N = self.N new_N = old_N + new_synapses self._resize(new_N) self.synaptic_pre[old_N:new_N] = sources self.synaptic_post[old_N:new_N] = targets synapse_idx = old_N for source, target in zip(sources, targets): synapses = self.pre_synaptic[source] synapses.resize(len(synapses) + 1) synapses[-1] = synapse_idx synapses = self.post_synaptic[target] synapses.resize(len(synapses) + 1) synapses[-1] = synapse_idx synapse_idx += 1 else: abstract_code = '_cond = ' + condition + '\n' abstract_code += '_n = ' + str(n) + '\n' abstract_code += '_p = ' + str(p) namespace = get_local_namespace(level + 1) additional_namespace = ('implicit-namespace', namespace) variables = { '_source_neurons': ArrayVariable('_source_neurons', Unit(1), self.source.item_mapping[:] - self.source.offset, constant=True), '_target_neurons': ArrayVariable('_target_neurons', Unit(1), self.target.item_mapping[:] - self.target.offset, constant=True), # The template needs to have access to the DynamicArray here, # having access to the underlying array (which would be much # faster), is not enough '_synaptic_pre': Variable(Unit(1), self.synaptic_pre, constant=True), '_synaptic_post': Variable(Unit(1), self.synaptic_post, constant=True), '_pre_synaptic': Variable(Unit(1), self.pre_synaptic, constant=True), '_post_synaptic': Variable(Unit(1), self.post_synaptic, constant=True), # Will be set in the template 'i': Variable(unit=Unit(1), constant=True), 'j': Variable(unit=Unit(1), constant=True) } codeobj = create_runner_codeobj(self.synapses, abstract_code, 'synapses_create', additional_variables=variables, additional_namespace=additional_namespace, check_units=False ) codeobj() number = len(self.synaptic_pre) for variable in self._registered_variables: variable.resize(number)
def __getitem__(self, index): ''' Returns synaptic indices for `index`, which can be a tuple of indices (including arrays and slices), a single index or a string. ''' if (not isinstance(index, (tuple, basestring)) and isinstance( index, (int, np.ndarray, slice, collections.Sequence))): index = (index, slice(None), slice(None)) if isinstance(index, tuple): if len(index) == 2: # two indices (pre- and postsynaptic cell) index = (index[0], index[1], slice(None)) elif len(index) > 3: raise IndexError('Need 1, 2 or 3 indices, got %d.' % len(index)) I, J, K = index pre_synapses = find_synapses(I, self.pre_synaptic, self.synaptic_pre) post_synapses = find_synapses(J, self.post_synaptic, self.synaptic_post) matching_synapses = np.intersect1d(pre_synapses, post_synapses, assume_unique=True) if K == slice(None): return matching_synapses elif isinstance(K, (int, slice)): test_k = slice_to_test(K) else: raise NotImplementedError(('Indexing synapses with arrays not' 'implemented yet')) pre_neurons = self.synaptic_pre[pre_synapses] post_neurons = self.synaptic_post[post_synapses] synapse_numbers = _synapse_numbers(pre_neurons, post_neurons) return np.intersect1d(matching_synapses, np.flatnonzero(test_k(synapse_numbers)), assume_unique=True) elif isinstance(index, basestring): # interpret the string expression identifiers = get_identifiers(index) variables = dict(self.variables) if 'k' in identifiers: synapse_numbers = _synapse_numbers(self.synaptic_pre[:], self.synaptic_post[:]) variables['k'] = ArrayVariable('k', Unit(1), synapse_numbers) namespace = get_local_namespace(1) additional_namespace = ('implicit-namespace', namespace) abstract_code = '_cond = ' + index codeobj = create_runner_codeobj( self.synapses, abstract_code, 'state_variable_indexing', additional_variables=variables, additional_namespace=additional_namespace, ) result = codeobj() return result else: raise IndexError( 'Unsupported index type {itype}'.format(itype=type(index)))
def _add_synapses(self, sources, targets, n, p, condition=None, level=0): if condition is None: sources = np.atleast_1d(sources) targets = np.atleast_1d(targets) n = np.atleast_1d(n) p = np.atleast_1d(p) if not len(p) == 1 or p != 1: use_connections = np.random.rand(len(sources)) < p sources = sources[use_connections] targets = targets[use_connections] n = n[use_connections] sources = sources.repeat(n) targets = targets.repeat(n) new_synapses = len(sources) old_N = self.N new_N = old_N + new_synapses self._resize(new_N) self.synaptic_pre[old_N:new_N] = sources self.synaptic_post[old_N:new_N] = targets synapse_idx = old_N for source, target in zip(sources, targets): synapses = self.pre_synaptic[source] synapses.resize(len(synapses) + 1) synapses[-1] = synapse_idx synapses = self.post_synaptic[target] synapses.resize(len(synapses) + 1) synapses[-1] = synapse_idx synapse_idx += 1 else: abstract_code = '_cond = ' + condition + '\n' abstract_code += '_n = ' + str(n) + '\n' abstract_code += '_p = ' + str(p) namespace = get_local_namespace(level + 1) additional_namespace = ('implicit-namespace', namespace) variables = { '_source_neurons': ArrayVariable('_source_neurons', Unit(1), self.source.item_mapping[:] - self.source.offset, constant=True), '_target_neurons': ArrayVariable('_target_neurons', Unit(1), self.target.item_mapping[:] - self.target.offset, constant=True), # The template needs to have access to the DynamicArray here, # having access to the underlying array (which would be much # faster), is not enough '_synaptic_pre': Variable(Unit(1), self.synaptic_pre, constant=True), '_synaptic_post': Variable(Unit(1), self.synaptic_post, constant=True), '_pre_synaptic': Variable(Unit(1), self.pre_synaptic, constant=True), '_post_synaptic': Variable(Unit(1), self.post_synaptic, constant=True), # Will be set in the template 'i': Variable(unit=Unit(1), constant=True), 'j': Variable(unit=Unit(1), constant=True) } codeobj = create_runner_codeobj( self.synapses, abstract_code, 'synapses_create', additional_variables=variables, additional_namespace=additional_namespace, check_units=False) codeobj() number = len(self.synaptic_pre) for variable in self._registered_variables: variable.resize(number)