# What do the connection inputs and outputs mean?

Hi,

I’m trying to understand the very basics of how connections work, but am having trouble finding exactly how a connection affects the voltage and current of the pre and post neurons. Is it in step_math of the neuron_type where the input from the previous layer is being used, or somewhere else? For example, if I make the following network, I am expecting that the input to b.neurons is the voltage array of a.neurons multiplied by the weights, which in this case, should be identical to the voltage of a.neurons. However, I don’t know where the inputs and outputs from probing the connection are coming from/what they mean:

``````weights = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])

model = nengo.Network()

with model:
a = nengo.Ensemble(3, dimensions=1, neuron_type=nengo.LIF())
b = nengo.Ensemble(3, dimensions=1, neuron_type=nengo.LIF())

conn = nengo.Connection(a.neurons, b.neurons, transform = weights)
spikes_probe = nengo.Probe(a.neurons, 'spikes')
voltage_probe = nengo.Probe(a.neurons, 'voltage')

b_spikes = nengo.Probe(b.neurons, 'spikes')
b_voltage = nengo.Probe(b.neurons, 'voltage')

conn_out = nengo.Probe(conn, 'output')
conn_in = nengo.Probe(conn, 'input')
with nengo.Simulator(model) as sim:
sim.run(.01)

plt.figure(figsize=(12, 6))
plt.subplot(131)
plt.plot(sim.trange(), sim.data[b_voltage][:,0], label = "b")
plt.plot(sim.trange(), sim.data[voltage_probe][:,0], label = 'a')
plt.xlabel('time [s]')
plt.ylabel('b voltage')
plt.legend()

plt.subplot(132)
plt.plot(sim.trange(), sim.data[b_voltage][:,1], label = "b")
plt.plot(sim.trange(), sim.data[voltage_probe][:,1], label = 'a')
plt.xlabel('time [s]')
plt.ylabel('b voltage')
plt.legend()

plt.subplot(133)
plt.plot(sim.trange(), sim.data[b_voltage][:,2], label = "b")
plt.plot(sim.trange(), sim.data[voltage_probe][:,2], label = 'a')
plt.xlabel('time [s]')
plt.ylabel('b voltage')
plt.legend()

sim.data[conn_out]
sim.data[conn_in]
``````

I get the following graphs and values for `conn_out` and `conn_in`.

Hi!
Regarding the question about probing, in general for a connection `c = nengo.Connection(pre, post)` in general, `nengo.Probe(c, "input")` is equivalent to `nengo.Probe(pre, "output")` , and `nengo.Probe(c, "output")` is equivalent to `nengo.Probe(post, "input")`. Given that `pre` and `post` are neurons in your example, the inputs to the connection are the spikes generated by ensemble `a`, which are scaled by `1/dt` and hence appear as 1000s if `dt` is one millisecond as per default, while the outputs from the connection are the result of multiplying input spikes by their corresponding connection weights and then passing them through a synaptic filter.

These outputs are then provided as inputs to the neurons in `post` or ensemble `b` in your example. Because the LIF neuron model has internal parameters (e.g., a bias), the voltage of each neuron is not determined solely by its input, and won’t be identical to that of a corresponding neuron in `a` (to do this kind of voltage comparison you’d also want to use an identity matrix instead of a full array of ones for the connection weights in order to ensure that spikes from a neuron in `a` only are received by a corresponding neuron in `b`).

Anyway, I hope this helps to clear things up, but please feel free to let us know if you have further questions.

Thank you, this is very helpful! I see now that when I make `synapse = None` and have an identity matrix as the weights, the connection input and output are identical. How do I know where this output is being used in the voltage update for the LIF neuron? I can’t seem to tell where this information is in the documentation. My ultimate goal is to create a custom neuron type where I can control where the input from the previous layer is being used.

A good starting point might be to look at the implementation for the LIF neuron type that you are currently using: https://www.nengo.ai/nengo/frontend-api.html#nengo.LIF

In general, a neuron type implementation has to have a `step` method that runs at every tilmestep during a simulation. Neurons also typically have a gain and bias associated with them, where the gain has a multiplicative effect on the input while the bias has an additive effect (see e.g: https://www.nengo.ai/nengo/_modules/nengo/neurons.html#NeuronType). If you set the gains to 1 and biases to 0, then the input `J` in the existing LIF `step` implementation will be the output of the connection object (the gains may be rolled into the connection weights, but for now, I’d start with setting them to 1 and go from here).