void PythonEngineField::addCustomExtensions() { // init field cython extensions initfield(); }
int main(int argc, char **argv) { int **ima,**varnum,**varnuminv,*dir,*size,*numvois,**vois,**voisinv,*mag_clipped,generate_image,numell,nflip,wrongpolarized,numpolarized,error; double *yy,*cpx,*cpy,**field,**hatf,*hloc,jcoup,**jj,*jchain,err_mess,onsager,frustr,hftyp,mse,sum,damping,fieldav,fieldnew; int L,Lmax,N,M,Mmax,seed,n,i,j,k,mu,numdir,iter,niter,sizemax,sizetot,s,writeperiod,numcan,numfrozen,nummicroc,microc_threshold,typecalc,nvmax,wrongspins; FILE *ImageOrig,*ImageRec,*Imtoimport,*binary_out; double *htot; if(argc!=11) {printf("Usage : %s L(0 to read in trybin_256.txt, -1 for the 1025-size one) numell numdir jcoup niter writeperiod microc_threshold damping BIGFIELD seed \n",argv[0]);exit(1);} L=atoi(argv[1]);// L=0 means that one reads the file trybin_256.txt. Any other L means one generates the image, of size L*L numell=atoi(argv[2]);// number of ellipses in the image numdir=atoi(argv[3]);//number of directions of measurement jcoup=atof(argv[4]); niter=atoi(argv[5]);// maximal number of iterations writeperiod=atoi(argv[6]);//period at which one fprints the spins and the local fields microc_threshold=atoi(argv[7]);// in principle, should be 1. But a smaller number, like .5, improves convergence... damping=atof(argv[8]); BIGFIELD=atof(argv[9]); seed=atoi(argv[10]);// seed for random number generator onsager=1; binary_out=fopen("binary_out.dat","w"); generate_image=1; if(L==0){ L=256; generate_image=0; Imtoimport=fopen("trybin_256.txt","r"); } if(L==-1){ L=1025; generate_image=0; Imtoimport=fopen("trybin.txt","r"); } N=L*L; Lmax=2*L;// maximum number of variables involved in one measurement printf("L=%i N=%i \n",L,N); initialize_rangen(seed); ima=imatrix(1,L,1,L); Mmax=numdir*L*SQR2;// upper bound on the number of measurements varnum=imatrix(1,Mmax,1,Lmax);//varnum[mu][r] gives the index of the r-th spin in the line mu. varnuminv=imatrix(1,Mmax,1,Lmax);// s=varnuminv[mu][k] <=> vois[varnum[mu][k]][s]=mu (mu is the s-th neighbour of his k-th neighbour) yy=dvector(1,Mmax);//results of measurements dir=ivector(1,Mmax);// in what direction was a measurement size=ivector(1,Mmax);//number of variables involved in a measurement jj=dmatrix(1,Mmax,1,Lmax);//Ising couplings in the chains jchain=dvector(1,Lmax);//Ising couplings in one given chain numvois=ivector(1,N);// number of measurements in which a varaible appears vois=imatrix(1,N,1,numdir);// list of measurements where a variable appears: vois[i][r] is the index of the r-th line where the vertex number i is present voisinv=imatrix(1,N,1,numdir);// s=voisinv[i][r] <=> varnum[vois[i][r]][s]=i (i is the s-th neighbour of his r-th neighbour). mag_clipped=ivector(1,N);// magnetization found by clipping htot htot=dvector(1,N);// full local field found by BP // Generate or read the image ImageOrig=fopen("ImageOrig.dat","w"); if(generate_image==1){ cpx=dvector(1,N); cpy=dvector(1,N); pixel_pos(L,cpx,cpy); genimage(L,numell,ima,cpx,cpy); free_dvector(cpx,1,N); free_dvector(cpy,1,N); } else{ for (i=1;i<=L;i++) { for(j=1;j<=L;j++) { fscanf(Imtoimport,"%i ",&k); if(k==0)ima[i][j]=1; else ima[i][j]=-1; } } } for(n=1;n<=N;n++){ matrixcoordinates(L,n,&i,&j); fprintf(ImageOrig,"%i ",ima[i][j]); //fprintf(ImageOrig,"\n"); } fclose(ImageOrig); // Perform the measurements (Radon) calc_measurements(L,Lmax,numdir,ima,varnum,yy,dir,size,vois,numvois,jj,jcoup,&M); if(M>Mmax){ printf("M>Mmax, please increase Mmax: %i %i\n",M,Mmax); exit(2); } sum=0; for (i=1;i<=L;i++) { for(j=1;j<=L;j++) sum+=ima[i][j]; } printf("generated an image with %i pixels and magnetization %i\n",L*L,(int)sum); // Geometry of the factor graph and checks calc_voisinv(N,numdir,vois,numvois,size,voisinv,varnum); calc_varnuminv(M,numdir,vois,numvois,size,varnum,varnuminv); sizemax=0;sizetot=0; for(mu=1;mu<=M;mu++){ sizetot+=size[mu]; if(size[mu]>sizemax) sizemax=size[mu]; if(verbose>5){ printf("Constraint mu=%i yy[mu]=%f size=%i: ",mu,yy[mu],size[mu]); for(i=1;i<=size[mu];i++) printf("%i ",varnum[mu][i]); printf("\n"); } } if(sizemax>Lmax){ printf("STOP sizemax>Lmax\n"); exit(12); } nvmax=0; for(i=1;i<=N;i++){ if(numvois[i]>nvmax)nvmax=numvois[i]; } //Initialisation of the messages field=dmatrix(1,M,1,sizemax);// field[mu][r] is the local magnetic field h_{mu to i} where i is the r-th neighbour of mu hatf=dmatrix(1,N,1,nvmax);//hatf[i][r] is the local magnetic field \hat h_{i to mu} where mu is the r-th neighbour of i initfield(M,field,size,yy); calc_hatf(N,L,field,hatf,htot,numvois,vois,voisinv,varnum,&frustr,&hftyp,ima,&mse); if(verbose>12){ printf("Initial field: \n"); for(mu=1;mu<=M;mu++){ for(n=1;n<=size[mu];n++) printf("%f ",field[mu][n]); printf("\n\n"); } printf("Initial hatf: \n"); for(n=1;n<=N;n++) { for (i=1;i<=numvois[n];i++) printf("%f ",hatf[n][i]); printf("\n\n"); } } hloc=dvector(1,sizemax); printf("%i Measurements done; starting iteration, niter=%i\n",M,niter);fflush(stdout); fprintf(binary_out,"# N=%i numdir=%i M=%i BIGFIELD= %f microc_threshold=%i\n",N, numdir, M, BIGFIELD,microc_threshold); for(n=1;n<=N;n++) mag_clipped[n]=1; //START BP ITERATION HERE! for(iter=0;iter<=niter;iter++){ err_mess=0; sizetot=0; fieldav=0; numcan=0;nummicroc=0;numfrozen=0; for(mu=1;mu<=M;mu++){ //update all messages h_{mu to i} if(verbose>10) printf("\n iter=%i: Solving chain mu=%i, with %i spins ",iter,mu,size[mu]); calc_field(mu,size,microc_threshold,onsager,varnum,varnuminv,yy,jj,hatf,hloc,&typecalc); if(typecalc==0) numfrozen++; if(typecalc==1) nummicroc++; if(typecalc==2) numcan++; for(k=1;k<=size[mu];k++) { // compute field err_mess+=fabs(tanh(hloc[k])-tanh(field[mu][k])); sizetot++; fieldnew=damping*field[mu][k]+(1.-damping)*hloc[k]; update_hatf(mu,k,varnum,varnuminv,vois,numvois,hatf,htot,fieldnew-field[mu][k]);// update hatf for all constraints nu neighbours of varaible i, except nu; field[mu][k]=fieldnew; fieldav+=fabs(field[mu][k]); } } //printf("\n"); err_mess/=sizetot; fieldav/=sizetot; printf("iter= %i, err_mess=%f, fieldav=%f ; frustration=%f, typical hatfield=%f, mse=%e, numcan=%i, nummicroc=%i,numfrozen=%i \n", iter,err_mess,fieldav,frustr,hftyp,mse,numcan,nummicroc,numfrozen); fflush(stdout); // Monitoring of the progress of BP: compute present image obtained by clipping, and how well it reconstructs nflip=0; wrongpolarized=0;numpolarized=0;wrongspins=0; for(n=1;n<=N;n++){ if(fabs(htot[n])>2*BIGFIELD) numpolarized++; if(htot[n]*mag_clipped[n]<0)nflip++; if(htot[n]>0) mag_clipped[n]=1; else mag_clipped[n]=-1; matrixcoordinates(L,n,&i,&j); if(mag_clipped[n]!=ima[i][j]) { wrongspins++; if(fabs(htot[n])>2*BIGFIELD) wrongpolarized++; } } error=0; for(mu=1;mu<=M;mu++){//check the constraints sum=0; for(k=1;k<=size[mu];k++) sum+=mag_clipped[varnum[mu][k]]; if(sum!=yy[mu]) error++; } printf("Number of wrong spins=%i, fraction wrong = %f ; nflip=%i ; number of unsat constraints=%i numpolarized=%i wrongpolarized=%i\n", wrongspins,((double)wrongspins)/N,nflip,error,numpolarized,wrongpolarized); if(wrongpolarized>0) printf("ATTENTION wrongpolarized!!!!!!!!!!\n"); fprintf(binary_out," %i %i %f %i %i\n",iter,(int)mse, mse/N,nflip,error); if(err_mess<.0001) break;//BP has converged if(error==0)break;// All constraints are satisfied } // fprintf the final image obtained by BP reconstruction ImageRec=fopen("ImageRec.dat","w"); for(i=1;i<=L;i++){ for(j=1;j<=L;j++){ fprintf(ImageRec,"%i ",mag_clipped[indexsite(L,i,j)]); } fprintf(ImageRec,"\n"); } fprintf(ImageRec,"\n"); return 1; }