Connections¶
The best way to understand the concept of a Connection in
Brian is to work through Tutorial 2: Connections.
-
class
brian.Connection(source, target, state=0, delay=0.0 * second, modulation=None, structure='sparse', weight=None, sparseness=None, max_delay=5.0 * msecond, **kwds)¶ Mechanism for propagating spikes from one group to another
A Connection object declares that when spikes in a source group are generated, certain neurons in the target group should have a value added to specific states. See Tutorial 2: Connections to understand this better.
With arguments:
source- The group from which spikes will be propagated.
target- The group to which spikes will be propagated.
state- The state variable name or number that spikes will be propagated to in the target group.
delay- The delay between a spike being generated at the source
and received at the target. Depending on the type of
delayit has different effects. Ifdelayis a scalar value, then the connection will be initialised with all neurons having that delay. For very long delays, this may raise an error. Ifdelay=Truethen the connection will be initialised as aDelayConnection, allowing heterogeneous delays (a different delay for each synapse).delaycan also be a pair(min,max)or a function of one or two variables, in both cases it will be initialised as aDelayConnection, see the documentation for that class for details. Note that in these cases, initialisation of delays will only have the intended effect if used with theweightandsparsenessarguments below. max_delay- If you are using a connection with heterogeneous delays, specify this to set the maximum allowed delay (smaller values use less memory). The default is 5ms.
modulation- The state variable name from the source group that scales the synaptic weights (for short-term synaptic plasticity).
structure- Data structure:
sparse(default),denseordynamic. See below for more information on structures. weight- If specified, the connection matrix will be initialised with
values specified by
weight, which can be any of the values allowed in the methods connect*` below. sparseness- If
weightis specified andsparsenessis not, a full connection is assumed, otherwise random connectivity with this level of sparseness is assumed.
Methods
connect_random(P,Q,p[,weight=1[,fixed=False[,seed=None]]])- Connects each neuron in
Pto each neuron inQwith independent probabilitypand weightweight(this is the amount that gets added to the target state variable). Iffixedis True, then the number of presynaptic neurons per neuron is constant. Ifseedis given, it is used as the seed to the random number generators, for exactly repeatable results. connect_full(P,Q[,weight=1])- Connect every neuron in
Pto every neuron inQwith the given weight. connect_one_to_one(P,Q)- If
PandQhave the same number of neurons then neuroniinPwill be connected to neuroniinQwith weight 1. connect(P,Q,W)- You can specify a matrix of weights directly (can be in any format
recognised by NumPy). Note that due to internal implementation details,
passing a full matrix rather than a sparse one may slow down your code
(because zeros will be propagated as well as nonzero values).
WARNING: No unit checking is done at the moment. For a more
efficient low-level method see
connect_from_sparse().
Additionally, you can directly access the matrix of weights by writing:
C = Connection(P,Q) print C[i,j] C[i,j] = ...
Where here
iis the source neuron andjis the target neuron. Note: ifC[i,j]should be zero, it is more efficient not to writeC[i,j]=0, if you write this then when neuronifires all the targets will have the value 0 added to them rather than just the nonzero ones. WARNING: No unit checking is currently done if you use this method. Take care to set the right units.Connection matrix structures
Brian currently features three types of connection matrix structures, each of which is suited for different situations. Brian has two stages of connection matrix. The first is the construction stage, used for building a weight matrix. This stage is optimised for the construction of matrices, with lots of features, but would be slow for runtime behaviour. Consequently, the second stage is the connection stage, used when Brian is being run. The connection stage is optimised for run time behaviour, but many features which are useful for construction are absent (e.g. the ability to add or remove synapses). Conversion between construction and connection stages is done by the
compress()method ofConnectionwhich is called automatically when it is used for the first time.The structures are:
dense- A dense matrix. Allows runtime modification of all values. If
connectivity is close to being dense this is probably the most
efficient, but in most cases it is less efficient. In addition,
a dense connection matrix will often do the wrong thing if
using STDP. Because a synapse will be considered to exist but
with weight 0, STDP will be able to create new synapses where
there were previously none. Memory requirements are
8NMbytes where(N,M)are the dimensions. (Adoublefloat value uses 8 bytes.) sparse- A sparse matrix. See
SparseConnectionMatrixfor details on implementation. This class features very fast row access, and slower column access if thecolumn_access=Truekeyword is specified (making it suitable for learning algorithms such as STDP which require this). Memory requirements are 12 bytes per nonzero entry for row access only, or 20 bytes per nonzero entry if column access is specified. Synapses cannot be created or deleted at runtime with this class (although weights can be set to zero). dynamic- A sparse matrix which allows runtime insertion and removal
of synapses. See
DynamicConnectionMatrixfor implementation details. This class features row and column access. The row access is slower than forsparseso this class should only be used when insertion and removal of synapses is crucial. Memory requirements are 24 bytes per nonzero entry. However, note that more memory than this may be required because memory is allocated using a dynamic array which grows by doubling its size when it runs out. If you know the maximum number of nonzero entries you will have in advance, specify thennzmaxkeyword to set the initial size of the array.
Low level methods
-
connect_from_sparse(W, delay=None, column_access=True)¶ Bypasses the usual Brian mechanisms for constructing and compressing matrices, and allows you to directly set the weight (and optionally delay) matrices from scipy sparse matrix objects. This can be more memory efficient, because the default sparse matrix used for construction is
scipy.sparse.lil_matrixwhich is very memory inefficient.Arguments:
W- The weight matrix
delay- Optional delay matrix if you are using heterogeneous delays.
column_access=True- Set to
Falseto save memory if you are not using STDP.
Warning
This is a low-level method that bypasses the usual checks on the data. In particular, make sure that if you pass a weight and delay matrix, that they have the same structure.
Advanced information
The following methods are also defined and used internally, if you are writing your own derived connection class you need to understand what these do.
propagate(spikes)- Action to take when source neurons with indices in
spikesfired. do_propagate()- The method called by the
Networkupdate()step, typically just propagates the spikes obtained by calling theget_spikesmethod of thesourceNeuronGroup.
-
class
brian.DelayConnection(source, target, state=0, modulation=None, structure='sparse', weight=None, sparseness=None, delay=None, max_delay=5.0 * msecond, **kwds)¶ Connection which implements heterogeneous postsynaptic delays
Initialised as for a
Connection, but with the additional keyword:max_delay- Specifies the maximum delay time for any neuron. Note, the smaller you make this the less memory will be used.
Overrides the following attribute of
Connection:-
delay¶ A matrix of delays. This array can be changed during a run, but at no point should it be greater than
max_delay.
In addition, the methods
connect,connect_random,connect_full, andconnect_one_to_onehave a new keyworddelay=...for setting the initial values of the delays, wheredelaycan be one of:- A float, all delays will be set to this value
- A pair (min, max), delays will be uniform between these two values.
- A function of no arguments, will be called for each nonzero entry in the weight matrix.
- A function of two argument
(i,j)will be called for each nonzero entry in the weight matrix. - A matrix of an appropriate type (e.g. ndarray or lil_matrix).
Finally, there is a method:
set_delays(source, target, delay)- Where
delaymust be of one of the types above.
Notes
This class implements post-synaptic delays. This means that the spike is propagated immediately from the presynaptic neuron with the synaptic weight at the time of the spike, but arrives at the postsynaptic neuron with the given delay. At the moment, Brian only provides support for presynaptic delays if they are homogeneous, using the
delaykeyword of a standardConnection.Implementation
DelayConnectionstores an array of size(n,m)wherenismax_delay/dtfordtof the targetNeuronGroup‘s clock, andmis the number of neurons in the target. This array can potentially be quite large. Each row in this array represents the array that should be added to the target state variable at some particular future time. Which row corresponds to which time is tracked using a circular indexing scheme.When a spike from neuron
iin the source is encountered, the delay time of neuroniis looked up, the row corresponding to the current time plus that delay time is found using the circular indexing scheme, and then the spike is propagated to that row as for a standard connection (although this won’t be propagated to the target until a later time).Warning
If you are using a dynamic connection matrix, it is your responsibility to ensure that the nonzero entries of the weight matrix and the delay matrix exactly coincide. This is not an issue for sparse or dense matrices.
-
class
brian.IdentityConnection(source, target, state=0, weight=1, delay=0.0 * second)¶ A
Connectionbetween two groups of the same size, where neuroniin the source group is connected to neuroniin the target group.Initialised with arguments:
source,target- The source and target
NeuronGroupobjects. state- The target state variable.
weight- The weight of the synapse, must be a scalar.
delay- Only homogeneous delays are allowed.
The benefit of this class is that it has no storage requirements and is optimised for this special case.
Connection matrix types¶
-
class
brian.ConnectionMatrix¶ Base class for connection matrix objects
Connection matrix objects support a subset of the following methods:
get_row(i),get_col(i)- Returns row/col
ias aDenseConnectionVectororSparseConnectionVectoras appropriate for the class. set_row(i, val),set_col(i, val)- Sets row/col with an array,
DenseConnectionVectororSparseConnectionVector(if supported). get_element(i, j),set_element(i, j, val)- Gets or sets a single value.
get_rows(rows)- Returns a list of rows, should be implemented without Python function calls for efficiency if possible.
get_cols(cols)- Returns a list of cols, should be implemented without Python function calls for efficiency if possible.
insert(i,j,x),remove(i,j)- For sparse connection matrices which support it, insert a new entry or remove an existing one.
getnnz()- Return the number of nonzero entries.
todense()- Return the matrix as a dense array.
The
__getitem__and__setitem__methods are implemented by default, and automatically select the appropriate methods from the above in the cases where the item to be got or set is of the form:,i,:,:,jori,j.
-
class
brian.DenseConnectionMatrix(val, **kwds)¶ Dense connection matrix
See documentation for
ConnectionMatrixfor details on connection matrix types.This matrix implements a dense connection matrix. It is just a numpy array. The
get_rowandget_colmethods returnDenseConnectionVector`objects.
-
class
brian.SparseConnectionMatrix(val, column_access=True, use_minimal_indices=False, **kwds)¶ Sparse connection matrix
See documentation for
ConnectionMatrixfor details on connection matrix types.This class implements a sparse matrix with a fixed number of nonzero entries. Row access is very fast, and if the
column_accesskeyword isTruethen column access is also supported (but is not as fast as row access). If theuse_minimal_indiceskeyword isTruethen the neuron and synapse indices will use the smallest possible integer type (16 bits for neuron indices if the number of neurons is less than2**16, otherwise 32 bits). Otherwise, it will use the word size for the CPU architecture (32 or 64 bits).The matrix should be initialised with a scipy sparse matrix.
The
get_rowandget_colmethods returnSparseConnectionVectorobjects. In addition to the usual slicing operations supported,M[:]=valis supported, wherevalmust be a scalar or an array of lengthnnz.Implementation details:
The values are stored in an array
alldataof lengthnnz(number of nonzero entries). The slicealldata[rowind[i]:rowind[i+1]]gives the values for rowi. These slices are stored in the listrowdataso thatrowdata[i]is the data for rowi. The arrayrowj[i]gives the corresponding columnjindices. For row access, the memory requirements are 12 bytes per entry (8 bytes for the float value, and 4 bytes for the column indices). The arrayalljof lengthnnzgives the columnjcoordinates for each element inalldata(the elements ofrowjare slices of this array so no extra memory is used).If column access is being used, then in addition to the above there are lists
coliandcoldataindices. For columnj, the arraycoli[j]gives the row indices for the data values in columnj, whilecoldataindices[j]gives the indices in the arrayalldatafor the values in columnj. Column access therefore involves a copy operation rather than a slice operation. Column access increases the memory requirements to 20 bytes per entry (4 extra bytes for the row indices and 4 extra bytes for the data indices).TODO: update size numbers when use_minimal_indices=True for different architectures.
-
class
brian.DynamicConnectionMatrix(val, nnzmax=None, dynamic_array_const=2, **kwds)¶ Dynamic (sparse) connection matrix
See documentation for
ConnectionMatrixfor details on connection matrix types.This class implements a sparse matrix with a variable number of nonzero entries. Row access and column access are provided, but are not as fast as for
SparseConnectionMatrix.The matrix should be initialised with a scipy sparse matrix.
The
get_rowandget_colmethods returnSparseConnectionVectorobjects. In addition to the usual slicing operations supported,M[:]=valis supported, wherevalmust be a scalar or an array of lengthnnz.Implementation details
The values are stored in an array
alldataof lengthnnzmax(maximum number of nonzero entries). This is a dynamic array, see:You can set the resizing constant with the argument
dynamic_array_const. Normally the default value 2 is fine but if memory is a worry it could be made smaller.Rows and column point in to this data array, and the list
rowjconsists of an array of column indices for each row, withcolicontaining arrays of row indices for each column. Similarly,rowdataindandcoldataindconsist of arrays of pointers to the indices in thealldataarray.
Construction matrix types¶
-
class
brian.ConstructionMatrix¶ Base class for construction matrices
A construction matrix is used to initialise and build connection matrices. A
ConstructionMatrixclass has to implement a methodconnection_matrix(*args, **kwds)which returns aConnectionMatrixobject of the appropriate type.
-
class
brian.DenseConstructionMatrix(val, **kwds)¶ Dense construction matrix. Essentially just numpy.ndarray.
The
connection_matrixmethod returns aDenseConnectionMatrixobject.The
__setitem__method is overloaded so that you can set values with a sparse matrix.
-
class
brian.SparseConstructionMatrix(arg, **kwds)¶ SparseConstructionMatrix is converted to SparseConnectionMatrix.
-
class
brian.DynamicConstructionMatrix(arg, **kwds)¶ DynamicConstructionMatrix is converted to DynamicConnectionMatrix.
Connection vector types¶
-
class
brian.ConnectionVector¶ Base class for connection vectors, just used for defining the interface
ConnectionVector objects are returned by ConnectionMatrix objects when they retrieve rows or columns. At the moment, there are two choices, sparse or dense.
This class has no real function at the moment.
-
class
brian.DenseConnectionVector¶ Just a numpy array.
-
class
brian.SparseConnectionVector¶ Sparse vector class
A sparse vector is typically a row or column of a sparse matrix. This class can be treated in many cases as if it were just a vector without worrying about the fact that it is sparse. For example, if you write
2*vit will evaluate to a new sparse vector. There is one aspect of the semantics which is potentially confusing. In a binary operation with a dense vector such assv+dvwheresvis sparse anddvis dense, the result will be a sparse vector with zeros wheresvhas zeros, the potentially nonzero elements ofdvwheresvhas no entry will be simply ignored. It is for this reason that it is aSparseConnectionVectorand not a generalSparseVector, because these semantics make sense for rows and columns of connection matrices but not in general.Implementation details:
The underlying numpy array contains the values, the attribute
nis the length of the sparse vector, andindis an array of the indices of the nonzero elements.