ctn-waterloo/nengo — pull request #227 by jaberg (2013-12-11 17:41:10+00:00)
Title: WIP: initial support for Node named inputs

Further to the Node API discussion in #224, here's a quick draft of what the named inputs idea might look like.

From `TestNode` we have:

```
def test_named_inputs(self):
dt = 0.001
m = nengo.Model("test_named_inputs", seed=0)

ys = []
zs = []
def hello(t, y, z):
ys.append(float(y))
zs.append(float(z))
return 0

with m:
a = nengo.Node(np.sin) # -- still works
b = nengo.Node(output=hello,
inputs={
'y': nengo.Vector(dimensions=1, descr="basically a docstring"),
'z': nengo.Vector(dimensions=1, descr="another docstring"),
}
)
nengo.Connection(a, b.y, filter=None)
nengo.Connection(a, b.z, filter=None)

sim = self.Simulator(m, dt=dt)
sim.run(0.01)
assert all(y == z for y, z in zip(ys, zs))
assert np.allclose(ys[9], 0.009, rtol=1e-4)
```

This isn't ready for merge yet, partly because this new node doesn't have a default "input_signal" to which other things can connect. Instead it has 0 or more named input signals in e.g. `b.y`, `b.z`. These input signals are enumerated in `b.inputs.*`.

Also, in discussing this approach, consider the relationship between these named inputs, potential *named outputs* (not implemented here) and the similarity of these named things and the "Probe-able" interface that people have been talking about. The similarity is that with this PR, the Node collects together a number of named things which could be probed in the "inputs" dictionary. If we make a second dictionary of outputs, then the two of them together would represent all of the things about a Node that you could potentially probe. We might want to even require that all model objects have a collection of things-which-are-not-yet-Signals-but-which-will-become-signals-in-the-build-process. Maybe call these "probe_points"? I don't know.

E.g.
```python
# -- see what we've got:
print b.probe_points

# -- probe a thing you know about in one of two ways:
Probe(b.probe_points.z)
# or just
Probe(b.z, sample_every=0.1)
```

Anyway, just wanted to clarify that I didn't want to make huge changes to the code, but that the interface we choose here should be done carefully because it touches on how the probe-able business will be handled, which in turn has consequences for how we arrange named things in e.g. Ensemble, Connection.

This mechanism is borrowed from a technique I was using for handling some new learning-rule stuff I'm writing, where I wanted to provide API-level access to a bunch of internal variables to the learning rule, which aren't technically allocated until build-time.