""" /***********************************************************************************************************\ This Cython script associated with paper: Ruben Tikidji-Hamburyan , Tarek El-Ghazawi , Jason Triplett Novel Models of Visual Topographic Map Alignment into Superior Colliculus Copyright: Ruben Tikidji-Hamburyan <rath@gwu.edu> Apr.2016 - Sep.2016 \************************************************************************************************************/ """ from __future__ import division import numpy as np cimport numpy as np import sys,os from libc.math cimport sqrt,exp,floor from libc.stdlib cimport rand,srand,RAND_MAX,malloc from libc.stdio cimport * import time PTYPE = np.uint DTYPE = np.float64 ctypedef np.uint_t PTYPE_T ctypedef np.float64_t DTYPE_T cdef extern from "stdio.h": #FILE * fopen ( const char * filename, const char * mode ) FILE *fopen(const char *, const char *) #int fclose ( FILE * stream ) int fclose(FILE *) #int fprintf(FILE *stream, const char *format, ...) int fprintf(FILE *, const char *, ...) #void * malloc( #Afinity cdef double cAaf = 20., cBaf = 30. #Competition cdef double cApr = 5., cBpr = 1., cDpr = 1. #Activity cdef double cBca = 11., cGca = 200., cRca = 3, cVca=11, cSca=1., cA2Pca=1.5 #??? cdef unsigned int xsize, ysize, Nstep, ic_sizeX, ic_sizeY cdef double xscl = 0, yscl = 0 cdef unsigned int cNorm, Don=1, Den3sigma=0 cdef double *pDf=NULL, *pLf=NULL cdef inline double FdEpr(PTYPE_T na, unsigned long nd): return cBpr*na**2-cApr*sqrt(na) + cDpr*nd**2 cdef inline double FdEaf(long xs, long ys, long xl, long yl, PTYPE_T p ): return ( cAaf*exp(float(xs)*xscl-1.)*exp(-float(xl)*xscl ) \ - cBaf*exp(float(ys)*yscl-1.)*exp( float(yl)*yscl-1.) )*float(p) cdef inline double Lfactor(long xs, long ys, long xl, long yl, double sigma): return exp( - sqrt( float( (xs-xl)**2 + (ys-yl)**2 ) ) / sigma ) cdef inline double Dfactor(long xs, long ys, long xl, long yl, double sigma): if Don: return exp( - float( (xs-xl)**2 + (ys-yl)**2 ) / (2. * sigma**2) ) else: return 1.0 cdef inline double FdEcaW(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): cdef double norm = Dfactor(xs,ys,xl,yl,cVca) * add, res = norm, df cdef unsigned int xls, yls for xls in xrange(xsize): for yls in xrange(ysize): if p[xs,ys,xls,yls] == 0: continue df = Dfactor(xs,ys,xls,yls,cVca) * float(p[xs,ys,xls,yls]) res += Lfactor(xl,yl,xls,yls,cBca) * df norm += df if norm > 0. and cNorm: res /= norm res += cRca*exp( - sqrt( (float(xs-xl)/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) ) return - cGca * res cdef inline double FdEcaM(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): cdef double norm = Dfactor(xs,ys,xl,yl,cVca) * add, res = norm, df cdef unsigned int xls, yls for xls in xrange(xsize): for yls in xrange(ysize): if p[xs,ys,xls,yls] == 0: continue df = Dfactor(xs,ys,xls,yls,cVca) * float(p[xs,ys,xls,yls]) res += Lfactor(xl,yl,xls,yls,cBca) * df norm += df if norm > 0. and cNorm: res /= norm res += cRca * (\ cA2Pca * exp( - sqrt( (float(xs-xl*0.5 )/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) )\ + exp( - sqrt( (float(xs-xl*0.5-xsize/2)/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) )\ ) return - cGca * res cdef inline double FdEcaW_JC(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): return - cGca * exp( - sqrt(float((xs-xl)**2+(ys-yl)**2))/cBca /cSca ) cdef inline double FdEcaM_JC(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): return - cGca * (\ cA2Pca * exp( - sqrt( (float(xs-xl*0.5 )/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) )\ + exp( - sqrt( (float(xs-xl*0.5-xsize/2)/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) )\ ) cdef inline double FdEcaW_SC(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): cdef double res = 0. cdef unsigned int xls, yls for xls in xrange(xsize): for yls in xrange(ysize): res += exp( - sqrt( (float(xs-xls)/cBca/cSca)**2 + (float(ys-yls)/cBca)**2 ) ) * Dfactor(xs,ys,xls,yls,cRca) return - cGca * res cdef inline double FdEcaM_SC(long xs, long ys, long xl, long yl, float add, np.ndarray[PTYPE_T, ndim=4] p): cdef double res = 0. cdef unsigned int xls, yls for xls in xrange(xsize): for yls in xrange(ysize): res += cA2Pca * exp( - sqrt( (float(xs-xl*0.5 )/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) ) * Dfactor(xs,ys,int(xl*0.5 ),yl,cRca) res += exp( - sqrt( (float(xs-xl*0.5-xsize/2)/cBca/cSca)**2 + (float(ys-yl)/cBca)**2 ) ) * Dfactor(xs,ys,int(xl*0.5-xsize/2),yl,cRca) return - cGca * res cdef inline double random(): return float(rand())/float(RAND_MAX) cdef inline unsigned int randint( unsigned int maxi): cdef unsigned int x = int( floor( float(rand()) * float(maxi) / float(RAND_MAX) ) ) if x >= maxi: return maxi-1 if x < 0 : return 0 return x def chaser(ixsize, iysize, iNstep, E12 = 1e5, Aaf = 20., Baf = 30., Bca = 11., Gca = 200., Rca=3., Vca=11., Sca=1., A2Pca=1.5, Apr = 5., Bpr = 1., Dpr = 1., TotalEnergy = False, Init = 'RANDOM', StartRec = False, StopRec = True, Knocked = False, Indicator = False, Log = True, Reporting = False, Graphs = False, RunDB = True, Model = 3 , Norm = True, ParentDir = "" , timestemp = "" ): global xscl, yscl global cAaf,cBaf,cApr,cBpr,cDpr,cBca,cGca,cRca,cVca,cSca,cA2Pca global xsize, ysize, Nstep, ic_sizeX, ic_sizeY global cNorm, Don, Den3sigma global pDf,pLf cAaf,cBaf,cApr,cBpr,cDpr,cBca,cGca,cRca,cVca,cSca, cA2Pca = Aaf,Baf,Apr,Bpr,Dpr,Bca,Gca,Rca,Vca,Sca,A2Pca xsize, ysize, Nstep = ixsize, iysize, iNstep cNorm = Norm cdef unsigned int fTotalEnergy = int(TotalEnergy),\ fIndicator = int(Indicator),\ fLog = int(Log),\ fReporting = int(Reporting),\ nGraphs = 0 cdef double cE12 = E12 timestemp_t = timestemp.encode("UTF-8") cdef char *timestemp_c = timestemp_t filenameprefix = ParentDir + timestemp xscl = 1./float(xsize) yscl = 1./float(ysize) cdef FILE *log = NULL logfilename_t = filenameprefix+"-log.csv" logfilename_t = logfilename_t.encode("UTF-8") cdef char *logfilename = logfilename_t cdef FILE *recdb = NULL redbfilename_t = filenameprefix+"-rec.db" redbfilename_t = redbfilename_t.encode("UTF-8") cdef char *redbfilename = redbfilename_t cdef long xs, ys, xl, yl, Niter, itr_c = 0, npos=0 cdef np.ndarray[long, ndim=1] pXs, pYs, pXl, pYl cdef double Epr=0., Eaf=0., Eca=0., E=0. if Model == 5: Den3sigma = int( np.ceil(cVca*3) ) pDf = <double *>malloc(Den3sigma**2*sizeof(double)) for xl in xrange(Den3sigma): for yl in xrange(Den3sigma): pDf[xl+yl*Den3sigma] = exp( - float( xl**2 + yl**2 ) / (2. * cVca**2) ) pLf = <double *>malloc(xsize*ysize*sizeof(double)) for xl in xrange(xsize): for yl in xrange(ysize): pLf[xl+yl*xsize ] = exp( - sqrt( float( xl**2 + yl**2 ) ) / cBca ) #Backword compability if type(Init) is bool: Init = "RANDOM" if Init else None if Graphs: if type(Graphs) is bool: nGraphs = 20 elif type(Graphs) is float: nGraphs = int(xsize*ysize*Graphs) elif type(Graphs) is int: nGraphs = int(Graphs) if RunDB: if not type(RunDB) is str: RunDB = timestemp + "-rundb.csv" print "#############################" print "# :MODEL ID: #" print " > Time Stamp :",timestemp print "# :PARAMETERS: #" print " > Aaf :",cAaf print " > Baf :",cBaf print " > Apr :",cApr print " > Bpr :",cBpr print " > Dpr :",cDpr print " > Bca :",cBca print " > Gca :",cGca print " > Rca :",cRca print " > Vca :",cVca print " > Sca :",cSca print " > A2Pca :",cA2Pca print " > XxY :",xsize,"x",ysize print " > Nstep :",Nstep print " > E1/2 :",cE12 print "# :FLAGS: #" print " > Model :",Model, if Model == 1: print "(Just Correlation)" elif Model == 2: print "(Sclaed Correlation)" elif Model == 3: print "(V1 and Retinal Inputs Interation)" elif Model == 4: print "(V1 and Retinal Inputs Interation withput convolution)" print " > Normalization :",bool(cNorm) print " > Knocked :",Knocked print " > TotalEnergy :",bool(fTotalEnergy) print " > Init :",Init print " > StartRec :",StartRec print " > StopRec :",StopRec print " > Log :",bool(fLog) print " > Reporting :",bool(fReporting) if fReporting: print " > every iter :",fReporting print " > Graphs :",bool(nGraphs) if nGraphs: print " > rendom cells:",nGraphs print " > Indicator :",bool(fIndicator) print "# :PATHS: #" print " > ParentDir :",ParentDir print " > Prefix :",filenameprefix print "# :FILES: #" if fLog: print " > Log :",logfilename if StartRec or StopRec or bool(fReporting): print " > Record :",redbfilename print " > RunDB :",RunDB print "#############################\n" if type(RunDB) is str: with open(RunDB,"a") as fd: #TIMESTEMP,xsize,ysize,Aaf,Baf,Bca,Gca,Rca,Vca,Sca,A2Pca,Apr,Bpr,Dpr,E12,Nstep,Knocked,TotalEnergy,Init,Record,Log,StartRec,StopRec,Report,Indicator,Model,Normalization fd.write("%s,%d,%d,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%g,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n"%(\ timestemp,xsize,ysize,\ Aaf,Baf,Bca,Gca,Rca,Vca,Sca,A2Pca,Apr, Bpr, Dpr,\ E12,Nstep,\ "Y" if Knocked else "N", "Y" if bool(fTotalEnergy) else "N", Init, filenameprefix+"-rec.db" if StartRec or StopRec or bool(fReporting) else "N", filenameprefix+"-log.csv" if bool(fLog) else "N", "Y" if StartRec else "N", "Y" if StopRec else "N", str(fReporting) if bool(fReporting) else "N", "Y" if bool(fIndicator) else "N", "JC" if Model == 1 else "SC" if Model == 2 else "INT" if Model == 3 else "INT-D" if Model == 4 else "DI", "Y" if bool(cNorm) else 'N' ) ) ### Squared distances #cBca,cSca = cBca**2,cSca**2 print "#############################" print "# Create synaptic densities #" cdef np.ndarray[PTYPE_T, ndim=2] ax = np.zeros((xsize, ysize),dtype=PTYPE) cdef np.ndarray[PTYPE_T, ndim=2] dn = np.zeros((xsize, ysize),dtype=PTYPE) cdef np.ndarray[PTYPE_T, ndim=4] p = np.zeros([xsize,ysize,xsize,ysize], dtype=PTYPE) print "# DONE #" print "#############################\n" if Knocked: if Model == 1: FdEca = FdEcaM_JC elif Model == 2: FdEca = FdEcaM_SC elif Model == 3: FdEca = FdEcaM elif Model == 4: FdEca = FdEcaM Don = 0 else: FdEca = FdEcaM else: if Model == 1: FdEca = FdEcaW_JC elif Model == 2: FdEca = FdEcaW_SC elif Model == 3: FdEca = FdEcaW elif Model == 4: FdEca = FdEcaW Don = 0 else: FdEca = FdEcaW srand( np.random.randint( RAND_MAX ) ) if Init == "RANDOM": print "#############################" print "# Random Initialization #" Niter = int( xsize * ysize * 50) # half of population for i in xrange(Niter): xs = randint(xsize) ys = randint(ysize) xl = randint(xsize) yl = randint(ysize) ax[xs,ys] += 1 dn[xl,yl] += 1 p[xs,ys,xl,yl] += 1 print "# DONE #" print "#############################\n" elif Init == None: pass else: if type(Init) is str: Init = (Init,-1) if len(Init) < 2: Init = (Init, -1) print "#############################" print "# Init conditions from File #" print " > File :", Init[0] print " > Fentch record :", Init[1],type(Init[1]) lastrec = None with open(Init[0],"r") as fd: for nl,l in enumerate(fd.readlines()): if len(l) <= 5: continue if type(Init[1]) is str: if l.split(":")[0] == Init[1] : lastrec = l elif type(Init[1]) is int: if Init[1] >= 0 and nl == Init[1] : lastrec = l elif Init[1] < 0: lastrec = l if lastrec == None: print " ERROR: Cannon find required record in ",Init, "... Skip" exit(1) else: lastrec = lastrec.split(":") if len(lastrec) < 5: print " ERROR: Last line in ",Init, "Has not records ....Skip" exit(1) else: for xs,ys,xl,yl,pn in [ ( int(xyxyp) for xyxyp in r.split(",") ) for r in lastrec[4:] ]: if xs >= xsize or ys >= ysize or xl >= xsize or yl >= ysize: print " ERROR: dementions {} doesn't match ....Skip".format(xs,ys,xl,yl,p) continue p[xs,ys,xl,yl] = pn print "# DONE #" print "#############################\n" if Init != None and bool(fTotalEnergy): print "#############################" print "# Calculate initial Energy #" for a,d in zip(ax,dn): for na,nd in zip(a,d): Epr += FdEpr(na, nd) #NP #Epr = np.sum(Bpr*ax**2-Apr*np.sqrt(ax)) + np.sum(Dpr*dn**2) pXs, pYs, pXl, pYl = np.where( p > 0. ) for xs, ys, xl, yl in zip(pXs, pYs, pXl, pYl): Eaf += FdEaf(xs, ys, xl, yl, p[xs, ys, xl, yl]) Eca += FdEca(xs, ys, xl, yl, 0., p) * p[xs, ys, xl, yl] #DB>> # import time # tb= time.time() # print "TB:",tb # Eca += FdEca(xs, ys, xl, yl, 0., p) * p[xs, ys, xl, yl] # te= time.time() # print te-tb # exit(0) #<<DB #NP # Eaf = sum( ( cAaf*np.exp(1.-pXs.astype(float)*xscl)*np.exp(1.-pXl.astype(float)*xscl)\ # - cBaf*np.exp(1.-pYs.astype(float)*yscl)*np.exp(1.-pYl.astype(float)*yscl))*p[pXs,pYs,pXl,pYl] ) # Eca = sum( -cGca * np.exp( - np.sqrt((pXs-pXl)**2+(pYs-pYl)**2)/cBca )*p[pXs, pYs, pXl, pYl] ) print " > Chemoaffinity :", Eaf print " > Competition :", Epr print " > Activity :", Eca E = Eaf + Eca + Epr print " > Total :", E print "#############################\n" #DB>> # exit(0) #<<DB if Graphs and Init != None: from matplotlib import pyplot as plt from matplotlib import cm cmap = cm.get_cmap('jet') Gax = plt.subplot(121) Gcells=[ [randint(xsize),randint(ysize),cmap(float(i)/float(nGraphs))] for i in xrange(nGraphs)] for xs,ys,c in Gcells: pXl, pYl = np.where( p[xs,ys,:,:].astype(int) > 0 ) for xl,yl in zip(pXl, pYl): plt.plot([xs,xl],[ys,yl],"-*",c=c,mfc=c,mec=c,lw=int(p[xs,ys,xl,yl]) ) if fLog: log = fopen(logfilename,"w") if log == NULL: sys.stderr.write("Cannot open Log file: '%s' for writing" %(filenameprefix+"-log.csv")) raise fprintf(log,"iter,+/-,xs,ys,xl,yl,dEpr,dEaf,dEca,dE,E,P0\n") if StartRec or StopRec or bool(fReporting): recdb = fopen(redbfilename,"w") if recdb == NULL: sys.stderr.write("Cannot open Record file: '%s' for writing" %(filenameprefix+"-rec.db")) raise if StartRec: fprintf(recdb,"%s:%010d",timestemp_c,itr_c) fprintf(recdb,":%g",E) pXs, pYs, pXl, pYl = np.where( p.astype(int) > 0 ) npos = int(pXs.shape[0]) fprintf(recdb,":%d",npos) for xs,ys,xl,yl in zip(pXs, pYs, pXl, pYl): fprintf(recdb,":%d,%d,%d,%d,%d",xs,ys,xl,yl,p[xs,ys,xl,yl]) fprintf(recdb,"\n") cdef double P0, dEpr, dEaf, dEca, dE Niter = xsize*ysize*Nstep #DB>> #Niter = Nstep #<<DB for itr in xrange(Niter): itr_c = itr # Add new synapse xs, ys, xl, yl = randint(xsize),randint(ysize),randint(xsize),randint(ysize) dEpr = FdEpr(ax[xs,ys]+1,dn[xl,yl]+1) - FdEpr(ax[xs,ys],dn[xl,yl]) dEaf = FdEaf(xs,ys,xl,yl,1) dEca = FdEca(xs,ys,xl,yl,1.,p) dE = dEpr + dEaf + dEca if dE > 100: P0 = 0. elif dE < -100: P0 = 1. else: P0 = 1./(1.+exp(4.*dE) ) if TotalEnergy: P0 *= E/(cE12+E) Pplus = False if np.random.random() < P0: Pplus = True p[xs,ys,xl,yl] += 1 ax[xs,ys] += 1 dn[xl,yl] += 1 Epr += dEpr Eaf += dEaf Eca += dEca E += dE if fLog: fprintf(log,"%d,+,%d,%d,%d,%d,%g,%g,%g,%g,%g,%g\n",itr_c,xs,ys,xl,yl,dEpr,dEaf,dEca,dEpr + dEaf + dEca,E,P0) if E <= 0. and fTotalEnergy: break if not (itr%1000) and fIndicator: sys.stderr.write("%d (+) %g %g [%g,%g,%g] %g ||"%(itr,E,dEpr + dEaf + dEca,dEpr,dEaf,dEca,P0)) #Remove connection cnt=0 xs, ys, xl, yl = randint(xsize),randint(ysize),randint(xsize),randint(ysize) while p[xs,ys,xl,yl] == 0 and cnt < 1000 : xs, ys, xl, yl = randint(xsize),randint(ysize),randint(xsize),randint(ysize) cnt += 1 if cnt < 1000: dEpr = FdEpr(ax[xs,ys]-1,dn[xl,yl]-1) - FdEpr(ax[xs,ys],dn[xl,yl]) dEaf = -FdEaf(xs,ys,xl,yl,1) dEca = -FdEca(xs,ys,xl,yl,1.,p) dE = dEpr + dEaf + dEca if dE > 100: P0 = 0. elif dE < -100: P0 = 1. else: P0 = 1./(1.+exp(4.*dE) ) if TotalEnergy: P0 *= E/(cE12+E) Pminus = False if np.random.random() < P0: Pminus = True p[xs,ys,xl,yl] -= 1 ax[xs,ys] -= 1 dn[xl,yl] -= 1 Epr += dEpr Eaf += dEaf Eca += dEca E += dE if fLog: fprintf(log,"%d,-,%d,%d,%d,%d,%g,%g,%g,%g,%g,%g\n",itr_c,xs,ys,xl,yl,dEpr,dEaf,dEca,dEpr + dEaf + dEca,E,P0) if not (itr%1000) and fIndicator: sys.stderr.write(" (-) %g %g [%g,%g,%g] %g \r[%s%s] "%(E,dEpr + dEaf + dEca,dEpr,dEaf,dEca,P0,"+" if Pplus else " ","-" if Pminus else " ")) else: if not (itr%1000) and fIndicator: sys.stderr.write(" (-) Not found \r[%s%s] "%("+" if Pplus else " "," " )) if E <= 0. and fTotalEnergy: break if fReporting and (not (itr%fReporting)): fprintf(recdb,"%s:%010d",timestemp_c,itr_c) fprintf(recdb,":%g",E) pXs, pYs, pXl, pYl = np.where( p.astype(int) > 0 ) npos = int(pXs.shape[0]) fprintf(recdb,":%d",npos) for xs,ys,xl,yl in zip(pXs, pYs, pXl, pYl): fprintf(recdb,":%d,%d,%d,%d,%d",xs,ys,xl,yl,p[xs,ys,xl,yl]) fprintf(recdb,"\n") print print "#############################" print "# STATISTIC #" print " > Mean Number of Axons :",np.mean(ax) print " > Mean Number of Dendrites :",np.mean(dn) print "#############################\n" if StopRec: fprintf(recdb,"%s:%010d",timestemp_c,itr_c) fprintf(recdb,":%g",E) pXs, pYs, pXl, pYl = np.where( p.astype(int) > 0 ) npos = int(pXs.shape[0]) fprintf(recdb,":%d",npos) for xs,ys,xl,yl in zip(pXs, pYs, pXl, pYl): fprintf(recdb,":%d,%d,%d,%d,%d",xs,ys,xl,yl,p[xs,ys,xl,yl]) fprintf(recdb,"\n") if StartRec or StopRec or bool(fReporting): fclose(recdb) if fLog: fclose(log) if Graphs: if Init == None: from matplotlib import pyplot as plt from matplotlib import cm cmap = cm.get_cmap('jet') Gcells=[ [randint(xsize),randint(ysize),cmap(float(i)/float(nGraphs))] for i in xrange(nGraphs)] else: plt.subplot(122,sharex=Gax,sharey=Gax) for xs,ys,c in Gcells: pXl, pYl = np.where( p[xs,ys,:,:] > 0 ) for xl,yl in zip(pXl, pYl): plt.plot([xs,xl],[ys,yl],"-*",c=c,mfc=c,mec=c,lw=int(p[xs,ys,xl,yl]) ) plt.title("Model: "+timestemp) plt.xlim(0,xsize) plt.ylim(0,ysize) plt.show() return p