#include "mex.h" /* for mex */ #include "math.h" /* for exp */ #include "stdlib.h" /* for qsort */ #define PK1(i_,t_) ( exp(-t_ / *(Alph+i_)) ) #define PK2(i_,t_) ( exp(-t_ / *(Beta+i_)) ) #define PU3(i_,t_) ( exp(-t_**(g+i_)*c) ) #define PU2(i_,pu3_,pk2_) ( c**(Beta+i_) * ( pu3_ - pk2_ ) / (*(Beta+i_)**(g+i_)*c-1) ) #define PU1(i_,pu3_,pk1_) ( c**(Alph+i_) * ( pk1_ - pu3_ ) / (*(Alph+i_)**(g+i_)*c-1) ) static int comp_st(const void *p1, const void *p2) { double **m1 = (double **)p1; double **m2 = (double **)p2; if(*(*m1+1) < *(*m2+1)) /* index 1 is spike time */ return -1; else return 1; } void snmex( double *IS, double *K, double *KD, double *St, double *TS, double *U, double *UD, double *Wv, const double *Alph, const double *Beta, const double bin_sze, const double c, const mxArray *cell_In, const mxArray *cell_Out, const mxArray *cell_pIn, const mxArray *cell_pOut, const double delta_t, const uint32_T *D, const double eta_wpos, const double eta_wneg, const double *g, const mxLogical *Ih, const int max_d, const int max_ps, const int mem, const int n, const int stdp_rule, const double t_rfr, const int t_sim, const double tau_pos, const double tau_neg, const double *Uthr, const double *Urst, const double v0, const double w_max) { int *Ind_s, ps, h, i, j, t_delay, t_delay_i, t_, neg, num_s, ind_s, k_in, k_out, a_h, w_h; double **S_it, *U0, *K0, *Pk1, *Pk2, *Pu1, *Pu2, *Pu3; double t, t_em, t1, pk1, pk2, pu1, pu2, pu3, pk1_em, pk2_em, delta_w, k0; uint32_T *In, *Out, *pIn, *pOut; U0 = (double *)mxMalloc(n*sizeof(double)); K0 = (double *)mxMalloc(2*n*sizeof(double)); Pk1 = (double *)mxMalloc(n*sizeof(double)); Pk2 = (double *)mxMalloc(n*sizeof(double)); Pu1 = (double *)mxMalloc(n*sizeof(double)); Pu2 = (double *)mxMalloc(n*sizeof(double)); Pu3 = (double *)mxMalloc(n*sizeof(double)); Ind_s = (int *)mxMalloc(n*sizeof(double)); S_it = (double **)mxMalloc(n*sizeof(double *)); for(i=0; i t_rfr){ /* emerging neurons */ t_em = *(St+i) + t_rfr + delta_t - t; /* CAREFUL, MACROS: PROTECT ALL INPUTS */ pk1_em = PK1(i,t_em)**(K0+i); pk2_em = PK2(i,t_em)**(K0+n+i); t_ = delta_t-t_em; pk1 = PK1(i,t_); pk2 = PK2(i,t_); pu3 = PU3(i,t_); pu2 = PU2(i,pu3,pk2); pu1 = PU1(i,pu3,pk1); *(U+i) *= pu3; *(U+i) += pu1*pk1_em + pu2*pk2_em; *(U+i) += *(UD+n*t_delay+i)*(1-t_em/delta_t); } } for(i=0; i*(Uthr+i)) *(Ind_s+num_s++)=i; if(num_s){ /* process spikes */ for(i=0; iw_max) *(Wv+w_h)=w_max; break; default: mexErrMsgTxt("STDP rule is not recognized."); } } for(h=0; h= max_ps) mexErrMsgTxt("Out of spike memory.\n"); } } } mxFree(U0); mxFree(K0); mxFree(Pk1); mxFree(Pk2); mxFree(Pu1); mxFree(Pu2); mxFree(Pu3); mxFree(Ind_s); for(i=0; i0 && i<5 && !mxIsCell(mxGetFieldByNumber(pn,0,i))) mexErrMsgTxt("Cells must be cells."); else if(i==5 && !mxIsLogical(mxGetFieldByNumber(pn,0,i))) mexErrMsgTxt("Logicals must be logical."); else if(i>5 && !mxIsDouble(mxGetFieldByNumber(pn,0,i))) mexErrMsgTxt("Doubles must be double."); if(!i) mexErrMsgTxt("Structure must be a structure."); cell_In = mxGetField(pn,0,"In"); cell_Out = mxGetField(pn,0,"Out"); cell_pIn = mxGetField(pn,0,"pIn"); cell_pOut = mxGetField(pn,0,"pOut"); g = mxGetPr(mxGetField(pn,0,"g")); Alph = mxGetPr(mxGetField(pn,0,"alpha")); Beta = mxGetPr(mxGetField(pn,0,"beta")); Ih = (mxLogical*)mxGetData(mxGetField(pn,0,"ih")); Uthr = mxGetPr(mexGetVariablePtr("caller","Uthr")); Urst = mxGetPr(mexGetVariablePtr("caller","Urest")); D = (uint32_T *)mxGetData(mexGetVariablePtr("caller","D")); n = 0.5 + *mxGetPr(mxGetField(pn,0,"N")); t_sim = 0.5 + *mxGetPr(mxGetField(pn,0,"T")); delta_t = *mxGetPr(mxGetField(pn,0,"delta_t")); bin_sze = *mxGetPr(mxGetField(pn,0,"bin_size")); c = *mxGetPr(mxGetField(pn,0,"c")); t_rfr = *mxGetPr(mxGetField(pn,0,"Trefr")); v0 = *mxGetPr(mxGetField(pn,0,"V0")); max_d = 0.5 + *mxGetPr(mexGetVariablePtr("caller","max_D")); stdp_rule = 0.5 + *mxGetPr(mxGetField(pn,0,"stdp_rule")); eta_wpos = *mxGetPr(mxGetField(pn,0,"Eta"))**mxGetPr(mxGetField(pn,0,"w_pos")); eta_wneg = *mxGetPr(mxGetField(pn,0,"Eta"))**mxGetPr(mxGetField(pn,0,"w_neg")); w_max = *mxGetPr(mxGetField(pn,0,"w_max")); tau_pos = *mxGetPr(mxGetField(pn,0,"tau_pos")); tau_neg = *mxGetPr(mxGetField(pn,0,"tau_neg")); mem = 0.5 + *mxGetPr(mexGetVariablePtr("caller","memory")); mxU = mexGetVariable("caller","U"); mxK = mexGetVariable("caller","K"); mxUD = mexGetVariable("caller","UD"); mxKD = mexGetVariable("caller","KD"); mxSt = mexGetVariable("caller","St"); mxWv = mexGetVariable("caller","Wv"); mxIS = mexGetVariable("caller","IS"); mxTS = mexGetVariable("caller","TS"); max_ps = mxGetNumberOfElements(mxIS); U = mxGetPr(mxU); K = mxGetPr(mxK); UD = mxGetPr(mxUD); KD = mxGetPr(mxKD); St = mxGetPr(mxSt); Wv = mxGetPr(mxWv); IS = mxGetPr(mxIS); TS = mxGetPr(mxTS); snmex(IS, K, KD, St, TS, U, UD, Wv, Alph, Beta, bin_sze, c, cell_In, cell_Out, cell_pIn, cell_pOut, delta_t, D, eta_wpos, eta_wneg, g, Ih, max_d, max_ps, mem, n, stdp_rule, t_rfr, t_sim, tau_pos, tau_neg, Uthr, Urst, v0, w_max); mexPutVariable("caller","U", mxU ); mexPutVariable("caller","K", mxK ); mexPutVariable("caller","UD",mxUD); mexPutVariable("caller","KD",mxKD); mexPutVariable("caller","St",mxSt); mexPutVariable("caller","Wv",mxWv); mexPutVariable("caller","IS",mxIS); mexPutVariable("caller","TS",mxTS); }