1
|
1
|
import numpy as np
|
2
|
|
|
3
|
1
|
from nengo.base import Process
|
4
|
1
|
from nengo.exceptions import ValidationError
|
5
|
1
|
from nengo.utils.stdlib import checked_call
|
6
|
|
|
7
|
1
|
__all__ = ['Callable']
|
8
|
|
|
9
|
|
|
10
|
1
|
class Callable(Process):
|
11
|
|
"""Adapter to convert any callable into a :class:`nengo.Process`.
|
12
|
|
|
13
|
|
Parameters
|
14
|
|
----------
|
15
|
|
func : ``callable``
|
16
|
|
A function that can be called with a single float argument (time).
|
17
|
|
default_dt : ``float``, optional
|
18
|
|
Default time-step for the process. Defaults to ``0.001`` seconds.
|
19
|
|
seed : ``integer``, optional
|
20
|
|
Seed for the process.
|
21
|
|
|
22
|
|
See Also
|
23
|
|
--------
|
24
|
|
:class:`nengo.Process`
|
25
|
|
|
26
|
|
Examples
|
27
|
|
--------
|
28
|
|
Making a sine wave process using a lambda:
|
29
|
|
|
30
|
|
>>> from nengolib.processes import Callable
|
31
|
|
>>> process = Callable(lambda t: np.sin(2*np.pi*t))
|
32
|
|
|
33
|
|
>>> import matplotlib.pyplot as plt
|
34
|
|
>>> plt.plot(process.ntrange(1000), process.run_steps(1000))
|
35
|
|
>>> plt.xlabel("Time (s)")
|
36
|
|
>>> plt.show()
|
37
|
|
"""
|
38
|
|
|
39
|
1
|
def __init__(self, func, default_dt=0.001, seed=None):
|
40
|
1
|
if not callable(func):
|
41
|
1
|
raise ValidationError("func (%s) must be callable" % func,
|
42
|
|
attr='func', obj=self)
|
43
|
1
|
self.func = func
|
44
|
1
|
value, invoked = checked_call(func, 0.)
|
45
|
1
|
if not invoked:
|
46
|
1
|
raise ValidationError(
|
47
|
|
"func (%s) must only take single float argument" % func,
|
48
|
|
attr='func', obj=self)
|
49
|
1
|
default_size_out = np.asarray(value).size
|
50
|
1
|
super(Callable, self).__init__(
|
51
|
|
default_size_in=0,
|
52
|
|
default_size_out=default_size_out,
|
53
|
|
default_dt=default_dt,
|
54
|
|
seed=seed)
|
55
|
|
|
56
|
1
|
def __repr__(self):
|
57
|
1
|
return "%s(func=%r, default_dt=%r, seed=%r)" % (
|
58
|
|
type(self).__name__, self.func, self.default_dt, self.seed)
|
59
|
|
|
60
|
1
|
def make_step(self, shape_in, shape_out, dt, rng):
|
61
|
1
|
if shape_in != (0,):
|
62
|
1
|
raise ValidationError("shape_in must be (0,), got %s" % (
|
63
|
|
shape_in,), attr='func', obj=self)
|
64
|
1
|
if shape_out != (self.default_size_out,):
|
65
|
1
|
raise ValidationError("shape_out must be (%s,), got %s" % (
|
66
|
|
self.default_size_out, shape_out), attr='func', obj=self)
|
67
|
|
|
68
|
1
|
def step(t):
|
69
|
1
|
return self.func(t)
|
70
|
1
|
return step
|