24 "Name",
"SeqSynHandler",
25 "Author",
"Upi Bhalla",
27 "The SeqSynHandler handles synapses that recognize sequentially "
28 "ordered input, where the ordering is both in space and time. "
29 "It assumes that the N input synapses are ordered and "
30 "equally spaced along a single linear vector.\n "
31 "To do this it maintains a record of recent synaptic input, "
32 "for a duration of *historyTime*, at a time interval *seqDt*. "
33 "*SeqDt* is typically longer than the simulation "
34 "timestep *dt* for the synapse, and cannot be shorter. "
35 "*SeqDt* should represent the characteristic time of advance "
37 "The SeqSynHandler uses a 2-D kernel to define how to recognize"
38 " a sequence, with dependence both on space and history. "
39 "This kernel is defined by the *kernelEquation* as a "
40 "mathematical expression in x (synapse number) and t (time)."
41 "It computes a vector with the local *response* term for each "
42 "point along all inputs, by taking a 2-d convolution of the "
43 "kernel with the history[time][synapse#] matrix."
44 "\nThe local response can affect the synapse in three ways: "
45 "1. It can sum the entire response vector, scale by the "
46 "*sequenceScale* term, and send to the synapse as a steady "
47 "activation. Consider this a cell-wide immediate response to "
48 "a sequence that it likes.\n"
49 "2. It do an instantaneous scaling of the weight of each "
50 "individual synapse by the corresponding entry in the response "
51 "vector. It uses the *plasticityScale* term to do this. "
53 "this a short-term plasticity effect on specific synapses. \n"
54 "3. It can do long-term plasticity of each individual synapse "
55 "using the matched local entries in the response vector and "
56 "individual synapse history as inputs to the learning rule. "
57 "This is not yet implemented.\n"
58 "In addition to all these, the SeqSynHandler can act just like "
59 "a regular synapse, where it responds to individual synaptic "
60 "input according to the weight of the synapse. The size of "
61 "this component of the output is scaled by *baseScale*\n"
66 "Sets up field Elements for synapse",
75 "Equation in x and t to define kernel for sequence recognition",
81 "Width of kernel, i.e., number of synapses taking part in seq.",
87 "Characteristic time for advancing the sequence.",
93 "Duration to keep track of history of inputs to all synapses.",
99 "Basal scaling factor for regular synaptic activation.",
105 "Scaling factor for sustained activation of synapse by seq",
111 "Mapping of synapse input order to spatial order on syn array."
112 "Entries in this vector are indices which must remain smaller "
113 "than numSynapses. The system will fix up if you mess up. "
114 "It does not insist on unique mappings, but these are "
115 "desirable as outcome is undefined for repeated entries.",
120 "synapseOrderOption",
121 "How to do the synapse order remapping. This rule stays in "
122 "place and guarantees safe mappings even if the number of "
123 "synapses is altered. Options:\n"
124 "-2: User ordering.\n"
125 "-1: Sequential ordering, 0 to numSynapses-1.\n"
126 "0: Random ordering using existing system seed.\n"
127 ">0: Random ordering using seed specified by this number\n"
128 "Default is -1, sequential ordering.",
134 "Reports summed activation of synaptic channel by sequence",
139 "Scaling factor for doing plasticity by scaling each synapse by response vector",
146 "Exponent for the outcome of the sequential calculations. "
147 "This is needed because linear summation of terms in the kernel"
148 "means that a brief stong sequence match is no better than lots"
149 "of successive low matches. In other words, 12345 is no better"
150 "than 11111. Using an exponent lets us select the former."
159 "Vector of weight scaling for each synapse",
164 "All entries of kernel, as a linear vector",
169 "All entries of history, as a linear vector",
173 static Finfo* seqSynHandlerFinfos[] = {
196 sizeof( seqSynHandlerFinfos ) /
sizeof (
Finfo* ),
199 sizeof( doc ) /
sizeof(
string )
211 kernelEquation_(
"" ),
216 sequenceScale_( 1.0 ),
217 plasticityScale_( 0.0 ),
218 sequencePower_( 1.0 ),
219 seqActivation_( 0.0 ),
220 synapseOrderOption_( -1 )
232 for ( vector< Synapse >::iterator
234 i->setHandler(
this );
245 unsigned int prevSize =
synapses_.size();
247 for (
unsigned int i = prevSize; i < v; ++i )
267 cout <<
"Warning: SeqSynHandler::getSynapse: index: " << i <<
268 " is out of range: " <<
synapses_.size() << endl;
279 vector< unsigned int > availableEntries( sz );
280 iota( availableEntries.begin(), availableEntries.end(), 0 );
281 for(
unsigned int i = 0; i < sz; ++i ) {
285 vector< unsigned int > ae;
286 for(
unsigned int i = 0; i < sz; ++i )
287 if ( availableEntries[i] < sz )
288 ae.push_back( availableEntries[i] );
290 auto jj = ae.begin();
291 for(
unsigned int i = 0; i < sz; ++i ) {
299 template <
typename T> vector<size_t>
sort_indexes(
const vector<T> &v) {
301 vector<size_t> idx(v.size());
302 iota(idx.begin(), idx.end(), 0);
304 sort(idx.begin(), idx.end(),
305 [&v](
size_t i1,
size_t i2) {
return v[i1] < v[i2];});
316 for (
unsigned int i = 0 ; i < newSize; ++i )
324 for (
unsigned int i = 0; i < newSize; ++i )
326 auto idx = sort_indexes< double >( x );
327 for (
unsigned int i = 0; i < newSize; ++i )
339 p.DefineVar(
"x", &x);
340 p.DefineVar(
"t", &t);
347 for (
int i = 0; i < nh; ++i ) {
457 vector< double > ret;
458 for (
int i = 0; i < nh; ++i ) {
468 vector< double > ret( numX * nh, 0.0 );
469 vector< double >::iterator k = ret.begin();
470 for (
int i = 0; i < nh; ++i ) {
471 for (
int j = 0; j < numX; ++j )
525 unsigned int newSynIndex =
synapses_.size();
527 synapses_[newSynIndex].setHandler(
this );
544 if ( nh > 0 &&
kernel_.size() > 0 ) {
554 for (
int i = 0; i < nh; ++i )
558 for ( vector< double >::iterator y = correlVec.begin();
559 y != correlVec.end(); ++y )
590 if ( activation != 0.0 )
vector< double > getKernel() const
void mtseed(unsigned int x)
Set the global seed or all rngs.
double getBaseScale() const
void resize(unsigned int numRows, unsigned int numColumns)
void setNumSynapses(unsigned int num)
void sumIntoRow(const vector< double > &input, unsigned int row)
vector< Synapse > synapses_
unsigned int addSynapse()
Adds a new synapse, returns its index.
vector< double > getWeightScaleVec() const
double getTopSpike(unsigned int index) const
priority_queue< PreSynEvent, vector< PreSynEvent >, CompareSynEvent > events_
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
double getSequenceScale() const
void setPlasticityScale(double v)
void vProcess(const Eref &e, ProcPtr p)
double getSequencePower() const
vector< unsigned int > getSynapseOrder() const
void addSpike(unsigned int index, double time, double weight)
void vReinit(const Eref &e, ProcPtr p)
unsigned int getNumSynapses() const
void setKernelEquation(string eq)
SeqSynHandler & operator=(const SeqSynHandler &other)
string getKernelEquation() const
void dropSynapse(unsigned int droppedSynNumber)
void refillSynapseOrder(unsigned int newSize)
vector< size_t > sort_indexes(const vector< T > &v)
double getPlasticityScale() const
static const Cinfo * initCinfo()
double historyTime_
Time to store history. KernelDt defines num of rows.
Synapse * vGetSynapse(unsigned int i)
Synapse * getSynapse(unsigned int i)
vector< double > weightScaleVec_
void setKernelWidth(unsigned int v)
static const Cinfo * initCinfo()
int getSynapseOrderOption() const
void vSetNumSynapses(unsigned int num)
static const Cinfo * initCinfo()
double getSeqActivation() const
static const Cinfo * seqSynHandlerCinfo
double baseScale_
Scaling factor for baseline synaptic responses.
void setSynapseOrderOption(int v)
void correl(vector< double > &ret, const vector< double > &input, unsigned int row) const
vector< vector< double > > kernel_
vector< double > getHistory() const
RollingMatrix history_
Kernel for seq selectivity.
unsigned int vGetNumSynapses() const
void setSequencePower(double v)
void setSynapseOrder(vector< unsigned int > v)
unsigned int getKernelWidth() const
static SrcFinfo1< double > * activationOut()
double mtrand(void)
Generate a random double between 0 and 1.
void setBaseScale(double v)
void setHistoryTime(double v)
vector< double > latestSpikes_
double get(unsigned int row, unsigned int column) const
unsigned int kernelWidth_
double getHistoryTime() const
void setSequenceScale(double v)
vector< unsigned int > synapseOrder_
Rows = time; cols = synInputs.
double sequenceScale_
Scaling factor for sequence recognition responses.