Source Code for Project IAC (User Override)


The following source file, led by a gray banner, contains all the class functions needed for the user override routines in Project IAC.  The sections highlighted by a yellow background Color are manually entered.  Code sections with white background color are from the skeleton code supplied with the SansGUI Modeling and Simulation Environment.  The source file is compiled into a dynamic linked library to be invoked by SansGUI during simulation runs.

For more details about this example, please read A Tour of SansGUI Examples in the SansGUI Getting Started Guide.

Implementation in C/C++ (MSVC)

Overriding Functions for Class Base.Neuron

/* SGover.cpp - sample user DLL override framework
 *
 * NOTES:
 * This source file demonstrates how simulation users can override

 * simulation developers' routines for run-time execution.
 *
 * For the IAC example model, this overriding DLL module implements

 * Grossberg's method for neuron input and evaluation calculations.
 */

#include <stdio.h>
#include <string.h>

#define SG_OVERRIDE_FUNC /* to use the function declarations in SGdll.h */
#include "SGdll.h"
#undef SG_OVERRIDE_FUNC /* just release the special definition */

/* Macros for attribute indices in class <Component>Base.Neuron

 * version [1.0.beta.0]

 */
#define SG_NDX_IHIDDEN 0 /* iHidden - Hidden Unit */
#define SG_NDX_FEXTINPUT 1 /* fExtInput - External Input */

#define SG_NDX_FACTIVATION 2 /* fActivation - Activation Level */
#define SG_NDX_FNETINPUT 3 /* fNetInput - Net Input */
#define SG_NDX_FEXCITATION 4 /* fExcitation - Excitation */
#define SG_NDX_FINHIBITION 5 /* fInhibition - Inhibition */
#define SG_NDX_FMAXACTIV 6 /* fMaxActiv - Maximum Activation */
#define SG_NDX_FMINACTIV 7 /* fMinActiv - Minimum Activation */
#define SG_NDX_FREST 8 /* fRest - Resting Activation Level */
#define SG_NDX_FDECAY 9 /* fDecay - Decay Rate */
#define SG_NDX_FESTR 10 /* fEstr - Scale Factor for External Input */
#define SG_NDX_FALPHA 11 /* fAlpha - Scale Factor for Excitatory Input */
#define SG_NDX_FGAMMA 12 /* fGamma - Scale Factor for Inhibitory Input */
#define SG_NDX_FDTR 13 /* fDTR - Decay Times Rest */
#define SG_NDX_FOMD 14 /* fOMD - 1 minus Decay */

/* Macros added to access link attributes */
#define LINK_NDX_INFO 0
#define LINK_NDX_FWOUTH 1
#define LINK_NDX_FWINH 2

/* ======================================================================

 * SG_xPreEval - called before SG_xEval() per cycle or event
 * ----------------------------------------------------------------------
 */
SG_RET_CODE SG_xPreEval(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    INT i;
    FLOAT fAct;
    FLOAT fWeight;
    INT iHidden = self->zValues[SG_NDX_IHIDDEN].iData[0];
    FLOAT* pfExcitation = &self->zValues[SG_NDX_FEXCITATION].fData[0];
    FLOAT* pfInhibition = &self->zValues[SG_NDX_FINHIBITION].fData[0];
    FLOAT* pfExtInput = &self->zValues[SG_NDX_FEXTINPUT].fData[0];

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* This routine implements get net input from each of the adjacent unit */

    /* zero out local excitation and inhibition level for accumulation */
    *pfExcitation = *pfInhibition = 0.0f;

    /* calculate excitation and inhibition level from adjacent units */
    for (i = 0; i < *piAdjObjs; i++)
    {
        fAct = adjObjs[i]->zValues[SG_NDX_FACTIVATION].fData[0];
        if (fAct > 0.0f)
        {
            fWeight = (iHidden != 0) ?

                      lnkObjs[i]->zValues[LINK_NDX_FWINH].fData[0] :
                      lnkObjs[i]->zValues[LINK_NDX_FWOUTH].fData[0];
            if (fWeight > 0.0f)
                *pfExcitation += fAct * fWeight;
            else if (fWeight < 0.0f)
                *pfInhibition += fAct * fWeight;
        }
    }

    /* scale excitation and inhibition */
    *pfExcitation *= self->zValues[SG_NDX_FALPHA].fData[0];
    *pfInhibition *= self->zValues[SG_NDX_FGAMMA].fData[0];

 

    /* using grossberg's method, adjust excitation and inhibition levels

     * separately according to the external input level
     */
    if (*pfExtInput > 0.0f)
        *pfExcitation += self->zValues[SG_NDX_FESTR].fData[0] *

                         (*pfExtInput);
    else if (*pfExtInput < 0.0f)
        *pfInhibition += self->zValues[SG_NDX_FESTR].fData[0] *

                         (*pfExtInput);

    return SG_R_OK;
}
/* ======================================================================
* SG_xEval - called at each simulation cycle or triggered by an event
* -----------------------------------------------------------------------
*/
SG_RET_CODE SG_xEval(SG_OBJ *const self,
          SG_OBJ *const simCtrl, SG_OBJ *const chgChild,
          SG_OBJ *const refObjs[], const INT *const piRefObjs,
          SG_OBJ *const adjObjs[], const INT *const piAdjObjs,
          SG_OBJ *const lnkObjs[], const INT *const piLnkObjs,
          TCHAR *const cMessage, const INT iMsgLen,
          TCHAR *const cCommand, const INT iCmdLen,
          SG_FILE *const pOutFile )
{
    /* TODO: declare your local variables here */

    FLOAT* pfAct = &self->zValues[SG_NDX_FACTIVATION].fData[0];
    FLOAT fMaxActiv = self->zValues[SG_NDX_FMAXACTIV].fData[0];
    FLOAT fMinActiv = self->zValues[SG_NDX_FMINACTIV].fData[0];

    if (!SG_IsSchemaOK(self->nSGobjSchema))
        return SG_R_SCHM;

    /* TODO: put your simulator code here */

    /* implements Grossberg's method for activation level update */
    *pfAct = self->zValues[SG_NDX_FEXCITATION].fData[0] *

                       (fMaxActiv - (*pfAct)) +
             self->zValues[SG_NDX_FINHIBITION].fData[0] *

                       ((*pfAct) - fMinActiv) +
             self->zValues[SG_NDX_FOMD].fData[0] * (*pfAct) +
             self->zValues[SG_NDX_FDTR].fData[0];

    /* adjust to max or min activation when out of range */
    if (*pfAct > fMaxActiv)
        *pfAct = fMaxActiv;
    else if (*pfAct < fMinActiv)
        *pfAct = fMinActiv;

 

    /* uncomment the following to show the message in the log --

     * slower update!

     */

    /*
     * strcpy(cMessage, "Use Grossberg's update method.");
     * return SG_R_LMSG;
     */

    return SG_R_OK;
}

 


SansGUI Modeling and Simulation Environment version 1.2

Copyright 2000-2003 ProtoDesign, Inc. All rights reserved.

http://protodesign-inc.com