file:/local_home/local_home/hugo/neurospaces_project/heccer/source/c/snapshots/0/vm.c (Wed Jul 2 11:07:16 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 <string.h>
20:
21: #include "heccer/heccer.h"
22: #include "heccer/vm.h"
23:
24:
25: struct HeccerCommandInfo
26: {
27: //m operation value
28:
29: int iValue;
30:
31: //m name of command
32:
33: char *pcName;
34:
35: //m length of command (number of operands + 1)
36:
37: int iLength;
38:
39: //m number of secondary operands, expressed in doubles
40:
41: int iSecondaries;
42:
43: //m sizeof secondaries
44:
45: int iSecondariesSize;
46: };
47:
48:
49: struct HeccerCommandTable
50: {
51: //m initialization status
52:
53: int iStatus;
54:
55: //m number of commands
56:
57: int iCommands;
58:
59: //m -1 means no formatted output
60:
61: int iFormatted;
62:
63: //m command info
64:
65: struct HeccerCommandInfo * phci;
66: };
67:
68:
69: static struct HeccerCommandInfo phciCops[] =
70: {
71: { HECCER_COP_FORWARD_ELIMINATION, "FORWARD_ELIMINATION", 2 * sizeof(int), },
72: { HECCER_COP_BACKWARD_SUBSTITUTION, "BACKWARD_SUBSTITUTION", 2 * sizeof(int), },
73: { HECCER_COP_FINISH_ROW, "FINISH_ROW", 1 * sizeof(int), },
74: { HECCER_COP_FINISH, "FINISH", 1 * sizeof(int), },
75: { HECCER_COP_SET_DIAGONAL, "SET_DIAGONAL", 1 * sizeof(int), },
76: { HECCER_COP_NEXT_ROW, "NEXT_ROW", 1 * sizeof(int), },
77: { -1, NULL, -1, },
78: };
79:
80:
81: static struct HeccerCommandTable hctCops =
82: {
83: 0,
84: sizeof(phciCops) / sizeof(struct HeccerCommandInfo) - 1,
85: 0,
86: phciCops,
87: };
88:
89:
90: static struct HeccerCommandInfo phciMops[] =
91: {
92: { HECCER_MOP_CALLOUT, "CALLOUT", 1 * sizeof(int), 0, sizeof(struct MatsCallout), },
93: { HECCER_MOP_COMPARTMENT, "COMPARTMENT", 1 * sizeof(int), 4, sizeof(struct MatsCompartment), },
94: { HECCER_MOP_CONCEPTGATE, "CONCEPTGATE", sizeof(struct MopsSingleGateConcept), 1, sizeof(struct MatsSingleGateConcept), },
95: { HECCER_MOP_EVENTGENERATE, "EVENTGENERATE", sizeof(struct MopsEventGenerate), 2, sizeof(struct MatsEventGenerate), },
96: { HECCER_MOP_EXPONENTIALDECAY, "EXPONENTIALDECAY", sizeof(struct MopsExponentialDecay), 1, sizeof(struct MatsExponentialDecay), },
97: { HECCER_MOP_FINISH, "FINISH", 1 * sizeof(int), 0, 0, },
98: { HECCER_MOP_FLUXPOOL, "FLUXPOOL", sizeof(struct MopsFluxPool), 1, sizeof(struct MatsFluxPool), },
99: { HECCER_MOP_INITIALIZECHANNEL, "INITIALIZECHANNEL", sizeof(struct MopsInitializeChannel), 0, 0, },
100: { HECCER_MOP_INITIALIZECHANNELEREV, "INITIALIZECHANNELEREV", sizeof(struct MopsInitializeChannelErev), 0, 0, },
101: { HECCER_MOP_LOADVOLTAGETABLE, "LOADVOLTAGETABLE", sizeof(struct MopsVoltageTableDependency), 0, 0, },
102: { HECCER_MOP_REGISTERCHANNELCURRENT, "REGISTERCHANNELCURRENT", sizeof(struct MopsRegisterChannelCurrent), 0, 0, },
103: { HECCER_MOP_UPDATECOMPARTMENTCURRENT, "UPDATECOMPARTMENTCURRENT", sizeof(struct MopsUpdateCompartmentCurrent), 0, 0, },
104: { HECCER_MOP_AGGREGATECURRENT, "AGGREGATECURRENT", sizeof(struct MopsAggregateCurrent), 0, 0, },
105: { HECCER_MOP_INTERNALNERNST, "INTERNALNERNST", sizeof(struct MopsInternalNernst), 1, sizeof(struct MatsInternalNernst), },
106: { HECCER_MOP_SPRINGMASS, "SPRINGMASS", sizeof(struct MopsSpringMass), 3, sizeof(struct MatsSpringMass), },
107: { HECCER_MOP_STORESINGLECHANNELCURRENT, "STORESINGLECHANNELCURRENT", sizeof(struct MopsStoreSingleChannelCurrent), 2, sizeof(struct MatsStoreSingleChannelCurrent), },
108: { -1, NULL, -1, },
109: };
110:
111:
112: static struct HeccerCommandTable hctMops =
113: {
114: 0,
115: sizeof(phciMops) / sizeof(struct HeccerCommandInfo) - 1,
116: 1,
117: phciMops,
118: };
119:
120:
121: static int operator_comparator(const void *pv1,const void *pv2)
122: {
123: struct HeccerCommandInfo *phci1 = (struct HeccerCommandInfo *)pv1;
124: struct HeccerCommandInfo *phci2 = (struct HeccerCommandInfo *)pv2;
125:
126: return(phci1->iValue < phci2->iValue
127: ? -1
128: : phci1->iValue > phci2->iValue ? 1 : 0);
129: }
130:
131:
132: static void SortTable(struct HeccerCommandTable *phct)
133: {
134: int iEntries = 0;
135:
136: while (phct->phci[iEntries].pcName != NULL)
137: {
138: iEntries++;
139: }
140:
141: phct->iCommands = iEntries;
142:
143: qsort
144: ((void *)phct->phci,
145: phct->iCommands,
146: sizeof(struct HeccerCommandInfo),
147: operator_comparator);
148:
149: phct->iStatus |= 1;
150: }
151:
152:
153: //f static prototypes
154:
155: static
156: struct HeccerCommandInfo *
157: HeccerCommandInfoLookup
158: (struct HeccerCommandTable *phct,
159: int iOp);
160:
161: static int
162: HeccerVMDumpOperators
163: (char * pcDescription,
164: struct VM *pvm,
165: int piArray[],
166: void *pvOperands,
167: struct HeccerCommandTable *phct,
168: int iStart,
169: int iEnd,
170: FILE *pfile);
171:
172:
173: /// ***************************************************************************
174: ///
175: /// NAME : HeccerCommandInfoLookup()
176: ///
177: /// SHORT : lookup info on given command
178: ///
179: /// PARAMETERS :
180: ///
181: /// phci....: array with info
182: /// iOp.....: operation to lookup
183: ///
184: /// RETURN : struct HeccerCommandInfo * : info on command
185: ///
186: /// DESCRIPTION : lookup info on given command
187: ///
188: /// ***************************************************************************
189:
190: static
191: struct HeccerCommandInfo *
192: HeccerCommandInfoLookup
193: (struct HeccerCommandTable *phct,
194: int iOp)
195: {
196: //- set default result : not found
197:
198: struct HeccerCommandInfo *phciResult = NULL;
199:
200: //- init top and bottom counters
201:
202: int iLower = 0;
203: int iUpper = phct->iCommands - 1;
204:
205: if (!(phct->iStatus & 1))
206: {
207: SortTable(phct);
208: }
209:
210: iLower = 0;
211: iUpper = phct->iCommands - 1;
212:
213: //! binary search
214:
215: //- search until the range to search in becomes invalid
216:
217: while (iUpper - iLower >= 0)
218: {
219: //- determine the middle of the search range
220:
221: int iMiddle = (iLower + iUpper) / 2;
222:
223: //- get pointer to this command info entry
224:
225: struct HeccerCommandInfo *phci = &phct->phci[iMiddle];
226:
227: //- set result and break out loop if search value is found here
228:
229: if (iOp == phci->iValue)
230: {
231: phciResult = phci;
232:
233: break;
234: }
235:
236: //- set a new lower or upper limit
237:
238: if (iOp > phci->iValue)
239: {
240: iLower = iMiddle + 1;
241: }
242: else
243: {
244: iUpper = iMiddle - 1;
245: }
246: }
247:
248: //- return result
249:
250: return(phciResult);
251: }
252:
253:
254: /// **************************************************************************
255: ///
256: /// SHORT: HeccerVMDump()
257: ///
258: /// ARGS.:
259: ///
260: /// pvm........: heccer vm.
261: /// pfile......: stdio file.
262: /// iSelection.: selection to dump.
263: ///
264: /// RTN..: int
265: ///
266: /// success of operation.
267: ///
268: /// DESCR: Dump VM functions.
269: ///
270: /// **************************************************************************
271:
272: int HeccerVMDump(struct VM *pvm, FILE *pfile, int iSelection)
273: {
274: //- set default result : ok
275:
276: int iResult = TRUE;
277:
278: //- dump compartment data
279:
280: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_DATA)
281: {
282: //! nothing here
283: }
284:
285: //- dump compartment operations
286:
287: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_OPERATIONS)
288: {
289: int iCops = pvm->iCops;
290:
291: int *piCops = pvm->piCops;
292:
293: //! cops are allocated as integers, dump array expects char's,
294: //! so that is why we have to multiply here.
295:
296: HeccerVMDumpOperators("Compartment operations", pvm, &piCops[0], NULL, &hctCops, 0, iCops * sizeof(int), pfile);
297: }
298:
299: //- dump mechanism data
300:
301: if (iSelection & HECCER_DUMP_VM_MECHANISM_DATA)
302: {
303: int iMats = pvm->iMats;
304:
305: void *pvMats = pvm->pvMats;
306:
307: /* HeccerVMDumpData("Mechanism data", pvm, pvMats, NULL, 0, iMats, pfile); */
308: }
309:
310: //- dump mechanism operations
311:
312: if (iSelection & HECCER_DUMP_VM_MECHANISM_OPERATIONS)
313: {
314: int iMops = pvm->iMops;
315:
316: int *piMops = (int *)pvm->pvMops;
317:
318: HeccerVMDumpOperators("Mechanism operations", pvm, &piMops[0], pvm->pvMats, &hctMops, 0, iMops, pfile);
319: }
320:
321: /* //- dump channel to pool fluxes */
322:
323: /* if (iSelection & HECCER_DUMP_VM_CHANNEL_POOL_FLUXES) */
324: /* { */
325: /* int i; */
326:
327: /* for (i = 0 ; i < pvm->iFluxes ; i++) */
328: /* { */
329: /* fprintf(pfile, "VM Fluxes (pdFluxes[%i]) : (%g)\n", i, pvm->pdFluxes[i]); */
330: /* } */
331: /* } */
332:
333: //- compartment data : diagonals
334:
335: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_MATRIX)
336: {
337: int i;
338:
339: for (i = 0 ; i < pvm->iDiagonals ; i++)
340: {
341: fprintf(pfile, "VM Diagonals (pdDiagonals[%i]) : (%g)\n", i, pvm->pdDiagonals[i]);
342: }
343: }
344:
345: //- compartment data : axial resistances
346:
347: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_MATRIX)
348: {
349: int i;
350:
351: for (i = 0 ; i < pvm->iAxres ; i++)
352: {
353: fprintf(pfile, "VM Axial Resistances (pdAxres[%i]) : (%g)\n", i, pvm->pdAxres[i]);
354: }
355: }
356:
357: //- results : intermediate
358:
359: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_MATRIX)
360: {
361: int i;
362:
363: for (i = 0 ; i < pvm->iResults ; i++)
364: {
365: fprintf(pfile, "VM Axial Resistances (pdResults[%i]) : (%g)\n", i, pvm->pdResults[i]);
366: }
367: }
368:
369: //- results : membrane potentials
370:
371: if (iSelection & HECCER_DUMP_VM_COMPARTMENT_MATRIX)
372: {
373: int i;
374:
375: for (i = 0 ; i < pvm->iVms ; i++)
376: {
377: fprintf(pfile, "VM Membrane Potentials (pdVms[%i]) : (%g)\n", i, pvm->pdVms[i]);
378: }
379: }
380:
381: //- results : aggregators
382:
383: if (iSelection & HECCER_DUMP_VM_AGGREGATORS)
384: {
385: int i;
386:
387: for (i = 0 ; i < pvm->iAggregators ; i++)
388: {
389: fprintf(pfile, "VM Membrane Aggregator results (pdAggregators[%i]) : (%g)\n", i, pvm->pdAggregators[i]);
390: }
391: }
392:
393: //- return result
394:
395: return(iResult);
396: }
397:
398:
399: /// ***************************************************************************
400: ///
401: /// NAME : HeccerVMDumpOperators()
402: ///
403: /// SHORT : print operations in given array according to given info array
404: ///
405: /// PARAMETERS :
406: ///
407: /// pvm.....: heccer vm.
408: /// piArray.: array to print
409: /// iSize...: size of one array entry
410: /// phct....: table with info on array to print
411: /// iStart..: start index
412: /// iEnd....: ending index
413: ///
414: /// RETURN : int
415: ///
416: /// success of operation.
417: ///
418: /// DESCRIPTION : print operations in given array.
419: ///
420: /// NOTE : length of operations is ignored at the moment
421: ///
422: /// ***************************************************************************
423:
424: static
425: int
426: HeccerVMDumpOperators
427: (char * pcDescription,
428: struct VM *pvm,
429: int piOperators[],
430: void *pvOperands,
431: struct HeccerCommandTable *phct,
432: int iStart,
433: int iEnd,
434: FILE *pfile)
435: {
436: //- set default result : ok
437:
438: int iResult = TRUE;
439:
440: //- give the banner
441:
442: fprintf(pfile, "%s\n", pcDescription);
443:
444: fprintf(pfile, "-----\n");
445:
446: //- initial line count is zero
447:
448: int iLineCount = 0;
449:
450: //- loop from start to end
451:
452: //! dump array expects char's but goes over the array as if they
453: //! are int's.
454:
455: //t fix char's int's mismatch somehow.
456:
457: int i;
458:
459: for (i = iStart; i < iEnd; )
460: {
461: char pcOutput1[500];
462: char pcOutput2[500];
463:
464: //- get current command
465:
466: int iCommand = piOperators[i / sizeof(int)];
467:
468: //- lookup info for current operand
469:
470: struct HeccerCommandInfo *phciCurrent
471: = HeccerCommandInfoLookup(phct, iCommand);
472:
473: int iCommandLength = phciCurrent->iLength;
474:
475: //- print counter
476:
477: sprintf(pcOutput1, "%5.5i ::", iLineCount);
478:
479: /* //- print numerical info */
480:
481: /* fprintf(pcOutput2, " %i", iCommand); */
482:
483: /* strcat(pcOutput1, pcOutput2); */
484:
485: //- if found
486:
487: if (phciCurrent)
488: {
489: //- print name of operator
490:
491: sprintf(pcOutput2, " %s", phciCurrent->pcName);
492:
493: strcat(pcOutput1, pcOutput2);
494:
495: //- if operand length is valid
496:
497: if (iCommandLength >= 2)
498: {
499: if (phct->iFormatted)
500: {
501: //t so only for five doubles ...
502:
503: char pc[100] = "";
504:
505: {
506: void *pv = (void *)&piOperators[i / sizeof(int) + 1];
507:
508: if (phciCurrent->iValue == HECCER_MOP_INITIALIZECHANNEL)
509: {
510: struct MopsInitializeChannel *pmops
511: = (struct MopsInitializeChannel *)&piOperators[i / sizeof(int)];
512:
513: sprintf(pc, " %g %g", pmops->dReversalPotential, pmops->dMaximalConductance);
514: }
515: else if (phciCurrent->iValue == HECCER_MOP_EXPONENTIALDECAY)
516: {
517: struct MopsExponentialDecay *pmops
518: = (struct MopsExponentialDecay *)&piOperators[i / sizeof(int)];
519:
520: sprintf(pc, " %g %g %g\n\t\t\t", pmops->dBeta, pmops->dSteadyState, pmops->dTau);
521:
522: uMC2Mat *puExternal = &pmops->puExternal[0];
523:
524: int k;
525:
526: char pc2[100];
527:
528: for (k = 0 ; k < EXPONENTIALDECAY_CONTRIBUTORS ; k++)
529: {
530: if (puExternal[k].pdValue)
531: {
532: sprintf(pc2, " (%g)", *puExternal[k].pdValue);
533: }
534: else
535: {
536: sprintf(pc2, " (nil)");
537: }
538:
539: strcat(pc, pc2);
540: }
541: }
542: else if (phciCurrent->iValue == HECCER_MOP_CONCEPTGATE)
543: {
544: struct MopsSingleGateConcept *pmops
545: = (struct MopsSingleGateConcept *)&piOperators[i / sizeof(int)];
546:
547: if (pmops->uState.pdValue)
548: {
549: sprintf(pc, " %i %i (%g)", pmops->iTableIndex, pmops->iPower, *pmops->uState.pdValue);
550: }
551: else
552: {
553: sprintf(pc, " %i %i (nil)", pmops->iTableIndex, pmops->iPower);
554: }
555: }
556: else if (phciCurrent->iValue == HECCER_MOP_INTERNALNERNST)
557: {
558: struct MopsInternalNernst *pmops
559: = (struct MopsInternalNernst *)&piOperators[i / sizeof(int)];
560:
561: sprintf(pc, " %g %g", pmops->dConstant, pmops->dExternal);
562:
563: int k;
564:
565: char pc2[100];
566:
567: for (k = 0 ; k < 1 ; k++)
568: {
569: if (pmops->uInternal.pdValue)
570: {
571: sprintf(pc2, " (%g)", *pmops->uInternal.pdValue);
572: }
573: else
574: {
575: sprintf(pc2, " (nil)");
576: }
577:
578: strcat(pc, pc2);
579: }
580: }
581: else if (phciCurrent->iValue == HECCER_MOP_INITIALIZECHANNELEREV)
582: {
583: struct MopsInitializeChannelErev *pmops
584: = (struct MopsInitializeChannelErev *)&piOperators[i / sizeof(int)];
585:
586: if (pmops->uReversalPotential.pdValue)
587: {
588: sprintf(pc, " (%g)", *pmops->uReversalPotential.pdValue);
589: }
590: else
591: {
592: sprintf(pc, "(nil)");
593: }
594:
595: char pc2[100];
596:
597: sprintf(pc2, " %g", pmops->dMaximalConductance);
598:
599: strcat(pc, pc2);
600: }
601: else if (phciCurrent->iValue == HECCER_MOP_SPRINGMASS)
602: {
603: struct MopsSpringMass *pmops
604: = (struct MopsSpringMass *)&piOperators[i / sizeof(int)];
605:
606: if (pmops->pdEvents
607: && pmops->pdEvents[0])
608: {
609: sprintf(pc, " %i %g %i %i %g", pmops->iEvent, pmops->pdEvents[pmops->iEvent], pmops->iDiscreteTarget, pmops->iTable, pmops->dFrequency);
610: }
611: else
612: {
613: sprintf(pc, " %i (nil) %i %i %g", pmops->iEvent, pmops->iDiscreteTarget, pmops->iTable, pmops->dFrequency);
614: }
615: }
616: else if (phciCurrent->iValue == HECCER_MOP_EVENTGENERATE)
617: {
618: struct MopsEventGenerate *pmops
619: = (struct MopsEventGenerate *)&piOperators[i / sizeof(int)];
620:
621: if (pmops->uSource.pdValue == (double *)-1)
622: {
623: sprintf(pc, " (%s) %g %g %i", "dVm", pmops->dThreshold, pmops->dRefractoryReset, pmops->iTable);
624: }
625: else if (pmops->uSource.pdValue)
626: {
627: sprintf(pc, " (%g) %g %g %i", *pmops->uSource.pdValue, pmops->dThreshold, pmops->dRefractoryReset, pmops->iTable);
628: }
629: else
630: {
631: sprintf(pc, " (nil) %g %g %i", pmops->dThreshold, pmops->dRefractoryReset, pmops->iTable);
632: }
633: }
634: else if (phciCurrent->iValue == HECCER_MOP_AGGREGATECURRENT)
635: {
636: struct MopsAggregateCurrent *pmops
637: = (struct MopsAggregateCurrent *)&piOperators[i / sizeof(int)];
638:
639: sprintf(pc, " %i (%g)", pmops->iIndex, pvm->pdAggregators[pmops->iIndex]);
640: }
641: }
642:
643: sprintf(pcOutput2, "%s", pc);
644:
645: strcat(pcOutput1, pcOutput2);
646: }
647: else
648: {
649: //- print operands numerically
650:
651: int j;
652:
653: for (j = sizeof(int) ; j < iCommandLength ; j += sizeof(int))
654: {
655: int iOperand;
656:
657: //- get current operand
658:
659: iOperand = piOperators[(i + j) / sizeof(int)];
660:
661: sprintf(pcOutput2, " %4i", iOperand);
662:
663: strcat(pcOutput1, pcOutput2);
664: }
665: }
666:
667: //- if a secondary operands array is given
668:
669: if (pvOperands)
670: {
671: if (phciCurrent->iSecondaries)
672: {
673: sprintf(pcOutput2, "\t\t\t\t\t\t\t");
674:
675: strcat(pcOutput1, pcOutput2);
676:
677: double *pdOperands = (double *)pvOperands;
678:
679: int iSecondary;
680:
681: for (iSecondary = 0; iSecondary < phciCurrent->iSecondaries; iSecondary++)
682: {
683: sprintf(pcOutput2, " %g", pdOperands[iSecondary]);
684:
685: strcat(pcOutput1, pcOutput2);
686: }
687: }
688:
689: pvOperands = (void *)&((char *)pvOperands)[phciCurrent->iSecondariesSize];
690: }
691: }
692: }
693: else
694: {
695: fprintf(pfile, " Error: %4i command not found in command table", iCommand);
696: }
697:
698: //- terminate line
699:
700: fprintf(pfile, "%s\n", pcOutput1);
701:
702: //- increment line count
703:
704: iLineCount++;
705:
706: //- add size of operands
707:
708: if (phciCurrent && iCommandLength >= 2)
709: {
710: i += iCommandLength;
711: }
712: else
713: {
714: i += sizeof(int);
715: }
716: }
717:
718: //- return result
719:
720: return(iResult);
721: }
722:
723:
724:
Generated by Xrefactory version 2.0.14 on Thu Jul 24 22:41:20 2008