def test_evaluate_with_mask_2D(self): ps2d = ParameterSpace( {"a": [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], "b": 7, "c": lambda i, j: 3 * i - 2 * j}, shape=(2, 5) ) ps2d.evaluate(mask=(slice(None), [1, 3, 4])) assert_array_equal(ps2d["a"], np.array([[3, 8, 13], [34, 89, 144]])) assert_array_equal(ps2d["c"], np.array([[-2, -6, -8], [1, -3, -5]]))
def test_create_with_tuple(self): schema = {'a': Sequence} ps = ParameterSpace({'a': (1, 2, 3)}, schema, shape=(2,)) ps.evaluate() assert_array_equal(ps['a'], np.array([Sequence([1, 2, 3]), Sequence([1, 2, 3])], dtype=Sequence))
def test_create_with_list_of_lists(self): schema = {'a': Sequence} ps = ParameterSpace({'a': [[1, 2, 3], [4, 5, 6]]}, schema, shape=(2,)) ps.evaluate() assert_array_equal(ps['a'], np.array([Sequence([1, 2, 3]), Sequence([4, 5, 6])], dtype=Sequence))
def test_create_with_array_of_sequences(self): schema = {"a": Sequence} ps = ParameterSpace( {"a": np.array([Sequence([1, 2, 3]), Sequence([4, 5, 6])], dtype=Sequence)}, schema, shape=(2,) ) ps.evaluate() assert_array_equal(ps["a"], np.array([Sequence([1, 2, 3]), Sequence([4, 5, 6])], dtype=Sequence))
def test_iteration(self): ps = ParameterSpace({'a': [2, 3, 5, 8, 13], 'b': 7, 'c': lambda i: 3*i+2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) self.assertEqual(list(ps), [{'a': 3, 'c': 5, 'b': 7}, {'a': 8, 'c': 11, 'b': 7}, {'a': 13, 'c': 14, 'b': 7}])
def test_iteration_items(self): ps = ParameterSpace({'a': [2, 3, 5, 8, 13], 'b': 7, 'c': lambda i: 3 * i + 2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) expected = {'a': np.array([3, 8, 13]), 'c': np.array([5, 11, 14]), 'b': np.array([7, 7, 7])} for key, value in ps.items(): assert_array_equal(expected[key], value)
def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) if parameters: self.parameter_space.update(**parameters)
def test_evaluate_with_mask(self): ps = ParameterSpace({'a': [2, 3, 5, 8, 13], 'b': 7, 'c': lambda i: 3 * i + 2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) expected = {'a': np.array([3, 8, 13]), 'c': np.array([5, 11, 14]), 'b': np.array([7, 7, 7])} for key in expected: assert_array_equal(expected[key], ps[key])
def test_iteration_items(self): ps = ParameterSpace({'a': [2, 3, 5, 8, 13], 'b': 7, 'c': lambda i: 3*i+2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) expected = {'a': np.array([3, 8, 13]), 'c': np.array([5, 11, 14]), 'b': np.array([7, 7, 7])} for key, value in ps.items(): assert_array_equal(expected[key], value)
def test_evaluate_with_mask(self): ps = ParameterSpace({'a': [2, 3, 5, 8, 13], 'b': 7, 'c': lambda i: 3*i+2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) expected = {'a': np.array([ 3, 8, 13]), 'c': np.array([ 5, 11, 14]), 'b': np.array([7, 7, 7])} for key in expected: assert_array_equal(expected[key], ps[key])
def test_create_with_sequence(self): schema = {'a': Sequence} ps = ParameterSpace({'a': Sequence([1, 2, 3])}, schema, shape=(2, )) ps.evaluate() assert_array_equal( ps['a'], np.array( [Sequence([1, 2, 3]), Sequence([1, 2, 3])], dtype=Sequence))
def __init__(self, **parameters): """ `parameters` should be a mapping object, e.g. a dict """ self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=None) if parameters: self.parameter_space.update(**parameters)
def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
class BaseModelType(object): """Base class for standard and native cell and synapse model classes.""" default_parameters = {} default_initial_values = {} parameter_checks = {} def __init__(self, **parameters): """ `parameters` should be a mapping object, e.g. a dict """ self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=None) if parameters: self.parameter_space.update(**parameters) def __repr__(self): # should really include the parameters explicitly, to be unambiguous return "%s(<parameters>)" % self.__class__.__name__ @classmethod def has_parameter(cls, name): """Does this model have a parameter with the given name?""" return name in cls.default_parameters @classmethod def get_parameter_names(cls): """Return the names of the parameters of this model.""" return list(cls.default_parameters.keys()) def get_schema(self): """ Returns the model schema: i.e. a mapping of parameter names to allowed parameter types. """ return dict((name, type(value)) for name, value in self.default_parameters.items()) def describe(self, template='modeltype_default.txt', engine='default'): """ Returns a human-readable description of the cell or synapse type. The output may be customized by specifying a different template togther with an associated template engine (see ``pyNN.descriptions``). If template is None, then a dictionary containing the template context will be returned. """ context = { "name": self.__class__.__name__, "default_parameters": self.default_parameters, "default_initial_values": self.default_initial_values, "parameters": self.parameter_space. _parameters, # should add a describe() method to ParameterSpace } return descriptions.render(engine, template, context)
def test_columnwise_iteration_single_column(self): ps2d = ParameterSpace({'a': [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], 'b': 7, 'c': lambda i, j: 3 * i - 2 * j}, shape=(2, 5)) ps2d.evaluate(mask=(slice(None), 3)) expected = [{'a': np.array([8, 89]), 'b': np.array([7, 7]), 'c': np.array([-6, -3])}] actual = list(ps2d.columns()) for x, y in zip(actual, expected): for key in y: assert_array_equal(x[key], y[key])
def test_columnwise_iteration_single_column(self): ps2d = ParameterSpace( {"a": [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], "b": 7, "c": lambda i, j: 3 * i - 2 * j}, shape=(2, 5) ) ps2d.evaluate(mask=(slice(None), 3)) expected = [{"a": np.array([8, 89]), "b": np.array([7, 7]), "c": np.array([-6, -3])}] actual = list(ps2d.columns()) for x, y in zip(actual, expected): for key in y: assert_array_equal(x[key], y[key])
def parameter_space(self): timing_parameters = self.timing_dependence.parameter_space weight_parameters = self.weight_dependence.parameter_space parameters = ParameterSpace({'weight': self.weight, 'delay': self.delay, 'dendritic_delay_fraction': self.dendritic_delay_fraction}, self.get_schema()) parameters.update(**timing_parameters) parameters.update(**weight_parameters) return parameters
def test_evaluate(self): ps = ParameterSpace( { 'a': [2, 3, 5, 8], 'b': 7, 'c': lambda i: 3 * i + 2 }, shape=(4, )) self.assertIsInstance(ps['c'], LazyArray) ps.evaluate() assert_array_equal(ps['c'], np.array([2, 5, 8, 11]))
def test_columnwise_iteration(self): ps2d = ParameterSpace({'a': [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], 'b': 7, 'c': lambda i, j: 3*i-2*j}, shape=(2, 5)) ps2d.evaluate(mask=(slice(None), [1, 3, 4])) expected = [{'a': np.array([3, 34]), 'b': np.array([7, 7]), 'c': np.array([-2, 1])}, {'a': np.array([8, 89]), 'b': np.array([7, 7]), 'c': np.array([-6, -3])}, {'a': np.array([13, 144]), 'b': np.array([7, 7]), 'c': np.array([-8, -5])}] for x, y in zip(ps2d.columns(), expected): for key in y: assert_array_equal(x[key], y[key])
def test_columnwise_iteration(self): ps2d = ParameterSpace({'a': [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], 'b': 7, 'c': lambda i, j: 3 * i - 2 * j}, shape=(2, 5)) ps2d.evaluate(mask=(slice(None), [1, 3, 4])) expected = [{'a': np.array([3, 34]), 'b': np.array([7, 7]), 'c': np.array([-2, 1])}, {'a': np.array([8, 89]), 'b': np.array([7, 7]), 'c': np.array([-6, -3])}, {'a': np.array([13, 144]), 'b': np.array([7, 7]), 'c': np.array([-8, -5])}] for x, y in zip(ps2d.columns(), expected): for key in y: assert_array_equal(x[key], y[key])
def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1, )) if parameters: self.parameter_space.update(**parameters) self.min_delay = state.min_delay self.timestep = state.dt # NoisyCurrentSource has a parameter called "dt", so use "timestep" here
def __init__(self, **parameters): super(StandardCurrentSource, self).__init__(**parameters) self.cell_list = [] self.indices = [] simulator.state.current_sources.append(self) parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1, )) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
class BaseModelType(object): """Base class for standard and native cell and synapse model classes.""" default_parameters = {} default_initial_values = {} parameter_checks = {} def __init__(self, **parameters): """ `parameters` should be a mapping object, e.g. a dict """ self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=None) if parameters: self.parameter_space.update(**parameters) def __repr__(self): return "%s(<parameters>)" % self.__class__.__name__ # should really include the parameters explicitly, to be unambiguous @classmethod def has_parameter(cls, name): """Does this model have a parameter with the given name?""" return name in cls.default_parameters @classmethod def get_parameter_names(cls): """Return the names of the parameters of this model.""" return list(cls.default_parameters.keys()) def get_schema(self): """ Returns the model schema: i.e. a mapping of parameter names to allowed parameter types. """ return dict((name, type(value)) for name, value in self.default_parameters.items()) def describe(self, template='modeltype_default.txt', engine='default'): """ Returns a human-readable description of the cell or synapse type. The output may be customized by specifying a different template togther with an associated template engine (see ``pyNN.descriptions``). If template is None, then a dictionary containing the template context will be returned. """ context = { "name": self.__class__.__name__, "default_parameters": self.default_parameters, "default_initial_values": self.default_initial_values, "parameters": self.parameter_space._parameters, # should add a describe() method to ParameterSpace } return descriptions.render(engine, template, context)
def test_evaluate_with_mask_2D(self): ps2d = ParameterSpace( { 'a': [[2, 3, 5, 8, 13], [21, 34, 55, 89, 144]], 'b': 7, 'c': lambda i, j: 3 * i - 2 * j }, shape=(2, 5)) ps2d.evaluate(mask=(slice(None), [1, 3, 4])) assert_array_equal(ps2d['a'], np.array([[3, 8, 13], [34, 89, 144]])) assert_array_equal(ps2d['c'], np.array([[-2, -6, -8], [1, -3, -5]]))
class NestCurrentSource(BaseCurrentSource): """Base class for a nest source of current to be injected into a neuron.""" def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) if parameters: self.parameter_space.update(**parameters) self.min_delay = state.min_delay self.dt = state.dt def inject_into(self, cells): for id in cells: if id.local and not id.celltype.injectable: raise TypeError("Can't inject current into a spike source.") if isinstance(cells, (Population, PopulationView, Assembly)): self.cell_list = [cell for cell in cells] else: self.cell_list = cells nest.Connect(self._device, self.cell_list, syn_spec={"delay": state.min_delay}) def _delay_correction(self, value): """ A change in a device requires a min_delay to take effect at the target """ corrected = value - self.min_delay # set negative times to zero if isinstance(value, numpy.ndarray): corrected = numpy.where(corrected > 0, corrected, 0.0) else: corrected = max(corrected, 0.0) return corrected def record(self): self.i_multimeter = nest.Create('multimeter', params={'record_from': ['I'], 'interval': state.dt}) nest.Connect(self.i_multimeter, self._device) def _get_data(self): events = nest.GetStatus(self.i_multimeter)[0]['events'] # Similar to recording.py: NEST does not record values at # the zeroth time step, so we add them here. t_arr = numpy.insert(numpy.array(events['times']), 0, 0.0) i_arr = numpy.insert(numpy.array(events['I']/1000.0), 0, 0.0) # NEST and pyNN have different concepts of current initiation times # To keep this consistent across simulators, we will have current # initiating at the electrode at t_start and effect on cell at next dt # This requires padding min_delay equivalent period with 0's pad_length = int(self.min_delay/self.dt) i_arr = numpy.insert(i_arr[:-pad_length], 0, [0]*pad_length) return t_arr, i_arr
def __init__(self, **parameters): super(StandardCurrentSource, self).__init__(**parameters) self.cell_list = [] self.indices = [] simulator.state.current_sources.append(self) parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
def __init__(self, **parameters): self._devices = [] self.cell_list = [] self._amplitudes = None self._times = None self._h_iclamps = {} parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
def __init__(self, **parameters): self._devices = [] self.cell_list = [] self._amplitudes = None self._times = None self._h_iclamps = {} parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1, )) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
def __init__(self, **parameters): super(StandardCurrentSource, self).__init__(**parameters) global current_sources self.cell_list = [] self.indices = [] self.ind = len(current_sources) # Todo use self.indices instead... current_sources.append(self) parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) parameter_space.update(**parameters) parameter_space = self.translate(parameter_space) self.set_native_parameters(parameter_space)
class NestCurrentSource(BaseCurrentSource): """Base class for a nest source of current to be injected into a neuron.""" def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) if parameters: self.parameter_space.update(**parameters) def inject_into(self, cells): for id in cells: if id.local and not id.celltype.injectable: raise TypeError("Can't inject current into a spike source.") if isinstance(cells, (Population, PopulationView, Assembly)): self.cell_list = [cell for cell in cells] else: self.cell_list = cells nest.Connect(self._device, self.cell_list, syn_spec={"delay": state.min_delay}) def _delay_correction(self, value): """ A change in a device requires a min_delay to take effect at the target """ corrected = value - state.min_delay # set negative times to zero if isinstance(value, numpy.ndarray): corrected = numpy.where(corrected > 0, corrected, 0.0) else: corrected = max(corrected, 0.0) return corrected def record(self): self.i_multimeter = nest.Create('multimeter', params={'record_from': ['I'], 'interval': state.dt}) nest.Connect(self.i_multimeter, self._device) def _get_data(self): events = nest.GetStatus(self.i_multimeter)[0]['events'] # Similar to recording.py: NEST does not record values at # the zeroth time step, so we add them here. t_arr = numpy.insert(numpy.array(events['times']), 0, 0.0) i_arr = numpy.insert(numpy.array(events['I']/1000.0), 0, 0.0) # NEST and pyNN have different concepts of current initiation times # To keep this consistent across simulators, we will have current # initiating at the electrode at t_start and effect on cell at next dt # This requires padding min_delay equivalent period with 0's pad_length = int(state.min_delay/state.dt) i_arr = numpy.insert(i_arr[:-pad_length], 0, [0]*pad_length) return t_arr, i_arr
def _get_attributes_as_list(self, attribute_names): if isinstance(self.post, common.Assembly) or isinstance( self.pre, common.Assembly): raise NotImplementedError values = [] syn_obj = self._brian2_synapses[0][0] for name in attribute_names: if name == "presynaptic_index": value = syn_obj.i[:] # _indices.synaptic_pre.get_value() if hasattr(self.pre, "parent"): # map index in parent onto index in view value = self.pre.index_from_parent_index(value) elif name == "postsynaptic_index": value = syn_obj.j[:] # _indices.synaptic_post.get_value() if hasattr(self.post, "parent"): # map index in parent onto index in view value = self.post.index_from_parent_index(value) else: value = getattr(syn_obj, name)[:] # should really use the translated name native_ps = ParameterSpace({name: value}, shape=value.shape) # this whole "get attributes" thing needs refactoring in all backends to properly use translation ps = self.synapse_type.reverse_translate(native_ps) ps.evaluate() value = ps[name] values.append(value) a = np.array(values) return [tuple(x) for x in a.T]
def translate(self, parameters): """Translate standardized model parameters to simulator-specific parameters.""" _parameters = deepcopy(parameters) cls = self.__class__ if parameters.schema != self.get_schema(): raise Exception( "Schemas do not match: %s != %s" % (parameters.schema, self.get_schema()) ) # should replace this with a PyNN-specific exception type native_parameters = {} for name in parameters.keys(): D = self.translations[name] pname = D['translated_name'] if callable(D['forward_transform']): pval = D['forward_transform'](**_parameters) else: try: pval = eval(D['forward_transform'], globals(), _parameters) except NameError as errmsg: raise NameError( "Problem translating '%s' in %s. Transform: '%s'. Parameters: %s. %s" % (pname, cls.__name__, D['forward_transform'], parameters, errmsg)) except ZeroDivisionError: raise #pval = 1e30 # this is about the highest value hoc can deal with native_parameters[pname] = pval return ParameterSpace(native_parameters, schema=None, shape=parameters.shape)
def set(self, **attributes): """ Set connection attributes for all connections on the local MPI node. Attribute names may be 'weight', 'delay', or the name of any parameter of a synapse dynamics model (e.g. 'U' for TsodyksMarkramSynapse). Each attribute value may be: (1) a single number (2) a RandomDistribution object (3) a list/1D array of the same length as the number of local connections (4) a 2D array with the same dimensions as the connectivity matrix (as returned by `get(format='array')` (5) a mapping function, which accepts a single float argument (the distance between pre- and post-synaptic cells) and returns a single value. Weights should be in nA for current-based and µS for conductance-based synapses. Delays should be in milliseconds. """ # should perhaps add a "distribute" argument, for symmetry with "gather" in get() attributes = self._value_list_to_array(attributes) parameter_space = ParameterSpace(attributes, self.synapse_type.get_schema(), (self.pre.size, self.post.size)) parameter_space = self._handle_distance_expressions(parameter_space) if isinstance(self.synapse_type, StandardSynapseType): parameter_space = self.synapse_type.translate(parameter_space) self._set_attributes(parameter_space)
def _get_attributes_as_list(self, *attribute_names): if isinstance(self.post, common.Assembly) or isinstance( self.pre, common.Assembly): raise NotImplementedError values = [] for name in attribute_names: if name == "presynaptic_index": value = self._brian_synapses[0][0].presynaptic elif name == "postsynaptic_index": value = self._brian_synapses[0][0].postsynaptic else: data_obj = getattr(self._brian_synapses[0][0], name).data if hasattr(data_obj, "tolist"): value = data_obj else: assert name == 'delay' value = data_obj.data * self._simulator.state.dt * ms ps = self.synapse_type.reverse_translate( ParameterSpace({name: value}, shape=( value.shape))) # should really use the translated name # this whole "get attributes" thing needs refactoring in all backends to properly use translation ps.evaluate() value = ps[name] #value = value.tolist() values.append(value) a = numpy.array(values) return [tuple(x) for x in a.T]
def _get_parameters(self, *names): """ return a ParameterSpace containing native parameters """ ids = self.local_cells.tolist() if hasattr(self.celltype, "uses_parrot") and self.celltype.uses_parrot: ids = [id.source for id in ids] if "spike_times" in names: parameter_dict = { "spike_times": [Sequence(value) for value in nest.GetStatus(ids, names)] } else: parameter_dict = {} for name in names: # one name at a time, since some parameter values may be tuples val = np.array(nest.GetStatus(ids, name)) if isinstance(val[0], tuple) or len(val.shape) == 2: val = np.array([ArrayParameter(v) for v in val]) val = LazyArray(simplify(val), shape=(self.local_size, ), dtype=ArrayParameter) parameter_dict[name] = val else: parameter_dict[name] = simplify(val) ps = ParameterSpace(parameter_dict, shape=(self.local_size, )) return ps
def _set(self, attr_name, value): ps = ParameterSpace({attr_name: value}, shape=(1, ), schema=self.projection.synapse_type.get_schema()) native_ps = self.projection.synapse_type.translate(ps) native_ps.evaluate() getattr(self._syn_obj, attr_name)[self.index] = native_ps[attr_name]
def connect(self, projection): """Connect-up a Projection.""" logger.debug("conn_list (original) = \n%s", self.conn_list) if numpy.any(self.conn_list[:, 0] >= projection.pre.size): raise errors.ConnectionError("source index out of range") if (self.conn_list.shape[1] < 3 or self.conn_list.shape[1] > 4 or (self.conn_list.shape[1] == 3 and projection.synapse_type.has_parameter('delay'))): raise errors.ConnectionError( "incompatible number of columns for connection list requires " "4 (3 for synapse type without delay)") # need to do some profiling, to figure out the best way to do this: # - order of sorting/filtering by local # - use numpy.unique, or just do in1d(self.conn_list)? idx = numpy.argsort(self.conn_list[:, 1]) targets = numpy.unique(self.conn_list[:, 1]).astype(numpy.int) local = numpy.in1d( targets, numpy.arange(projection.post.size)[projection.post._mask_local], assume_unique=True) local_targets = targets[local] self.conn_list = self.conn_list[idx] left = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'left') right = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'right') logger.debug("idx = %s", idx) logger.debug("targets = %s", targets) logger.debug("local_targets = %s", local_targets) logger.debug("conn_list (sorted by target) = \n%s", self.conn_list) logger.debug("left = %s", left) logger.debug("right = %s", right) schema = projection.synapse_type.get_schema() for tgt, l, r in zip(local_targets, left, right): sources = self.conn_list[l:r, 0].astype(numpy.int) param_dict = {'weight': self.conn_list[l:r, 2]} if self.conn_list.shape[1] == 4: param_dict['delay'] = self.conn_list[l:r, 3] connection_parameters = ParameterSpace(param_dict, schema=schema, shape=(r - l, )) if isinstance(projection.synapse_type, StandardSynapseType): connection_parameters = projection.synapse_type.translate( connection_parameters) connection_parameters.evaluate() projection._convergent_connect(sources, tgt, **connection_parameters)
def _get_parameters(self, *names): """ return a ParameterSpace containing native parameters """ parameter_dict = {} for name in names: parameter_dict[name] = simplify(self._parameters[name]) return ParameterSpace(parameter_dict, shape=(self.local_size, ))
def _get_parameters(self, *names): """Return a ParameterSpace containing native parameters""" parameter_space = {} for name in names: value = simplify(self.celltype.parameter_space[name]) if isinstance(value, np.ndarray): value = value[self.mask] parameter_space[name] = value return ParameterSpace(parameter_space, shape=(self.size, ))
def _get_parameters(self, *names): """ return a ParameterSpace containing native parameters """ parameter_dict = {} for name in names: value = simplify(getattr(self.brian_group, name)) parameter_dict[name] = value return ParameterSpace(parameter_dict, shape=(self.size, ))
def test_reverse_translate(): M = StandardModelType M.default_parameters = {'a': 22.2, 'b': 33.3, 'c': 44.4} M.translations = build_translations( ('a', 'A'), ('b', 'B', 1000.0), ('c', 'C', 'c + a', 'C - A'), ) assert_equal(_parameter_space_to_dict(M().reverse_translate(ParameterSpace({'A': 23.4, 'B': 34500.0, 'C': 69.0})), 88), {'a': 23.4, 'b': 34.5, 'c': 45.6})
def connect(self, projection): """Connect-up a Projection.""" logger.debug("conn_list (original) = \n%s", self.conn_list) if numpy.any(self.conn_list[:, 0] >= projection.pre.size): raise errors.ConnectionError("source index out of range") if (self.conn_list.shape[1] < 3 or self.conn_list.shape[1] > 4 or (self.conn_list.shape[1] == 3 and projection.synapse_type.has_parameter('delay'))): raise errors.ConnectionError("incompatible number of columns for connection list requires " "4 (3 for synapse type without delay)") # need to do some profiling, to figure out the best way to do this: # - order of sorting/filtering by local # - use numpy.unique, or just do in1d(self.conn_list)? idx = numpy.argsort(self.conn_list[:, 1]) targets = numpy.unique(self.conn_list[:, 1]).astype(numpy.int) local = numpy.in1d(targets, numpy.arange(projection.post.size)[projection.post._mask_local], assume_unique=True) local_targets = targets[local] self.conn_list = self.conn_list[idx] left = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'left') right = numpy.searchsorted(self.conn_list[:, 1], local_targets, 'right') logger.debug("idx = %s", idx) logger.debug("targets = %s", targets) logger.debug("local_targets = %s", local_targets) logger.debug("conn_list (sorted by target) = \n%s", self.conn_list) logger.debug("left = %s", left) logger.debug("right = %s", right) schema = projection.synapse_type.get_schema() for tgt, l, r in zip(local_targets, left, right): sources = self.conn_list[l:r, 0].astype(numpy.int) param_dict = {'weight': self.conn_list[l:r, 2] } if self.conn_list.shape[1] == 4: param_dict['delay'] = self.conn_list[l:r, 3] connection_parameters = ParameterSpace(param_dict, schema=schema, shape=(r-l,)) if isinstance(projection.synapse_type, StandardSynapseType): connection_parameters = projection.synapse_type.translate( connection_parameters) connection_parameters.evaluate() projection._convergent_connect(sources, tgt, **connection_parameters)
def __init__(self, **parameters): self._device = nest.Create(self.nest_name) self.cell_list = [] self.parameter_space = ParameterSpace(self.default_parameters, self.get_schema(), shape=(1,)) if parameters: self.parameter_space.update(**parameters) self.min_delay = state.min_delay self.dt = state.dt
def _get_parameters(self, *names): """ return a ParameterSpace containing native parameters """ parameter_dict = {} for name in names: value = simplify(getattr(self.brian_group, name)) if isinstance(value, numpy.ndarray): value = value[self.mask] parameter_dict[name] = value return ParameterSpace(parameter_dict, shape=(self.size, ))
def _get_parameters(self, *names): """ return a ParameterSpace containing native parameters """ parameter_dict = {} for name in names: value = getattr(self.brian2_group, name) if hasattr(value, "shape") and value.shape: value = value[self.mask] parameter_dict[name] = simplify(value) return ParameterSpace(parameter_dict, shape=(self.size,))
def test_evaluate(self): ps = ParameterSpace({'a': [2, 3, 5, 8], 'b': 7, 'c': lambda i: 3*i+2}, shape=(4,)) self.assertIsInstance(ps['c'], LazyArray) ps.evaluate() assert_array_equal(ps['c'], np.array([ 2, 5, 8, 11]))
def test_evaluate(self): ps = ParameterSpace({"a": [2, 3, 5, 8], "b": 7, "c": lambda i: 3 * i + 2}, shape=(4,)) self.assertIsInstance(ps["c"], LazyArray) ps.evaluate() assert_array_equal(ps["c"], np.array([2, 5, 8, 11]))
def test_iteration(self): ps = ParameterSpace({"a": [2, 3, 5, 8, 13], "b": 7, "c": lambda i: 3 * i + 2}, shape=(5,)) ps.evaluate(mask=[1, 3, 4]) self.assertEqual(list(ps), [{"a": 3, "c": 5, "b": 7}, {"a": 8, "c": 11, "b": 7}, {"a": 13, "c": 14, "b": 7}])