normalize.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. /*Copyright (C) 2005, 2006, 2007 Frank Michler, Philipps-University Marburg, Germany
  2. This program is free software; you can redistribute it and/or
  3. modify it under the terms of the GNU General Public License
  4. as published by the Free Software Foundation; either version 2
  5. of the License, or (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  13. */
  14. #include "sys.hpp" // for libcwd
  15. #include "debug.hpp" // for libcwd
  16. #include "normalize.hpp"
  17. #include "layer.hpp"
  18. AbstractNormalize::AbstractNormalize()
  19. : SimElement(seNormalize), RewiringOn(false)
  20. {
  21. }
  22. void AbstractNormalize::SetRewiring(float _IncommingConnectivity, float _SynDelThreshold, float _InitialWeights)
  23. {
  24. RewiringOn=true;
  25. IncommingConnectivity=_IncommingConnectivity;
  26. SynDelThreshold=_SynDelThreshold;
  27. InitialWeights=_InitialWeights;
  28. }
  29. void AbstractNormalize::SetRewiringOff()
  30. {
  31. RewiringOn=false;
  32. }
  33. ////////Normalize//////////////////////////////////
  34. Normalize::Normalize()
  35. : AbstractNormalize(), Target(0), NTarget(0)
  36. {
  37. }
  38. int Normalize::AddConnection(connection* newcon)
  39. {
  40. if (Target == 0)
  41. {
  42. Target = newcon->GetTargetLayer();
  43. NTarget = Target->N;
  44. }
  45. if (Target == newcon->GetTargetLayer()) ConList.push_back(newcon);
  46. else cout << "ERROR: Target-Layer not the same\n";
  47. }
  48. int Normalize::proceede(int TotalTime)
  49. {
  50. }
  51. int Normalize::prepare(int Step)
  52. {
  53. }
  54. int Normalize::WriteSimInfo(fstream &fw)
  55. {
  56. stringstream sstr;
  57. sstr << "<Target id=\"" << Target->IdNumber << "\"/> \n";
  58. SimElement::WriteSimInfo(fw, sstr.str());
  59. }
  60. int Normalize::WriteSimInfo(fstream &fw, const string &ChildInfo)
  61. {
  62. stringstream sstr;
  63. sstr << "<Target id=\"" << Target->IdNumber << "\"/> \n";
  64. sstr << ChildInfo;
  65. SimElement::WriteSimInfo(fw, sstr.str());
  66. }
  67. /////////////////////
  68. FiringRateNormalize::FiringRateNormalize(float _NormThresh, float _NormFactor, float _Tau)
  69. : PostSynFirePot(0), PostSynLastFirings(0), Tau(_Tau/dt), NormThreshold(_NormThresh), NormFactor(_NormFactor)
  70. {
  71. cout << "FiringRateNormalization\n";
  72. cout << "Thresh=" << NormThreshold << " Factor=" << NormFactor << " Tau=" << Tau*dt << " ms\n";
  73. }
  74. int FiringRateNormalize::AddConnection(connection* newcon)
  75. {
  76. Normalize::AddConnection(newcon);
  77. if (PostSynFirePot == 0)
  78. {
  79. PostSynFirePot = new float [NTarget];
  80. PostSynLastFirings = new int [NTarget];
  81. int i;
  82. for (i=0;i<NTarget;++i)
  83. {
  84. PostSynFirePot[i]=0;
  85. PostSynLastFirings[i]=0;
  86. }
  87. }
  88. }
  89. int FiringRateNormalize::proceede(int TotalTime)
  90. {
  91. int t = int(TotalTime % MacroTimeStep);
  92. int spike = Target->last_N_firings;
  93. int CurTarget;
  94. int i,j;
  95. while (spike < Target->N_firings) {
  96. CurTarget = Target->firings[spike][1];
  97. PostSynFirePot[CurTarget] *= exp(-(t-PostSynLastFirings[CurTarget])/Tau);
  98. if (PostSynFirePot[CurTarget] > NormThreshold) {
  99. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  100. {
  101. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  102. }
  103. }
  104. PostSynFirePot[CurTarget] += 1;
  105. PostSynLastFirings[CurTarget]=t;
  106. ++spike;
  107. }
  108. }
  109. int FiringRateNormalize::prepare(int Step)
  110. {
  111. int i;
  112. for (i=0;i<NTarget;++i) PostSynLastFirings[i] -= MacroTimeStep;
  113. //FixMe: what if neuron never fires?? prevent negative integer overflow??
  114. }
  115. //////////////////////////////
  116. /*! \brief normalizing synapit weights if firing rates are above a threshold
  117. NormFrequency: above this spike frequency normalization occurs
  118. Weights are multiplied with (1-NormFactor)
  119. if spike frequency is higher then weight reduction is larger
  120. maximum: (1-NormFactor*MaxNormFactor)
  121. a look up table is used to determine the current normalization factor,
  122. depending on the current spike frequency (time difference DeltaT between current spike and last spike):
  123. NormLut(DeltaT)=1-MaxNormFactor*NormFactor*exp(-DeltaT/Tau),
  124. weight is multiplied with NormLut(DeltaT)
  125. @param _NormFrequency threshold frequency, above this frequency normalization occurs
  126. @param _NormFactor weight normalization factor,
  127. if postsynaptic neuron fires with _NormFrequency, synaptic weight is mulitiplied with 1-_NormFactor
  128. @param _MaxNormFactor maximal normalization: (1-NormFactor*MaxNormFactor)
  129. If postsynaptic neuron fires with frequency higher than _NormFrequency, the normalization is stronger.
  130. For infinite firing rate normalization strength can raise up to _MaxNormFactor times.
  131. @author (fm)
  132. */
  133. FiringRateNormalize2::FiringRateNormalize2(
  134. float _NormFrequency, float _NormFactor, float _MaxNormFactor)
  135. : PostSynLastFirings(0),
  136. MaxNormFactor(_MaxNormFactor),
  137. NormFactor(_NormFactor),
  138. NormFrequency(_NormFrequency)
  139. {
  140. NormDeltaT = 1000./(NormFrequency*dt);
  141. Tau = NormDeltaT/log(MaxNormFactor);
  142. // NormLut(DeltaT)=1-MaxNormFactor*NormFactor*exp(-DeltaT/Tau)
  143. NormLut = ExpDecayLut(NormLutN, Tau, -MaxNormFactor*NormFactor, 1, dt, NormDeltaT/Tau);
  144. cout << "FiringRateNormalization2\n";
  145. cout << "NormLut=" << "\n";
  146. for (int i=0;i<NormLutN;++i) cout << NormLut[i] << "\n";
  147. cout << " Factor=" << NormFactor << " MaxNormFactor=" << MaxNormFactor << " Tau=" << Tau*dt << " ms\n";
  148. }
  149. int FiringRateNormalize2::WriteSimInfo(fstream &fw)
  150. {
  151. stringstream sstr;
  152. sstr << "<MaxNormFactor value=\"" << MaxNormFactor << "\"/>\n";
  153. sstr << "<NormFrequency value=\"" << NormFrequency << "\"/>\n";
  154. sstr << "<NormFactor value=\"" << NormFactor << "\"/>\n";
  155. Normalize::WriteSimInfo(fw, sstr.str());
  156. }
  157. int FiringRateNormalize2::AddConnection(connection* newcon)
  158. {
  159. Normalize::AddConnection(newcon);
  160. if (PostSynLastFirings == 0)
  161. {
  162. PostSynLastFirings = new int [NTarget];
  163. int i;
  164. for (i=0;i<NTarget;++i)
  165. {
  166. PostSynLastFirings[i]=0;
  167. }
  168. }
  169. }
  170. int FiringRateNormalize2::proceede(int TotalTime)
  171. {
  172. int t = int(TotalTime % MacroTimeStep);
  173. int spike = Target->last_N_firings;
  174. int CurTarget;
  175. int i,j, TDiff;
  176. float NormFactor=1;
  177. while (spike < Target->N_firings) {
  178. CurTarget = Target->firings[spike][1];
  179. int TDiff = t-PostSynLastFirings[CurTarget];
  180. if (TDiff < NormLutN) {
  181. NormFactor = NormLut[TDiff];
  182. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  183. {
  184. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  185. }
  186. }
  187. PostSynLastFirings[CurTarget]=t;
  188. ++spike;
  189. }
  190. }
  191. int FiringRateNormalize2::prepare(int Step)
  192. {
  193. int i;
  194. for (i=0;i<NTarget;++i) PostSynLastFirings[i] -= MacroTimeStep;
  195. //FixMe: what if neuron never fires?? prevent negative integer overflow??
  196. }
  197. //////////////////////////////
  198. ConstSFNormalize::ConstSFNormalize(float _DesiredSpikeFreq, float _NormFactor, float _Tau)
  199. : PostSynFirePot(0), PostSynLastFirings(0), Tau(_Tau/dt)
  200. {
  201. cout << "ConstSFNormalization\n";
  202. cout << "DesiredSpikeFrequency=" << NormThreshold << " Factor=" << NormFactor << " Tau=" << Tau*dt << " ms\n";
  203. // one spike potential value
  204. float DeltaT = 1000./(_DesiredSpikeFreq*dt); // inter spike interval in number of time steps
  205. float DesiredSglSpikePot = exp(-DeltaT/Tau);
  206. // spike train equilibrium
  207. DesiredFirePot = 1/(1-exp(-DeltaT/Tau));
  208. NormFactor = _NormFactor/(DesiredFirePot-1);
  209. }
  210. int ConstSFNormalize::AddConnection(connection* newcon)
  211. {
  212. Normalize::AddConnection(newcon);
  213. if (PostSynFirePot == 0)
  214. {
  215. PostSynFirePot = new float [NTarget];
  216. PostSynLastFirings = new int [NTarget];
  217. int i;
  218. for (i=0;i<NTarget;++i)
  219. {
  220. PostSynFirePot[i]=0;
  221. PostSynLastFirings[i]=0;
  222. }
  223. }
  224. }
  225. int ConstSFNormalize::proceede(int TotalTime)
  226. {
  227. int t = int(TotalTime % MacroTimeStep);
  228. int spike = Target->last_N_firings;
  229. int CurTarget;
  230. int i,j;
  231. while (spike < Target->N_firings) {
  232. CurTarget = Target->firings[spike][1];
  233. PostSynFirePot[CurTarget] *= exp(-(t-PostSynLastFirings[CurTarget])/Tau);
  234. PostSynFirePot[CurTarget] += 1;
  235. PostSynLastFirings[CurTarget]=t;
  236. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  237. {
  238. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) += *((*it)->s_pre[CurTarget][i])*NormFactor*(DesiredFirePot-PostSynFirePot[CurTarget]);
  239. }
  240. ++spike;
  241. }
  242. }
  243. int ConstSFNormalize::prepare(int Step)
  244. {
  245. int i;
  246. for (i=0;i<NTarget;++i) PostSynLastFirings[i] -= MacroTimeStep;
  247. //FixMe: what if neuron never fires?? prevent negative integer overflow??
  248. }
  249. int ConstSFNormalize::WriteSimInfo(fstream &fw)
  250. {
  251. fw << "<" << seTypeString << " id=\"" << IdNumber << "\" Type=\"" << seType << "\" Name=\"" << Name << "\"> \n";
  252. fw << "<Target id=\"" << Target->IdNumber << "\"/> \n";
  253. fw << "<DesiredFirePot Value=\"" << DesiredFirePot << "\"/> \n";
  254. fw << "<NormFactor Value=\"" << NormFactor << "\"/> \n";
  255. fw << "</" << seTypeString << "> \n";
  256. }
  257. ///////////////////////////////////
  258. ConstSumNormalize::ConstSumNormalize(float _WeightSum, bool _quadratic)
  259. : WeightSum(_WeightSum), quadratic(_quadratic)
  260. {
  261. cout << "ConstSumNormalization\n";
  262. cout << "WeightSum=" << WeightSum << " quadratic=" << quadratic << " \n";
  263. }
  264. // int ConstSumNormalize::AddConnection(connection* newcon)
  265. // {
  266. // Normalize::AddConnection(newcon);
  267. // }
  268. int ConstSumNormalize::proceede(int TotalTime)
  269. {
  270. int t = int(TotalTime % MacroTimeStep);
  271. int spike = Target->last_N_firings;
  272. int CurTarget;
  273. int i,j;
  274. float CurWeightSum, NormFactor;
  275. float tmpweight;
  276. if (quadratic)
  277. {
  278. while (spike < Target->N_firings) {
  279. CurTarget = Target->firings[spike][1];
  280. // calculate WeightSum
  281. CurWeightSum=0;
  282. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  283. {
  284. for (i=0;i<(*it)->N_pre[CurTarget];++i) {
  285. tmpweight= (*((*it)->s_pre[CurTarget][i]));
  286. if (tmpweight <0) { // delete this thread
  287. cout << "EEEEEEEEEERRRROOORRR, weight deletion didn't work\n";
  288. fflush(stdout);
  289. exit(2);
  290. }
  291. CurWeightSum += (*((*it)->s_pre[CurTarget][i]))*(*((*it)->s_pre[CurTarget][i]));
  292. }
  293. }
  294. // DEBUG
  295. if (CurWeightSum > 100) {
  296. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  297. {
  298. cout << "N_pre=" << (*it)->N_pre[CurTarget] << "\n";
  299. for (i=0;i<(*it)->N_pre[CurTarget];++i) {
  300. tmpweight= (*((*it)->s_pre[CurTarget][i]));
  301. cout << "w"<< i << "=" << tmpweight << "I_pre=" << (*it)->I_pre[CurTarget][i] << "\n";
  302. }
  303. }
  304. fflush(stdout);
  305. exit(2);
  306. }
  307. // END DEBUG
  308. NormFactor = WeightSum/sqrt(CurWeightSum);
  309. cout << "NormFactor=" << NormFactor << "WeightSum" << CurWeightSum << "\n";
  310. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  311. {
  312. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  313. }
  314. ++spike;
  315. }
  316. }
  317. else {
  318. while (spike < Target->N_firings) {
  319. CurTarget = Target->firings[spike][1];
  320. // calculate WeightSum
  321. CurWeightSum=0;
  322. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  323. {
  324. for (i=0;i<(*it)->N_pre[CurTarget];++i) CurWeightSum += *((*it)->s_pre[CurTarget][i]);
  325. }
  326. NormFactor = WeightSum/CurWeightSum;
  327. // multiplicatively normalize weights
  328. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  329. {
  330. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  331. }
  332. ++spike;
  333. }
  334. }
  335. }
  336. int ConstSumNormalize::NormalizeAll()
  337. {
  338. cout << "Normalizing All ...";
  339. int CurTarget;
  340. int i,j;
  341. float CurWeightSum, NormFactor;
  342. if (quadratic)
  343. {
  344. for (CurTarget=0;CurTarget<Target->N;++CurTarget)
  345. {
  346. CurWeightSum=0; // wie oben
  347. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  348. {
  349. for (i=0;i<(*it)->N_pre[CurTarget];++i) CurWeightSum += (*((*it)->s_pre[CurTarget][i]))*(*((*it)->s_pre[CurTarget][i]));
  350. }
  351. NormFactor = WeightSum/sqrt(CurWeightSum);
  352. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  353. {
  354. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  355. }
  356. }
  357. }
  358. else {
  359. for (CurTarget=0;CurTarget<Target->N;++CurTarget)
  360. {
  361. // calculate WeightSum
  362. CurWeightSum=0;
  363. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  364. {
  365. for (i=0;i<(*it)->N_pre[CurTarget];++i) CurWeightSum += *((*it)->s_pre[CurTarget][i]);
  366. }
  367. NormFactor = WeightSum/CurWeightSum;
  368. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  369. {
  370. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  371. }
  372. }
  373. }
  374. cout << " [done]\n";
  375. }
  376. void ConstSumNormalize::CalcInitWeightSum()
  377. {
  378. cout << "Calculating Initial Weight Sum ...";
  379. int CurTarget;
  380. int i,j;
  381. float CurWeightSum, NormFactor;
  382. float TmpWeightSum=0;
  383. if (quadratic)
  384. {
  385. for (CurTarget=0;CurTarget<Target->N;++CurTarget)
  386. {
  387. CurWeightSum=0; // wie oben
  388. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  389. {
  390. for (i=0;i<(*it)->N_pre[CurTarget];++i) CurWeightSum += (*((*it)->s_pre[CurTarget][i]))*(*((*it)->s_pre[CurTarget][i]));
  391. }
  392. TmpWeightSum += sqrt(CurWeightSum);
  393. }
  394. WeightSum = TmpWeightSum/Target->N;
  395. }
  396. else {
  397. for (CurTarget=0;CurTarget<Target->N;++CurTarget)
  398. {
  399. // calculate WeightSum
  400. CurWeightSum=0;
  401. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  402. {
  403. for (i=0;i<(*it)->N_pre[CurTarget];++i) CurWeightSum += *((*it)->s_pre[CurTarget][i]);
  404. }
  405. TmpWeightSum += CurWeightSum;
  406. }
  407. WeightSum = TmpWeightSum/Target->N;
  408. }
  409. cout << " [done]\n";
  410. }
  411. float ConstSumNormalize::GetWeightSum()
  412. {
  413. return WeightSum;
  414. }
  415. int ConstSumNormalize::SetWeightSum(float NewWeightSum)
  416. {
  417. WeightSum=NewWeightSum;
  418. }
  419. int ConstSumNormalize::WriteSimInfo(fstream &fw)
  420. {
  421. stringstream sstr;
  422. sstr << "<WeightSum Value=\"" << WeightSum << "\"/> \n";
  423. sstr << "<Quadratic Value=\"" << quadratic << "\"/> \n";
  424. Normalize::WriteSimInfo(fw, sstr.str());
  425. }
  426. // int ConstSumNormalize::prepare(int Step)
  427. // {
  428. // }
  429. /////////////////////
  430. NormalizePsp::NormalizePsp(float _NormThresh, float _NormFactor)
  431. : NormThreshold(_NormThresh), NormFactor(_NormFactor), PspPot(0)
  432. {
  433. cout << "NormalizePsp\n";
  434. cout << "Thresh=" << NormThreshold << " Factor=" << NormFactor << "\n";
  435. }
  436. int NormalizePsp::AddConnection(connection* newcon)
  437. {
  438. Normalize::AddConnection(newcon);
  439. if (PspPot == 0)
  440. {
  441. PspPot = Target->GetPspPointer(csimInputChannel_AMPA); //ToDo: Info aus connectio nverwenden
  442. }
  443. }
  444. int NormalizePsp::proceede(int TotalTime)
  445. {
  446. int t = int(TotalTime % MacroTimeStep);
  447. int spike = Target->last_N_firings;
  448. int CurTarget;
  449. int i,j;
  450. while (spike < Target->N_firings) {
  451. CurTarget = Target->firings[spike][1];
  452. if (PspPot[CurTarget] > NormThreshold) {
  453. for(vector<connection*>::iterator it=ConList.begin(); it !=ConList.end(); ++it)
  454. {
  455. for (i=0;i<(*it)->N_pre[CurTarget];++i) *((*it)->s_pre[CurTarget][i]) *= NormFactor;
  456. }
  457. }
  458. ++spike;
  459. }
  460. }
  461. int NormalizePsp::WriteSimInfo(fstream &fw)
  462. {
  463. stringstream sstr;
  464. sstr << "<NormThreshold Value=\"" << NormThreshold << "\"/> \n";
  465. sstr << "<NormFactor Value=\"" << NormFactor << "\"/> \n";
  466. Normalize::WriteSimInfo(fw, sstr.str());
  467. }