#include #include /* n is the number of values to return ncon is the number of connections each guy gets index[n][ncon] is the list of indices to which it connects weight[n][ncon] is the list of weights root is the address of lowest entry in the variable array To wit: for sparse type name(i) produces values[i] value[i] = sum(k=0..ncon-1)of(w[i][k]*root[index[i][k]]) ODE FILE CALL: special f=sparse( n, ncon, w,index,rootname) special f=conv(type,n,ncon,w,rootname) index,w are tables that are loaded by the "tabular" command. rootname here is the name of the root quantity. type is either ep0 for conv. conv0 conve convp type value[i]= sum(j=-ncon;j<=ncon;i++){ k=i+j; 0 type if(k>=0 && k=n)k=n-k; ... p type k=mod(2*n+i+j,n) for example discretized diffusion tabular dd % 3 -1 1 3*abs(t)-2 special diff=conv(even, 51, 2, dd,v0) v[0..50]'=f(v[j],w[j])+d*diff([j]) another example nnetwork tabular wgt % 51 -25 25 .032*cos(.5*pi*t/25) special stot=conv(0, 51, 25, wgt,v0) v[0..50]'=f(v[j],w[j])-gsyn*stot([j])*(v([j])-vsyn) last example -- random sparse network 51 cells 5 connections each tabular w % 251 0 250 .2*rand(1) tabular con % 251 0 250 flr(rand(1)*5) special stot=sparse(51,5,w,con,v0) v[0..50]'=f(v[j],w[j])-gsyn*stot([j])*(v([j])-vsyn) more stuff: special f=mmult(n,m,w,root) -- note that here m is the number of return values and n is the size of input root f[j] = sum(i=0,n-1)of(w(i+n*j)*root(i)) j=0,..,m-1 special f=fmmult(n,m,w,root1,root2,fname) f[j] = sum(i=0,n-1)of(w(i+n*j)*fname(root1[i],root2[j]) special f=fsparse( n, ncon,w,index,root1,root2,fname) special f=fconv(type,n,ncon,w,root1,root2,fname) sum(j=-ncon,ncon)w(j)*fname(root1[i+j],root2[i]) similarly for fsparse special k=fftcon(type,n,wgt,v0) uses the fft to convolve v0 with the wgt which must be of length n if type=periodic 2n if type=0 special f=interp(type,n,root) this produces an interpolated value of x for x \in [0,n) type =0 for linear (all that works now) root0,....rootn-1 are values at the integers Like a table, but the integer values are variables */ #include #include extern int NODE; #define MAX_TAB 50 #define IC 2 extern int fftn (int /* ndim */, const int /* dims */[], double /* Re */[], double /* Im */[], int /* isign */, double /* scaling */); /* simple network stuff */ typedef struct { double xlo,xhi,dx; double *y,*x; int n,flag,interp,autoeval; int xyvals; /* flag=0 if virgin array, flag=1 if already allocated; flag=2 for function interp=0 for normal interpolation, interp=1 for 'step' table and finally, xyvals=1 if both x and y vals are needed (xyvals=0 is faster lookup )*/ char filename[128],name[12]; }TABULAR; extern TABULAR my_table[MAX_TAB]; typedef struct { int type,ncon,n; char name[20]; int root,root2; int f[20]; int iwgt; int *gcom; /* for group commands */ double *values,*weight,*index; double *fftr,*ffti,*dr,*di; } NETWORK; #define CONVE 0 #define CONV0 1 #define CONVP 2 #define SPARSE 3 #define FCONVE 10 #define FCONV0 11 #define FCONVP 12 #define FSPARSE 13 #define FFTCON0 4 #define FFTCONP 5 #define MMULT 6 #define FMMULT 7 #define GILLTYPE 25 #define INTERP 30 extern double variables[]; #define MAXNET 50 char *get_first(/* char *string,char *src */); char *get_next(/* char *src */); double evaluate(); NETWORK my_net[MAXNET]; int n_network=0; double net_interp(double x, int i) { int jlo=(int)x; double *y; int n=my_net[i].n; double dx=x-(double)jlo; y=&variables[my_net[i].root]; if(jlo<0 || jlo>(n-1))return 0.0; /* out of range */ return (1-dx)*y[jlo]+dx*y[jlo+1]; } double network_value(x, i) double x; int i; { int j=(int)x; if(my_net[i].type==INTERP){ return net_interp(x,i); } if(j>=0&&j=n_network){ printf(" No such name %s ?? \n",name); return 0; } switch(type){ case 1: /* convolution */ get_first(rhs,"("); str=get_next(","); ntype=-1; if(str[0]=='E')ntype=CONVE; if(str[0]=='0'||str[0]=='Z')ntype=CONV0; if(str[0]=='P')ntype=CONVP; if(ntype==-1){ printf(" No such convolution type %s \n",str); return 0; } str=get_next(","); ntot=atoi(str); if(ntot<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); ncon=atoi(str); if(ncon<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); strcpy(wgtname,str); iwgt=find_lookup(wgtname); if(iwgt<0){ printf("in network %s, %s is not a table \n", name,wgtname); return 0; } str=get_next(")"); strcpy(rootname,str); ivar=get_var_index(rootname); if(ivar<0){ printf(" In %s , %s is not valid variable\n", name,rootname); return 0; } my_net[ind].values=(double *)malloc((ntot+1)*sizeof(double)); init_net(my_net[ind].values,ntot); my_net[ind].weight=my_table[iwgt].y; my_net[ind].type=ntype; my_net[ind].root=ivar; my_net[ind].n=ntot; my_net[ind].ncon=ncon; printf(" Added net %s type %d len=%d x %d using %s var[%d] \n", name,ntype,ntot,ncon,wgtname,ivar); return 1; break; case 2: /* sparse */ get_first(rhs,"("); str=get_next(","); ntype=SPARSE; ntot=atoi(str); if(ntot<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); ncon=atoi(str); if(ncon<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); strcpy(wgtname,str); iwgt=find_lookup(wgtname); if(iwgt<0){ printf("in network %s, %s is not a table \n", name,wgtname); return 0; } str=get_next(","); strcpy(indname,str); iind=find_lookup(indname); if(iind<0){ printf("in network %s, %s is not a table \n", name,indname); return 0; } str=get_next(")"); strcpy(rootname,str); ivar=get_var_index(rootname); if(ivar<0){ printf(" In %s , %s is not valid variable\n", name,rootname); return 0; } my_net[ind].values=(double *)malloc((ntot+1)*sizeof(double)); init_net(my_net[ind].values,ntot); my_net[ind].weight=my_table[iwgt].y; my_net[ind].index=my_table[iind].y; my_net[ind].type=ntype; my_net[ind].root=ivar; my_net[ind].n=ntot; my_net[ind].ncon=ncon; printf(" Added sparse %s len=%d x %d using %s var[%d] and %s\n", name,ntot,ncon,wgtname,ivar,indname ); return 1; break; case 3: /* convolution */ get_first(rhs,"("); str=get_next(","); ntype=-1; if(str[0]=='E')ntype=FCONVE; if(str[0]=='0'||str[0]=='Z')ntype=FCONV0; if(str[0]=='P')ntype=FCONVP; if(ntype==-1){ printf(" No such convolution type %s \n",str); return 0; } str=get_next(","); ntot=atoi(str); if(ntot<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); ncon=atoi(str); if(ncon<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); strcpy(wgtname,str); iwgt=find_lookup(wgtname); if(iwgt<0){ printf("in network %s, %s is not a table \n", name,wgtname); return 0; } str=get_next(","); strcpy(rootname,str); ivar=get_var_index(rootname); if(ivar<0){ printf(" In %s , %s is not valid variable\n", name,rootname); return 0; } str=get_next(","); strcpy(root2name,str); ivar2=get_var_index(root2name); if(ivar2<0){ printf(" In %s , %s is not valid variable\n", name,root2name); return 0; } str=get_next(")"); strcpy(fname,str); sprintf(junk,"%s(%s,%s)",fname,rootname,root2name); if(add_expr(junk,my_net[ind].f,&elen)){ printf(" bad function %s \n",fname); return 0; } my_net[ind].values=(double *)malloc((ntot+1)*sizeof(double)); init_net(my_net[ind].values,ntot); my_net[ind].weight=my_table[iwgt].y; my_net[ind].type=ntype; my_net[ind].root=ivar; my_net[ind].root2=ivar2; my_net[ind].n=ntot; my_net[ind].ncon=ncon; printf(" Added net %s type %d len=%d x %d using %s %s(var[%d],var[%d]) \n", name,ntype,ntot,ncon,wgtname,fname,ivar,ivar2); return 1; break; case 4: /* sparse */ get_first(rhs,"("); str=get_next(","); ntype=FSPARSE; ntot=atoi(str); if(ntot<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); ncon=atoi(str); if(ncon<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); strcpy(wgtname,str); iwgt=find_lookup(wgtname); if(iwgt<0){ printf("in network %s, %s is not a table \n", name,wgtname); return 0; } str=get_next(","); strcpy(indname,str); iind=find_lookup(indname); if(iind<0){ printf("in network %s, %s is not a table \n", name,indname); return 0; } str=get_next(","); strcpy(rootname,str); ivar=get_var_index(rootname); if(ivar<0){ printf(" In %s , %s is not valid variable\n", name,rootname); return 0; } str=get_next(","); strcpy(root2name,str); ivar2=get_var_index(root2name); if(ivar2<0){ printf(" In %s , %s is not valid variable\n", name,root2name); return 0; } str=get_next(")"); strcpy(fname,str); sprintf(junk,"%s(%s,%s)",fname,rootname,root2name); if(add_expr(junk,my_net[ind].f,&elen)){ printf(" bad function %s \n",fname); return 0; } my_net[ind].values=(double *)malloc((ntot+1)*sizeof(double)); init_net(my_net[ind].values,ntot); my_net[ind].weight=my_table[iwgt].y; my_net[ind].index=my_table[iind].y; my_net[ind].type=ntype; my_net[ind].root=ivar; my_net[ind].root2=ivar2; my_net[ind].n=ntot; my_net[ind].ncon=ncon; printf(" Sparse %s len=%d x %d using %s %s(var[%d],var[%d]) and %s\n", name,ntot,ncon,wgtname,fname,ivar,ivar2,indname ); return 1; break; case 5: /* fft convolution */ get_first(rhs,"("); str=get_next(","); ntype=-1; /* if(str[0]=='E')ntype=CONVE; */ if(str[0]=='0'||str[0]=='Z')ntype=FFTCON0; if(str[0]=='P')ntype=FFTCONP; if(ntype==-1){ printf(" No such fft convolution type %s \n",str); return 0; } str=get_next(","); ntot=atoi(str); if(ntot<=0){ printf(" %s must be positive int \n",str); return 0; } str=get_next(","); strcpy(wgtname,str); iwgt=find_lookup(wgtname); if(iwgt<0){ printf("in network %s, %s is not a table \n", name,wgtname); return 0; } ntab=get_lookup_len(iwgt); if(type==FFTCONP&&ntab=MAXNET){ return; } strcpy(my_net[n_network].name,name); add_net_name(n_network,name); n_network++; } else printf(" No such special type ...\n"); } is_network(s) char *s; { int i,n; de_space(s); strupr(s); n=strlen(s); if(s[0]=='C' &&s[1]=='O' &&s[2]=='N' && s[3]=='V')return 1; if(s[0]=='S' &&s[1]=='P' &&s[2]=='A' && s[3]=='R')return 2; if(s[0]=='F'&&s[1]=='C' &&s[2]=='O' &&s[3]=='N' && s[4]=='V')return 3; if(s[0]=='F' && s[1]=='S' &&s[2]=='P' &&s[3]=='A' && s[4]=='R')return 4; if(s[0]=='F' && s[1]=='F' && s[2]=='T' && s[3]=='C' )return 5; if(s[0]=='M' &&s[1]=='M' &&s[2]=='U' && s[3]=='L')return 6; if(s[0]=='F'&& s[1]=='M' &&s[2]=='M' &&s[3]=='U' && s[4]=='L')return 7; if(s[0]=='G'&& s[1]=='I' &&s[2]=='L' &&s[3]=='L')return 10; if(s[0]='I' && s[1]=='N' &&s[2]=='T' && s[3]=='E' && s[4]=='R')return INTERP; /* if(s[0]=='G'&& s[1]=='R' && s[2]=='O' && s[3]=='U')return 8; */ return 0; } eval_all_nets() { int i; for(i=0;i0){ my_net[ind].weight=(double *)malloc(my_net[ind].root*NODE*sizeof(double)); make_gill_nu(my_net[ind].weight,NODE,my_net[ind].root,my_net[ind].values); my_net[ind].ncon=0; } one_gill_step(my_net[ind].iwgt,my_net[ind].root,my_net[ind].gcom,my_net[ind].values); break; case CONVE: for(i=0;i=n)k=abs(twon-2-k); sum+=(w[j+ncon]*y[k]); } } values[i]=sum; } break; case CONV0: for(i=0;i=0) sum+=(w[j+ncon]*y[k]); } values[i]=sum; } break; case CONVP: for(i=0;i=0&&k=n)k=abs(twon-2-k); f[1]=(int)(&y[k]); z=evaluate(f); sum+=(w[j+ncon]*z); } } values[i]=sum; } break; case FCONV0: f=my_net[ind].f; yp=&variables[root2]; for(i=0;i=0){ f[1]=(int)(&y[k]); z=evaluate(f); sum+=(w[j+ncon]*z); } } values[i]=sum; } break; case FCONVP: f=my_net[ind].f; yp=&variables[root2]; for(i=0;i=0&&k(n-1)){ piece[jp]=0; if(g_namelist(piece,b,&f,&i1,&i2)==0){ printf("Bad gillespie list %s\n",s); return 0; } if(f==0) { printf("added %s\n",b); iv=get_var_index(b); if(iv<0){ printf("No such name %s\n",b); return 0; } ind[k]=iv; k++; } else { printf("added %s{%d-%d}\n",b,i1,i2); m=i2-i1+1; for(id=0;id(n-1)){ *nn=k; return 1; } jp=0; } else { piece[jp]=c; jp++; } i++; } *nn=k; return 1; } /* plucks info out of xxx{aa-bb} or returns string */ int g_namelist(char *s,char *root,int *flag,int *i1,int*i2) { int i,n=strlen(s),ir=-1,j=0; char c,num[20]; *flag=0; for(i=0;i