123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- /*
- * izhikevich.cpp
- *
- * This file is part of the Izhikevich console application.
- *
- * Copyright (C) 2016, Author: Guido Trensch
- *
- * The Izhikevich console application is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * It is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this application. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // = IZHIKEVICH MODEL
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // =
- // = compile with:
- // = g++ main.cpp -o izhikevich -I/usr/include/plplot -lplplotcxxd -lplplotd
- // =
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- #include <plstream.h>
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <cstring>
- #include "izhikevich.h"
- #include "izhikevich_model.h"
- #include "ode_solvers.h"
- #define PRINT_DEBUG printf
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // = SIMULATION PARAMETERS
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- #define SIMULATION_TIME (float)(600.0) // in milliseconds
- #define INTEGRATION_STEP_SIZE (float)(1.000) // in milliseconds
- #define HIGHRES_INTEGRATION_STEP_SIZE (float)(0.001) // in milliseconds
- #define PLOT_SHIFT (float)(0.000) // shift plot for debug, e.g. 5.0
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // = FORWARD DECLARATIONS
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- void drawGraph( CNTXT* pCntxt, plstream* pPlStream, int numDataPoints, PLFLT* pTimesArray, PLFLT* pVoltagesArray, int plot_color, int plot_line_style, char* pLegendText );
- void exitProgram( CNTXT* pCntxt );
- void finalizeContext( CNTXT* pCntxt );
- void finalizePlot( CNTXT* pCntxt, plstream* pPlStream );
- void finalizeSimulation( CNTXT* pCntxt, PLFLT* pTimesArray, PLFLT* pVoltagesArray, float* pCurrentArray );
- void initializeContext( CNTXT** ppCntxt );
- void initializePlot( CNTXT* pCntxt, plstream** pPlStream );
- void initializeSimulation( CNTXT* pCntxt, float simulationTime, float integrationStepSize, PLFLT** ppTimesArray, PLFLT** ppVoltagesArray, PLFLT** ppFrequencyArray, float** ppCurrentArray );
- int runSimulation( CNTXT* pCntxt, ENUM_ODESOLVER_METHOD method, float simulationTime, float integrationStepSize, PLFLT* pTimesArray, PLFLT* pVoltagesArray, PLFLT* pFrequencyArray, float* pCurrentArray );
- void setCurrentShape( CNTXT* pCntxt, float* pCurrentArray, int numDataPoints, float integrationStepSize );
- void processMainArguments( CNTXT* pCntxt, int argc, char** argv );
- void processOPT_C( CNTXT* pCntxt, int argc, char** argv );
- void processOPT_F( CNTXT* pCntxt, int argc, char** argv );
- void processOPT_H( CNTXT* pCntxt, int argc, char** argv );
- void processOPT_M( CNTXT* pCntxt, int argc, char** argv );
- void processOPT_N( CNTXT* pCntxt, int argc, char** argv );
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // = MAIN ENTRY
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- int main (int argc, char** argv)
- {
- CNTXT* pCntxt = NULL;
- PLFLT* pVoltagesArray = NULL;
- PLFLT* pTimesArray = NULL;
- PLFLT* pFrequencyArray = NULL;
- float* pCurrentArray = NULL;
- int numDataPoints = 0;
- plstream* pPlStream = NULL;
- initializeContext( &pCntxt );
- processMainArguments( pCntxt, argc, argv );
- initializePlot( pCntxt, &pPlStream );
-
- // PERFORM STANDARD EULER
- if( pCntxt->args.fOdeSolverStandardEuler ) {
- PRINT_DEBUG( " Debug: + + + perform standard Euler + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, STANDARD_EULER, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- // ***GTR print frequency
- // drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pFrequencyArray, PLOT_COLOR_RED, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_STANDARD_EULER );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_RED, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_STANDARD_EULER );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // PERFORM SYMPLECTIC EULER
- if( pCntxt->args.fOdeSolverSymplecticEuler ) {
- PRINT_DEBUG( " Debug: + + + symplectic Euler + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, SYMPLECTIC_EULER, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_GREEN, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_SYMPLECTIC_EULER );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // PERFORM EXPLICIT EULER SPINNAKER
- if( pCntxt->args.fOdeSolverEulerSpiNNaker ) {
- PRINT_DEBUG( " Debug: + + + perform explicit Euler - SpiNNaker implementation + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, EXPLICIT_EULER_SPINNAKER, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_MAGENTA, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_EULER_SPINNAKER );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // EXPLICIT EULER NEST
- if( pCntxt->args.fOdeSolverEulerNEST ) {
- PRINT_DEBUG( " Debug: + + + explicit Euler - NEST implementation + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, EXPLICIT_EULER_NEST, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_YELLOW, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_EULER_NEST );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // EXPLICIT IZHIKEVICH NUMERICS NEST
- if( pCntxt->args.fOdeSolverIzhikevichNEST ) {
- PRINT_DEBUG( " Debug: + + + explicit Izhikevich numerics - NEST implementation + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, EXPLICIT_IZHIKEVICH_NUMERICS_NEST, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_CYAN, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_IZHIKEVICH_NEST );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
-
- // GSL library
- if( pCntxt->args.fOdeSolverGSL ) {
- PRINT_DEBUG( " Debug: + + + GSL library + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, GSL_LIBRARY, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_GREY, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_GSL );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // Heun
- if( pCntxt->args.fOdeSolverHeun ) {
- PRINT_DEBUG( " Debug: + + + Heun's method + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, HEUN_METHOD, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_BROWN, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_HEUN );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // Euler with adaptive stepsize
- if( pCntxt->args.fOdeSolverAdaptiveEuler ) {
- PRINT_DEBUG( " Debug: + + + perform adaptive Euler + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, ADAPTIVE_EULER, SIMULATION_TIME, INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_BROWN, PLOT_LINE_FULL, STR_ODE_SOLVER_METHOD_ADAPTIVE_EULER );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- // HIGH RESOLUTION REFERENCE USING STANDARD EULER
- if( pCntxt->args.fOdeSolverHighResolutionEuler ) {
- PRINT_DEBUG( " Debug: + + + reference high resolution standard Euler + + +\n" );
- initializeSimulation( pCntxt, SIMULATION_TIME, HIGHRES_INTEGRATION_STEP_SIZE, &pTimesArray, &pVoltagesArray, &pFrequencyArray, &pCurrentArray );
- numDataPoints = runSimulation( pCntxt, STANDARD_EULER, SIMULATION_TIME, HIGHRES_INTEGRATION_STEP_SIZE, pTimesArray, pVoltagesArray, pFrequencyArray, pCurrentArray );
- drawGraph( pCntxt, pPlStream, numDataPoints, pTimesArray, pVoltagesArray, PLOT_COLOR_BLUE, PLOT_LINE_DOTTED, STR_ODE_SOLVER_METHOD_HIGH_RESOLUTION_EULER );
- finalizeSimulation( pCntxt, pTimesArray, pVoltagesArray, pCurrentArray );
- }
- finalizePlot( pCntxt, pPlStream );
- finalizeContext( pCntxt );
- printf( " Terminated normally\n" );
- return 0;
- }
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // HELPER FUNCTIONS
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // Plot graph, i.e. write to svg file
- // Multiple graphs can be plotted and overlayed
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- void drawGraph( CNTXT* pCntxt, plstream* pPlStream, int numDataPoints, PLFLT* pTimesArray, PLFLT* pVoltagesArray, int plot_color, int plot_line_style, char* pLegendText )
- {
- PRINT_DEBUG( " Debug: plot graph, i.e. write to svg file: %s\n", pCntxt->args.outputSvgFilename );
- pllsty( plot_line_style );
- plcol0( plot_color );
- pPlStream->line( numDataPoints, pTimesArray, pVoltagesArray );
- plptex( 80.0, pCntxt->legendYOffset, 0.0, 0.0, 0.5, pLegendText );
- pCntxt->legendYOffset += 5;
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Free program context area and exit the program
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void exitProgram( CNTXT* pCntxt )
- {
- finalizeContext( pCntxt );
- exit( 0 );
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Free program context area
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void finalizeContext( CNTXT* pCntxt )
- {
- if( pCntxt != NULL ) {
- free( pCntxt );
- }
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Delete Plplot stream
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void finalizePlot( CNTXT* pCntxt, plstream* pPlStream )
- {
- delete pPlStream;
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Free data arrays
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void finalizeSimulation( CNTXT* pCntxt, PLFLT* pTimesArray, PLFLT* pVoltagesArray, float* pCurrentArray )
- {
- PRINT_DEBUG( " Debug: finalize\n" );
- free( pTimesArray );
- free( pVoltagesArray );
- free( pCurrentArray );
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Allocate and initialize the program's context area.
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void initializeContext( CNTXT** ppCntxt )
- {
- PRINT_DEBUG( " Debug: initialize context\n" );
- *ppCntxt = (CNTXT*)malloc( S_CNTXT );
- if( *ppCntxt == NULL ) {
- printf( "ERRROR: Failed to allocate program context area\n");
- exitProgram( NULL );
- }
- memset( *ppCntxt, NULLCHR, S_CNTXT );
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Set up Plplot
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void initializePlot( CNTXT* pCntxt, plstream** pPlStream )
- {
- *pPlStream = new plstream();
- plsdev("svg");
- plsfnam( pCntxt->args.outputSvgFilename );
- plscolbg( 255, 255, 255 );
- plscmap0n(16);
- (*pPlStream)->init();
- (*pPlStream)->env( 0, SIMULATION_TIME, -80, 50, 0, 0 );
- // | | | | | |
- // | | | | | +--- axis - 0 draw axis box and numeric labels
- // | | | | +------ just - 0 axis scales independently
- // | | | +---------- ymax
- // | | +-------------- ymin
- // | +-------------------------------- xmax
- // +----------------------------------- xmin
- (*pPlStream)->lab( "Time [ms]", "Voltage [mv]", pCntxt->neuronTypeName );
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Allocate and set up data structures
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void initializeSimulation( CNTXT* pCntxt, float simulationTime, float integrationStepSize, PLFLT** ppTimesArray, PLFLT** ppVoltagesArray, PLFLT** ppFrequencyArray, float** ppCurrentArray )
- {
- PRINT_DEBUG( " Debug: initialize simulation and prepare data arrays\n" );
- PLFLT* pVoltagesArray = NULL;
- PLFLT* pTimesArray = NULL;
- PLFLT* pFrequencyArray = NULL;
- float* pCurrentArray = NULL;
- int numDataPoints = floor(simulationTime / integrationStepSize) + 10; // due to rounding errors there might be a few more datapoints returned from the simulation run; just add 10 to be on the save side
-
- PRINT_DEBUG( " Debug: number of data points calculated: %d\n", numDataPoints );
- pVoltagesArray = (PLFLT*)malloc( numDataPoints * sizeof(PLFLT) );
- pTimesArray = (PLFLT*)malloc( numDataPoints * sizeof(PLFLT) );
- pFrequencyArray = (PLFLT*)malloc( numDataPoints * sizeof(PLFLT) );
- pCurrentArray = (float*)malloc( numDataPoints * sizeof(float) );
- if( NULL == pVoltagesArray || NULL == pTimesArray || NULL == pFrequencyArray || NULL == pCurrentArray ) {
- printf( "ERROR: failed to allocate memory\n" );
- exitProgram( pCntxt );
- }
- memset( pVoltagesArray, 0x00, numDataPoints * sizeof(PLFLT) );
- memset( pTimesArray, 0x00, numDataPoints * sizeof(PLFLT) );
- memset( pFrequencyArray, 0x00, numDataPoints * sizeof(PLFLT) );
- memset( pCurrentArray, 0x00, numDataPoints * sizeof(float) );
- setCurrentShape( pCntxt, pCurrentArray, numDataPoints, integrationStepSize );
- *ppTimesArray = pTimesArray;
- *ppVoltagesArray = pVoltagesArray;
- *ppFrequencyArray = pFrequencyArray;
- *ppCurrentArray = pCurrentArray;
- // set Izhikevich model constants
- IZHIKEVICH_A = pCntxt->neuronParam_A;
- IZHIKEVICH_B = pCntxt->neuronParam_B;
- IZHIKEVICH_C = pCntxt->neuronParam_C;
- IZHIKEVICH_D = pCntxt->neuronParam_D;
- IZHIKEVICH_THR = pCntxt->neuronParam_THR;
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Depending on parameter "method", call the corresponding ODE solver and
- // perform the simulation
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- int runSimulation( CNTXT* pCntxt, ENUM_ODESOLVER_METHOD method, float simulationTime, float integrationStepSize
- , PLFLT* pTimesArray, PLFLT* pVoltagesArray, PLFLT* pFrequencyArray, float* pCurrentArray )
- {
- PFUNCD pODE1dxdt = (PFUNCD)dvdt; // Izhikevich ODE1
- PFUNCD pODE2dydt = (PFUNCD)dudt; // Izhikevich ODE2
- float v_t = pCntxt->neuronParam_V_INIT;
- float u_t = pCntxt->neuronParam_U_INIT;
- float v_tplus1 = 0;
- float u_tplus1 = 0;
- float t = 0;
- int dataPointIndex = 0;
- PRINT_DEBUG( " Debug: run simulation\n" );
- switch( method ) {
- case STANDARD_EULER:
- t = PLOT_SHIFT * 1;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- ode2dSolver_StandardEuler( pODE1dxdt, pODE2dydt, integrationStepSize, v_t, u_t, &v_tplus1, &u_tplus1, &pCurrentArray[dataPointIndex] );
- if( threshold( &v_tplus1, &u_tplus1 )) {
- pFrequencyArray[dataPointIndex] = 30;
- };
- v_t = v_tplus1;
- u_t = u_tplus1;
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case SYMPLECTIC_EULER:
- t = PLOT_SHIFT * 2;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- ode2dSolver_SymplecticEuler( pODE1dxdt, pODE2dydt, integrationStepSize, v_t, u_t, &v_tplus1, &u_tplus1, &pCurrentArray[dataPointIndex] );
- threshold( &v_tplus1, &u_tplus1 );
- v_t = v_tplus1;
- u_t = u_tplus1;
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case EXPLICIT_EULER_SPINNAKER:
- t = PLOT_SHIFT * 3;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- explizitSpiNNaker( integrationStepSize, &v_t, &u_t, pCurrentArray[dataPointIndex] );
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case EXPLICIT_EULER_NEST:
- t = PLOT_SHIFT * 4;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- explizitNEST1( integrationStepSize, &v_t, &u_t, pCurrentArray[dataPointIndex] );
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case EXPLICIT_IZHIKEVICH_NUMERICS_NEST:
- t = PLOT_SHIFT * 5;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- explizitNEST2( integrationStepSize, &v_t, &u_t, pCurrentArray[dataPointIndex] );
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case GSL_LIBRARY:
- t = PLOT_SHIFT * 6;
- gslODESolver_Init();
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- gslODESolver_Integrate( integrationStepSize, &v_t, &u_t, pCurrentArray[dataPointIndex] );
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case HEUN_METHOD:
- t = PLOT_SHIFT * 7;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- ode2dSolver_Heun( pODE1dxdt, pODE2dydt, integrationStepSize, v_t, u_t, &v_tplus1, &u_tplus1, &pCurrentArray[dataPointIndex] );
- threshold( &v_tplus1, &u_tplus1 );
- v_t = v_tplus1;
- u_t = u_tplus1;
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- case ADAPTIVE_EULER:
- t = PLOT_SHIFT * 8;
- while( t <= simulationTime ) {
- pTimesArray[dataPointIndex] = t;
- pVoltagesArray[dataPointIndex] = v_t;
- ode2dSolver_AdaptiveEuler( pODE1dxdt, pODE2dydt, integrationStepSize, v_t, u_t, &v_tplus1, &u_tplus1, &pCurrentArray[dataPointIndex] );
- threshold( &v_tplus1, &u_tplus1 );
- v_t = v_tplus1;
- u_t = u_tplus1;
- t += integrationStepSize;
- dataPointIndex++;
- }
- break;
- default:
- printf( "ERROR: ODE solver method not defined\n");
- exitProgram( pCntxt );
- }
-
- PRINT_DEBUG( " Debug: number of data points: %d\n", dataPointIndex );
- return( dataPointIndex ); // return number of data points, hence the dataPointIndex
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Fill the current-data-array with the desired current-shape.
- // The size of the array, i.e. the number od datapoints depend on the
- // resolution, hence the integration step size.
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void setCurrentShape( CNTXT* pCntxt, float* pCurrentArray, int numDataPoints, float integrationStepSize )
- {
- PRINT_DEBUG( " Debug: initialize current-shape array\n" );
- switch( pCntxt->args.currentShape ) {
- case CURRENT_STEP_150:
- for( int i = 0; i < numDataPoints; ++i ) {
- pCurrentArray[i] = pCntxt->neuronParam_I_EXT;
- }
- for( int i = 0; i < floor( 150 / integrationStepSize ); ++i ) {
- pCurrentArray[i] = 0;
- }
- // printf( " i +------------------------ \n" );
- // printf( " 0 ----+ \n" );
- // printf( " 150 t [ms] \n" );
- break;
- case CURRENT_PULSE:
- for( int i = 0; i < numDataPoints; ++i ) {
- pCurrentArray[i] = pCntxt->neuronParam_I_EXT;
- }
- for( int i = 0; i < floor( 150 / integrationStepSize ); ++i ) {
- pCurrentArray[i] = 0;
- }
- for( int i = floor( 200 / integrationStepSize ) ; i < floor( (200 + 2) / integrationStepSize ); ++i ) {
- pCurrentArray[i] = pCntxt->neuronParam_I_EXT + 5 ;
- }
- // printf( " +--+ \n" );
- // printf( " | | i + 5 pA \n" );
- // printf( " i +----------+ +---------- \n" );
- // printf( " 0 ----+ \n" );
- // printf( " 150 200 202 t [ms] \n" );
- break;
- case CURRENT_NEGATIVE_STEP:
- for( int i = 0; i < numDataPoints; ++i ) {
- pCurrentArray[i] = - pCntxt->neuronParam_I_EXT;
- }
- for( int i = floor( 150 / integrationStepSize ); i < numDataPoints; ++i ) {
- pCurrentArray[i] = 0;
- }
- // printf( " 0 +------------------------ \n" );
- // printf( " -i ----+ \n" );
- // printf( " 150 t [ms] \n" );
- break;
- default:
- printf( "ERROR: Failed to set up current shape\n" );
- exitProgram( pCntxt ) ;
- }
- return;
- }
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // HELPER FUNCTIONS TO PROCESS PROGRAM MAIN ARGUMENTS
- // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Check program options
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processMainArguments( CNTXT* pCntxt, int argc, char** argv )
- {
- while( --argc ) {
- if( argv[argc][0] != '-' ) {
- printf( "ERROR: Parameter error\n");
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- switch( argv[argc][1] ) {
- case OPT_C:
- processOPT_C( pCntxt, argc, argv );
- break;
- case OPT_F:
- processOPT_F( pCntxt, argc, argv );
- break;
- case OPT_H:
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- break;
- case OPT_M:
- processOPT_M( pCntxt, argc, argv );
- break;
- case OPT_N:
- processOPT_N( pCntxt, argc, argv );
- break;
- default:
- printf( "ERROR: Parameter error\n");
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- }
- // some parameter checks
- if( pCntxt->args.currentShape == 0 ) {
- printf( "ERROR: option -c not set\n" );
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- if( pCntxt->args.outputSvgFilename[0] == NULLCHR ) {
- printf( "ERROR: option -f not set\n" );
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- if( pCntxt->neuronParam_A == 0 ) {
- printf( "ERROR: option -n not set\n" );
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- if(( pCntxt->args.fOdeSolverStandardEuler || pCntxt->args.fOdeSolverSymplecticEuler || pCntxt->args.fOdeSolverEulerSpiNNaker ||
- pCntxt->args.fOdeSolverEulerNEST || pCntxt->args.fOdeSolverIzhikevichNEST || pCntxt->args.fOdeSolverHighResolutionEuler ||
- pCntxt->args.fOdeSolverGSL || pCntxt->args.fOdeSolverHeun || pCntxt->args.fOdeSolverAdaptiveEuler ) == 0 ) {
- printf( "ERROR: option -m not set\n" );
- processOPT_H( pCntxt, argc, argv );
- exitProgram( pCntxt );
- }
- printf( "+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +\n" );
- printf( "+ INZHIKEVICH MODEL SIMULATION +\n" );
- printf( "+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +\n" );
- printf( "Following parameters are in use for this run:\n" );
- printf( " SVG Output File Name: %s\n", pCntxt->args.outputSvgFilename );
- printf( " Neuron Type : %s\n", pCntxt->neuronTypeName );
-
- switch( pCntxt->args.currentShape ) {
- case CURRENT_STEP_150:
- printf( " Current Shape : step current at 150ms\n" );
- printf( " i +------------------------ \n" );
- printf( " 0 ----+ \n" );
- printf( " 150 t [ms] \n" );
- break;
- case CURRENT_PULSE:
- printf( " Current Shape : step current at 150ms with pulse at 200ms for 2ms\n" );
- printf( " +--+ \n" );
- printf( " | | i + 5 pA \n" );
- printf( " i +----------+ +---------- \n" );
- printf( " 0 ----+ \n" );
- printf( " 150 200 202 t [ms] \n" );
- break;
- case CURRENT_NEGATIVE_STEP:
- printf( " Current Shape : negative step current at 150ms\n" );
- printf( " 0 +------------------------ \n" );
- printf( " -i ----+ \n" );
- printf( " 150 t [ms] \n" );
- break;
- }
- printf( " ODE solver selected : \n" );
- if( pCntxt->args.fOdeSolverStandardEuler ) {
- printf( " Standard Euler\n" );
- }
- if( pCntxt->args.fOdeSolverSymplecticEuler ) {
- printf( " Symplextic Euler\n" );
- }
- if( pCntxt->args.fOdeSolverEulerSpiNNaker ) {
- printf( " Explicit Euler SpiNNaker implementation\n" );
- }
- if( pCntxt->args.fOdeSolverEulerNEST ) {
- printf( " Explicit Euler NEST implementation\n" );
- }
- if( pCntxt->args.fOdeSolverIzhikevichNEST ) {
- printf( " Izhikevich numerics NEST implementation\n" );
- }
- if( pCntxt->args.fOdeSolverGSL ) {
- printf( " GSL library\n" );
- }
- if( pCntxt->args.fOdeSolverHeun ) {
- printf( " Heun's method\n" );
- }
- if( pCntxt->args.fOdeSolverHighResolutionEuler ) {
- printf( " Standard Euler with a high integration step resolution, i.e. 1 micro second\n" );
- }
- if( pCntxt->args.fOdeSolverAdaptiveEuler ) {
- printf( " Standard Euler with an adaptive integration step size\n" );
- }
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Set the current shape
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processOPT_C( CNTXT* pCntxt, int argc, char** argv )
- {
- if( strncmp( &argv[argc][2], STR_CURRENT_STEP_150, sizeof( STR_CURRENT_STEP_150 )) == 0 ) {
- pCntxt->args.currentShape = CURRENT_STEP_150;
- }
- else if ( strncmp( &argv[argc][2], STR_CURRENT_PULSE, sizeof( STR_CURRENT_PULSE )) == 0 ) {
- pCntxt->args.currentShape = CURRENT_PULSE;
- }
- else if ( strncmp( &argv[argc][2], STR_CURRENT_NEGATIVE_STEP, sizeof( STR_CURRENT_NEGATIVE_STEP )) == 0 ) {
- pCntxt->args.currentShape = CURRENT_NEGATIVE_STEP;
- }
- else {
- printf( "ERROR: Parameter error, failed to set current shape\n" );
- exitProgram( pCntxt );
- }
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Set the svg output file name
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processOPT_F( CNTXT* pCntxt, int argc, char** argv )
- {
- strncpy( pCntxt->args.outputSvgFilename, &argv[argc][2], S_NAME - 1 );
- pCntxt->args.outputSvgFilename[S_NAME - 1] = NULLCHR;
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Show help text
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processOPT_H( CNTXT* pCntxt, int argc, char** argv )
- {
- printf( "USAGE : izhikevich -n<neuron type> -c<current shape> -f<svg output path/file.svg> -m<ODE solver method> ... -m<ODE solver method>\n" );
- printf( " -f filename svg output file name, e.g. svg\\RS_step150.svg\n" );
- printf( " -n RS regular spiking\n" );
- printf( " IB intrinsically bursting\n" );
- printf( " CH chattering\n" );
- printf( " FS fast spiking\n" );
- printf( " TC thalamo cortical\n" );
- printf( " RZ resonance\n" );
- printf( " LTS low threshold spiking\n" );
- printf( "\n" );
- printf( " -c step150 step current at 150ms\n" );
- printf( " i +------------------------ \n" );
- printf( " 0 ----+ \n" );
- printf( " 150 t [ms] \n" );
- printf( " pulse step current at 150ms with pulse at 200ms for 2ms\n" );
- printf( " +--+ \n" );
- printf( " | | i + 5 pA \n" );
- printf( " i +----------+ +---------- \n" );
- printf( " 0 ----+ \n" );
- printf( " 150 200 202 t [ms] \n" );
- printf( " nstep negative step current at 150ms\n" );
- printf( " 0 +------------------------ \n" );
- printf( " -i ----+ \n" );
- printf( " 150 t [ms] \n" );
- printf( "\n" );
- printf( " -m stdEuler standard Euler\n" );
- printf( " sympEuler symplectic Euler\n" );
- printf( " SpiNNaker explicit Euler SpiNNaker implementation\n" );
- printf( " EulerNEST explicit Euler NEST implementation\n" );
- printf( " IzhikevichNEST Izhikevich numerics implementation in NEST\n" );
- printf( " GSL use GSL library\n" );
- printf( " Heun Heun method\n" );
- printf( " highResEuler standard Euler with a high resolution integration step size, i.e. 1 micro second\n" );
- printf( " adaptiveEuler standard Euler with an adaptive integration step size\n" );
- printf( "\n" );
- printf( "EXAMPLE: compare different ODE solver methods for a regular spiking neuron with a positive external step current at 150 milliseconds\n" );
- printf( " izhikevich -nRS -cstep150 -fsvg/RS_step150.svg -mstdEuler -msympEuler -mSpiNNaker -mEulerNEST -mIzhikevichNEST -mhighResEuler\n" );
- printf( "\n" );
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Set ODE solver method(s)
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processOPT_M( CNTXT* pCntxt, int argc, char** argv )
- {
- if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_STANDARD_EULER, sizeof( STR_ODE_SOLVER_METHOD_STANDARD_EULER )) == 0 ) {
- pCntxt->args.fOdeSolverStandardEuler = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_SYMPLECTIC_EULER, sizeof( STR_ODE_SOLVER_METHOD_SYMPLECTIC_EULER )) == 0 ) {
- pCntxt->args.fOdeSolverSymplecticEuler = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_EULER_SPINNAKER, sizeof( STR_ODE_SOLVER_METHOD_EULER_SPINNAKER )) == 0 ) {
- pCntxt->args.fOdeSolverEulerSpiNNaker = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_EULER_NEST, sizeof( STR_ODE_SOLVER_METHOD_EULER_NEST )) == 0 ) {
- pCntxt->args.fOdeSolverEulerNEST = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_IZHIKEVICH_NEST, sizeof( STR_ODE_SOLVER_METHOD_IZHIKEVICH_NEST )) == 0 ) {
- pCntxt->args.fOdeSolverIzhikevichNEST = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_GSL, sizeof( STR_ODE_SOLVER_METHOD_GSL )) == 0 ) {
- pCntxt->args.fOdeSolverGSL = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_HEUN, sizeof( STR_ODE_SOLVER_METHOD_HEUN )) == 0 ) {
- pCntxt->args.fOdeSolverHeun = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_HIGH_RESOLUTION_EULER, sizeof( STR_ODE_SOLVER_METHOD_HIGH_RESOLUTION_EULER )) == 0 ) {
- pCntxt->args.fOdeSolverHighResolutionEuler = TRUE;
- }
- else if( strncmp( &argv[argc][2], STR_ODE_SOLVER_METHOD_ADAPTIVE_EULER, sizeof( STR_ODE_SOLVER_METHOD_ADAPTIVE_EULER )) == 0 ) {
- pCntxt->args.fOdeSolverAdaptiveEuler = TRUE;
- }
- else {
- printf( "ERROR: Parameter error, invalid ODE solver method\n" );
- exitProgram( pCntxt );
- }
- return;
- }
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Set model parameters depending on the neuron type
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- void processOPT_N( CNTXT* pCntxt, int argc, char** argv )
- {
- if( strncmp( &argv[argc][2], STR_NEURON_TYPE_RS, sizeof( STR_NEURON_TYPE_RS )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_RS;
- strncpy( pCntxt->neuronTypeName, RS_TYPENAME, sizeof( RS_TYPENAME ));
- pCntxt->neuronParam_A = RS_A;
- pCntxt->neuronParam_B = RS_B;
- pCntxt->neuronParam_C = RS_C;
- pCntxt->neuronParam_D = RS_D;
- pCntxt->neuronParam_THR = RS_THR;
- pCntxt->neuronParam_I_EXT = RS_I_EXT;
- pCntxt->neuronParam_V_INIT = RS_V_INIT;
- pCntxt->neuronParam_U_INIT = RS_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_IB, sizeof( STR_NEURON_TYPE_IB )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_IB;
- strncpy( pCntxt->neuronTypeName, IB_TYPENAME, sizeof( IB_TYPENAME ));
- pCntxt->neuronParam_A = IB_A;
- pCntxt->neuronParam_B = IB_B;
- pCntxt->neuronParam_C = IB_C;
- pCntxt->neuronParam_D = IB_D;
- pCntxt->neuronParam_THR = IB_THR;
- pCntxt->neuronParam_I_EXT = IB_I_EXT;
- pCntxt->neuronParam_V_INIT = IB_V_INIT;
- pCntxt->neuronParam_U_INIT = IB_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_CH, sizeof( STR_NEURON_TYPE_CH )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_CH;
- strncpy( pCntxt->neuronTypeName, CH_TYPENAME, sizeof( CH_TYPENAME ));
- pCntxt->neuronParam_A = CH_A;
- pCntxt->neuronParam_B = CH_B;
- pCntxt->neuronParam_C = CH_C;
- pCntxt->neuronParam_D = CH_D;
- pCntxt->neuronParam_THR = CH_THR;
- pCntxt->neuronParam_I_EXT = CH_I_EXT;
- pCntxt->neuronParam_V_INIT = CH_V_INIT;
- pCntxt->neuronParam_U_INIT = CH_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_FS, sizeof( STR_NEURON_TYPE_FS )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_FS;
- strncpy( pCntxt->neuronTypeName, FS_TYPENAME, sizeof( FS_TYPENAME ));
- pCntxt->neuronParam_A = FS_A;
- pCntxt->neuronParam_B = FS_B;
- pCntxt->neuronParam_C = FS_C;
- pCntxt->neuronParam_D = FS_D;
- pCntxt->neuronParam_THR = FS_THR;
- pCntxt->neuronParam_I_EXT = FS_I_EXT;
- pCntxt->neuronParam_V_INIT = FS_V_INIT;
- pCntxt->neuronParam_U_INIT = FS_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_TC, sizeof( STR_NEURON_TYPE_TC )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_TC;
- strncpy( pCntxt->neuronTypeName, TC_TYPENAME, sizeof( TC_TYPENAME ));
- pCntxt->neuronParam_A = TC_A;
- pCntxt->neuronParam_B = TC_B;
- pCntxt->neuronParam_C = TC_C;
- pCntxt->neuronParam_D = TC_D;
- pCntxt->neuronParam_THR = TC_THR;
- pCntxt->neuronParam_I_EXT = TC_I_EXT;
- pCntxt->neuronParam_V_INIT = TC_V_INIT;
- pCntxt->neuronParam_U_INIT = TC_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_RZ, sizeof( STR_NEURON_TYPE_RZ )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_RZ;
- strncpy( pCntxt->neuronTypeName, RZ_TYPENAME, sizeof( RZ_TYPENAME ));
- pCntxt->neuronParam_A = RZ_A;
- pCntxt->neuronParam_B = RZ_B;
- pCntxt->neuronParam_C = RZ_C;
- pCntxt->neuronParam_D = RZ_D;
- pCntxt->neuronParam_THR = RZ_THR;
- pCntxt->neuronParam_I_EXT = RZ_I_EXT;
- pCntxt->neuronParam_V_INIT = RZ_V_INIT;
- pCntxt->neuronParam_U_INIT = RZ_U_INIT;
- }
- else if( strncmp( &argv[argc][2], STR_NEURON_TYPE_LTS, sizeof( STR_NEURON_TYPE_LTS )) == 0 ) {
- pCntxt->args.neuronType = NEURON_TYPE_LTS;
- strncpy( pCntxt->neuronTypeName, LTS_TYPENAME, sizeof( LTS_TYPENAME ));
- pCntxt->neuronParam_A = LTS_A;
- pCntxt->neuronParam_B = LTS_B;
- pCntxt->neuronParam_C = LTS_C;
- pCntxt->neuronParam_D = LTS_D;
- pCntxt->neuronParam_THR = LTS_THR;
- pCntxt->neuronParam_I_EXT = LTS_I_EXT;
- pCntxt->neuronParam_V_INIT = LTS_V_INIT;
- pCntxt->neuronParam_U_INIT = LTS_U_INIT;
- }
- else {
- printf( "ERROR: Failed to set neuron type and neuron type properties\n" );
- exitProgram( pCntxt );
- }
- return;
- }
|