def validate(self, instance, ndarray): ndim = len(self.shape) try: ndarray = np.asarray(ndarray, dtype=np.float64) except TypeError: raise ValueError("Must be a float NumPy array (got type '%s')" % ndarray.__class__.__name__) if ndarray.ndim != ndim: raise ValueError("ndarray must be %dD (got %dD)" % (ndim, ndarray.ndim)) for i, attr in enumerate(self.shape): assert is_integer(attr) or is_string(attr), ( "shape can only be an int or str representing an attribute") if attr == '*': continue if is_integer(attr): desired = attr elif is_string(attr): desired = getattr(instance, attr) if ndarray.shape[i] != desired: raise ValueError("shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i])) return ndarray
def __init__(self, *args, **kwargs): # Pop the label, seed, and add_to_network, so that they are not passed # to self.initialize or self.make. self.label = kwargs.pop('label', None) self.seed = kwargs.pop('seed', None) add_to_network = kwargs.pop( 'add_to_network', len(NengoObject.context) > 0) if not (self.label is None or is_string(self.label)): raise ValueError("Label '%s' must be None, str, or unicode." % self.label) self.ensembles = [] self.nodes = [] self.connections = [] self.networks = [] super(Network, self).__init__( add_to_network=add_to_network, *args, **kwargs) # Start object keys with the model hash. # We use the hash because it's deterministic, though this # may be confusing if models use the same label. self._next_key = hash(self) with self: self.make(*args, **kwargs)
def shrink(self, limit=None): """Reduces the size of the cache to meet a limit. Parameters ---------- limit : int, optional Maximum size of the cache in bytes. """ if limit is None: limit = rc.get('decoder_cache', 'size') if is_string(limit): limit = human2bytes(limit) fileinfo = [] excess = -limit for path in self.get_files(): stat = safe_stat(path) if stat is not None: aligned_size = byte_align(stat.st_size, self._fragment_size) excess += aligned_size fileinfo.append((stat.st_atime, aligned_size, path)) # Remove the least recently accessed first fileinfo.sort() for _, size, path in fileinfo: if excess <= 0: break excess -= size safe_remove(path)
def validate(self, instance, ndarray): ndim = len(self.shape) try: ndarray = np.asarray(ndarray, dtype=np.float64) except TypeError: raise ValueError("Must be a float NumPy array (got type '%s')" % ndarray.__class__.__name__) if ndarray.ndim != ndim: raise ValueError("ndarray must be %dD (got %dD)" % (ndim, ndarray.ndim)) for i, attr in enumerate(self.shape): assert is_integer(attr) or is_string(attr), ( "shape can only be an int or str representing an attribute") if attr == '*': continue desired = attr if is_integer(attr) else getattr(instance, attr) if not is_integer(desired): raise ValueError("%s not yet initialized; cannot determine " "if shape is correct. Consider using a " "distribution instead." % attr) if ndarray.shape[i] != desired: raise ValueError("shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i])) return ndarray
def __init__(self, name, default=Unconfigurable, optional=False, readonly=None): # freeze Unconfigurables by default readonly = default is Unconfigurable if readonly is None else readonly if not is_string(name): raise ValueError("'name' must be a string (got %r)" % name) if not isinstance(optional, bool): raise ValueError("'optional' must be boolean (got %r)" % optional) if not isinstance(readonly, bool): raise ValueError("'readonly' must be boolean (got %r)" % readonly) self.name = name self.default = default self.optional = optional self.readonly = readonly # default values set by config system self._defaults = WeakKeyIDDictionary() # param values set on objects self.data = WeakKeyIDDictionary()
def shrink(self, limit=None): """Reduces the size of the cache to meet a limit. Parameters ---------- limit : int, optional Maximum size of the cache in bytes. """ if limit is None: limit = rc.get('decoder_cache', 'size') if is_string(limit): limit = human2bytes(limit) fileinfo = [] for filename in self.get_files(): path = os.path.join(self.cache_dir, filename) stat = safe_stat(path) if stat is not None: fileinfo.append((stat.st_atime, stat.st_size, path)) # Remove the least recently accessed first fileinfo.sort() excess = self.get_size_in_bytes() - limit for _, size, path in fileinfo: if excess <= 0: break excess -= size safe_remove(path) # We may have removed a decoder file but not solver_info file # or vice versa, so we'll remove all orphans self.remove_orphans()
def recorder_dirname(request, name): """Returns the directory to put test artifacts in. Test artifacts produced by Nengo include plots and analytics. Note that the return value might be None, which indicates that the artifacts should not be saved. """ record = request.config.getvalue(name) if is_string(record): return record elif not record: return None simulator, nl = TestConfig.RefSimulator, None if 'Simulator' in request.funcargnames: simulator = request.getfuncargvalue('Simulator') # 'nl' stands for the non-linearity used in the neuron equation if 'nl' in request.funcargnames: nl = request.getfuncargvalue('nl') elif 'nl_nodirect' in request.funcargnames: nl = request.getfuncargvalue('nl_nodirect') dirname = "%s.%s" % (simulator.__module__, name) if nl is not None: dirname = os.path.join(dirname, nl.__name__) return dirname
def recorder_dirname(request, name): """Returns the directory to put test artifacts in. Test artifacts produced by Nengo include plots and analytics. Note that the return value might be None, which indicates that the artifacts should not be saved. """ record = request.config.getvalue(name) if is_string(record): return record elif not record: return None simulator, nl = TestConfig.RefSimulator, None if 'Simulator' in request.funcargnames: simulator = request.getfixturevalue('Simulator') # 'nl' stands for the non-linearity used in the neuron equation if 'nl' in request.funcargnames: nl = request.getfixturevalue('nl') elif 'nl_nodirect' in request.funcargnames: nl = request.getfixturevalue('nl_nodirect') dirname = "%s.%s" % (simulator.__module__, name) if nl is not None: dirname = os.path.join(dirname, nl.__name__) return dirname
def find_modules(root_path, prefix=[], pattern='^test_.*\\.py$'): """Find matching modules (files) in all subdirectories of a given path. Parameters ---------- root_path : string The path of the directory in which to begin the search. prefix : string or list, optional A string or list of strings to append to each returned modules list. pattern : string, optional A regex pattern for matching individual file names. Defaults to looking for all testing scripts. Returns ------- modules : list A list of modules. Each item in the list is a list of strings containing the module path. """ if is_string(prefix): prefix = [prefix] elif not isinstance(prefix, list): raise TypeError("Invalid prefix type '%s'" % type(prefix).__name__) modules = [] for path, dirs, files in os.walk(root_path): base = prefix + os.path.relpath(path, root_path).split(os.sep) for filename in files: if re.search(pattern, filename): name, ext = os.path.splitext(filename) modules.append(base + [name]) return modules
def __init__( self, dimensions, strict=True, max_similarity=0.1, pointer_gen=None, name=None, algebra=None): if algebra is None: algebra = HrrAlgebra() self.algebra = algebra if not is_integer(dimensions) or dimensions < 1: raise ValidationError("dimensions must be a positive integer", attr='dimensions', obj=self) if pointer_gen is None: pointer_gen = UnitLengthVectors(dimensions) elif isinstance(pointer_gen, np.random.RandomState): pointer_gen = UnitLengthVectors(dimensions, pointer_gen) if not is_iterable(pointer_gen) or is_string(pointer_gen): raise ValidationError( "pointer_gen must be iterable or RandomState", attr='pointer_gen', obj=self) self.dimensions = dimensions self.strict = strict self.max_similarity = max_similarity self._key2idx = {} self._keys = [] self._vectors = np.zeros((0, dimensions), dtype=float) self.pointer_gen = pointer_gen self.name = name
def __call__(self, value): if isinstance(value, PointerSymbol): value = value.expr if is_string(value): value = self.vocab.parse(value) if isinstance(value, SemanticPointer): value = value.v return value
def allclose(t, target, signals, plotter=None, filename=None, labels=None, atol=1e-8, rtol=1e-5, buf=0, delay=0): """Perform an allclose check between two signals, with the potential to buffer both ends of the signal, account for a delay, and make a plot.""" signals = np.asarray(signals) vector_in = signals.ndim < 2 if vector_in: signals.shape = (1, -1) slice1 = slice(buf, -buf - delay) slice2 = slice(buf + delay, -buf) if plotter is not None: with plotter as plt: if labels is None: labels = [None] * len(signals) elif is_string(labels): labels = [labels] bound = atol + rtol * np.abs(target) # signal plot ax = plt.subplot(2, 1, 1) ax.plot(t, target, 'k:') for signal, label in zip(signals, labels): ax.plot(t, signal, label=label) ax.plot(t[slice2], (target + bound)[slice1], 'k--') ax.plot(t[slice2], (target - bound)[slice1], 'k--') ax.set_ylabel('signal') legend = (ax.legend(loc=2, bbox_to_anchor=(1., 1.)) if labels[0] is not None else None) # error plot errors = np.array([signal[slice2] - target[slice1] for signal in signals]) ymax = 1.1 * max(np.abs(errors).max(), bound.max()) ax = plt.subplot(2, 1, 2) ax.plot(t[slice2], np.zeros_like(t[slice2]), 'k:') for error, label in zip(errors, labels): plt.plot(t[slice2], error, label=label) ax.plot(t[slice2], bound[slice1], 'k--') ax.plot(t[slice2], -bound[slice1], 'k--') ax.set_ylim((-ymax, ymax)) ax.set_xlabel('time') ax.set_ylabel('error') if filename is not None: plt.savefig(filename, bbox_inches='tight', bbox_extra_artists=(legend,) if legend else ()) else: plt.show() plt.close() close = [np.allclose(signal[slice2], target[slice1], atol=atol, rtol=rtol) for signal in signals] return close[0] if vector_in else close
def coerce_ndarray(self, instance, ndarray): # noqa: C901 if isinstance(ndarray, np.ndarray): ndarray = ndarray.view() else: try: ndarray = np.array(ndarray, dtype=np.float64) except (ValueError, TypeError): raise ValidationError( "Must be a float NumPy array (got type %r)" % type(ndarray).__name__, attr=self.name, obj=instance) if self.readonly: ndarray.setflags(write=False) if self.shape is None: return ndarray if '...' in self.shape: # Convert '...' to the appropriate number of '*'s nfixed = len(self.shape) - 1 n = ndarray.ndim - nfixed if n < 0: raise ValidationError("ndarray must be at least %dD (got %dD)" % (nfixed, ndarray.ndim), attr=self.name, obj=instance) i = self.shape.index('...') shape = list(self.shape[:i]) + (['*'] * n) if i < len(self.shape) - 1: shape.extend(self.shape[i+1:]) else: shape = self.shape if ndarray.ndim != len(shape): raise ValidationError("ndarray must be %dD (got %dD)" % (len(shape), ndarray.ndim), attr=self.name, obj=instance) for i, attr in enumerate(shape): assert is_integer(attr) or is_string(attr), ( "shape can only be an int or str representing an attribute") if attr == '*': continue desired = attr if is_integer(attr) else getattr(instance, attr) if not is_integer(desired): raise ValidationError( "%s not yet initialized; cannot determine if shape is " "correct. Consider using a distribution instead." % attr, attr=self.name, obj=instance) if ndarray.shape[i] != desired: raise ValidationError("shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i]), attr=self.name, obj=instance) return ndarray
def validate(self, instance, ndarray): # noqa: C901 if isinstance(ndarray, np.ndarray): ndarray = ndarray.view() else: try: ndarray = np.array(ndarray, dtype=np.float64) except (ValueError, TypeError): raise ValidationError( "Must be a float NumPy array (got type %r)" % ndarray.__class__.__name__, attr=self.name, obj=instance, ) if self.readonly: ndarray.setflags(write=False) if "..." in self.shape: # Convert '...' to the appropriate number of '*'s nfixed = len(self.shape) - 1 n = ndarray.ndim - nfixed if n < 0: raise ValidationError( "ndarray must be at least %dD (got %dD)" % (nfixed, ndarray.ndim), attr=self.name, obj=instance ) i = self.shape.index("...") shape = list(self.shape[:i]) + (["*"] * n) if i < len(self.shape) - 1: shape.extend(self.shape[i + 1 :]) else: shape = self.shape if ndarray.ndim != len(shape): raise ValidationError( "ndarray must be %dD (got %dD)" % (len(shape), ndarray.ndim), attr=self.name, obj=instance ) for i, attr in enumerate(shape): assert is_integer(attr) or is_string(attr), "shape can only be an int or str representing an attribute" if attr == "*": continue desired = attr if is_integer(attr) else getattr(instance, attr) if not is_integer(desired): raise ValidationError( "%s not yet initialized; cannot determine if shape is " "correct. Consider using a distribution instead." % attr, attr=self.name, obj=instance, ) if ndarray.shape[i] != desired: raise ValidationError( "shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i]), attr=self.name, obj=instance ) return ndarray
def coerce(self, instance, size_in): if is_string(size_in): if size_in not in self.valid_strings: raise ValidationError( "%r is not a valid string value (must be one of %s)" % (size_in, self.strings), attr=self.name, obj=instance) return size_in else: return super(LearningRuleTypeSizeInParam, self).coerce( instance, size_in) # IntParam validation
def audio(self, audio_): if is_string(audio_): # Assuming this is a wav file audio_, fs = sf.read(audio_) self.fs = fs assert is_array(audio_) if audio_.ndim == 1: audio_ = audio_[:, np.newaxis] self.mfcc.audio = audio_ self.periphery.sound_process = ArrayProcess(audio_)
def __init__(self, name, default=Unconfigurable, values=(), lower=True, optional=False, readonly=None): assert all(is_string(s) for s in values) if lower: values = tuple(s.lower() for s in values) value_set = set(values) assert len(values) == len(value_set) self.values = values self.value_set = value_set self.lower = lower super(EnumParam, self).__init__(name, default, optional, readonly)
def to_node_output(cls, fn, input_vocab=None, output_vocab=None): if fn is None: return None elif callable(fn): if input_vocab is not None: fn = make_sp_func(fn, input_vocab) if output_vocab is not None: fn = make_parse_func(fn, output_vocab) return fn elif is_string(fn) or isinstance(fn, (SemanticPointer, PointerSymbol)): return SpArrayExtractor(output_vocab)(fn) else: raise ValueError("Invalid output type {!r}".format(type(fn)))
def validate(self, instance, ndarray): # noqa: C901 if isinstance(ndarray, np.ndarray): ndarray = ndarray.view() else: try: ndarray = np.array(ndarray, dtype=np.float64) except TypeError: raise ValueError( "Must be a float NumPy array (got type '%s')" % ndarray.__class__.__name__) if self.readonly: ndarray.setflags(write=False) if '...' in self.shape: nfixed = len(self.shape) - 1 n = ndarray.ndim - nfixed if n < 0: raise ValueError("ndarray must be at least %dD (got %dD)" % (nfixed, ndarray.ndim)) i = self.shape.index('...') shape = list(self.shape[:i]) + (['*'] * n) if i < len(self.shape) - 1: shape.extend(self.shape[i + 1:]) else: shape = self.shape if ndarray.ndim != len(shape): raise ValueError("ndarray must be %dD (got %dD)" % (len(shape), ndarray.ndim)) for i, attr in enumerate(shape): assert is_integer(attr) or is_string(attr), ( "shape can only be an int or str representing an attribute") if attr == '*': continue desired = attr if is_integer(attr) else getattr(instance, attr) if not is_integer(desired): raise ValueError("%s not yet initialized; cannot determine " "if shape is correct. Consider using a " "distribution instead." % attr) if ndarray.shape[i] != desired: raise ValueError("shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i])) return ndarray
def coerce(self, obj, fn): fn = super(TranscodeFunctionParam, self).coerce(obj, fn) pointer_cls = (SemanticPointer, PointerSymbol) if fn is None: return fn elif callable(fn): return self.coerce_callable(obj, fn) elif not obj.input_vocab and (is_string(fn) or isinstance(fn, pointer_cls)): return fn else: raise ValidationError("Invalid output type {!r}".format(type(fn)), attr=self.name, obj=obj)
def validate(self, instance, ndarray): # noqa: C901 if isinstance(ndarray, np.ndarray): ndarray = ndarray.view() else: try: ndarray = np.array(ndarray, dtype=np.float64) except TypeError: raise ValueError("Must be a float NumPy array (got type '%s')" % ndarray.__class__.__name__) if self.readonly: ndarray.setflags(write=False) if '...' in self.shape: nfixed = len(self.shape) - 1 n = ndarray.ndim - nfixed if n < 0: raise ValueError("ndarray must be at least %dD (got %dD)" % (nfixed, ndarray.ndim)) i = self.shape.index('...') shape = list(self.shape[:i]) + (['*'] * n) if i < len(self.shape) - 1: shape.extend(self.shape[i+1:]) else: shape = self.shape if ndarray.ndim != len(shape): raise ValueError("ndarray must be %dD (got %dD)" % (len(shape), ndarray.ndim)) for i, attr in enumerate(shape): assert is_integer(attr) or is_string(attr), ( "shape can only be an int or str representing an attribute") if attr == '*': continue desired = attr if is_integer(attr) else getattr(instance, attr) if not is_integer(desired): raise ValueError("%s not yet initialized; cannot determine " "if shape is correct. Consider using a " "distribution instead." % attr) if ndarray.shape[i] != desired: raise ValueError("shape[%d] should be %d (got %d)" % (i, desired, ndarray.shape[i])) return ndarray
def shrink(self, limit=None): # noqa: C901 """Reduces the size of the cache to meet a limit. Parameters ---------- limit : int, optional Maximum size of the cache in bytes. """ if self.readonly: logger.info("Tried to shrink a readonly cache.") return if self._index is None: warnings.warn("Cannot shrink outside of a `with cache` block.") return if limit is None: limit = rc.get('decoder_cache', 'size') if is_string(limit): limit = human2bytes(limit) self._close_fd() fileinfo = [] excess = -limit for path in self.get_files(): stat = safe_stat(path) if stat is not None: aligned_size = byte_align(stat.st_size, self._fragment_size) excess += aligned_size fileinfo.append((stat.st_atime, aligned_size, path)) # Remove the least recently accessed first fileinfo.sort() for _, size, path in fileinfo: if excess <= 0: break excess -= size self._index.remove_file_entry(path) safe_remove(path) self._index.sync()
def recorder_dirname(request, name): record = request.config.getvalue(name) if is_string(record): return record elif not record: return None simulator, nl = ReferenceSimulator, None if 'Simulator' in request.funcargnames: simulator = request.getfuncargvalue('Simulator') if 'nl' in request.funcargnames: nl = request.getfuncargvalue('nl') elif 'nl_nodirect' in request.funcargnames: nl = request.getfuncargvalue('nl_nodirect') dirname = "%s.%s" % (simulator.__module__, name) if nl is not None: dirname = os.path.join(dirname, nl.__name__) return dirname
def shrink(self, limit=None): # noqa: C901 """Reduces the size of the cache to meet a limit. Parameters ---------- limit : int, optional Maximum size of the cache in bytes. """ if self.readonly: logger.info("Tried to shrink a readonly cache.") return if limit is None: limit = rc.get('decoder_cache', 'size') if is_string(limit): limit = human2bytes(limit) self._close_fd() fileinfo = [] excess = -limit for path in self.get_files(): stat = safe_stat(path) if stat is not None: aligned_size = byte_align(stat.st_size, self._fragment_size) excess += aligned_size fileinfo.append((stat.st_atime, aligned_size, path)) # Remove the least recently accessed first fileinfo.sort() try: with self._index: for _, size, path in fileinfo: if excess <= 0: break excess -= size self.remove_file(path) except TimeoutError: logger.debug("Not shrinking cache. Lock could not be acquired.")
def shrink(self, limit=None): """Reduces the size of the cache to meet a limit. Parameters ---------- limit : int, optional Maximum size of the cache in bytes. """ if limit is None: limit = rc.get('decoder_cache', 'size') if is_string(limit): limit = human2bytes(limit) filelist = [] for filename in os.listdir(self.cache_dir): key, ext = os.path.splitext(filename) if ext == self._SOLVER_INFO_EXT: continue path = os.path.join(self.cache_dir, filename) stat = os.stat(path) filelist.append((stat.st_atime, key)) filelist.sort() excess = self.get_size_in_bytes() - limit for _, key in filelist: if excess <= 0: break decoder_path = os.path.join( self.cache_dir, key + self._DECODER_EXT) solver_info_path = os.path.join( self.cache_dir, key + self._SOLVER_INFO_EXT) excess -= os.stat(decoder_path).st_size os.remove(decoder_path) if os.path.exists(solver_info_path): excess -= os.stat(solver_info_path).st_size os.remove(solver_info_path)
def ifmax(name, condition=None, *actions): """Defines a potential action within an `ActionSelection` context. This implementation allows Nengo objects in addition to AST nodes as condition argument. Parameters ---------- name : str, optional Name for the action. Can be omitted. condition : nengo_spa.ast.base.Node or NengoObject The utility value for the given actions. actions : sequence of `RoutedConnection` The actions to activate if the given utility is the highest. Returns ------- NengoObject Nengo object that can be connected to, to provide additional input to the utility value. It is possible (but not necessary) to use SPA style connections of the form ``scalar >> utility`` to this object. """ if not is_string(name): if condition is not None: actions = (condition, ) + actions condition = name name = None if condition is None: raise ValueError("Must provide `condition` (though it may be 0).") elif condition == 0: condition = Noop(TScalar) else: condition = as_ast_node(condition) return actions_ifmax(name, as_ast_node(condition), *actions)
def validate(self, instance, string): if string is not None and not is_string(string): raise ValueError("Must be a string; got '%s'" % string) super(StringParam, self).validate(instance, string)
def __repr__(self): if is_string(self._argreprs): return "<%s at 0x%x>" % (type(self).__name__, id(self)) return "%s(%s)" % (type(self).__name__, ", ".join(self._argreprs))
def ensuretuple(val): if val is None: return val if is_string(val) or not is_iterable(val): return tuple([val]) return tuple(val)
def allclose( t, target, signals, plotter=None, filename=None, # noqa:C901 labels=None, atol=1e-8, rtol=1e-5, buf=0, delay=0): """Perform an allclose check between two signals, with the potential to buffer both ends of the signal, account for a delay, and make a plot.""" target = target.squeeze() if target.ndim > 1: raise ValueError("Can only pass one target signal") signals = np.asarray(signals) vector_in = signals.ndim < 2 if signals.ndim > 2: raise ValueError("'signals' cannot have more than two dimensions") elif vector_in: signals.shape = (1, -1) nt = t.size if signals.shape[1] != nt: raise ValueError("'signals' must have time along the second axis") slice1 = slice(buf, nt - buf - delay) slice2 = slice(buf + delay, nt - buf) if plotter is not None: with plotter as plt: if labels is None: labels = [None] * len(signals) elif is_string(labels): labels = [labels] bound = atol + rtol * np.abs(target) # signal plot ax = plt.subplot(2, 1, 1) ax.plot(t, target, 'k:') for signal, label in zip(signals, labels): ax.plot(t, signal, label=label) ax.plot(t[slice2], (target + bound)[slice1], 'k--') ax.plot(t[slice2], (target - bound)[slice1], 'k--') ax.set_ylabel('signal') legend = (ax.legend(loc=2, bbox_to_anchor=(1., 1.)) if labels[0] is not None else None) # error plot errors = np.array( [signal[slice2] - target[slice1] for signal in signals]) ymax = 1.1 * max(np.abs(errors).max(), bound.max()) ax = plt.subplot(2, 1, 2) ax.plot(t[slice2], np.zeros_like(t[slice2]), 'k:') for error, label in zip(errors, labels): plt.plot(t[slice2], error, label=label) ax.plot(t[slice2], bound[slice1], 'k--') ax.plot(t[slice2], -bound[slice1], 'k--') ax.set_ylim((-ymax, ymax)) ax.set_xlabel('time') ax.set_ylabel('error') if filename is not None: plt.savefig(filename, bbox_inches='tight', bbox_extra_artists=(legend, ) if legend else ()) else: plt.show() plt.close() close = [ np.allclose(signal[slice2], target[slice1], atol=atol, rtol=rtol) for signal in signals ] return close[0] if vector_in else close
def validate(self, instance, string): if string is not None and not is_string(string): raise ValidationError("Must be a string; got '%s'" % string, attr=self.name, obj=instance) super(StringParam, self).validate(instance, string)
def allclose(t, targets, signals, # noqa:C901 atol=1e-8, rtol=1e-5, buf=0, delay=0, plt=None, show=False, labels=None, individual_results=False): """Ensure all signal elements are within tolerances. Allows for delay, removing the beginning of the signal, and plotting. Parameters ---------- t : array_like (T,) Simulation time for the points in `target` and `signals`. targets : array_like (T, 1) or (T, N) Reference signal or signals for error comparison. signals : array_like (T, N) Signals to be tested against the target signals. atol, rtol : float Absolute and relative tolerances. buf : float Length of time (in seconds) to remove from the beginnings of signals. delay : float Amount of delay (in seconds) to account for when doing comparisons. plt : matplotlib.pyplot or mock Pyplot interface for plotting the results, unless it's mocked out. show : bool Whether to show the plot immediately. labels : list of string, length N Labels of each signal to use when plotting. individual_results : bool If True, returns a separate `allclose` result for each signal. """ t = np.asarray(t) dt = t[1] - t[0] assert t.ndim == 1 assert np.allclose(np.diff(t), dt) targets = np.asarray(targets) signals = np.asarray(signals) if targets.ndim == 1: targets = targets.reshape((-1, 1)) if signals.ndim == 1: signals = signals.reshape((-1, 1)) assert targets.ndim == 2 and signals.ndim == 2 assert t.size == targets.shape[0] assert t.size == signals.shape[0] assert targets.shape[1] == 1 or targets.shape[1] == signals.shape[1] buf = int(np.round(buf / dt)) delay = int(np.round(delay / dt)) slice1 = slice(buf, len(t) - delay) slice2 = slice(buf + delay, None) if plt is not None: if labels is None: labels = [None] * len(signals) elif is_string(labels): labels = [labels] colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] def plot_target(ax, x, b=0, c='k'): bound = atol + rtol * np.abs(x) y = x - b ax.plot(t[slice2], y[slice1], c + ':') ax.plot(t[slice2], (y + bound)[slice1], c + '--') ax.plot(t[slice2], (y - bound)[slice1], c + '--') # signal plot ax = plt.subplot(2, 1, 1) for y, label in zip(signals.T, labels): ax.plot(t, y, label=label) if targets.shape[1] == 1: plot_target(ax, targets[:, 0], c='k') else: color_cycle = itertools.cycle(colors) for x in targets.T: plot_target(ax, x, c=next(color_cycle)) ax.set_ylabel('signal') if labels[0] is not None: ax.legend(loc='upper left', bbox_to_anchor=(1., 1.)) ax = plt.subplot(2, 1, 2) if targets.shape[1] == 1: x = targets[:, 0] plot_target(ax, x, b=x, c='k') for y, label in zip(signals.T, labels): ax.plot(t[slice2], y[slice2] - x[slice1]) else: color_cycle = itertools.cycle(colors) for x, y, label in zip(targets.T, signals.T, labels): c = next(color_cycle) plot_target(ax, x, b=x, c=c) ax.plot(t[slice2], y[slice2] - x[slice1], c, label=label) ax.set_xlabel('time') ax.set_ylabel('error') if show: plt.show() if individual_results: if targets.shape[1] == 1: return [np.allclose(y[slice2], targets[slice1, 0], atol=atol, rtol=rtol) for y in signals.T] else: return [np.allclose(y[slice2], x[slice1], atol=atol, rtol=rtol) for x, y in zip(targets.T, signals.T)] else: return np.allclose(signals[slice2, :], targets[slice1, :], atol=atol, rtol=rtol)
def __init__(self, selection_net, input_vocab, output_vocab=None, mapping=None, n_neurons=50, label="Associative memory", seed=None, add_to_container=None, vocabs=None, **selection_net_args): super(AssociativeMemory, self).__init__(label=label, seed=seed, add_to_container=add_to_container, vocabs=vocabs) if output_vocab is None: output_vocab = input_vocab elif mapping is None: raise ValidationError( "The mapping argument needs to be provided if an output " "vocabulary is given.", attr='mapping', obj=self) self.input_vocab = input_vocab self.output_vocab = output_vocab if mapping is None: raise TypeError("Must provide 'mapping' argument.") elif mapping == 'by-key': mapping = self.input_vocab.keys() elif is_string(mapping): raise ValidationError( "The mapping argument must be a dictionary, the string " "'by-key' or a sequence of strings.", attr='mapping', obj=self) if not hasattr(mapping, 'keys'): mapping = {k: k for k in mapping} if len(mapping) < 1: raise ValidationError( "At least one item must be provided with the mapping " "argument.", attr='mapping', obj=self) input_keys = mapping.keys() input_vectors = [self.input_vocab.parse(key).v for key in input_keys] output_keys = [mapping[k] for k in input_keys] output_vectors = [ self.output_vocab.parse(key).v for key in output_keys ] input_vectors = np.asarray(input_vectors) output_vectors = np.asarray(output_vectors) with self: self.selection = selection_net(n_neurons=n_neurons, n_ensembles=len(input_vectors), label="selection", **selection_net_args) self.input = nengo.Node(size_in=self.input_vocab.dimensions, label="input") self.output = nengo.Node(size_in=self.output_vocab.dimensions, label="output") nengo.Connection(self.input, self.selection.input, transform=input_vectors) nengo.Connection(self.selection.output, self.output, transform=output_vectors.T) self.declare_input(self.input, self.input_vocab) self.declare_output(self.output, self.output_vocab)
def __getitem__(self, key): if is_string(key): key = self._name2idx[key] return self._utilities[key]