示例#1
0
int main(int argc, char **argv)
{
    double s1, delta_vir, omega_m, x;
    int i, j;
    FILE *fp;

#ifdef PARALLEL
    printf("STARTING>>>\n");
    fflush(stdout);
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
    MPI_Comm_size(MPI_COMM_WORLD, &NTask);
    printf("TASK %d reporting for duty.\n",ThisTask);
    fflush(stdout);
#endif

    ARGC = argc;
    ARGV = argv;

    OUTPUT=0;
    HOD.fredc = HOD.freds = 1.0;

    for(i=1; i<=99; ++i)
        HOD.free[i]=0;
    wp.esys=0;

    Work.chi2=0;
    Work.imodel=1;

    USE_ERRORS = 0;
    ITRANS=4;
    HUBBLE=0.7;
    BEST_FIT = 0;
    HOD.M_sat_break = 1.0e14;
    HOD.alpha1 = 1.0;

    if(argc==1)
        endrun("./HOD.x hod.bat_file > output");

    read_parameter_file(argv[1]);

    if(REDSHIFT>0)
    {
        SIGMA_8 = SIGMA_8*growthfactor(REDSHIFT);
        HUBBLEZ = sqrt(OMEGA_M*pow(1+REDSHIFT,3.0)+1-OMEGA_M);
        OMEGA_Z = OMEGA_M*pow(1+REDSHIFT,3.0)/(OMEGA_M*pow(1+REDSHIFT,3.0)+(1-OMEGA_M));
        fprintf(stdout,"SIGMA_8(Z=%.3f)= %.4f\n",REDSHIFT,SIGMA_8);
        fprintf(stdout,"H(Z=%.3f)/H0= %.4f\n",REDSHIFT,HUBBLEZ);
        HOD.M_min = 0;
        RESET_COSMOLOGY++;
        set_HOD_params();
    }

    /* Output the virial overdensity for reference.
     */
    if(OUTPUT)
    {
        omega_m=OMEGA_M*pow(1+REDSHIFT,3.0)/(OMEGA_M*pow(1+REDSHIFT,3.0)+(1-OMEGA_M));
        x=omega_m-1;
        delta_vir=(18*PI*PI+82*x-39*x*x)/(1+x);
        printf("DELTA_VIR(Omega_m,z) = %f\n",delta_vir);
    }

    /* Do some initialization if we're doing SHMR
     */
    if(SHMR_FLAG)
    {
        if(SATELLITE_PARAMETERIZATION)SHMR_PARAMS = 14;
        if(VARIABLE_ALPHA)SHMR_PARAMS += 2;
        if(VARIABLE_EXCLUSION)wpl.a[SHMR_PARAMS+1] = EXCLUSION_RADIUS;
        wpl.ncf = SHMR_PARAMS + VARIABLE_EXCLUSION;

        HOD.pdfs = 100;
        HOD.pdfc = 101;
        wpx.calculate_two_halo = 1;
        input_stellar_mass_bins();
        // if we have input from the prompt, take that
        if(argc>2 && atoi(argv[2])!=999)
        {
            fp = openfile(argv[2]);
            fscanf(fp,"%d %d",&i,&j);
            for(i=1; i<=wpl.ncf; ++i)
                fscanf(fp,"%lf",&wpl.a[i]);
            fclose(fp);
        }
    }

    for(i=1; i<=wpl.ncf; ++i)
        printf("wpl.a[%d]= %e\n",i,wpl.a[i]);

    /* LENSING TESTING FOR ALEXIE
     */
    if(argc>2)
        IDUM_MCMC=atoi(argv[2]);
    SIGMA_8Z0 = 0.8;

    if(argc>2)
        if(atoi(argv[2])==999)
            test(argc,argv);

    /* If there's no cross-correlation function,
     * set the second number density equal to the first
     */
    if(!XCORR)
        GALAXY_DENSITY2 = GALAXY_DENSITY;

    /* Initialize the non-linear power spectrum.
     */
    nonlinear_sigmac(8.0);
    sigmac_interp(1.0E13);
    sigmac_radius_interp(1.0);

    /* Skip the HOD stuff if we're SHMR-ing it:
     */
    if(SHMR_FLAG)
    {
        if(argc>2 && atoi(argv[2])==999)test(argc, argv);
        if(argc>3 && atoi(argv[3])==999)test(argc, argv);
        goto TASKS;
    }

    /* Get the galaxy bias factor
     */
    s1=qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt);
    GALAXY_BIAS=s1/GALAXY_DENSITY;
    if(OUTPUT)
        fprintf(stdout,"Galaxy Bias bg= %f\n",GALAXY_BIAS);
    fflush(stdout);

    /* Get the galaxy satellite fraction
     */
    s1=qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/
       GALAXY_DENSITY;
    if(OUTPUT)
        fprintf(stdout,"fsat %e\n",s1);
    fflush(stdout);

    /* Mean halo mass.
     */
    if(OUTPUT)
        fprintf(stdout,"M_eff %e\n",number_weighted_halo_mass());
    fflush(stdout);

    /* Set up BETA for wp integration.
     */
    BETA = pow(OMEGA_M,0.6)/GALAXY_BIAS;
    if(OUTPUT)
        printf("BETA = %f\n",BETA);

