def __init__(self, group, template, code='', user_code=None, dt=None, clock=None, when='start', order=0, name='coderunner*', check_units=True, template_kwds=None, needed_variables=None, override_conditional_write=None, codeobj_class=None, generate_empty_code=True ): BrianObject.__init__(self, clock=clock, dt=dt, when=when, order=order, name=name) self.group = weakproxy_with_fallback(group) self.template = template self.user_code = user_code self.abstract_code = code self.check_units = check_units if needed_variables is None: needed_variables = [] self.needed_variables = needed_variables self.template_kwds = template_kwds self.override_conditional_write = override_conditional_write if codeobj_class is None: codeobj_class = group.codeobj_class self.codeobj_class = codeobj_class self.generate_empty_code = generate_empty_code self.codeobj = None
def __init__(self, name, unit, owner, size, device, dtype=None, constant=False, scalar=False, read_only=False): super(ArrayVariable, self).__init__(unit=unit, name=name, dtype=dtype, scalar=scalar, constant=constant, read_only=read_only) #: The `Group` to which this variable belongs. self.owner = weakproxy_with_fallback(owner) #: The `Device` responsible for memory access. self.device = device #: The size of this variable. self.size = size if scalar and size != 1: raise ValueError(('Scalar variables need to have size 1, not ' 'size %d.') % size) #: Another variable, on which the write is conditioned (e.g. a variable #: denoting the absence of refractoriness) self.conditional_write = None
def __init__(self, source, start, stop, name=None): # First check if the source is itself a Subgroup # If so, then make this a Subgroup of the original Group if isinstance(source, Subgroup): source = source.source start = start + source.start stop = stop + source.start self.source = source else: self.source = weakproxy_with_fallback(source) if name is None: name = source.name + '_subgroup*' # We want to update the spikes attribute after it has been updated # by the parent, we do this in slot 'thresholds' with an order # one higher than the parent order to ensure it takes place after the # parent threshold operation schedule = Scheduler(clock=source.clock, when='thresholds', order=source.order + 1) Group.__init__(self, when=schedule, name=name) self._N = stop - start self.start = start self.stop = stop # All the variables have to go via the _sub_idx to refer to the # appropriate values in the source group self.variables = Variables(self, default_index='_sub_idx') # overwrite the meaning of N and i self.variables.add_constant('_offset', unit=Unit(1), value=self.start) self.variables.add_reference('_source_i', source, 'i') self.variables.add_subexpression('i', unit=Unit(1), dtype=source.variables['i'].dtype, expr='_source_i - _offset') self.variables.add_constant('N', unit=Unit(1), value=self._N) # add references for all variables in the original group self.variables.add_references(source, source.variables.keys()) # Only the variable _sub_idx itself is stored in the subgroup # and needs the normal index for this group self.variables.add_arange('_sub_idx', size=self._N, start=self.start, index='_idx') for key, value in self.source.variables.indices.iteritems(): if value not in ('_idx', '0'): raise ValueError( ('Do not know how to deal with variable %s ' 'using index %s in a subgroup') % (key, value)) self.namespace = self.source.namespace self.codeobj_class = self.source.codeobj_class self._enable_group_attributes()
def __init__(self, source, start, stop, name=None): # First check if the source is itself a Subgroup # If so, then make this a Subgroup of the original Group if isinstance(source, Subgroup): source = source.source start = start + source.start stop = stop + source.start self.source = source else: self.source = weakproxy_with_fallback(source) if name is None: name = source.name + '_subgroup*' # We want to update the spikes attribute after it has been updated # by the parent, we do this in slot 'thresholds' with an order # one higher than the parent order to ensure it takes place after the # parent threshold operation schedule = Scheduler(clock=source.clock, when='thresholds', order=source.order+1) Group.__init__(self, when=schedule, name=name) self._N = stop-start self.start = start self.stop = stop # All the variables have to go via the _sub_idx to refer to the # appropriate values in the source group self.variables = Variables(self, default_index='_sub_idx') # overwrite the meaning of N and i self.variables.add_constant('_offset', unit=Unit(1), value=self.start) self.variables.add_reference('_source_i', source, 'i') self.variables.add_subexpression('i', unit=Unit(1), dtype=source.variables['i'].dtype, expr='_source_i - _offset') self.variables.add_constant('N', unit=Unit(1), value=self._N) # add references for all variables in the original group self.variables.add_references(source, source.variables.keys()) # Only the variable _sub_idx itself is stored in the subgroup # and needs the normal index for this group self.variables.add_arange('_sub_idx', size=self._N, start=self.start, index='_idx') for key, value in self.source.variables.indices.iteritems(): if value not in ('_idx', '0'): raise ValueError(('Do not know how to deal with variable %s ' 'using index %s in a subgroup') % (key, value)) self.namespace = self.source.namespace self.codeobj_class = self.source.codeobj_class self._enable_group_attributes()
def __init__(self, owner, default_index='_idx'): #: A reference to the `Group` owning these variables self.owner = weakproxy_with_fallback(owner) # The index that is used for arrays if no index is given explicitly self.default_index = default_index # We do the import here to avoid a circular dependency. from brian2.devices.device import get_device self.device = get_device() self._variables = {} #: A dictionary given the index name for every array name self.indices = collections.defaultdict( functools.partial(str, default_index))
def __init__(self, name, unit, owner, expr, device, dtype=None, scalar=False): super(Subexpression, self).__init__(unit=unit, name=name, dtype=dtype, scalar=scalar, constant=False, read_only=True) #: The `Group` to which this variable belongs self.owner = weakproxy_with_fallback(owner) #: The `Device` responsible for memory access self.device = device #: The expression defining the subexpression self.expr = expr.strip() if scalar: from brian2.parsing.sympytools import str_to_sympy # We check here if the corresponding sympy expression contains a # reference to _vectorisation_idx which indicates that an implicitly # vectorized function (e.g. rand() ) has been used. We do not allow # this since it would lead to incorrect results when substituted into # vector equations sympy_expr = str_to_sympy(self.expr) if sympy.Symbol('_vectorisation_idx') in sympy_expr.atoms(): raise SyntaxError(('The scalar subexpression %s refers to an ' 'implicitly vectorized function -- this is ' 'not allowed since it leads to different ' 'interpretations of this subexpression ' 'depending on whether it is used in a ' 'scalar or vector context.') % name) #: The identifiers used in the expression self.identifiers = get_identifiers(expr)
def __init__(self, source, start, stop, name=None): # First check if the source is itself a Subgroup # If so, then make this a Subgroup of the original Group if isinstance(source, Subgroup): source = source.source start = start + source.start stop = stop + source.start self.source = source else: self.source = weakproxy_with_fallback(source) # Store a reference to the source's equations (if any) self.equations = None if hasattr(self.source, 'equations'): self.equations = weakproxy_with_fallback(self.source.equations) if name is None: name = source.name + '_subgroup*' # We want to update the spikes attribute after it has been updated # by the parent, we do this in slot 'thresholds' with an order # one higher than the parent order to ensure it takes place after the # parent threshold operation Group.__init__(self, clock=source._clock, when='thresholds', order=source.order+1, name=name) self._N = stop-start self.start = start self.stop = stop self.events = self.source.events # All the variables have to go via the _sub_idx to refer to the # appropriate values in the source group self.variables = Variables(self, default_index='_sub_idx') # overwrite the meaning of N and i if self.start > 0: self.variables.add_constant('_offset', value=self.start) self.variables.add_reference('_source_i', source, 'i') self.variables.add_subexpression('i', dtype=source.variables['i'].dtype, expr='_source_i - _offset', index='_idx') else: # no need to calculate anything if this is a subgroup starting at 0 self.variables.add_reference('i', source) self.variables.add_constant('N', value=self._N) self.variables.add_constant('_source_N', value=len(source)) # add references for all variables in the original group self.variables.add_references(source, source.variables.keys()) # Only the variable _sub_idx itself is stored in the subgroup # and needs the normal index for this group self.variables.add_arange('_sub_idx', size=self._N, start=self.start, index='_idx') # special indexing for subgroups self._indices = Indexing(self, self.variables['_sub_idx']) # Deal with special indices for key, value in self.source.variables.indices.iteritems(): if value == '0': self.variables.indices[key] = '0' elif value == '_idx': continue # nothing to do, already uses _sub_idx correctly else: raise ValueError(('Do not know how to deal with variable %s ' 'using index %s in a subgroup') % (key, value)) self.namespace = self.source.namespace self.codeobj_class = self.source.codeobj_class self._enable_group_attributes()
def __init__(self, source, start, stop, name=None): # First check if the source is itself a Subgroup # If so, then make this a Subgroup of the original Group if isinstance(source, Subgroup): source = source.source start = start + source.start stop = stop + source.start self.source = source else: self.source = weakproxy_with_fallback(source) # Store a reference to the source's equations (if any) self.equations = None if hasattr(self.source, 'equations'): self.equations = weakproxy_with_fallback(self.source.equations) if name is None: name = source.name + '_subgroup*' # We want to update the spikes attribute after it has been updated # by the parent, we do this in slot 'thresholds' with an order # one higher than the parent order to ensure it takes place after the # parent threshold operation Group.__init__(self, clock=source._clock, when='thresholds', order=source.order + 1, name=name) self._N = stop - start self.start = start self.stop = stop self.events = self.source.events # All the variables have to go via the _sub_idx to refer to the # appropriate values in the source group self.variables = Variables(self, default_index='_sub_idx') # overwrite the meaning of N and i if self.start > 0: self.variables.add_constant('_offset', value=self.start) self.variables.add_reference('_source_i', source, 'i') self.variables.add_subexpression('i', dtype=source.variables['i'].dtype, expr='_source_i - _offset', index='_idx') else: # no need to calculate anything if this is a subgroup starting at 0 self.variables.add_reference('i', source) self.variables.add_constant('N', value=self._N) self.variables.add_constant('_source_N', value=len(source)) # add references for all variables in the original group self.variables.add_references(source, list(source.variables.keys())) # Only the variable _sub_idx itself is stored in the subgroup # and needs the normal index for this group self.variables.add_arange('_sub_idx', size=self._N, start=self.start, index='_idx') # special indexing for subgroups self._indices = Indexing(self, self.variables['_sub_idx']) # Deal with special indices for key, value in self.source.variables.indices.items(): if value == '0': self.variables.indices[key] = '0' elif value == '_idx': continue # nothing to do, already uses _sub_idx correctly else: raise ValueError( ('Do not know how to deal with variable %s ' 'using index %s in a subgroup') % (key, value)) self.namespace = self.source.namespace self.codeobj_class = self.source.codeobj_class self._enable_group_attributes()
def __init__(self, name, variable, group, unit=None): self.name = name self.variable = variable self.group = weakproxy_with_fallback(group) self.unit = unit