Ejemplo n.º 1
0
void PythonEngineField::addCustomExtensions()
{
    // init field cython extensions
    initfield();
}
Ejemplo n.º 2
0
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;
}