class Connection(NengoObject): """Connects two objects together. Almost any Nengo object can act as the pre or post side of a connection. Additionally, you can use Python slice syntax to access only some of the dimensions of the pre or post object. For example, if ``node`` has ``size_out=2`` and ``ensemble`` has ``size_in=1``, we could not create the following connection:: nengo.Connection(node, ensemble) But, we could create either of these two connections. nengo.Connection(node[0], ensemble) nengo.Connection(ndoe[1], ensemble) Parameters ---------- pre : Ensemble or Neurons or Node The source Nengo object for the connection. post : Ensemble or Neurons or Node or Probe The destination object for the connection. label : string A descriptive label for the connection. dimensions : int The number of output dimensions of the pre object, including `function`, but not including `transform`. eval_points : (n_eval_points, pre_size) array_like or int Points at which to evaluate `function` when computing decoders, spanning the interval (-pre.radius, pre.radius) in each dimension. synapse : float, optional Post-synaptic time constant (PSTC) to use for filtering. transform : (post_size, pre_size) array_like, optional Linear transform mapping the pre output to the post input. This transform is in terms of the sliced size; if either pre or post is a slice, the transform must be of shape (len(pre_slice), len(post_slice)). solver : Solver Instance of a Solver class to compute decoders or weights (see `nengo.solvers`). If solver.weights is True, a full connection weight matrix is computed instead of decoders. function : callable, optional Function to compute using the pre population (pre must be Ensemble). modulatory : bool, optional Specifies whether the connection is modulatory (does not physically connect to post, for use by learning rules), or not (default). eval_points : (n_eval_points, pre_size) array_like or int, optional Points at which to evaluate `function` when computing decoders, spanning the interval (-pre.radius, pre.radius) in each dimension. scale_eval_points : bool Indicates whether the eval_points should be scaled by the radius of the pre Ensemble. Defaults to True. learning_rule_type : instance or list or dict of LearningRuleType, optional Methods of modifying the connection weights during simulation. Attributes ---------- dimensions : int The number of output dimensions of the pre object, including `function`, but before applying the `transform`. function : callable The given function. function_size : int The output dimensionality of the given function. Defaults to 0. label : str A human-readable connection label for debugging and visualization. Incorporates the labels of the pre and post objects. learning_rule : LearningRule or collection of LearningRule The LearningRule objects corresponding to `learning_rule_type`, and in the same format. Use these to probe the learning rules. learning_rule_type : instance or list or dict of LearningRuleType, optional The learning rule types. post : Ensemble or Neurons or Node or Probe The given pre object. pre : Ensemble or Neurons or Node The given pre object. transform : (post_size, pre_size) array_like Linear transform mapping the pre output to the post input. modulatory : bool Whether the output of this signal is to act as an error signal for a learning rule. seed : int The seed used for random number generation. """ pre = NengoObjectParam(nonzero_size_out=True) post = NengoObjectParam(nonzero_size_in=True) synapse = SynapseParam(default=Lowpass(0.005)) transform = TransformParam(default=np.array(1.0)) solver = ConnectionSolverParam(default=LstsqL2()) function_info = ConnectionFunctionParam(default=None, optional=True) modulatory = BoolParam(default=False) learning_rule_type = ConnectionLearningRuleTypeParam(default=None, optional=True) eval_points = EvalPointsParam(default=None, optional=True, sample_shape=('*', 'size_in')) scale_eval_points = BoolParam(default=True) seed = IntParam(default=None, optional=True) probeable = ListParam(default=['output', 'input', 'transform', 'decoders']) def __init__(self, pre, post, synapse=Default, transform=Default, solver=Default, learning_rule_type=Default, function=Default, modulatory=Default, eval_points=Default, scale_eval_points=Default, seed=Default): self.pre = pre self.post = post self.probeable = Default self.solver = solver # Must be set before learning rule self.learning_rule_type = learning_rule_type self.modulatory = modulatory self.synapse = synapse self.transform = transform self.scale_eval_points = scale_eval_points self.eval_points = eval_points # Must be set before function self.function_info = function # Must be set after transform @property def function(self): return self.function_info.function @function.setter def function(self, function): self.function_info = function @property def pre_obj(self): return self.pre.obj if isinstance(self.pre, ObjView) else self.pre @property def pre_slice(self): return self.pre.slice if isinstance(self.pre, ObjView) else slice(None) @property def post_obj(self): return self.post.obj if isinstance(self.post, ObjView) else self.post @property def post_slice(self): return (self.post.slice if isinstance(self.post, ObjView) else slice(None)) @property def size_in(self): """Output size of sliced `pre`; input size of the function.""" return self.pre.size_out @property def size_mid(self): """Output size of the function; input size of the transform. If the function is None, then `size_in == size_mid`. """ size = self.function_info.size return self.size_in if size is None else size @property def size_out(self): """Output size of the transform; input size to the sliced post.""" return self.post.size_in @property def _label(self): return "from %s to %s%s" % (self.pre, self.post, " computing '%s'" % self.function.__name__ if self.function is not None else "") def __str__(self): return "<Connection %s>" % self._label def __repr__(self): return "<Connection at 0x%x %s>" % (id(self), self._label) @property def learning_rule(self): if self.learning_rule_type is not None and self._learning_rule is None: types = self.learning_rule_type if isinstance(types, dict): self._learning_rule = types.__class__() # dict of same type for k, v in iteritems(types): self._learning_rule[k] = LearningRule(self, v) elif is_iterable(types): self._learning_rule = [LearningRule(self, v) for v in types] elif isinstance(types, LearningRuleType): self._learning_rule = LearningRule(self, types) else: raise ValueError("Invalid type for `learning_rule_type`: %s" % (types.__class__.__name__)) return self._learning_rule
class Test(object): nop = NengoObjectParam('nop')
class Test(object): nin = NengoObjectParam('nin', nonzero_size_in=True) nout = NengoObjectParam('nout', nonzero_size_out=True)
class Test: nop = NengoObjectParam('nop')
class Probe(NengoObject): """A probe is an object that receives data from the simulation. This is to be used in any situation where you wish to gather simulation data (spike data, represented values, neuron voltages, etc.) for analysis. Probes cannot directly affect the simulation. TODO: Example usage for each object. Parameters ---------- target : Ensemble, Node, Connection The Nengo object to connect to the probe. attr : str, optional The quantity to probe. Refer to the target's ``probeable`` list for details. Defaults to the first element in the list. sample_every : float, optional Sampling period in seconds. conn_args : dict, optional Optional keyword arguments to pass to the Connection created for this probe. For example, passing ``synapse=pstc`` will filter the data. """ target = NengoObjectParam(nonzero_size_out=True) attr = StringParam(default=None) sample_every = NumberParam(default=None, optional=True, low=1e-10) conn_args = DictParam(default=None) seed = IntParam(default=None, optional=True) def __init__(self, target, attr=Default, sample_every=Default, **conn_args): if not hasattr(target, 'probeable') or len(target.probeable) == 0: raise TypeError("Type '%s' is not probeable" % target.__class__.__name__) conn_args.setdefault('synapse', None) # We'll use the first in the list as default self.attr = attr if attr is not Default else target.probeable[0] if self.attr not in target.probeable: raise ValueError("'%s' is not probeable for '%s'" % (self.attr, target)) self.target = target self.sample_every = sample_every self.conn_args = conn_args self.seed = conn_args.get('seed', None) @property def label(self): return "Probe(%s.%s)" % (self.target.label, self.attr) @property def size_in(self): # TODO: A bit of a hack; make less hacky. if isinstance(self.target, Ensemble) and self.attr != "decoded_output": return self.target.neurons.size_out return self.target.size_out @property def size_out(self): return 0
class Test: nop = NengoObjectParam("nop")
class Test: nin = NengoObjectParam("nin", nonzero_size_in=True) nout = NengoObjectParam("nout", nonzero_size_out=True)
class Connection(NengoObject): """Connects two objects together. TODO: Document slice syntax here and in the transform parameter. Parameters ---------- pre : Ensemble or Neurons or Node The source Nengo object for the connection. post : Ensemble or Neurons or Node or Probe The destination object for the connection. label : string A descriptive label for the connection. dimensions : int The number of output dimensions of the pre object, including `function`, but not including `transform`. eval_points : (n_eval_points, pre_size) array_like or int Points at which to evaluate `function` when computing decoders, spanning the interval (-pre.radius, pre.radius) in each dimension. synapse : float, optional Post-synaptic time constant (PSTC) to use for filtering. transform : (post_size, pre_size) array_like, optional Linear transform mapping the pre output to the post input. solver : Solver Instance of a Solver class to compute decoders or weights (see `nengo.decoders`). If solver.weights is True, a full connection weight matrix is computed instead of decoders. function : callable, optional Function to compute using the pre population (pre must be Ensemble). modulatory : bool, optional Specifies whether the connection is modulatory (does not physically connect to post, for use by learning rules), or not (default). eval_points : (n_eval_points, pre_size) array_like or int, optional Points at which to evaluate `function` when computing decoders, spanning the interval (-pre.radius, pre.radius) in each dimension. learning_rule : LearningRule or list of LearningRule, optional Methods of modifying the connection weights during simulation. Attributes ---------- dimensions : int The number of output dimensions of the pre object, including `function`, but before applying the `transform`. function : callable The given function. function_size : int The output dimensionality of the given function. Defaults to 0. label : str A human-readable connection label for debugging and visualization. Incorporates the labels of the pre and post objects. learning_rule : list of LearningRule The given learning rules. If given a single LearningRule, this will be a list with a single element. post : Ensemble or Neurons or Node or Probe The given pre object. pre : Ensemble or Neurons or Node The given pre object. transform : (post_size, pre_size) array_like Linear transform mapping the pre output to the post input. modulatory : bool Whether the output of this signal is to act as an error signal for a learning rule. seed : int The seed used for random number generation. """ pre = NengoObjectParam(nonzero_size_out=True) post = NengoObjectParam(nonzero_size_in=True) synapse = SynapseParam(default=Lowpass(0.005)) transform = TransformParam(default=np.array(1.0)) solver = ConnectionSolverParam(default=LstsqL2()) function_info = ConnectionFunctionParam(default=None, optional=True) modulatory = BoolParam(default=False) learning_rule = ConnectionLearningRuleParam(default=None, optional=True) eval_points = EvalPointsParam(default=None, optional=True, shape=('*', 'size_in')) seed = IntParam(default=None, optional=True) probeable = ListParam(default=['signal']) def __init__(self, pre, post, synapse=Default, transform=Default, solver=Default, learning_rule=Default, function=Default, modulatory=Default, eval_points=Default, seed=Default): self.pre = pre self.post = post self.probeable = Default self.solver = solver # Must be set before learning rule self.learning_rule = learning_rule self.modulatory = modulatory self.synapse = synapse self.transform = transform self.eval_points = eval_points # Must be set before function self.function_info = function # Must be set after transform @property def function(self): return self.function_info.function @function.setter def function(self, function): self.function_info = function @property def pre_obj(self): return self.pre.obj if isinstance(self.pre, ObjView) else self.pre @property def pre_slice(self): return self.pre.slice if isinstance(self.pre, ObjView) else slice(None) @property def post_obj(self): return self.post.obj if isinstance(self.post, ObjView) else self.post @property def post_slice(self): return (self.post.slice if isinstance(self.post, ObjView) else slice(None)) @property def size_in(self): """Output size of sliced `pre`; input size of the function.""" return self.pre.size_out @property def size_mid(self): """Output size of the function; input size of the transform. If the function is None, then `size_in == size_mid`. """ size = self.function_info.size return self.size_in if size is None else size @property def size_out(self): """Output size of the transform; input size to the sliced post.""" return self.post.size_in @property def label(self): label = "%s->%s" % (self.pre.label, self.post.label) if self.function is not None: return "%s:%s" % (label, self.function.__name__) return label