Advertisement
Guest User

Izhikevich_test

a guest
Jan 28th, 2016
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.82 KB | None | 0 0
  1. /*
  2. Izhikevich in integer math
  3. Zach Fredin
  4. zach@neurotinker.com
  5. 1/18/2016
  6.  
  7. Copyright (c) 2016 by Zach Fredin
  8.  
  9. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  10.  
  11. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  12.  
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  14.  
  15.  
  16. This program attemts to convert Izhikevich's neuron model to purely
  17. integer math by iterating through test values and improving the
  18. model "fit" versus his original equations. I'm not sure it will work.
  19.  
  20. [test.c is the baseline using floating point math!]
  21. */
  22.  
  23. /*  Izhikevich model
  24.  
  25.     dv/dt = 0.04v^2 + 5v +140 - u + I
  26.     du/dt = a(bv - u)
  27.     if v >= 30 (neuron fires)
  28.     v <- c; u <- u + d
  29.  
  30.     Typical parameters for a regular spiking neuron:
  31.     a   0.02
  32.     b   0.2
  33.     c   -65
  34.     d   8
  35.     I   6
  36.  
  37.     Model start at t=0
  38.     v0 = -65
  39.     u0 = 0
  40.  
  41.     Arbitrary names for the coefficients:
  42.     dv/dt = E*v^2 + F*v + G - u + I
  43.     du/dt = a(bv - u)
  44.     if v >= H (neuron fires)
  45.     v <- c; u <- u + d
  46. */
  47.  
  48. /*  Measuring model "fit"
  49.     Various checks based on typical parameters listed above
  50.     Check conditions
  51.         0 <= t < 500
  52.         slope threshold = 1.0*t
  53.  
  54.     Number of firings       6
  55.     Fire ratio          0.132
  56.     Linear region avg slope     0.252
  57.     Linear region range pct     0.180
  58.  
  59.     Optimize for:
  60.     - fire ratio at a given slope
  61.     - number of firings
  62.     - linear region avg slope
  63.     - linear region range pct
  64.     - not overflowing 16-bit signed integers
  65. */
  66.  
  67. #include <stdio.h>
  68. #include <time.h>
  69. #include <tgmath.h>
  70. #include <stdlib.h>
  71.  
  72. /*  Izhikevich model inputs */
  73. const float inp_I = 6;
  74. const float inp_v = -65; //starting point for v
  75. const float inp_u = 0; //starting point for u
  76.  
  77. /*  Izhikevich model variable array */
  78. volatile float var_v[500];
  79. volatile float var_u[500];
  80.  
  81. /*  Izhikevich model parameters (constants for now) */
  82. const float para_a = 0.02;
  83. const float para_b = 0.2;
  84. const float para_c = -65;
  85. const float para_d = 8;
  86.  
  87. /*  Izhikevich model coefficients (iteratively optimized) */
  88. volatile float coef_E; //v^2
  89. volatile float coef_Ebest;
  90. volatile float coef_F; //v
  91. volatile float coef_Fbest;
  92. volatile float coef_G; //offset
  93. volatile float coef_Gbest;
  94. volatile float coef_H; //threshold to reset v and u
  95. volatile float coef_Hbest;
  96.  
  97. /*  Izhikevich model coefficient limts (all minimums are 0) */
  98. const float max_E = 0.20;
  99. const float max_F = 20;
  100. const float max_G = 500;
  101. const float max_H = 200;
  102.  
  103. /*  Slope threshold */
  104. volatile float model_slopeThresh = 1.0;
  105.  
  106. /*  Calculated outputs */
  107. volatile int model_numFirings;
  108. volatile float model_fireRatio;
  109. volatile float model_linSlopeAvg;
  110. volatile float model_linRangePct;
  111.  
  112. /*  Ideal values */
  113. const int ideal_numFirings = 6;
  114. const float ideal_fireRatio = 0.136;
  115. const float ideal_linSlopeAvg = 0.252;
  116. const float ideal_linRangePct = 0.180;
  117.  
  118. /*  Optimization parameters */
  119. const int iterations = 1000000;
  120. const float wgt_numFirings = 0.25;
  121. const float wgt_fireRatio = 0.25;
  122. const float wgt_linSlopeAvg = 0.25;
  123. const float wgt_linRangePct = 0.25;
  124.  
  125. /*  Model fit variable (current and best) */
  126. volatile float fit = 0;
  127. volatile float fitbest = 0;
  128.  
  129. /*  Execution time variables */
  130. clock_t start, end;
  131. double cpu_time_used;
  132.  
  133. double randomDouble(double scale) {
  134.     srand((double)clock());
  135.     return ((double)rand()/(double)(RAND_MAX)) * scale;
  136. }
  137.  
  138. void initializeOutputs(void) {
  139.     int i;
  140.     model_numFirings = 0;
  141.     model_fireRatio = 0;
  142.     model_linSlopeAvg = 0;
  143.     model_linRangePct = 0;
  144. }  
  145.  
  146. void calcFit(void) {
  147.     float fit_numFirings = wgt_numFirings * fabs((float)model_numFirings - (float)ideal_numFirings) / (float)ideal_numFirings;
  148.     float fit_fireRatio = wgt_fireRatio * fabs(model_fireRatio - ideal_fireRatio) / ideal_fireRatio;
  149.     float fit_linSlopeAvg = wgt_linSlopeAvg * fabs(model_linSlopeAvg - ideal_linSlopeAvg) / ideal_linSlopeAvg;
  150.     float fit_linRangePct = wgt_linRangePct * fabs(model_linRangePct - ideal_linRangePct) / ideal_linRangePct;
  151.     fit = 1 - (fit_numFirings + fit_fireRatio + fit_linSlopeAvg + fit_linRangePct);
  152. }
  153.    
  154. void calcOutputs(void) {
  155.     initializeOutputs();
  156.     int i;
  157.     int counter_fireRatio = 0;
  158.     float acc_linSlopeAvg = 0;
  159.     float lin_min = 0;
  160.     float lin_max = 0;
  161.     for(i=1;i<500;i++) {
  162.         // calculate fire ratio
  163.         if(((var_v[i] - var_v[i-1]) > model_slopeThresh) | ((var_v[i-1] - var_v[i]) > model_slopeThresh)) {
  164.             counter_fireRatio++;
  165.         }
  166.  
  167.         else {
  168.             //calculate linear region average slope
  169.             acc_linSlopeAvg += (var_v[i] - var_v[i-1]);
  170.  
  171.             //record min/max for linear region
  172.             if(lin_min == 0 | (var_v[i] < lin_min)) {
  173.                 lin_min = var_v[i];
  174.             }
  175.             if(lin_max == 0 | (var_v[i] > lin_max)) {
  176.                 lin_max = var_v[i];
  177.             }
  178.         }
  179.  
  180.         // calculate number of firings
  181.         if(var_v[i] > coef_H) {
  182.             model_numFirings++;
  183.         }
  184.     }          
  185.  
  186.     model_fireRatio = (float)counter_fireRatio / 500;
  187.     model_linSlopeAvg = acc_linSlopeAvg / (500 - (float)counter_fireRatio);
  188.     model_linRangePct = (lin_max - lin_min) / (coef_H - lin_min);
  189. }
  190.  
  191. void runModel(void) {
  192.     int i;
  193.     var_v[0] = inp_v;
  194.     var_u[0] = inp_u;  
  195.     for(i=1;i<500;i++) {
  196.         if(var_v[i-1] > coef_H) {
  197.             var_v[i] = para_c;
  198.             var_u[i] = var_u[i-1] + para_d;
  199.         }
  200.         else {
  201.             var_v[i] = var_v[i-1] + coef_E * var_v[i-1] * var_v[i-1] + coef_F * var_v[i-1] + coef_G - var_u[i-1] + inp_I;
  202.             var_u[i] = var_u[i-1] + para_a * (para_b * var_v[i-1] - var_u[i-1]);
  203.         }
  204.     }
  205. }
  206.    
  207. int main(void) {
  208.     int i;
  209.     start = clock();
  210.     printf("Izhikevich model optimizer \n");
  211.    
  212.     for (i=0; i<iterations; i++) {
  213.         coef_E = randomDouble(max_E);
  214.         coef_F = randomDouble(max_F);
  215.         coef_G = randomDouble(max_G);
  216.         coef_H = randomDouble(max_H);
  217.         runModel();
  218.         calcOutputs();
  219.         calcFit();
  220.         if(fit > fitbest) {
  221.             fitbest = fit;
  222.             coef_Ebest = coef_E;
  223.             coef_Fbest = coef_F;
  224.             coef_Gbest = coef_G;
  225.             coef_Hbest = coef_H;
  226.         }
  227.     }
  228.  
  229.     printf("Model iterations: %i\n", iterations);
  230.     printf("Best fit: %f\n", fitbest);
  231.     printf("    E %f\n", coef_Ebest);
  232.     printf("    F %f\n", coef_Fbest);
  233.     printf("    G %f\n", coef_Gbest);
  234.     printf("    H %f\n", coef_Hbest);
  235.  
  236.     end = clock();
  237.     printf("execution time (s): %f\n", ((double)(end-start))/CLOCKS_PER_SEC);
  238.     return 0;
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement