file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/mathcomponent.c        (Mon Jun 16 00:04:15 2008 )        HOME


   1: //
   2: // Heccer : a compartmental solver that implements efficient Crank-Nicolson
   3: // integration for neuronal models.
   4: //
   5: 
   6: //////////////////////////////////////////////////////////////////////////////
   7: //'
   8: //' Heccer : testbed C implementation
   9: //'
  10: //' Copyright (C) 2006-2008 Hugo Cornelis
  11: //'
  12: //' functional ideas .. Hugo Cornelis, hugo.cornelis@gmail.com
  13: //'
  14: //' coding ............ Hugo Cornelis, hugo.cornelis@gmail.com
  15: //'
  16: //////////////////////////////////////////////////////////////////////////////
  17: 
  18: 
  19: #include <stdio.h>
  20: #include <stdlib.h>
  21: #include <string.h>
  22: 
  23: #include "heccer/mathcomponent.h"
  24: #include "heccer/mechanism.h"
  25: 
  26: 
  27: static struct MathComponentInfo pmci[] =
  28: {
  29:     MATH_TYPE_ChannelAct,               ((char *)&((struct ChannelAct *)0)[1]) - ((char *)&((struct ChannelAct *)0)[0]),
  30:     MATH_TYPE_ChannelActConc,           ((char *)&((struct ChannelActConc *)0)[1]) - ((char *)&((struct ChannelActConc *)0)[0]),
  31:     MATH_TYPE_ChannelActInact,          ((char *)&((struct ChannelActInact *)0)[1]) - ((char *)&((struct ChannelActInact *)0)[0]),
  32:     MATH_TYPE_ChannelPersistentSteadyStateDualTau,      ((char *)&((struct ChannelPersistentSteadyStateDualTau *)0)[1]) - ((char *)&((struct ChannelPersistentSteadyStateDualTau *)0)[0]),
  33:     MATH_TYPE_ChannelPersistentSteadyStateTau,  ((char *)&((struct ChannelPersistentSteadyStateTau *)0)[1]) - ((char *)&((struct ChannelPersistentSteadyStateTau *)0)[0]),
  34:     MATH_TYPE_ChannelSpringMass,        ((char *)&((struct ChannelSpringMass *)0)[1]) - ((char *)&((struct ChannelSpringMass *)0)[0]),
  35:     MATH_TYPE_ChannelSteadyStateSteppedTau,     ((char *)&((struct ChannelSteadyStateSteppedTau *)0)[1]) - ((char *)&((struct ChannelSteadyStateSteppedTau *)0)[0]),
  36:     MATH_TYPE_ExponentialDecay,         ((char *)&((struct ExponentialDecay *)0)[1]) - ((char *)&((struct ExponentialDecay *)0)[0]),
  37:     MATH_TYPE_InternalNernst,           ((char *)&((struct InternalNernst *)0)[1]) - ((char *)&((struct InternalNernst *)0)[0]),
  38:     MATH_TYPE_SpikeGenerator,           ((char *)&((struct SpikeGenerator *)0)[1]) - ((char *)&((struct SpikeGenerator *)0)[0]),
  39:     -1, -1,
  40: };
  41: 
  42: 
  43: /// **************************************************************************
  44: ///
  45: /// SHORT: MathComponentArrayCallocData()
  46: ///
  47: /// ARGS.:
  48: ///
  49: ///     pmca...: math component array.
  50: ///     iTypes.: set of math component types to allocate for, -1 terminated.
  51: ///
  52: /// RTN..: int
  53: ///
  54: ///     success of operation.
  55: ///
  56: /// DESCR: Allocate the math component data for the given set of types.
  57: ///
  58: ///     As a side effect, sets the number of expected math components
  59: ///     to the number of types, and the cursor to zero.  After this,
  60: ///     fill the array by calling for each math component
  61: ///     MathComponentArraySetAdvance().
  62: ///
  63: /// **************************************************************************
  64: 
  65: int MathComponentArrayCallocData(struct MathComponentArray *pmca, int *piTypes)
  66: {
  67:     //- set default result : not ok
  68: 
  69:     int iResult = 0;
  70: 
  71:     //- compute size
  72: 
  73:     int iSize = 0;
  74: 
  75:     int i;
  76: 
  77:     for (i = 0 ; piTypes[i] > 0 ; i++)
  78:     {
  79:         //- lookup the type int the size table
  80: 
  81:         struct MathComponentInfo *pmci = MathComponentInfoLookup(piTypes[i]);
  82: 
  83:         if (!pmci)
  84:         {
  85:             return(0);
  86:         }
  87: 
  88:         //- increment size to allocate
  89: 
  90:         int iChars = pmci->iChars;
  91: 
  92:         iSize += iChars;
  93:     }
  94: 
  95:     //- if we need to allocate something
  96: 
  97:     if (iSize)
  98:     {
  99:         //- allocate memory
 100: 
 101:         pmca->pmc = (struct MathComponent *)calloc(iSize, sizeof(char));
 102: 
 103:         //- set cursor for filling the mathcomponent array
 104: 
 105:         pmca->iCursor = 0;
 106: 
 107:         pmca->pmcCursor = pmca->pmc;
 108: 
 109:         //- set the number of math components
 110: 
 111:         pmca->iMathComponents = i;
 112: 
 113:         //- clear out the index
 114: 
 115:         pmca->ppmcIndex = NULL;
 116:     }
 117: 
 118:     //- return result : ok
 119: 
 120:     return(1);
 121: }
 122: 
 123: 
 124: #ifdef HECCER_SOURCE_NEUROSPACES
 125: 
 126: /// **************************************************************************
 127: ///
 128: /// SHORT: MathComponentArrayLookupSerial()
 129: ///
 130: /// ARGS.:
 131: ///
 132: ///     pmca....: math component array.
 133: ///     iSerial.: serial to search.
 134: ///
 135: /// RTN..: int
 136: ///
 137: ///     index of matching math component, -1 for not found.
 138: ///
 139: /// DESCR: Look up a math component by serial.
 140: ///
 141: /// **************************************************************************
 142: 
 143: int
 144: MathComponentArrayLookupSerial
 145: (struct MathComponentArray *pmca, int iSerial)
 146: {
 147:     //- set default result : not found
 148: 
 149:     int iResult = -1;
 150: 
 151:     //- loop over all mathcomponents
 152: 
 153:     struct MathComponent * pmc = pmca->pmc;
 154: 
 155:     int iMathComponent;
 156: 
 157:     for (iMathComponent = 0 ; iMathComponent < pmca->iMathComponents ; iMathComponent++)
 158:     {
 159:         //- if serials match
 160: 
 161:         if (pmc->iSerial == iSerial)
 162:         {
 163:             //- set result : current index
 164: 
 165:             iResult = iMathComponent;
 166: 
 167:             //- break searching loop
 168: 
 169:             break;
 170:         }
 171: 
 172:         //- advance to the next math component
 173: 
 174:         pmc = MathComponentNext(pmc);
 175:     }
 176: 
 177:     //- return result
 178: 
 179:     return(iResult);
 180: }
 181: 
 182: #endif
 183: 
 184: 
 185: /// **************************************************************************
 186: ///
 187: /// SHORT: MathComponentArraySetAdvance()
 188: ///
 189: /// ARGS.:
 190: ///
 191: ///     pmca...: math component array.
 192: ///     pmc....: math component to add.
 193: ///
 194: /// RTN..: int
 195: ///
 196: ///     success of operation.
 197: ///
 198: /// DESCR: Add math component at current cursor position, advance.
 199: ///
 200: /// NOTE.:
 201: ///
 202: ///     There is no protection for overflows by checking the cursor
 203: ///     with the number of math components.
 204: ///
 205: /// **************************************************************************
 206: 
 207: int
 208: MathComponentArraySetAdvance
 209: (struct MathComponentArray *pmca, struct MathComponent *pmc)
 210: {
 211:     //- set default result : failure
 212: 
 213:     int iResult = 0;
 214: 
 215:     //- determine size to copy
 216: 
 217:     int iType = pmc->iType;
 218: 
 219:     struct MathComponentInfo *pmci = MathComponentInfoLookup(iType);
 220: 
 221:     if (!pmci)
 222:     {
 223:         return(0);
 224:     }
 225: 
 226:     int iChars = pmci->iChars;
 227: 
 228:     //- copy the math component to the current cursor position
 229: 
 230:     memcpy(pmca->pmcCursor, pmc, iChars);
 231: 
 232:     //- advance the cursor
 233: 
 234:     pmca->iCursor++;
 235: 
 236:     pmca->pmcCursor = (struct MathComponent *)&((char *)pmca->pmcCursor)[iChars];
 237: 
 238:     //- return result
 239: 
 240:     return(1);
 241: }
 242: 
 243: 
 244: /// **************************************************************************
 245: ///
 246: /// SHORT: MathComponentCopyNext()
 247: ///
 248: /// ARGS.:
 249: ///
 250: ///     pmcTarget.: math component target.
 251: ///     pmcSource.: math component source.
 252: ///
 253: /// RTN..: struct MathComponent *
 254: ///
 255: ///     Next math component in the array, NULL for failure.
 256: ///
 257: /// DESCR: Copy a math component, advance to the next math component.
 258: ///
 259: ///     The original content of pmcTarget is completely ignored and
 260: ///     overwritten.
 261: ///
 262: /// TODO:
 263: ///
 264: ///     This need an additional helper function that takes an ///
 265: ///     non-linear array of math components and linearizes them in
 266: ///     memory.
 267: ///
 268: /// **************************************************************************
 269: 
 270: struct MathComponent *
 271: MathComponentCopyNext
 272: (struct MathComponent *pmcTarget, struct MathComponent *pmcSource)
 273: {
 274:     //- set default result : failure
 275: 
 276:     struct MathComponent *pmcResult = NULL;
 277: 
 278:     //- determine size to copy
 279: 
 280:     int iType = pmcSource->iType;
 281: 
 282:     struct MathComponentInfo *pmci = MathComponentInfoLookup(iType);
 283: 
 284:     if (!pmci)
 285:     {
 286:         return(NULL);
 287:     }
 288: 
 289:     int iChars = pmci->iChars;
 290: 
 291:     //- copy the math component to the current cursor position
 292: 
 293:     memcpy(pmcTarget, pmcSource, iChars);
 294: 
 295:     //- set result
 296: 
 297:     pmcResult = MathComponentNext(pmcTarget);
 298: 
 299:     //- return result
 300: 
 301:     return(pmcResult);
 302: }
 303: 
 304: 
 305: /// **************************************************************************
 306: ///
 307: /// SHORT: MathComponentInfoLookup()
 308: ///
 309: /// ARGS.:
 310: ///
 311: ///     iType.: math component type.
 312: ///
 313: /// RTN..: struct MathComponentInfo *
 314: ///
 315: ///     Math component info, respecting compilation options.
 316: ///
 317: /// DESCR: Lookup math component type, respecting compilation options.
 318: ///
 319: /// NOTE.:
 320: ///
 321: ///     This function is for the purpose of constructing
 322: ///     intermediaries from C level.  The info returned depends on
 323: ///     compilation options.  See the test code for an example of its
 324: ///     use.
 325: ///
 326: /// **************************************************************************
 327: 
 328: struct MathComponentInfo * MathComponentInfoLookup(int iType)
 329: {
 330:     //- set default result : failure
 331: 
 332:     struct MathComponentInfo *pmciResult = NULL;
 333: 
 334:     //- loop & search
 335: 
 336:     int j;
 337: 
 338:     for (j = 0 ; pmci[j].iType > 0 ; j++)
 339:     {
 340:         //- if found, set result
 341: 
 342:         if (pmci[j].iType == iType)
 343:         {
 344:             pmciResult = &pmci[j];
 345: 
 346:             break;
 347:         }
 348:     }
 349: 
 350:     //- return result
 351: 
 352:     return pmciResult;
 353: }
 354: 
 355: 
 356: /// **************************************************************************
 357: ///
 358: /// SHORT: MathComponentNext()
 359: ///
 360: /// ARGS.:
 361: ///
 362: ///     pmc....: math component in the array.
 363: ///
 364: /// RTN..: struct MathComponent *
 365: ///
 366: ///     Next math component, NULL for failure.
 367: ///
 368: /// DESCR: Access a math component, and lookup the next component.
 369: ///
 370: /// NOTE.:
 371: ///
 372: ///     There is no protection for overflows by checking the cursor
 373: ///     with the number of math components.
 374: ///
 375: /// **************************************************************************
 376: 
 377: struct MathComponent * MathComponentNext(struct MathComponent *pmc)
 378: {
 379:     //- set default result : next math component
 380: 
 381:     //- determine size
 382: 
 383:     int iType = pmc->iType;
 384: 
 385:     struct MathComponentInfo *pmci = MathComponentInfoLookup(iType);
 386: 
 387:     if (!pmci)
 388:     {
 389:         return(0);
 390:     }
 391: 
 392:     int iChars = pmci->iChars;
 393: 
 394:     struct MathComponent *pmcResult
 395:         = (struct MathComponent *)&((char *)pmc)[iChars];
 396: 
 397:     //- return result
 398: 
 399:     return(pmcResult);
 400: }
 401: 
 402: 
 403: 








































Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008