Ejemplo n.º 1
0
void Sridge_annealing(double *cost, double *smodulus,
  double *phi, double *plambda, double *pmu, double *pc, int *psigsize,
  int *pnscale, int *piteration, int *pstagnant, int *pseed,
  int *pcount, int *psub, int *pblocksize, int *psmodsize)
{
  int i,sigsize,ncount,iteration,up,pos,num,a,count, costcount,sub;
  long idum=-9;
  int again, tbox, blocksize,smodsize;
  int nscale, stagnant, recal;
  double lambda, c, mu;
  double *bcost, *phi2;
  double ran, gibbs;
  double cost1;
  double temperature, tmp=0.0;
  /* FILE *fp; */


  /* Generalities; initializations
     -----------------------------*/
  mu = *pmu;
  stagnant = *pstagnant;
  nscale = *pnscale;
  iteration = *piteration;
  lambda = *plambda;
  c = *pc;
  sigsize = *psigsize;
  idum = *pseed;
  sub = *psub;
  blocksize = *pblocksize;
  smodsize = *psmodsize;

  recal = 1000000; /* recompute cost function every 'recal' iterations */

  if(!(bcost = (double *) R_alloc(blocksize, sizeof(double) )))
    Rf_error("Memory allocation failed for bcost at ridge_annealing.c \n");

  if(!(phi2 = (double *)S_alloc((smodsize+1)*sub,sizeof(double))))
    Rf_error("Memory allocation failed for phi2 at ridge_annealing.c \n");

/*
  if(blocksize != 1) {
    if((fp = fopen("annealing.cost","w")) == NULL)
      Rf_error("can't open file at ridge_annealing.c \n");
  }
*/
  tbox = 0;
  ncount = 0; /* count for cost */
  count = 0; /* total count */
  temperature = c/log(2. + (double)count); /* Initial temperature */
  cost1 = 0;


  /* Smooth and subsample the wavelet transform modulus
     --------------------------------------------------*/
/*  smoothwt(modulus,smodulus,sigsize,nscale,sub); */
/*  smoothwt2(modulus,smodulus,sigsize,nscale,sub, &smodsize); */
/*   printf("smodsize=%d\n",smodsize); */
/*  for(i=0;i<smodsize;i++){
    phi[i] = phi[sub*i];
  } */

  for(i=0;i<smodsize;i++){
    phi[i] = phi[(int)((sigsize-1)/(smodsize-1)*i)];
  }


  /* Iterations:
     -----------*/

  while(1) {
    for(costcount = 0; costcount < blocksize; costcount++) {


      /* Initialize the cost function
	 ----------------------------*/
      if(count == 0) {
	for(i = 1; i < smodsize-1; i++) {
	  tmp = (double)((phi[i-1]+ phi[i+1]-2 * phi[i]));
	  cost1 += (double)((lambda * tmp * tmp));

	  tmp = (double)((phi[i] - phi[i+1]));
	  cost1 += (double)((mu * tmp * tmp));

	  a = (int)phi[i];
          tmp = smodulus[smodsize * a + i];
/*	  cost1 -= (tmp * tmp - noise[a]); */
	  cost1 -= tmp;
	}

        tmp = (double)((phi[0] - phi[1]));
	cost1 += (double) ((mu * tmp * tmp));
	a = (int)phi[0];
        tmp = smodulus[smodsize * a];
/*	cost1 -= (tmp * tmp - noise[a]); */
	cost1 -= tmp;

	a = (int)phi[smodsize-1];
        tmp = smodulus[smodsize * a + smodsize-1];
/*	cost1 -= (tmp * tmp - noise[a]); */
	cost1 -= tmp;

	cost[ncount++] = (double)cost1;
	bcost[0] = (double)cost1;
	count ++;
	costcount = 1;
	if(costcount == blocksize) break;
      }

      /* Generate potential random move
	 ------------------------------*/
      again = YES;
      while(again) {
	randomwalker2(smodsize,&num,&idum); 
	/* returns between 0 and 2 * smodsize - 1*/
	pos = num/2;
	up = -1;
	if(num%2 == 0) up = 1;
	again = NO;
	if((((int)phi[pos] == 0) && (up == -1)) ||
	   (((int)phi[pos] == (nscale-1) && (up == 1)))) again = YES; 
	   /* boundary effects */
      }

      /* Compute corresponding update of the cost function
	 -------------------------------------------------*/
      if(inrange(2,pos,smodsize-3)) {
	tmp = (double)(lambda*up);
	tmp *=(double)((6*up+(12*phi[pos]-8*(phi[pos-1]+phi[pos+1])
		+2*(phi[pos-2]+phi[pos+2]))));

	tmp += (double)(mu*up*(4.0*phi[pos]
		-2.0*(phi[pos-1]+phi[pos+1])+2.0*up));

	a = (int)phi[pos];
/*	tmp += ((smodulus[smodsize*a+pos]*smodulus[smodsize*a+pos])
		-noise[a]);  */
	tmp += smodulus[smodsize*a+pos];
	a = (int)phi[pos] +  up;
/*	tmp -= ((smodulus[smodsize*a+pos]*smodulus[smodsize * a + pos])
		-noise[a]); */
	tmp -= smodulus[smodsize*a+pos];
      }

      if(inrange(2,pos,smodsize-3) == NO) {
	tmp = (double)(lambda*up);
	if(pos == 0) {
	  tmp *= (double)((up+2.0*(phi[0]-2*phi[1]+phi[2])));
	  tmp += (double)(mu*up*((2.0*phi[pos]-2.0*phi[pos+1]) + up));
	}
	else if(pos == 1) {
	  tmp *= (double)((5*up+2.0*(-2*phi[0]+5*phi[1]-4*phi[2]+phi[3])));
	  tmp += (double)(mu*up*(4.0*phi[pos]-2.0*(phi[pos-1]+phi[pos+1])
				 +2.0*up));
	}
	else if(pos == (smodsize-2)) {
	  tmp *= (double)((5*up+2.0*(phi[pos-2]-4*phi[pos-1]+5*phi[pos]
				     -2*phi[pos+1])));
	  tmp += (double)(mu*up*(4.0*phi[pos]-2.0*(phi[pos-1]+phi[pos+1])
				 +2.0*up));
	}
	else if(pos == (smodsize-1)) {
	  tmp *= (double)((up+2.0*(phi[pos-2]-2*phi[pos-1]+phi[pos])));
	  tmp += (double)(mu*up*((2.0*phi[pos]-2.0*phi[pos-1]) + up));
	}
	a = (int)phi[pos];
/*	tmp +=((smodulus[smodsize*a+pos]*smodulus[smodsize*a+pos])-noise[a]); */
	tmp += smodulus[smodsize*a+pos];
	a = (int)phi[pos] +  up;
/*	tmp -=((smodulus[smodsize*a+pos]*smodulus[smodsize*a+pos])-noise[a]); */
	tmp -= smodulus[smodsize*a+pos];
      }

      /* To move or not to move: that's the question
	 -------------------------------------------*/
      if(tmp < (double)0.0) {
	phi[pos] = phi[pos] + up; /* good move */
	if(phi[pos] < 0) Rprintf("Error \n");
	cost1 += tmp;
	tbox = 0;
      }
      else {
	gibbs = exp(-tmp/temperature);
	ran = ran1(&idum); 
	if(ran < gibbs) {      
	  phi[pos] = phi[pos] + up; /* adverse move */
	  cost1 += tmp;
	  tbox = 0;
	}
	tbox ++;
	if(tbox >= stagnant)  {
	  cost[ncount++] = (double)cost1;
	  *pcount = ncount;
/*	  if((blocksize != 1)){
	    for(i = 0; i < costcount+1; i++)
	      fprintf(fp, "%f ", bcost[i]);
	    fclose(fp);
	  }
*/
	  /* Interpolate from subsampled ridge
	     --------------------------------*/
	  splridge(sub, phi, smodsize, phi2);
	  for(i=0;i<sigsize;i++) phi[i]=phi2[i];
	  /* splridge(1, phi, smodsize, phi2);
	  for(i=0;i<sigsize;i++) phi[i]=phi2[i];*/
	  return;
	}
      }
      bcost[costcount] = (double)cost1;

      count ++;
      if(count >=  iteration) 	{
	cost[ncount++] = (double)cost1;
	*pcount = ncount;

	/* Write cost function to a file
	   -----------------------------*/
/*	if((blocksize != 1)){
	  for(i = 0; i < costcount+1; i++)
	    fprintf(fp, "%f ", bcost[i]);
	  fclose(fp);
	}
*/
	/* Interpolate from subsampled ridge
	   --------------------------------*/
	splridge(sub, phi, smodsize, phi2);
	for(i=0;i<sigsize;i++) phi[i]=phi2[i];
	/* splridge(1, phi, smodsize, phi2);
	for(i=0;i<sigsize;i++) phi[i]=phi2[i];*/
	//printf("Done !\n");
	return;
      }
      temperature = c/log(1. + (double)count);
    }

    bcost[blocksize-1] = (double)cost1;
    if((blocksize != 1)){
/*      for(i = 0; i < blocksize; i++)
	fprintf(fp, "%f ", bcost[i]); */
      for(i = 0; i < blocksize; i++)
	bcost[i] = 0.0;
    }

    /* recalculate cost to prevent error propagation 
       ---------------------------------------------*/
    if(count % recal == 0) {
      cost1 = 0.0;
      for(i = 1; i < smodsize-1; i++) {
	tmp = (double)((phi[i-1]+ phi[i+1]-2 * phi[i]));
	cost1 += (double)((lambda * tmp * tmp));
	tmp = (double)((phi[i]-phi[i+1]));
	cost1 += (double)((mu * tmp * tmp));

	a = (int)phi[i];
	cost1 -= smodulus[smodsize * a + i];
/*	cost1 -= (smodulus[smodsize * a + i] * smodulus[smodsize * a + i]
		  -noise[a]); */
      }
      a = (int)phi[0];
      tmp = (double)((phi[0]-phi[1]));
      cost1 += (double)((mu * tmp * tmp));
      cost1 -= smodulus[smodsize * a];
/*      cost1 -= (smodulus[smodsize * a] * smodulus[smodsize * a]
		-noise[a]); */
      a = (int)phi[smodsize-1];
/*      cost1 -= (smodulus[smodsize * a + smodsize-1] *
		smodulus[smodsize * a + smodsize-1] -noise[a]); */
      cost1 -= smodulus[smodsize * a + smodsize-1];
    }
    cost[ncount++] = (double)cost1;
  }
  /* return; */
}
Ejemplo n.º 2
0
void Sridge_coronoid(float *cost, double *smodulus,
  float *phi, float *plambda, float *pmu, float *pc, int *psigsize,
  int *pnscale, int *piteration, int *pstagnant, int *pseed,
  int *pcount, int *psub, int *pblocksize, int *psmodsize)
{
  int i,sigsize,ncount,iteration,up,pos,num,a,count,costcount,sub;
  long idum=-9;
  int again, tbox, blocksize,smodsize;
  int nscale, stagnant, recal;
  double lambda, c, mu;
  float *bcost, *phi2;
  double ran, gibbs;
  double cost1;
  double temperature, tmp=0.0, tmp_cost =0.0, tmp_mod;
  double der_plus,der_minus,der_sec,der_sec_plus,der_sec_minus;
  FILE *fp;


  /* Generalities; initializations
     -----------------------------*/
  mu = (double)(*pmu);
  stagnant = *pstagnant;
  nscale = *pnscale;
  iteration = *piteration;
  lambda = (double)(*plambda);
  c = (double)(*pc);
  sigsize = *psigsize;
  idum = (long) (*pseed);
  sub = *psub;
  blocksize = *pblocksize;
  smodsize = *psmodsize;

  recal = 1000; /* recompute cost function every 'recal' iterations */

  if(!(bcost = (float *)R_alloc(blocksize, sizeof(float) )))
    error("Memory allocation failed for bcost at ridge_annealing.c \n");

  if(!(phi2 = (float *)R_alloc((smodsize+1)*sub,sizeof(float))))
    error("Memory allocation failed for phi2 at ridge_annealing.c \n");

/*  if(blocksize != 1) {
    if((fp = fopen("annealing.cost","w")) == NULL)
      error("can't open file at ridge_annealing.c \n");
  }
*/  
  tbox = 0;
  ncount = 0; /* count for cost */
  count = 0; /* total count */
  temperature = c/log(2. + (double)count); /* Initial temperature */
  cost1 = 0;


  /* Smooth and subsample the wavelet transform modulus
     --------------------------------------------------*/
/*  smoothwt2(modulus,smodulus,sigsize,nscale,sub,&smodsize); */

  /* Subsample the initial guess for the ridge
     -----------------------------------------*/
  for(i=0;i<smodsize;i++){
    phi[i] = phi[sub*i];
  }

  /* Take into account discretization
     --------------------------------*/
  tmp = (double)(sub*sub);
  mu /= tmp;
  lambda /= (tmp*tmp);


  /* Iterations:
     -----------*/
  while(1) {
    for(costcount = 0; costcount < blocksize; costcount++) {


      /* Initialize the cost function
	 ----------------------------*/
      if(count == 0) {
	for(i = 1; i < smodsize-1; i++) {
	  der_sec = (double)(phi[i-1]+ phi[i+1]-2 * phi[i]);
	  tmp_cost = (double)(lambda * der_sec * der_sec);

	  der_plus = (double)(phi[i] - phi[i+1]);
	  tmp_cost += (double)(mu * der_plus * der_plus);

	  a = (int)(phi[i]);
          tmp_mod = smodulus[smodsize * a + i];
/*	  cost1 -= (tmp_mod * tmp_mod - noise[a])*(1. - tmp_cost); */
	  cost1 -= (tmp_mod*(1. - tmp_cost)); 

	}

        tmp = (double)(phi[0] - phi[1]);
	tmp_cost = mu * tmp * tmp;
	a = (int)(phi[0]);
        tmp_mod = smodulus[smodsize * a];
	cost1 -= (tmp_mod*(1.- tmp_cost)); 
/*	cost1 -= (tmp_mod * tmp_mod - noise[a])*(1.- tmp_cost); */

	a = (int)(phi[smodsize-1]);
        tmp_mod = smodulus[smodsize * a + smodsize-1];
/*	cost1 -= (tmp_mod * tmp_mod - noise[a]); */
	cost1 -= tmp_mod;

	cost[ncount++] = (float)cost1;
	bcost[0] = (float)cost1;
	count ++;
	costcount = 1;
	if(costcount == blocksize) break;
      }

      /* Generate potential random move
	 ------------------------------*/
      again = YES;
      while(again) {
	randomwalker2(smodsize,&num,&idum); 
	/* returns between 0 and 2 * smodsize - 1*/
	pos = num/2;
	up = -1;
	if(num%2 == 0) up = 1;
	again = NO;
	if((((int)(phi[pos]) == 0) && (up == -1)) ||
	   (((int)(phi[pos]) == (nscale-1) && (up == 1)))) again = YES; 
	   /* boundary effects */
      }

      /* Compute corresponding update of the cost function
	 -------------------------------------------------*/
      /* tmp: update of cost function */

      if(inrange(2,pos,smodsize-3)) {
	der_plus = (double)(phi[pos +1]-phi[pos]);
	der_minus = (double)(phi[pos] -phi[pos-1]);
	der_sec = der_plus - der_minus;
	der_sec_plus = (double)(phi[pos+2] - 2.*phi[pos+1] + phi[pos]);
	der_sec_minus = (double)(phi[pos-2] - 2.*phi[pos-1] + phi[pos]);

	a = (int)(phi[pos]) +  up;
	tmp_mod = smodulus[smodsize*a+pos];
/*	tmp_cost = (tmp_mod * tmp_mod - noise[a]); */
	tmp_cost = tmp_mod;

	a = (int)(phi[pos]);
	tmp_mod = smodulus[smodsize*a+pos];
/*	tmp_cost -= (tmp_mod * tmp_mod - noise[a]); */
	tmp_cost -= tmp_mod;

	tmp = tmp_cost*(-1.+mu*der_plus*der_plus+lambda*der_sec*der_sec);


	tmp_cost = mu*(1. - 2.*up*der_plus);
	tmp_cost +=  4.*lambda*(1.-up*der_sec);
	a = (int)(phi[pos]) +up;
	tmp_mod = smodulus[smodsize*a+pos];
/*	tmp += tmp_cost*(tmp_mod*tmp_mod - noise[a]); */
	tmp += (tmp_cost*tmp_mod);


	tmp_cost = mu*(1. + 2.*up*der_minus);
	tmp_cost += 2.*lambda*(up*der_sec_minus +1.);
	a = (int)(phi[pos-1]);
	tmp_mod = smodulus[smodsize*a+pos-1];
/*	tmp += tmp_cost*(tmp_mod*tmp_mod - noise[a]); */
	tmp += (tmp_cost*tmp_mod);


	tmp_cost = 2.*lambda*(up*der_sec_plus +1.);
	a = (int)(phi[pos+1]);
	tmp_mod = smodulus[smodsize*a+pos+1];
/*	tmp += tmp_cost*(tmp_mod*tmp_mod - noise[a]); */
	tmp += (tmp_cost * tmp_mod);
      }

      if(inrange(2,pos,smodsize-3) == NO) {

	if(pos == 0) {
	  der_plus = (double)(phi[pos +1]-phi[pos]);
	  der_sec_plus = (double)(phi[pos+2] - 2.*phi[pos+1] + phi[pos]);

	  a = (int)(phi[pos]) +  up;
	  tmp_mod = smodulus[smodsize*a+pos];
/*	  tmp_cost = (tmp_mod * tmp_mod - noise[a]); */
	  tmp_cost = tmp_mod;

	  a = (int)(phi[pos]);
	  tmp_mod = smodulus[smodsize*a+pos];
/*	  tmp_cost -= (tmp_mod * tmp_mod - noise[a]); */
	  tmp_cost -= tmp_mod;

	  tmp = tmp_cost*(-1. + mu*der_plus*der_plus);

	  a = (int)(phi[pos]) + up;
	  tmp_mod = smodulus[smodsize*a+pos];
	  tmp_cost = mu*(1. - 2.*up*der_plus);
/*	  tmp += tmp_cost*(tmp_mod*tmp_mod -noise[a]); */
	  tmp += (tmp_cost*tmp_mod);

	  a = (int)(phi[pos+1]);
	  tmp_mod = smodulus[smodsize*a+pos+1];
	  tmp_cost = lambda*(1. + 2.*up*der_sec_plus);
/*	  tmp += tmp_cost*(tmp_mod*tmp_mod -noise[a]); */
	  tmp += (tmp_cost*tmp_mod);
	}
	else if(pos == (smodsize-1)) {
	  der_minus = (double)(phi[pos] -phi[pos-1]);
	  der_sec_minus = (double)(phi[pos-2] - 2.*phi[pos-1] + phi[pos]);

	  a = (int)(phi[pos]) +  up;
	  tmp_mod = smodulus[smodsize*a+pos];
/*	  tmp_cost = (tmp_mod * tmp_mod - noise[a]); */
	  tmp_cost = tmp_mod;

	  a = (int)(phi[pos]);
	  tmp_mod = smodulus[smodsize*a+pos];
/*	  tmp_cost -= (tmp_mod * tmp_mod - noise[a]); */
	  tmp_cost -= tmp_mod;

	  tmp = -tmp_cost;

	  a = (int)(phi[pos-1]);
	  tmp_mod = smodulus[smodsize*a+pos-1];
	  tmp_cost = mu*(1. +2.*up*der_minus);
	  tmp_cost += lambda*(1.+2*up*der_sec_minus);
/*	  tmp += tmp_cost*(tmp_mod*tmp_mod -noise[a]); */
	  tmp += (tmp_cost*tmp_mod);
	}

      }

      /* To move or not to move: that's the question
	 -------------------------------------------*/
      if(tmp < (double)0.0) {
	phi[pos] = phi[pos] + up; /* good move */
	cost1 += tmp;
	tbox = 0;
      }
      else {
	gibbs = exp(-tmp/temperature);
	ran = ran1(&idum); 
	if(ran < gibbs) {      
	  phi[pos] = phi[pos] + (float)up; /* adverse move */
	  cost1 += tmp;
	  tbox = 0;
	}
	tbox ++;
	if(tbox >= stagnant)  {
	  cost[ncount++] = (float)cost1;
	  *pcount = ncount;
/*	  if((blocksize != 1)){
	    for(i = 0; i < costcount+1; i++)
	      fprintf(fp, "%f ", bcost[i]);
	    fclose(fp);
	  } */

	  /* Interpolate from subsampled ridge
	     --------------------------------*/
	  splridge(sub, phi, smodsize, phi2);
	  for(i=0;i<sigsize;i++) phi[i]=phi2[i];
	  /* splridge(1, phi, smodsize, phi2);
	  for(i=0;i<sigsize;i++) phi[i]=phi2[i];*/
	  /* free((char *)bcost); */
	  return;
	}
      }
      bcost[costcount] = (float)cost1;

      count ++;
      if(count >=  iteration) 	{
	cost[ncount++] = (float)cost1;
	*pcount = ncount;

	/* Write cost function to a file
	   -----------------------------*/
/*	if((blocksize != 1)){
	  for(i = 0; i < costcount+1; i++)
	    fprintf(fp, "%f ", bcost[i]);
	  fclose(fp);
	}
*/
	/* Interpolate from subsampled ridge
	   --------------------------------*/
	splridge(sub, phi, smodsize, phi2);
	for(i=0;i<sigsize;i++) phi[i]=phi2[i];
	/* splridge(1, phi, smodsize, phi2);
	for(i=0;i<sigsize;i++) phi[i]=phi2[i];*/
	/* free((char *)bcost); */
	printf("Done !\n");
	return;
      }
      temperature = c/log(1. + (double)count);
    }

    bcost[blocksize-1] = (float)cost1;
    if((blocksize != 1)){
/*      for(i = 0; i < blocksize; i++)
	fprintf(fp, "%f ", bcost[i]); */
      for(i = 0; i < blocksize; i++)
	bcost[i] = 0.0;
    }

    /* recalculate cost to prevent error propagation 
       ---------------------------------------------*/
    if(count % recal == 0) {
      cost1 = 0.0;
	for(i = 1; i < smodsize-1; i++) {
	  der_sec = (double)((phi[i-1]+ phi[i+1]-2 * phi[i]));
	  tmp_cost = (double)((lambda * der_sec * der_sec));

	  der_plus = (double)((phi[i] - phi[i+1]));
	  tmp_cost += (double)((mu * der_plus * der_plus));

	  a = (int)(phi[i]);
          tmp_mod = smodulus[smodsize * a + i];
	  cost1 -= (tmp_mod*(1. - tmp_cost));
/*	  cost1 -= (tmp_mod * tmp_mod - noise[a])*(1. - tmp_cost); */
	}
      
      tmp = (double)((phi[0] - phi[1]));
      tmp_cost = (double) ((mu * tmp * tmp));
      a = (int)(phi[0]);
      tmp_mod = smodulus[smodsize * a];
/*      cost1 -= (tmp_mod * tmp_mod - noise[a])*(1.- tmp_cost); */
      cost1 -= (tmp_mod*(1.- tmp_cost));

      a = (int)(phi[smodsize-1]);
      tmp_mod = smodulus[smodsize * a + smodsize-1];
/*      cost1 -= (tmp_mod * tmp_mod - noise[a]); */
      cost1 -= tmp_mod;
      
    }
    cost[ncount++] = (float)cost1;
  }
  /* return; */
}