Can't fully understand for the implementation of LinearFilter

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?

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

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