9 #include "HyPerLayer.hpp"    11 #include "checkpointing/CheckpointEntryRandState.hpp"    12 #include "include/default_params.h"    13 #include "include/pv_common.h"    14 #include "io/fileio.hpp"    15 #include "io/randomstateio.hpp"    25 void LIF_update_state_arma(
    50 void LIF_update_state_beginning(
    75 void LIF_update_state_original(
   102 LIF::LIF() { initialize_base(); }
   104 LIF::LIF(
const char *name, HyPerCol *hc) {
   106    initialize(name, hc, 
"LIF_update_state");
   110    if (numChannels > 0) {
   119 int LIF::initialize_base() {
   131 int LIF::initialize(
const char *name, HyPerCol *hc, 
const char *kernel_name) {
   139    ioParam_Vrest(ioFlag);
   140    ioParam_Vexc(ioFlag);
   141    ioParam_Vinh(ioFlag);
   142    ioParam_VinhB(ioFlag);
   143    ioParam_VthRest(ioFlag);
   145    ioParam_tauE(ioFlag);
   146    ioParam_tauI(ioFlag);
   147    ioParam_tauIB(ioFlag);
   148    ioParam_tauVth(ioFlag);
   149    ioParam_deltaVth(ioFlag);
   150    ioParam_deltaGIB(ioFlag);
   159    ioParam_noiseAmpE(ioFlag);
   160    ioParam_noiseAmpI(ioFlag);
   161    ioParam_noiseAmpIB(ioFlag);
   162    ioParam_noiseFreqE(ioFlag);
   163    ioParam_noiseFreqI(ioFlag);
   164    ioParam_noiseFreqIB(ioFlag);
   166    ioParam_method(ioFlag);
   169 void LIF::ioParam_Vrest(
enum ParamsIOFlag ioFlag) {
   170    parent->parameters()->ioParamValue(ioFlag, name, 
"Vrest", &lParams.Vrest, (
float)V_REST);
   172 void LIF::ioParam_Vexc(
enum ParamsIOFlag ioFlag) {
   173    parent->parameters()->ioParamValue(ioFlag, name, 
"Vexc", &lParams.Vexc, (
float)V_EXC);
   175 void LIF::ioParam_Vinh(
enum ParamsIOFlag ioFlag) {
   176    parent->parameters()->ioParamValue(ioFlag, name, 
"Vinh", &lParams.Vinh, (
float)V_INH);
   178 void LIF::ioParam_VinhB(
enum ParamsIOFlag ioFlag) {
   179    parent->parameters()->ioParamValue(ioFlag, name, 
"VinhB", &lParams.VinhB, (
float)V_INHB);
   181 void LIF::ioParam_VthRest(
enum ParamsIOFlag ioFlag) {
   182    parent->parameters()->ioParamValue(ioFlag, name, 
"VthRest", &lParams.VthRest, (
float)VTH_REST);
   184 void LIF::ioParam_tau(
enum ParamsIOFlag ioFlag) {
   185    parent->parameters()->ioParamValue(ioFlag, name, 
"tau", &lParams.tau, (
float)TAU_VMEM);
   187 void LIF::ioParam_tauE(
enum ParamsIOFlag ioFlag) {
   188    parent->parameters()->ioParamValue(ioFlag, name, 
"tauE", &lParams.tauE, (
float)TAU_EXC);
   190 void LIF::ioParam_tauI(
enum ParamsIOFlag ioFlag) {
   191    parent->parameters()->ioParamValue(ioFlag, name, 
"tauI", &lParams.tauI, (
float)TAU_INH);
   193 void LIF::ioParam_tauIB(
enum ParamsIOFlag ioFlag) {
   194    parent->parameters()->ioParamValue(ioFlag, name, 
"tauIB", &lParams.tauIB, (
float)TAU_INHB);
   196 void LIF::ioParam_tauVth(
enum ParamsIOFlag ioFlag) {
   197    parent->parameters()->ioParamValue(ioFlag, name, 
"tauVth", &lParams.tauVth, (
float)TAU_VTH);
   199 void LIF::ioParam_deltaVth(
enum ParamsIOFlag ioFlag) {
   200    parent->parameters()->ioParamValue(
   201          ioFlag, name, 
"deltaVth", &lParams.deltaVth, (
float)DELTA_VTH);
   203 void LIF::ioParam_deltaGIB(
enum ParamsIOFlag ioFlag) {
   204    parent->parameters()->ioParamValue(
   205          ioFlag, name, 
"deltaGIB", &lParams.deltaGIB, (
float)DELTA_G_INHB);
   207 void LIF::ioParam_noiseAmpE(
enum ParamsIOFlag ioFlag) {
   208    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseAmpE", &lParams.noiseAmpE, 0.0f);
   210 void LIF::ioParam_noiseAmpI(
enum ParamsIOFlag ioFlag) {
   211    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseAmpI", &lParams.noiseAmpI, 0.0f);
   213 void LIF::ioParam_noiseAmpIB(
enum ParamsIOFlag ioFlag) {
   214    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseAmpIB", &lParams.noiseAmpIB, 0.0f);
   217 void LIF::ioParam_noiseFreqE(
enum ParamsIOFlag ioFlag) {
   218    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseFreqE", &lParams.noiseFreqE, 250.0f);
   219    if (ioFlag == PARAMS_IO_READ) {
   220       float dt_sec = 0.001f * (float)parent->getDeltaTime(); 
   221       if (dt_sec * lParams.noiseFreqE > 1.0f) {
   222          lParams.noiseFreqE = 1.0f / dt_sec;
   227 void LIF::ioParam_noiseFreqI(
enum ParamsIOFlag ioFlag) {
   228    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseFreqI", &lParams.noiseFreqI, 250.0f);
   229    if (ioFlag == PARAMS_IO_READ) {
   230       float dt_sec = 0.001f * (float)parent->getDeltaTime(); 
   231       if (dt_sec * lParams.noiseFreqI > 1.0f) {
   232          lParams.noiseFreqI = 1.0f / dt_sec;
   237 void LIF::ioParam_noiseFreqIB(
enum ParamsIOFlag ioFlag) {
   238    parent->parameters()->ioParamValue(ioFlag, name, 
"noiseFreqIB", &lParams.noiseFreqIB, 250.0f);
   239    if (ioFlag == PARAMS_IO_READ) {
   240       float dt_sec = 0.001f * (float)parent->getDeltaTime(); 
   241       if (dt_sec * lParams.noiseFreqIB > 1.0f) {
   242          lParams.noiseFreqIB = 1.0f / dt_sec;
   247 void LIF::ioParam_method(
enum ParamsIOFlag ioFlag) {
   250    const char *default_method = 
"arma";
   251    parent->parameters()->ioParamString(
   252          ioFlag, name, 
"method", &methodString, default_method, 
true );
   253    if (ioFlag != PARAMS_IO_READ) {
   257    assert(methodString);
   258    if (methodString[0] == 
'\0') {
   260       methodString = strdup(default_method);
   261       if (methodString == NULL) {
   263                "%s: unable to set method string: %s\n", getDescription_c(), strerror(errno));
   266    method = methodString ? methodString[0]
   268    if (method != 
'o' && method != 
'b' && method != 
'a') {
   269       if (parent->columnId() == 0) {
   271                "LIF::setLIFParams error.  Layer \"%s\" has method \"%s\".  Allowable values are "   272                "\"arma\", \"beginning\" and \"original\".",
   276       MPI_Barrier(parent->getCommunicator()->communicator());
   280       if (parent->columnId() == 0) {
   282                "LIF layer \"%s\" integration method \"%s\" is deprecated.  Method \"arma\" is "   290 int LIF::setActivity() {
   291    float *activity = clayer->activity->data;
   292    memset(activity, 0, 
sizeof(
float) * clayer->numExtendedAllBatches);
   297 LIF::communicateInitInfo(std::shared_ptr<CommunicateInitInfoMessage const> message) {
   298    return HyPerLayer::communicateInitInfo(message);
   301 Response::Status LIF::allocateDataStructures() {
   302    auto status = HyPerLayer::allocateDataStructures();
   308    randState = 
new Random(getLayerLoc(), 
false );
   309    if (randState == 
nullptr) {
   311             "LIF::initialize:  %s unable to create object of Random class.\n", getDescription_c());
   314    int numNeurons = getNumNeuronsAllBatches();
   316    for (
size_t k = 0; k < numNeurons; k++) {
   317       Vth[k] = lParams.VthRest; 
   319    return Response::SUCCESS;
   322 void LIF::allocateBuffers() {
   323    allocateConductances(numChannels);
   324    Vth = (
float *)calloc((
size_t)getNumNeuronsAllBatches(), 
sizeof(float));
   327             "%s: rank %d process unable to allocate memory for Vth: %s\n",
   332    HyPerLayer::allocateBuffers();
   335 void LIF::allocateConductances(
int num_channels) {
   336    assert(num_channels >= 3); 
   337    const int numNeurons = getNumNeuronsAllBatches();
   338    G_E = (
float *)calloc((
size_t)(getNumNeuronsAllBatches() * numChannels), 
sizeof(
float));
   341             "%s: rank %d process unable to allocate memory for %d conductances: %s\n",
   348    G_I  = G_E + 1 * numNeurons;
   349    G_IB = G_E + 2 * numNeurons;
   352 Response::Status LIF::readStateFromCheckpoint(
Checkpointer *checkpointer) {
   353    if (initializeFromCheckpointFlag) {
   354       auto status = HyPerLayer::readStateFromCheckpoint(checkpointer);
   358       readVthFromCheckpoint(checkpointer);
   359       readG_EFromCheckpoint(checkpointer);
   360       readG_IFromCheckpoint(checkpointer);
   361       readG_IBFromCheckpoint(checkpointer);
   362       readRandStateFromCheckpoint(checkpointer);
   363       return Response::SUCCESS;
   366       return Response::NO_ACTION;
   370 void LIF::readVthFromCheckpoint(
Checkpointer *checkpointer) {
   371    checkpointer->readNamedCheckpointEntry(std::string(name), 
"Vth", 
false );
   374 void LIF::readG_EFromCheckpoint(
Checkpointer *checkpointer) {
   375    checkpointer->readNamedCheckpointEntry(std::string(name), 
"G_E", 
false );
   378 void LIF::readG_IFromCheckpoint(
Checkpointer *checkpointer) {
   379    checkpointer->readNamedCheckpointEntry(std::string(name), 
"G_I", 
false );
   382 void LIF::readG_IBFromCheckpoint(
Checkpointer *checkpointer) {
   383    checkpointer->readNamedCheckpointEntry(std::string(name), 
"G_IB", 
false );
   386 void LIF::readRandStateFromCheckpoint(
Checkpointer *checkpointer) {
   387    checkpointer->readNamedCheckpointEntry(std::string(name), 
"rand_state", 
false );
   390 Response::Status LIF::registerData(
Checkpointer *checkpointer) {
   391    auto status = HyPerLayer::registerData(checkpointer);
   395    checkpointPvpActivityFloat(checkpointer, 
"Vth", Vth, 
false );
   396    checkpointPvpActivityFloat(checkpointer, 
"G_E", G_E, 
false );
   397    checkpointPvpActivityFloat(checkpointer, 
"G_I", G_I, 
false );
   398    checkpointPvpActivityFloat(checkpointer, 
"G_IB", G_IB, 
false );
   399    checkpointRandState(checkpointer, 
"rand_state", randState, 
false );
   400    return Response::SUCCESS;
   403 Response::Status LIF::updateState(
double time, 
double dt) {
   404    update_timer->start();
   406    const int nx       = clayer->loc.nx;
   407    const int ny       = clayer->loc.ny;
   408    const int nf       = clayer->loc.nf;
   409    const PVHalo *halo = &clayer->loc.halo;
   410    const int nbatch   = clayer->loc.nbatch;
   412    float *GSynHead = GSyn[0];
   413    float *activity = clayer->activity->data;
   417          LIF_update_state_arma(
   430                randState->getRNG(0),
   440          LIF_update_state_beginning(
   453                randState->getRNG(0),
   463          LIF_update_state_original(
   476                randState->getRNG(0),
   485       default: assert(0); 
break;
   487    update_timer->stop();
   488    return Response::SUCCESS;
   491 float LIF::getChannelTimeConst(
enum ChannelType channel_type) {
   492    float channel_time_const = 0.0f;
   493    switch (channel_type) {
   494       case CHANNEL_EXC: channel_time_const  = lParams.tauE; 
break;
   495       case CHANNEL_INH: channel_time_const  = lParams.tauI; 
break;
   496       case CHANNEL_INHB: channel_time_const = lParams.tauIB; 
break;
   497       default: channel_time_const           = 0.0f; 
break;
   499    return channel_time_const;
   502 int LIF::findPostSynaptic(
   514       int nConnectedNeurons[],
   526 inline float LIF_Vmem_derivative(
   536    float totalconductance = 1.0f + G_E + G_I + G_IB;
   537    float Vmeminf          = (Vrest + V_E * G_E + V_I * G_I + V_IB * G_IB) / totalconductance;
   538    return totalconductance * (Vmeminf - Vmem) / tau;
   554 void LIF_update_state_original(
   556       const int numNeurons,
   579    const float exp_tauE   = expf(-dt / params->tauE);
   580    const float exp_tauI   = expf(-dt / params->tauI);
   581    const float exp_tauIB  = expf(-dt / params->tauIB);
   582    const float exp_tauVth = expf(-dt / params->tauVth);
   584    const float dt_sec = 0.001f * dt; 
   586    for (k = 0; k < nx * ny * nf * nbatch; k++) {
   587       int kex = kIndexExtendedBatch(k, nbatch, nx, ny, nf, lt, rt, dn, up);
   594       float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth, deltaGIB;
   596       const float GMAX = 10.0f;
   604       float l_Vth = Vth[k];
   606       float l_G_E  = G_E[k];
   607       float l_G_I  = G_I[k];
   608       float l_G_IB = G_IB[k];
   610       float *GSynExc   = &GSynHead[CHANNEL_EXC * nbatch * numNeurons];
   611       float *GSynInh   = &GSynHead[CHANNEL_INH * nbatch * numNeurons];
   612       float *GSynInhB  = &GSynHead[CHANNEL_INHB * nbatch * numNeurons];
   613       float l_GSynExc  = GSynExc[k];
   614       float l_GSynInh  = GSynInh[k];
   615       float l_GSynInhB = GSynInhB[k];
   618       float tauInf, VmemInf;
   629       VinhB = params->VinhB;
   630       Vrest = params->Vrest;
   632       VthRest  = params->VthRest;
   633       deltaVth = params->deltaVth;
   634       deltaGIB = params->deltaGIB;
   639       l_rnd = cl_random_get(l_rnd);
   640       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqE) {
   641          l_rnd     = cl_random_get(l_rnd);
   642          l_GSynExc = l_GSynExc + params->noiseAmpE * cl_random_prob(l_rnd);
   645       l_rnd = cl_random_get(l_rnd);
   646       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqI) {
   647          l_rnd     = cl_random_get(l_rnd);
   648          l_GSynInh = l_GSynInh + params->noiseAmpI * cl_random_prob(l_rnd);
   651       l_rnd = cl_random_get(l_rnd);
   652       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqIB) {
   653          l_rnd      = cl_random_get(l_rnd);
   654          l_GSynInhB = l_GSynInhB + params->noiseAmpIB * cl_random_prob(l_rnd);
   657       l_G_E  = l_GSynExc + l_G_E * exp_tauE;
   658       l_G_I  = l_GSynInh + l_G_I * exp_tauI;
   659       l_G_IB = l_GSynInhB + l_G_IB * exp_tauIB;
   661       l_G_E  = (l_G_E > GMAX) ? GMAX : l_G_E;
   662       l_G_I  = (l_G_I > GMAX) ? GMAX : l_G_I;
   663       l_G_IB = (l_G_IB > GMAX) ? GMAX : l_G_IB;
   665       tauInf  = (dt / tau) * (1.0f + l_G_E + l_G_I + l_G_IB);
   666       VmemInf = (Vrest + l_G_E * Vexc + l_G_I * Vinh + l_G_IB * VinhB)
   667                 / (1.0f + l_G_E + l_G_I + l_G_IB);
   669       l_V = VmemInf + (l_V - VmemInf) * expf(-tauInf);
   675       l_Vth = VthRest + (l_Vth - VthRest) * exp_tauVth;
   681       bool fired_flag = (l_V > l_Vth);
   683       l_activ = fired_flag ? 1.0f : 0.0f;
   684       l_V     = fired_flag ? Vrest : l_V;
   685       l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
   686       l_G_IB  = fired_flag ? l_G_IB + deltaGIB : l_G_IB;
   698       activity[kex] = l_activ;
   714 void LIF_update_state_beginning(
   716       const int numNeurons,
   742    const float exp_tauE   = expf(-dt / params->tauE);
   743    const float exp_tauI   = expf(-dt / params->tauI);
   744    const float exp_tauIB  = expf(-dt / params->tauIB);
   745    const float exp_tauVth = expf(-dt / params->tauVth);
   747    const float dt_sec = 0.001f * dt; 
   749    for (k = 0; k < nx * ny * nf * nbatch; k++) {
   751       int kex = kIndexExtendedBatch(k, nbatch, nx, ny, nf, lt, rt, dn, up);
   758       float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth, deltaGIB;
   760       const float GMAX = 10.0f;
   768       float l_Vth = Vth[k];
   773       float l_G_E  = G_E[k];
   774       float l_G_I  = G_I[k];
   775       float l_G_IB = G_IB[k];
   777       float *GSynExc   = &GSynHead[CHANNEL_EXC * nbatch * numNeurons];
   778       float *GSynInh   = &GSynHead[CHANNEL_INH * nbatch * numNeurons];
   779       float *GSynInhB  = &GSynHead[CHANNEL_INHB * nbatch * numNeurons];
   780       float l_GSynExc  = GSynExc[k];
   781       float l_GSynInh  = GSynInh[k];
   782       float l_GSynInhB = GSynInhB[k];
   793       VinhB = params->VinhB;
   794       Vrest = params->Vrest;
   796       VthRest  = params->VthRest;
   797       deltaVth = params->deltaVth;
   798       deltaGIB = params->deltaGIB;
   803       l_rnd = cl_random_get(l_rnd);
   804       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqE) {
   805          l_rnd     = cl_random_get(l_rnd);
   806          l_GSynExc = l_GSynExc + params->noiseAmpE * cl_random_prob(l_rnd);
   809       l_rnd = cl_random_get(l_rnd);
   810       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqI) {
   811          l_rnd     = cl_random_get(l_rnd);
   812          l_GSynInh = l_GSynInh + params->noiseAmpI * cl_random_prob(l_rnd);
   815       l_rnd = cl_random_get(l_rnd);
   816       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqIB) {
   817          l_rnd      = cl_random_get(l_rnd);
   818          l_GSynInhB = l_GSynInhB + params->noiseAmpIB * cl_random_prob(l_rnd);
   822       float G_E_initial, G_I_initial, G_IB_initial, G_E_final, G_I_final, G_IB_final;
   825       G_E_initial  = l_G_E + l_GSynExc;
   826       G_I_initial  = l_G_I + l_GSynInh;
   827       G_IB_initial = l_G_IB + l_GSynInhB;
   829       G_E_initial  = (G_E_initial > GMAX) ? GMAX : G_E_initial;
   830       G_I_initial  = (G_I_initial > GMAX) ? GMAX : G_I_initial;
   831       G_IB_initial = (G_IB_initial > GMAX) ? GMAX : G_IB_initial;
   833       G_E_final  = G_E_initial * exp_tauE;
   834       G_I_final  = G_I_initial * exp_tauI;
   835       G_IB_final = G_IB_initial * exp_tauIB;
   837       dV1 = LIF_Vmem_derivative(
   838             l_V, G_E_initial, G_I_initial, G_IB_initial, Vexc, Vinh, VinhB, Vrest, tau);
   839       dV2 = LIF_Vmem_derivative(
   840             l_V + dt * dV1, G_E_final, G_I_final, G_IB_final, Vexc, Vinh, VinhB, Vrest, tau);
   841       dV  = (dV1 + dV2) * 0.5f;
   848       l_Vth = VthRest + (l_Vth - VthRest) * exp_tauVth;
   855       bool fired_flag = (l_V > l_Vth);
   857       l_activ = fired_flag ? 1.0f : 0.0f;
   858       l_V     = fired_flag ? Vrest : l_V;
   859       l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
   860       l_G_IB  = fired_flag ? l_G_IB + deltaGIB : l_G_IB;
   872       activity[kex] = l_activ;
   884 void LIF_update_state_arma(
   886       const int numNeurons,
   909    const float exp_tauE   = expf(-dt / params->tauE);
   910    const float exp_tauI   = expf(-dt / params->tauI);
   911    const float exp_tauIB  = expf(-dt / params->tauIB);
   912    const float exp_tauVth = expf(-dt / params->tauVth);
   914    const float dt_sec = 0.001f * dt; 
   916    for (k = 0; k < nx * ny * nf * nbatch; k++) {
   917       int kex = kIndexExtendedBatch(k, nbatch, nx, ny, nf, lt, rt, dn, up);
   924       float tau, Vrest, VthRest, Vexc, Vinh, VinhB, deltaVth, deltaGIB;
   926       const float GMAX = 10.0;
   934       float l_Vth = Vth[k];
   939       float l_G_E  = G_E[k];
   940       float l_G_I  = G_I[k];
   941       float l_G_IB = G_IB[k];
   943       float *GSynExc   = &GSynHead[CHANNEL_EXC * nbatch * numNeurons];
   944       float *GSynInh   = &GSynHead[CHANNEL_INH * nbatch * numNeurons];
   945       float *GSynInhB  = &GSynHead[CHANNEL_INHB * nbatch * numNeurons];
   946       float l_GSynExc  = GSynExc[k];
   947       float l_GSynInh  = GSynInh[k];
   948       float l_GSynInhB = GSynInhB[k];
   959       VinhB = params->VinhB;
   960       Vrest = params->Vrest;
   962       VthRest  = params->VthRest;
   963       deltaVth = params->deltaVth;
   964       deltaGIB = params->deltaGIB;
   969       l_rnd = cl_random_get(l_rnd);
   970       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqE) {
   971          l_rnd     = cl_random_get(l_rnd);
   972          l_GSynExc = l_GSynExc + params->noiseAmpE * cl_random_prob(l_rnd);
   975       l_rnd = cl_random_get(l_rnd);
   976       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqI) {
   977          l_rnd     = cl_random_get(l_rnd);
   978          l_GSynInh = l_GSynInh + params->noiseAmpI * cl_random_prob(l_rnd);
   981       l_rnd = cl_random_get(l_rnd);
   982       if (cl_random_prob(l_rnd) < dt_sec * params->noiseFreqIB) {
   983          l_rnd      = cl_random_get(l_rnd);
   984          l_GSynInhB = l_GSynInhB + params->noiseAmpIB * cl_random_prob(l_rnd);
   988       float G_E_initial, G_I_initial, G_IB_initial, G_E_final, G_I_final, G_IB_final;
   989       float tau_inf_initial, tau_inf_final, V_inf_initial, V_inf_final;
   991       G_E_initial     = l_G_E + l_GSynExc;
   992       G_I_initial     = l_G_I + l_GSynInh;
   993       G_IB_initial    = l_G_IB + l_GSynInhB;
   994       tau_inf_initial = tau / (1 + G_E_initial + G_I_initial + G_IB_initial);
   995       V_inf_initial   = (Vrest + Vexc * G_E_initial + Vinh * G_I_initial + VinhB * G_IB_initial)
   996                       / (1 + G_E_initial + G_I_initial + G_IB_initial);
   998       G_E_initial  = (G_E_initial > GMAX) ? GMAX : G_E_initial;
   999       G_I_initial  = (G_I_initial > GMAX) ? GMAX : G_I_initial;
  1000       G_IB_initial = (G_IB_initial > GMAX) ? GMAX : G_IB_initial;
  1002       G_E_final  = G_E_initial * exp_tauE;
  1003       G_I_final  = G_I_initial * exp_tauI;
  1004       G_IB_final = G_IB_initial * exp_tauIB;
  1006       tau_inf_final = tau / (1 + G_E_final + G_I_final + G_IB_initial);
  1007       V_inf_final   = (Vrest + Vexc * G_E_final + Vinh * G_I_final + VinhB * G_IB_final)
  1008                     / (1 + G_E_final + G_I_final + G_IB_final);
  1010       float tau_slope = (tau_inf_final - tau_inf_initial) / dt;
  1011       float f1        = tau_slope == 0.0f ? expf(-dt / tau_inf_initial)
  1012                                    : powf(tau_inf_final / tau_inf_initial, -1 / tau_slope);
  1013       float f2 = tau_slope == -1.0f
  1014                        ? tau_inf_initial / dt * logf(tau_inf_final / tau_inf_initial + 1.0f)
  1015                        : (1 - tau_inf_initial / dt * (1 - f1)) / (1 + tau_slope);
  1016       float f3 = 1.0f - f1 - f2;
  1017       l_V      = f1 * l_V + f2 * V_inf_initial + f3 * V_inf_final;
  1021       l_G_IB = G_IB_final;
  1023       l_Vth = VthRest + (l_Vth - VthRest) * exp_tauVth;
  1030       bool fired_flag = (l_V > l_Vth);
  1032       l_activ = fired_flag ? 1.0f : 0.0f;
  1033       l_V     = fired_flag ? Vrest : l_V;
  1034       l_Vth   = fired_flag ? l_Vth + deltaVth : l_Vth;
  1035       l_G_IB  = fired_flag ? l_G_IB + deltaGIB : l_G_IB;
  1047       activity[kex] = l_activ;
 
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
static bool completed(Status &a)
int initialize(const char *name, HyPerCol *hc)