Now, I’m watching how the Synapse work on. By default, the Synapse is related to the LinearFilter that invoked after the Lowpass. In the case of the LinearFilter.Simple, I can’t match the implementation of LinearFilter.Simple.call and controllable canonical form. How the implementation can be transformed from the form in wiki?

# Can't fully understand for the implementation of LinearFilter

When the synapse is converted from transfer function to state-space representation (using scipy.signal.tf2ss) it is put into controllable canonical form (CCF). However the state-space matrices are then discretized (using zero-order hold by default, which involves a matrix exponential) which then changes its form. The system must in general be discretized in some way in order to simulate the synapses on digital hardware (e.g., CPU/GPU/etc). Once it has been discretized you can put it back into CCF using scipy (by calling `tf2ss`

and then `ss2tf`

again), but this may result in a loss of accuracy as it requires computing the characteristic polynomial.

At the same time, nengolib.signal.LinearSystem provides access to a bunch of helper methods for working with synapse objects in Nengo. One that you might find useful is the `controllable`

property which returns the synapse in CCF. By accessing the `.ss`

attribute on that object you will get the (A, B, C, D) matrices in CCF. Depending on whether the synapse has `analog=True`

or `analog=False`

those matrices will represent either a continuous-time LTI or a discrete-time LTI, respectively.

```
import nengolib
synapse = nengolib.Alpha(0.1)
synapse.controllable.ss
(array([[ -20., -100.],
[ 1., 0.]]), array([[1.],
[0.]]), array([[ 0., 100.]]), array([[0.]]))
```

Thank you for reply !

After that, I try to study about it detail and organize steps as follows

- Suppose that input and output signals are discrete signals
- To process discrete signals, we need to design a digital filter
- In the case of Lowpass filter, we have to transform a continuous time-domain impulse response to a continuous transfer function with Laplacian transform.
- With Controllable Canonical Form, we can get four parameters about state space representation from both numerators and denominators for the function.
- With an assumption, the parameters can be discretized. In this case, I don’t know what a method is applied to.
- Now, we can get numerators and denominators of a discretized transfer function from the discretized state space representation.
- Finally, we can have discrete output signals from previous step.

However, I’m not sure it is correct.

Sounds right. For point 5, the discretization method we use by default is assuming “zero-order hold” which is detailed in Discretization of linear state space models (Wikipedia), notably the equations that map $(A, B, C, D) \mapsto (A_d, B_d, C_d, D_d)$. These same equations are also provided on pg. 100 of my thesis. In short, this assumes that the underlying continuous-time signal is step-wise with the input held constant across each discrete time-step. See scipy.signal.cont2discrete and zero-order hold for more information.

Thank you. Now, I get an understanding for synapse. Btw, this is not relating with the synapse, Nengo uses an ensemble to represent a vector. Would you please explain why nengo uses ensemble?

Ensembles of neurons are used to represent vectors by having each neuron respond along a particular “preferred direction” in vector space. By heterogeneously encoding the vector space (i.e., randomly distributing the neural responses), the ensemble allows nonlinear high-dimensional vector functions to be “decoded” from the resultling neural activity. I would suggest reading the NEF summary documentation or a summary from one of our papers, and opening a separate thread in the forum if you have any follow-up questions.