#ifndef _define_h_
#define _define_h_
#include<iostream.h>
#include<iomanip.h>
#include<fstream.h>
#include<math.h>
#include <vector>
#include<string>
#include<cstring>
#include<sstream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "../../Neuron.h"
#include "../../Synapse.h"
#include "../../rk4.h"
#include "../../Insynapse/Insynapse.h"
#include "../../Insynapse/Insynapse.cc"
#include "../../HHneuron/HHneuron.h"
#include "../../Izhineuron/Izhineuron.h"
#include "../../Rose/Rose.h"
#include "../../TwoDsynapse/TwoDsynapse.h"
#include "../../Henrysynapse/Henrysynapse.h"
#include "../../Ihcurrent/Ih.h"
#include "../../IAcurrent/IA.h"
#include "../../IMcurrent/IM.h"
#include "../../matrix.h"
#include "../../Calciumchannel.h"
#include "../../ITcalcium/IT.h"
#include "../../randomc.h"
#include "../../PDrule/PD.h"
#include "../../Couplingcurrent/Couplingcurrent.h"
#include "../../Connectivity.h"
#include "../../IOpto/IOpto.h"
#include <time.h>
#include <algorithm>
#include <vector>
#define N 4
#ifndef _NO_NAMESPACE
using namespace std;
using namespace math;
#define STD std
#else
#define STD
#endif
#ifndef _NO_TEMPLATE
typedef matrix < double >Matrix;
#else
typedef matrix Matrix;
#endif
/*
Function Spikecount : Stores the times, in the dynamics when v>vpeak..
Basically stores the ISI for Izhikevich type models where u have resetting of the function
when it exceeds certian peak.
Function ISI, computes the average interspike interval from the data generated out of spikecount
Function Max_vect, Min_vect computes the max and min from vector
Function Entropy : Divides the entire range of frequencies, into N bins, and computes the
probability of each bin. From that determines the std informatio entropy. The output is the
Relative entropy which is the Entropy computed divided by the max entropy=log(Nbins)
Function Complexity: Takes in the computed Relative Entropy and spits out, the Complexity
measure: Which characterises the amount of order and disorder in the network.
*/
string IntToStdStr(const int d)
{
std::ostringstream ostr;
ostr << d;
return ostr.str();
}
string DoubleToStdStr(const double d)
{
std::ostringstream ostr;
ostr << d;
return ostr.str();
}
void GeneratePulseData(int Num,double StartTime, double Width, double DutyCycle,vector<double> &TON,vector<double>&TOFF)
{
for (int i=0;i<Num;i++)
{
TON.push_back(StartTime+i*(Width+DutyCycle));
TOFF.push_back(StartTime+Width+i*(Width+DutyCycle));
}
}
double Heaviside(double x)
{
double Out;
if (x>=0)
Out=1;
else
Out=0;
return(Out);
}
double GetPulse(vector<double> TON,vector<double> TOFF,double &tim)
{
double pulse=0;
for (int i=0;i<TON.size();i++)
pulse=pulse+Heaviside(tim-TON[i])*Heaviside(TOFF[i]-tim);
return pulse;
}
double GetPhaseDiff(double &Ref,vector<double>&B)
{
vector<double> Diff;
double Temp;
int bul=0;
int start=0;
if (B.size()<20)
start=0;
else
start=B.size()-20;
for (int i=start;i<B.size();i++)
Diff.push_back(Ref-B[i]);
sort(Diff.begin(),Diff.end());
for (int i=0;i<Diff.size();i++)
{
if (Diff[i]>0 && bul==0)
{
Temp=Diff[i];
bul=1;
}
}
return Temp;
}
double
ISI (vector < double >&y,double Time)
{
vector < double >s;
double average, sum;
int sze;
sze=y.size();
sum = 0;
if (sze>=2)
{
for (unsigned int i = 1; i < y.size (); i++)
{
if (y[i-1]>Time) //eliminates the transient upto 200 msec
s.push_back (y[i] - y[i - 1]);
}
for (unsigned int i = 0; i < s.size (); i++)
sum = sum + s[i];
average = sum / (s.size ());
// cout<<sum<<" "<<s.size()<<" "<<y.size()<<" "<<average<<endl;
}
else
{
cout<<"insufficient spike increase duration of time or the neuron did not spike "<<endl;
average=0;
}
s.clear();
return (average);
}
double
max_vect (vector < double >&y)
{
double val = 0;
for (unsigned int i = 0; i < y.size (); i++)
{
val = max (y[i], val);
}
return (val);
}
double
min_vect (vector < double >&y)
{
double val = 0;
for (unsigned int i = 0; i < y.size (); i++)
{
if (val != 0)
val = min (y[i], val);
}
return (val);
}
double
Spikepresent (double *tim, double *v, double threshold, double spikewidth,
double vpeak, int &boolean, double *spiketrigger)
{
double spike = 0;
if (*tim > 0 && *v > threshold && boolean == 0)
{
boolean = 1;
spiketrigger[0] = *tim;
}
if (*tim >= spiketrigger[0] && *tim <= spiketrigger[0] + spikewidth)
{
spike = 1;
}
if (*v > vpeak)
boolean = 0;
return (spike);
}
void
Fread (char *y, Matrix & M, int Ntotal)
{
ifstream fread;
vector < double >read (Ntotal, 0);
int row = 0;
fread.open (y, ios::in);
for (int i = 0; i < Ntotal; i++)
fread >> read[i];
if (!fread)
{
cerr << "error in opening" << endl;
exit (0);
}
while (!fread.eof ())
{
for (int j = 0; j < Ntotal; j++)
{
M (row, j) = read[j];
}
for (int j = 0; j < Ntotal; j++)
fread >> read[j];
row += 1;
}
}
/****Function to compute spike times for any given spike train****/
void
spiketimes (double *tim, double *v, double Th, int &bol, vector < double >&y)
{
if (*v > Th && bol == 0)
{
y.push_back (*tim);
bol=1;
}
if (*v <= Th)
bol = 0;
}
double
RuleInhib (double x, double a, double b, double c, double d,double strength)
{
double out, outmax, outmax1;
outmax = pow (a / b, a) * exp (-a);
outmax1 = pow (c / d, c) * exp (-c);
if (x > 0)
out = strength * (pow (x, 1. * a) * exp (-b * fabs (x))) / outmax;
else
{
if (fmod (c, 2.0) == 0)
{
out = -strength * (pow (x, c) * exp (-d * fabs (x))) / (1 * outmax1);
}
else
{
out = strength * (pow (x, c) * exp (-d * fabs (x))) / (1 * outmax1);
}
}
return out;
}
double RuleExcite(double x,double ap,double ad,double bp,double bd,double eta,double strength)
{
double out, A,B;
A=strength*ap*pow(ad,eta)/(bp+eta*bd);
B=strength*ad*pow(ap,eta)/(eta*bp+bd);
if (x>=0)
out=A*exp(-bp*x)-B*exp(-eta*bp*x);
else
out=A*exp(eta*bd*x)-B*exp(bd*x);
return out;
}
double box_muller (double m, double s, int32 seed) /* normal random variate generator */
{
/* mean m, standard deviation s */
double y1,y2,x1,x2,w=2;
TRandomMersenne rg(seed);
do{
x1=2*rg.Random()-1;
x2=2*rg.Random()-1;
w=x1*x1+x2*x2;
}while(w>=1);
w = sqrt( (-2.0 * log( w ) ) / w );
y1 = x1 * w;
y2 = x2 * w;
return (m + y1 * s);
}
double
Average (vector < double >y)
{
double result;
double sum = 0;
int k = y.size ();
if (k != 0)
{
for (int i = 0; i < k; i++)
sum = sum + y[i];
result = sum / k;
}
else
result = 0.0;
return (result);
}
double Variance(vector <double>y)
{
double result,Temp,Avg;
double sum=0;
for (int i=0;i<y.size();i++)
sum=sum+y[i]*y[i];
Temp=sum/y.size();
Avg=Average(y);
result=Temp-Avg*Avg;
return(result);
}
void
Raster (ofstream & Outfile, double &tim, int &bul, double &volt,
double threshold, int &i)
{
//rastercomputation
//takes in the outfile file, tim, bul: a boolean number, volt the neurons spiking, the threshold to detect spike, and spits out the time of neuron "i" firing
bul = 0;
if (volt > threshold && bul == 0)
{
Outfile << tim << " " << i + 1 << endl;
bul = 1;
}
else;
}
void
alpha_syn (double *tim, double g, double alph, vector < double >&Tspk,
vector < double >&sum, int &i)
{
double *x;
x = new double[1000];
for (unsigned int j = 0; j < Tspk.size (); j++)
{
x[j] = *tim - Tspk[j];
if (x[j] > 0)
{
sum[i] = sum[i] + g * x[j] * alph * alph * exp (-alph * x[j]);
}
}
delete x;
}
double
Maprule (vector < double >Tpre, vector < double >Tpost, double a, double b,
double c, double d)
{
double out = 0;
double diff;
vector < double >Result;
int sizeTpost = Tpost.size ();
if (sizeTpost == 1)
{
for (unsigned int j = 0; j < Tpre.size (); j++)
{
diff = Tpost[0] - Tpre[j];
Result.push_back (diff);
}
}
if (sizeTpost==2||sizeTpost>2)
{
for (unsigned int j=0;j<Tpre.size();j++)
{
if (Tpre[j]<Tpost[0])
diff=Tpost[0]-Tpre[j];
else if(Tpre[j]>Tpost[1])
diff=Tpost[1]-Tpre[j];
else if (Tpre[j]>=Tpost[0] && Tpre[j]<=Tpost[1])
{
diff=Tpost[0]-Tpre[j];
Result.push_back(diff);
diff=Tpost[1]-Tpre[j];
}
else;
Result.push_back(diff);
}
}
/* double wold = 1000;
if (sizeTpost >= 2)
{
for (int j = 1; j < Tpre.size (); j++)
{
wold=1000;
for (int i = 0; i < sizeTpost; i++)
{
double u = Tpost[i] - Tpre[j];
// cout << " " << sizeTpost << " " << Tpre.
// size () << " " << u << endl;
if (fabs (u) >= 3 && fabs (u) < fabs (wold))
wold=u;
else;
}
diff = wold;
// cout << diff << endl;
Result.push_back (diff);
}
}
*/
for (unsigned int j = 0; j < Result.size (); j++)
out += RuleInhib (Result[j], a, b, c, d,.5);
//out+=Rule(Result[j],3.0,.5,5.0,.25);
return (out);
}
void
Pulsedetect (double *tim, vector < double >&Tspike, int &count, double &pulse)
{
for (unsigned int j = 0; j < Tspike.size (); j++)
{
if (*tim > Tspike[count] + .5)
count += 1;
if (*tim > Tspike[count] && *tim < Tspike[count] + .5)
pulse = 1;
else
pulse = 0;
}
}
double Kuramoto(vector<double> &Tpre,vector<double> &Tpost,double period)
{
double phaseterm, costerm, sinterm, cossum = 0, sinsum = 0, kura;
double size=min(Tpre.size(),Tpost.size());
for (int i = 0; i < size; i++)
{
phaseterm = fmod (fabs (Tpost[i] - Tpre[i]), period);
costerm = cos (phaseterm);
sinterm = sin (phaseterm);
cossum += costerm;
sinsum += sinterm;
}
kura = sqrt (cossum * cossum + sinsum * sinsum) / size;
return(kura);
}
void
SlowRise (double &tim,double Threshold, double &volt, int &bul, double tauR,double &ref_time, double &out)
{
if (volt > Threshold && bul==0)
{ ref_time=tim;
// cout<<ref_time<<endl;
}
if (volt>Threshold)
bul = 1;
else bul=0;
if (tim >= ref_time && tim < ref_time + tauR)
{out = 1.0;}
else
out = 0.0;
}
double Phase_Compute(double pre,double post,double period)
{
double phase,inter;
inter=fabs((pre-post));
phase=fmod(inter,period);
//phase=(pre-post)-floor(inter)*period;
return(phase);
}
void ReadNetwork(string Y,int row,int column,double **A)
{
ifstream DataFile;
DataFile.open((char *)Y.c_str(),ios::in);
int Man,Nan;
double Temp;
while(!DataFile.eof())
{
DataFile>>Man>>Nan>>Temp;
A[Man-1][Nan-1]=Temp/Temp;
}
DataFile.close();
}
void SumMatrixColumn(double **A,int NN,int MM,vector<double>&ColumnSum)
{
double sum;
for (int i=0;i<NN;i++)
{
sum=0;
for (int j=0;j<MM;j++)
{sum=sum+A[i][j];}
ColumnSum.push_back(sum);
}
}
void SumMatrixRow(double **A,int NN,int MM,vector<double>&RowSum)
{
double sum;
for (int j=0;j<MM;j++)
{
sum=0;
for (int i=0;i<NN;i++)
sum=sum+A[i][j];
RowSum.push_back(sum);
}
}
void GeneratePoisson(double endtime,double Rate,vector<double>&Poisson,int32 seed)
{
//int32 seed = time(NULL);
double Temp,Exp;
double sum=0;
TRandomMersenne rg(seed);
while(sum<endtime)
{
Temp=rg.Random();
Exp=(1000/Rate)*log(1/(1-Temp));
if (Exp>1) //account for refractory period;
{
sum=sum+Exp;
Poisson.push_back(sum);
}
}
}
double HenrySpikeGen(double tim, vector<double>Poisson,int *count)
{
double Out=0;
if (tim>Poisson[*count])
{
if (tim<Poisson[*count]+.75)
Out=1;
else if (tim>=Poisson[*count]+.75& tim<Poisson[*count]+.75+.02)
*count+=1;
}
return Out;
}
double DelayBuff(vector<double>&Data,double volt)
{
double out;
if (Data.size()==0)
out=volt;
else
{
Data.erase(Data.begin());
Data.push_back(volt);
out=Data[0];
}
return out;
}
int ActiveNeurons(vector<double>*y,int MM,double Tim)
{
int Out=0;
int count;
for (int i=0;i<MM;i++)
{
count=0;
while(count<y[i].size())
{
if (y[i][count]>=Tim)
{
count=y[i].size();
Out=Out+1;
}
else
{
count=count+1;
}
}
}
return (Out);
}
void IniConditionForDelay(int Num,vector<double>&PhiIniSpikes,int32 seed)
{
int BulSp=1;
int RanOld=0;
int RanNew=0;
TRandomMersenne rg(seed);
double Siz=PhiIniSpikes.size();
while(Siz<Num)
{
if (BulSp)
{
RanNew=rg.IRandom(1,50);
if (fabs(double(RanNew)-double(RanOld))>=2)
BulSp=0;
}
if (~BulSp)
{
PhiIniSpikes.push_back(RanNew/epsilon);
BulSp=1;
}
Siz=PhiIniSpikes.size();
}
sort(PhiIniSpikes.begin(),PhiIniSpikes.end());
}
#endif