TASKS:
    tasks(argc,argv);
}
示例#2
0
文件: m2n_mcmc.c 项目: rmredd/HOD_MN
/******************************************************************
 *
 * HOD.free[] also controls which variables will be held constant/vary
 * during MCMC minimization. Since this routine will also so z-space
 * minimization if requested, indices>6 are cosmological.
 *
 *  i     variable
 * ---    --------
 * [1] ->  M_min
 * [2] ->  M1
 * [3] ->  alpha
 * [4] ->  M_cut
 * [5] ->  sigmaM
 * [6] ->  CVIR_FAC
 * [7] ->  MaxCen (or M_cen_max)
 * [8] ->  M_sat_break
 * [9] ->  alpha1
 *
 * [10]->  OMEGA_M
 * [11]->  SIGMA_8
 * [12]->  VBIAS
 * [13]->  VBIAS_C
 * [14]->  GAMMA
 * [15]->  SPECTRAL_INDX
 * [16]->  HUBBLE PARAMETER [used for P(k)]
 *
 * [0] -> The galaxy_density will be considered data with errors on it,
 *         and therefore no variable will be fixed by the galaxy density.
 * 
 */
void m2n_mcmc()
{
  double stepfac=1;
  double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
    **evect,*eval,*aprev,*atemp,**tmp1,*opar,x1,fsat,**chain,*start_dev,*eval_prev;
  int n,i,j,k,nrot,niter=0,count=0,imax_chain=100000,NSTEP=50,NSTEP_MAX=10000,convergence=0;
  long IDUM=-555;

  int *pcheck,pcnt,ptot=20,firstflag=1,*iweight,total_weight;
  double t0,tprev,temp,chi2a,chi2b;

  double delta_halo_rhoc = 200;

  int icvir;

  //test_pdf();

  // initialize use of SYSTEMATIC ERROR
  USE_ERRORS = 1;
  M2N.IDUM = -5555;
  
  // fix the value of OEMGA_M fot T(k)
  M2N.fix_omegam = 0;
  M2N.constant_omegam = 0.27;

  opar=dvector(1,100);

  MCMC=Task.MCMC;

  pcheck=calloc(ptot,sizeof(int));

  /* Since we're at constant halo overdensity wrt RHO_CRIT,
   * set the overdensity of the halo
   */
  H2OFZ = 0.27*pow(1.25,3.0)+0.73;
  DELTA_HALO = delta_halo_rhoc/OMEGA_M*(OMEGA_M*1.25*1.25*1.25 + (1-OMEGA_M))/(1.25*1.25*1.25);

  /* read in the wp data for a single luminosity threshold sample.
   */
  wp_input();

  /* read in the M2N data.
   */
  m2n_input();
  //input_maxbcg_counts();

  Work.imodel=2;
  Work.chi2=1;


  srand48(32498793);

  /* Find the number of free parameters in the minimization
   * for the real-space correlation function.
   */
  for(n=0,i=1;i<100;++i)
    {
      n+=HOD.free[i];
      /* if(i>N_HOD_PARAMS && HOD.free[i])MCMC=3;*/
      if(OUTPUT)
	printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
    }
  if(USE_ERRORS)
    n+=3;
  if(USE_VARIABLE_ROZO)
    n+=3;
  wp.ncf=n;

  /* Find out which free parameter is for CVIR_FAC
   */
  j=0;
  if(HOD.free[6])
    for(i=0;i<6;++i)
      if(HOD.free[i])j++;
  icvir=j+1;

  if(HOD.free[0])
    {
      wp.ngal = GALAXY_DENSITY;
      wp.ngal_err = 0.1*wp.ngal;
      FIX_PARAM = 0;
    }

  if(OUTPUT)
    printf("mcmc_min> %d  free parameters\n",n);

  a=dvector(1,n);
  start_dev=dvector(1,n);
  aprev=dvector(1,n);
  atemp=dvector(1,n);
  cov1=dmatrix(1,n,1,n);
  avg1=dvector(1,n);

  tmp=dmatrix(1,n,1,n);
  tmp1=dmatrix(1,n,1,1);
  evect=dmatrix(1,n,1,n);
  eval=dvector(1,n);
  eval_prev=dvector(1,n);

  chain=dmatrix(1,imax_chain,1,n);
  iweight = ivector(1,imax_chain);
  for(i=1;i<=imax_chain;++i)
    iweight[i] = 0;

  IDUM=IDUM_MCMC;

  chi2prev=m2n_initialize(a,cov1,avg1,start_dev);
  niter++;
  for(i=1;i<=n;++i)
    {
      aprev[i] = a[i];
      chain[1][i] = a[i];
    }

  pcnt=0;
  pcheck[pcnt]=1;

  stepfac=1;
  while(niter<NSTEP)
    {
      pcnt++;
      if(pcnt==ptot)
	{
	  for(j=i=0;i<ptot;++i)j+=pcheck[i];
	  stepfac = stepfac*pow(0.9,5-j);
	  if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
	  pcnt=0;
	}
      stepfac=0.7;
      for(i=1;i<=n;++i)
	a[i] = (1+gasdev(&IDUM)*start_dev[i]*stepfac)*aprev[i];

      
      if(MCMC>1)
	{
	  RESET_COSMOLOGY++;
	  j=0;
	  for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
	  i=N_HOD_PARAMS;
	  if(HOD.free[++i])OMEGA_M         = a[++j];
	  if(HOD.free[++i])SIGMA_8         = a[++j];
	  if(HOD.free[++i])VBIAS           = a[++j];
	  if(HOD.free[++i])VBIAS_C         = a[++j];
	  if(HOD.free[++i])GAMMA           = a[++j];
	  if(HOD.free[++i])SPECTRAL_INDX   = a[++j];
	  if(HOD.free[++i])HUBBLE          = a[++j];
	}
      if(VBIAS_C<0)continue;

      if(USE_ERRORS)
	{
	  M2N.mf_amp = a[++j];
	  M2N.bias_amp = a[++j];
	  M2N.scalebias_amp = a[++j];
	}
      if(USE_VARIABLE_ROZO)
	{
	  alpha_rozo = a[++j];
	  B_rozo = a[++j];
	  sig_rozo = a[++j];
	}

      /* Hard-wire CVIR variation
       */
      if(HOD.free[6])
	CVIR_FAC = a[icvir];

      /* Since we're at constant halo overdensity wrt RHO_CRIT,
       * set the overdensity of the halo
       */
      DELTA_HALO = delta_halo_rhoc/OMEGA_M*(OMEGA_M*1.25*1.25*1.25 + (1-OMEGA_M))/(1.25*1.25*1.25);

      // Check to see if any of our parameters are out of range.
      if(parameter_out_of_range(a)){ muh(1); continue; }

 
      /* Draw random value of cvir from prior.
       */
      /* if(CVIR_FAC<0.3 || CVIR_FAC>1.2)continue; */
      /* CVIR_FAC = 0.9*drand48()+0.3;  */
      /* GAMMA = gasdev(&IDUM)*0.02 + 0.15; */


      chi2=m2n_chi2_wp_wrapper(a);
      // reset cosmology for z=0.25
      SIGMA_8 = SIGMA_8*growthfactor(0.25);
      RESET_COSMOLOGY++;
      if(MCMC>1 && chi2<1.0E7)chi2+= chi2a = chi2_m2n();
      if(MCMC>1 && chi2<1.0E7)chi2+= chi2b = chi2_number_profiles();

      if(!ThisTask){
	printf("TRY %d ",++count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	printf("%e\n",chi2);fflush(stdout);
      }
      pcheck[pcnt]=1;
      if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
	{
	  /* This for loop puts the prev element in the chain is
	   * the current trial point is rejected.
	   */

	  /* For the initialization, don't use this: we need
	   * separate elements for estimating the covariance matrix.
	   */
	  /*
	  for(i=1;i<=n;++i)
	    a[i] = aprev[i];
	  chi2 = chi2prev;
	  */
	  if(USE_IWEIGHT)
	    iweight[niter+1]++;
	  pcheck[pcnt]=0;
	  continue;
	  
	}

      niter++;
      iweight[niter]++;

      for(i=1;i<=n;++i)
	chain[niter][i]=a[i];
      for(i=1;i<=n;++i)
	avg1[i] += a[i];
      for(i=1;i<=n;++i)
	aprev[i] = a[i];
      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  cov1[i][j] += a[i]*a[j];
      chi2prev=chi2;

      if(!ThisTask){
	printf("ACCEPT %d %d ",niter,count);
	for(i=1;i<=n;++i)
	  printf("%e ",a[i]);
	printf("%e %e %e %e\n",chi2,chi2a,chi2b,chi2-chi2a-chi2b);fflush(stdout);
	printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
	       number_weighted_central_mass(),
	       qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);

	fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
	printf("FSAT %d %e %e %e %e\n",niter,fsat,HOD.M_min,HOD.sigma_logM,qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
      }

    }

  stepfac=1.6/sqrt(n);
  pcnt=-1;
  t0 = second();

  NSTEP = niter;

  while(niter<imax_chain)
    {
      pcnt++;
      if(pcnt==ptot)
	{
	  for(j=i=0;i<ptot;++i)j+=pcheck[i];
	  stepfac=1.6/sqrt(n);
	  if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
	  pcnt=0;
	}
      stepfac=1.6/sqrt(n)*1.2;

      if(convergence)goto SKIP_MATRIX;

      for(j=1;j<=n;++j)
	{
	  avg1[j]=0;
	  for(k=1;k<=n;++k)
	    cov1[j][k]=0;
	}
      total_weight = 0;
      for(i=1;i<=niter;++i)
	{
	  for(j=1;j<=n;++j)
	    {
	      avg1[j]+=chain[i][j]*iweight[i];
	      for(k=1;k<=n;++k)
		cov1[j][k]+=chain[i][j]*chain[i][k]*iweight[i];
	    }
	  total_weight+=iweight[i];
	}

      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  tmp[i][j] = cov1[i][j]/total_weight - avg1[i]*avg1[j]/(total_weight*total_weight);

      jacobi(tmp,n,eval,evect,&nrot);
      gaussj(evect,n,tmp1,1);

    SKIP_MATRIX:
      for(i=1;i<=n;++i)
	atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;

      for(i=1;i<=n;++i)
	for(a[i]=0,j=1;j<=n;++j)
	  a[i] += atemp[j]*evect[j][i];

      for(i=1;i<=n;++i) 
	a[i] += aprev[i];

      /* We seem to be having a problem with this.
       * So, broadcast the model params from the root processor.
       */
#ifdef PARALLEL      
      MPI_Bcast(&a[1],n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD);
#endif

      if(MCMC>1)
	{
	  RESET_COSMOLOGY++;
	  j=0;
	  for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
	  i=N_HOD_PARAMS;
	  if(HOD.free[++i])OMEGA_M         = a[++j];
	  if(HOD.free[++i])SIGMA_8         = a[++j];
	  if(HOD.free[++i])VBIAS           = a[++j];
	  if(HOD.free[++i])VBIAS_C         = a[++j];
	  if(HOD.free[++i])GAMMA           = a[++j];
	  if(HOD.free[++i])SPECTRAL_INDX   = a[++j];
	  if(HOD.free[++i])HUBBLE          = a[++j];
	}
      if(VBIAS_C<0)continue;

      if(USE_ERRORS)
	{
	  M2N.mf_amp = a[++j];
	  M2N.bias_amp = a[++j];
	  M2N.scalebias_amp = a[++j];
	}
      if(USE_VARIABLE_ROZO)
	{
	  alpha_rozo = a[++j];
	  B_rozo = a[++j];
	  sig_rozo = a[++j];
	}
      
      /* Hard-wire CVIR variation
       */
      if(HOD.free[6])
	CVIR_FAC = a[icvir];

      /* Since we're at constant halo overdensity wrt RHO_CRIT,
       * set the overdensity of the halo
       */
      DELTA_HALO = delta_halo_rhoc/OMEGA_M*(OMEGA_M*1.25*1.25*1.25 + (1-OMEGA_M))/(1.25*1.25*1.25);

      // Check to see if any of our parameters are out of range.
      if(parameter_out_of_range(a))continue;


      /* Draw random value of cvir from prior.
       */
      /* CVIR_FAC = a[n]; */
      /* if(CVIR_FAC<0.3 || CVIR_FAC>1.2)continue; */
      /* CVIR_FAC = 0.7*drand48()+0.3; */
      /* GAMMA = gasdev(&IDUM)*0.02 + 0.15; */
      //      printf("GAMMA %d %f %f\n",count+1,GAMMA,CVIR_FAC);

      chi2=m2n_chi2_wp_wrapper(a);
      // reset cosmology for z=0.25
      SIGMA_8 = SIGMA_8*growthfactor(0.25);
      RESET_COSMOLOGY++;
      if(MCMC>1 && chi2<1.0E7)chi2 += chi2a = chi2_m2n();
      if(MCMC>1 && chi2<1.0E7)chi2 += chi2b = chi2_number_profiles();

      tprev = t0;
      t0 = second();
      ++count;
      if(!ThisTask) {
	printf("TRY %d ",count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	if(RESTART==2) {
	  printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
		 timediff(tprev,t0));fflush(stdout); }
	else {
	  printf("%e %.2f\n",chi2,
		 timediff(tprev,t0));fflush(stdout); }
      }
      if(0) {
	printf("CPU%02d %d ",ThisTask,count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	if(RESTART==2) {
	  printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
		 timediff(tprev,t0));fflush(stdout); }
	else {
	  printf("%e %.2f\n",chi2,
		 timediff(tprev,t0));fflush(stdout); }
      }

      pcheck[pcnt]=0;
      if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
	{
	  /*
	  for(i=1;i<=n;++i)
	    a[i] = aprev[i];
	  chi2 = chi2prev;
	  */
	  if(USE_IWEIGHT)
	    iweight[niter+1]++;
	  continue;
	}
      pcheck[pcnt]=1;

      //      if(NSTEP<NSTEP_MAX)NSTEP++;
      niter++;
      if(!convergence)NSTEP = niter;
      iweight[niter]++;

      if(niter%NSTEP_MAX==0 && !convergence && niter>NSTEP_MAX)
	{
	  convergence = 1;
	  for(i=1;i<=n;++i)
	    {
	      x1=fabs(eval[i]-eval_prev[i])/eval_prev[i];
	      if(x1>0.01)convergence = 0;
	      printf("CONVERGENCE CHECK %d %d %e %e %e\n",niter/NSTEP_MAX,i,x1,eval[i],eval_prev[i]);
	    }
	  for(i=1;i<=n;++i)
	    eval_prev[i] = eval[i];
	  convergence = 0;

	  if(convergence)
	    printf("CONVERGENCE ACCOMPLISHED %d %d \n",niter,count);	    
	}
      if(niter==NSTEP_MAX)
	{
	  for(i=1;i<=n;++i)
	    eval_prev[i] = eval[i];
	}


      for(i=1;i<=n;++i)
	chain[niter][i]=a[i];
      for(i=1;i<=n;++i)
	avg1[i] += a[i];
      for(i=1;i<=n;++i)
	aprev[i] = a[i];
      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  cov1[i][j] += a[i]*a[j];
      chi2prev=chi2;

      if(!ThisTask) {
	printf("ACCEPT %d %d ",niter,count);
	for(i=1;i<=n;++i)
	  printf("%e ",a[i]);
	printf("%e %e %e %e\n",chi2,chi2a,chi2b,chi2-chi2a-chi2b);fflush(stdout);
	
	if(MCMC==1)
	  {
	    printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
		   number_weighted_central_mass(),
		   qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
	    
	    fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
	    printf("FSAT %d %e %e %e %e\n",niter,fsat,HOD.M_min,HOD.sigma_logM,qromo(func_galaxy_bias,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
	  }
      }

    }
}
示例#3
0
void mcmc_color_minimization()
{
  double stepfac=1;
  double error=1,tolerance=0,**cov1,**tmp,*a,*avg1,chi2,chi2prev,
    **evect,*eval,*aprev,*atemp,**tmp1,*opar,x1,fsat,**chain,*start_dev,*eval_prev;
  int n,i,j,k,nrot,niter=0,count=0,imax_chain=100000,NSTEP=50,NSTEP_MAX=10000,convergence=0;
  long IDUM=-555;

  int *pcheck,pcnt,ptot=20,firstflag=1,*iweight,total_weight;
  double t0,tprev,temp,chi2a,chi2b;

  opar=dvector(1,100);

  MCMC=Task.MCMC;

  pcheck=calloc(ptot,sizeof(int));

  Work.imodel=2;
  Work.chi2=1;

  
  OUTPUT=1;
  

  fprintf(stderr,"\n\nMCMC OF W_P(R_P) COLOR  DATA..........\n");
  fprintf(stderr,    "--------------------------------------------\n\n");

  HOD.blue_fraction = 0.5857; /* <- Millenium fraction (sloan);; SDSS fraction -> 0.565; */
  HOD.blue_fraction = 0.6555; /* <- Millenium fraction (B-V>0.8) */
  HOD.blue_fraction = 0.565; /* SDSS -19,-20 */
  HOD.blue_fraction = 0.492; /* SDSS -20,-21 */
  HOD.blue_fraction = 0.379; /* SDSS -21 */

  wp_color.ON = 1;

  wp_color_input();


  srand48(32498793);

  /* Find the number of free parameters in the minimization
   * for the real-space correlation function.
   */
  for(n=0,i=1;i<12;++i)
    {
      n+=HOD.free[i];
      /* if(i>N_HOD_PARAMS && HOD.free[i])MCMC=3;*/
      if(OUTPUT)
	printf("mcmc_min> free[%i] = %d\n",i,HOD.free[i]);
    }

  // add 3 parameters for the color stuff
  n+=3;
  wp.ncf=n;

  if(HOD.free[0])
    {
      wp.ngal = GALAXY_DENSITY;
      wp.ngal_err = 0.1*wp.ngal;
      FIX_PARAM = 0;
    }

  if(OUTPUT)
    printf("mcmc_min> %d  free parameters\n",n);

  a=dvector(1,n);
  start_dev=dvector(1,n);
  aprev=dvector(1,n);
  atemp=dvector(1,n);
  cov1=dmatrix(1,n,1,n);
  avg1=dvector(1,n);

  tmp=dmatrix(1,n,1,n);
  tmp1=dmatrix(1,n,1,1);
  evect=dmatrix(1,n,1,n);
  eval=dvector(1,n);
  eval_prev=dvector(1,n);

  chain=dmatrix(1,imax_chain,1,n);
  iweight = ivector(1,imax_chain);
  for(i=1;i<=imax_chain;++i)
    iweight[i] = 0;

  IDUM=IDUM_MCMC;

  //chi2prev=mcmc_initialize(a,cov1,avg1,start_dev);
  chi2prev=mcmc_color_initialize(a,cov1,avg1,start_dev);
  //initial_color_values(a,pp,yy);

  niter++;
  for(i=1;i<=n;++i)
    {
      aprev[i] = a[i];
      chain[1][i] = a[i];
    }

  pcnt=0;
  pcheck[pcnt]=1;

  stepfac=1;
  while(niter<NSTEP)
    {
      pcnt++;
      if(pcnt==ptot)
	{
	  for(j=i=0;i<ptot;++i)j+=pcheck[i];
	  stepfac = stepfac*pow(0.9,5-j);
	  if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
	  pcnt=0;
	}
      /* stepfac=0.7; */
      for(i=1;i<=n;++i)
	a[i] = (1+gasdev(&IDUM)*start_dev[i]*stepfac)*aprev[i];

      
      if(MCMC>1)
	{
	  RESET_COSMOLOGY++;
	  j=0;
	  for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
	  i=N_HOD_PARAMS;
	  if(HOD.free[++i])OMEGA_M = a[++j];
	  if(HOD.free[++i])SIGMA_8 = a[++j];
	  if(HOD.free[++i])VBIAS   = a[++j];
	  if(HOD.free[++i])VBIAS_C = a[++j];
	  if(HOD.free[++i])GAMMA   = a[++j];
	  if(HOD.free[++i])SPECTRAL_INDX   = a[++j];
	  /* if(HOD.free[++i])SIGV    = a[++j]; */
	}
      if(VBIAS_C<0)continue;

      /* Hard-wire CVIR variation
       */
      if(HOD.free[6])
	CVIR_FAC = a[3];

      chi2=chi2_wp_color_wrapper(a);	  

      if(!ThisTask){
	printf("TRY %d ",++count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	printf("%e\n",chi2);fflush(stdout);
      }

      pcheck[pcnt]=1;
      if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
	{
	  /* This for loop puts the prev element in the chain is
	   * the current trial point is rejected.
	   */
	  /* For the initialization, don't use this: we need
	   * separate elements for estimating the covariance matrix.
	   */
	  /*
	  for(i=1;i<=n;++i)
	    a[i] = aprev[i];
	  chi2 = chi2prev;
	  */
	  pcheck[pcnt]=0;
	  continue;
	  
	}

      niter++;
      iweight[niter]++;

      for(i=1;i<=n;++i)
	chain[niter][i]=a[i];
      for(i=1;i<=n;++i)
	avg1[i] += a[i];
      for(i=1;i<=n;++i)
	aprev[i] = a[i];
      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  cov1[i][j] += a[i]*a[j];
      chi2prev=chi2;

      if(!ThisTask){
	printf("ACCEPT %d %d ",niter,count);
	for(i=1;i<=n;++i)
	  printf("%e ",a[i]);
	printf("%e\n",chi2);fflush(stdout);
	printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
	       number_weighted_central_mass(),
	       qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
	printf("FSAT %d %e %e %e %e\n",niter,HOD.M_min,wp.fsat_red,wp.fsat_blue,wp.fsat_all);

      }

    }
 RESTART_POINT:

  stepfac=1.6/sqrt(n);
  pcnt=-1;
  t0 = second();

  NSTEP = niter;

  while(niter<imax_chain)
    {
      pcnt++;
      if(pcnt==ptot)
	{
	  for(j=i=0;i<ptot;++i)j+=pcheck[i];
	  //stepfac=1.6/sqrt(n);
	  //stepfac=0.6/sqrt(n);
	  //	  stepfac = stepfac*pow(0.9,6-j);
	  stepfac = 0.25;
	  stepfac = 0.5;
	  stepfac=1.6/sqrt(n);
	  if(!ThisTask)printf("STEPFAC %f %d %d\n",stepfac,j,count);
	  pcnt=0;
	}
      stepfac=1.6/sqrt(n);
      //stepfac = 0;

      if(convergence)goto SKIP_MATRIX;
      // if(niter>NSTEP_MAX && niter%NSTEP_MAX!=0)goto SKIP_MATRIX;

      for(j=1;j<=n;++j)
	{
	  avg1[j]=0;
	  for(k=1;k<=n;++k)
	    cov1[j][k]=0;
	}
      total_weight = 0;
      for(i=1;i<=niter;++i)
	{
	  for(j=1;j<=n;++j)
	    {
	      avg1[j]+=chain[i][j]*iweight[i];
	      for(k=1;k<=n;++k)
		cov1[j][k]+=chain[i][j]*chain[i][k]*iweight[i];
	    }
	  total_weight+=iweight[i];
	}

      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  tmp[i][j] = cov1[i][j]/total_weight - avg1[i]*avg1[j]/(total_weight*total_weight);

      jacobi(tmp,n,eval,evect,&nrot);
      gaussj(evect,n,tmp1,1);

    SKIP_MATRIX:
      if(RESTART==4)convergence = 1;

      if(RESTART && count==0)stepfac=0;
      for(i=1;i<=n;++i)
	atemp[i] = gasdev(&IDUM)*sqrt(eval[i])*stepfac;

      for(i=1;i<=n;++i)
	for(a[i]=0,j=1;j<=n;++j)
	  a[i] += atemp[j]*evect[j][i];

      for(i=1;i<=n;++i) 
	a[i] += aprev[i];

      /* We seem to be having a problem with this.
       * So, broadcast the model params from the root processor.
       */
#ifdef PARALLEL      
      MPI_Bcast(&a[1],n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD);
#endif

      // CHeck that the chi2 for the last point in the restart chain
      // is recovered.
      /*
      if(RESTART && !count)
	for(i=1;i<=n;++i)
	  a[i] = aprev[i];
      */
      if(RESTART==5)
	{
	  j = count+1;
	  if(j>4000)exit(0);
	  for(i=1;i<=n;++i)
	    a[i] = chain[j][i];
	}

      /*
      if(!ThisTask)
	for(i=1;i<=n;++i)
	  {
	    printf("COV %d %d %e ",count,i,sqrt(eval[i]));
	    for(j=1;j<=n;++j)
	      printf("%e ",evect[j][i]);
	    printf("\n");
	  }
      */

      /* Using only variances
       */
      //for(i=1;i<=n;++i) 
      //	a[i] = aprev[i] + gasdev(&IDUM)*sqrt(tmp[i][i])*stepfac;

      if(MCMC>1)
	{
	  RESET_COSMOLOGY++;
	  j=0;
	  for(i=1;i<=N_HOD_PARAMS;++i)if(HOD.free[i])j++;
	  i=N_HOD_PARAMS;
	  if(HOD.free[++i])OMEGA_M = a[++j];
	  if(HOD.free[++i])SIGMA_8 = a[++j];
	  if(HOD.free[++i])VBIAS   = a[++j];
	  if(HOD.free[++i])VBIAS_C = a[++j];
	  if(HOD.free[++i])GAMMA   = a[++j];
	  if(HOD.free[++i])SPECTRAL_INDX   = a[++j];
	  /* if(HOD.free[++i])SIGV    = a[++j]; */
	}
      if(VBIAS_C<0)continue;
      
      /* Hard-wire CVIR variation
       */
      if(HOD.free[6])
	CVIR_FAC = a[3];

      chi2=chi2_wp_color_wrapper(a);	  

      tprev = t0;
      t0 = second();
      ++count;
      if(!ThisTask) {
	printf("TRY %d ",count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	if(RESTART==2) {
	  printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
		 timediff(tprev,t0));fflush(stdout); }
	else {
	  printf("%e %.2f\n",chi2,
		 timediff(tprev,t0));fflush(stdout); }
      }
      if(0) {
	printf("CPU%02d %d ",ThisTask,count);
	for(i=1;i<=n;++i)
	  printf("%.4e ",a[i]);
	if(RESTART==2) {
	  printf("%e %e %.2f\n",chi2,chi2/(1+exp(-count/100.0)),
		 timediff(tprev,t0));fflush(stdout); }
	else {
	  printf("%e %.2f\n",chi2,
		 timediff(tprev,t0));fflush(stdout); }
      }

      pcheck[pcnt]=0;
      if(!(chi2<chi2prev || drand48() <= exp(-(chi2-chi2prev)/2)))
	{
	  /*
	  for(i=1;i<=n;++i)
	    a[i] = aprev[i];
	  chi2 = chi2prev;
	  */
	  continue;
	}
      pcheck[pcnt]=1;

      //      if(NSTEP<NSTEP_MAX)NSTEP++;
      niter++;
      if(!convergence)NSTEP = niter;
      iweight[niter]++;

      if(niter%NSTEP_MAX==0 && !convergence && niter>NSTEP_MAX)
	{
	  convergence = 1;
	  for(i=1;i<=n;++i)
	    {
	      x1=fabs(eval[i]-eval_prev[i])/eval_prev[i];
	      if(x1>0.01)convergence = 0;
	      printf("CONVERGENCE CHECK %d %d %e %e %e\n",niter/NSTEP_MAX,i,x1,eval[i],eval_prev[i]);
	    }
	  for(i=1;i<=n;++i)
	    eval_prev[i] = eval[i];
	  convergence = 0;

	  if(convergence)
	    printf("CONVERGENCE ACCOMPLISHED %d %d \n",niter,count);	    
	}
      if(niter==NSTEP_MAX)
	{
	  for(i=1;i<=n;++i)
	    eval_prev[i] = eval[i];
	}


      for(i=1;i<=n;++i)
	chain[niter][i]=a[i];
      for(i=1;i<=n;++i)
	avg1[i] += a[i];
      for(i=1;i<=n;++i)
	aprev[i] = a[i];
      for(i=1;i<=n;++i)
	for(j=1;j<=n;++j)
	  cov1[i][j] += a[i]*a[j];
      chi2prev=chi2;

      if(!ThisTask) {
	printf("ACCEPT %d %d ",niter,count);
	for(i=1;i<=n;++i)
	  printf("%e ",a[i]);
	printf("%e\n",chi2);fflush(stdout);
	
	printf("FSAT %d %e %e %e %e\n",niter,HOD.M_min,wp.fsat_red,wp.fsat_blue,wp.fsat_all);
	if(MCMC==1)
	  {
	    printf("HSTATS %d %e %e %e %e\n",niter,HOD.M_min,number_weighted_halo_mass(),
		   number_weighted_central_mass(),
		   qromo(func_satellite_density,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY);
	    
	    fsat = qromo(func_satfrac,log(HOD.M_low),log(HOD.M_max),midpnt)/GALAXY_DENSITY;
	  }
      }

    }
}