Ejemplo n.º 1
0
void spline_coef(int *method, int *n, double *x, double *y,
		 double *b, double *c, double *d, double *e)
{
    switch(*method) {
    case 1:
	periodic_spline(*n, x, y, b, c, d, e);	break;

    case 2:
	natural_spline(*n, x, y, b, c, d);	break;

    case 3:
	fmm_spline(*n, x, y, b, c, d);	break;
    }
}
Ejemplo n.º 2
0
void random_wave(double *wav_org, double *dist, int N, int flag, double *y, int NS){
  
/* wav_org  - array of input wavelegnth
   dist     - array of photon number distribution
   N        - size of wav_org and dist
   flag     - interpolation degree : 0 (for line list) or 3 (for continious spectra)
   y        - output: randomly sampled wavelength
   NS       - size of y (number of sampling points) 
*/

    clock_t start = clock();
    srand48((long)time(NULL));
    int n, N_plus = N + 1;					//number of extended data

    if (flag == 0){     					// no interpolation, step-like CDF, emission-line spectra 
	printf("Dealing with line list\n");
	double *CDF  = malloc(sizeof(double) * N_plus);
	CDF[0] = 0;
	for (n = 0; n < N; n++)
	    CDF[n+1] = CDF[n] + dist[n];
	double total = CDF[N];
	for (n = 0; n <= N; n++)
	    CDF[n] = CDF[n] / total;				//normalization
	
	unsigned long long ns;
	double random;
	int i, j, k;
	//double *num_den = malloc(sizeof(double) * N);
	for (ns = 0; ns < NS; ns ++) {
	    random = drand48();
	    i = 0;
	    j = N;
	    do{      						// search algorithm (bi-section) to find position of random in CDF
		k = (i+j)/2;
		if (random < CDF[k])
		    j = k;
		else i = k;
	    } while(j > i+1);      				//until random number falls into (CDF[i], CDF[i+1])
	    y[ns] = wav_org[i];
	    //num_den[i] ++;
	}
	
	/*---data analysis---*/
/*      
	FILE *num_den_file;
	    num_den_file = fopen("./num_den_cum.dat", "w+");
	FILE *normalized_PDF_file;
	    normalized_PDF_file = fopen("./normalized_PDF.dat", "w+");    
	printf("Writing statistics to file\n");
	for (n = 0; n < N; n++) {
	    fprintf(num_den_file, "%lf\t%le\n", wav_org[n], (double) num_den[n] / NS);	//normalization
	    fprintf(normalized_PDF_file, "%lf\t%le\n", wav_org[n], dist[n] / total);
	}
	fclose(num_den_file);
	fclose(normalized_PDF_file);
*/      
    }
    
  if (flag == 3){  						//continious spectra, data interpolation
      
      /*---CDF; Data extension---*/
      
      double *wav 		= malloc(sizeof(double) * N_plus);
      double *CDF 		= malloc(sizeof(double) * N_plus);
      double *delta_lambda 	= malloc(sizeof(double) * N);
      double *flux 		= malloc(sizeof(double) * N);
           
      /*---add a threshold where flux is too small---*/
  
      double sum = 0;
      for (n = 0; n < N; n++) {
	  flux[n] = dist[n];
	  sum += flux[n];
      }
      double threshold = sum * pow(10, -14);	//15 decimal places for double precision
      
      for (n = 0; n < N; n++)
	  if (flux[n] < threshold)
		  flux[n] = threshold;
      
      //---delta lambda---  
      delta_lambda[0] = wav_org[1] - wav_org[0];
      for (n = 1; n < N-1; n++)
	  delta_lambda[n] = (wav_org[n+1] - wav_org[n-1]) / 2;
      delta_lambda[N-1] = wav_org[N-1] - wav_org[N-2];
      
      //---CDF---
      CDF[0] = 0;
      CDF[1] = flux[0] * delta_lambda[0];
      wav[0] = 1.5 * wav_org[0] - 0.5 * wav_org[1];
      for (n = 1; n < N; n++) {
	  CDF[n+1] = CDF[n] + flux[n] * delta_lambda[n];
	  wav[n] = (wav_org[n-1] + wav_org[n]) / 2;
      }
      wav[N] = 1.5 * wav_org[N-1] - 0.5 * wav_org[N-2];
      double total = CDF[N];
      //printf("total = %le\n", total);
      for (n = 0; n < N_plus; n++) 
	  CDF[n] = CDF[n] / total;
     
      free(flux);
      /*---data output---
      FILE *order_43;
	  order_43 = fopen("./order_43.dat", "w+");
      for(n = 0; n < N_plus; n++)
	  fprintf(order_43, "%le\t%le\n", wav[n], CDF[n]);
      fclose(order_43);
      
      FILE *spec_43;
	  spec_43 = fopen("./spec_43.dat", "w+");
      for(n = 0; n < N; n++)
	  fprintf(spec_43, "%le\t%le\n", wav_org[n], dist[n]);
      fclose(spec_43);      */
      
      /*FILE *inter_43;
	  inter_43 = fopen("./inter_43.dat", "w+");*/
      
	       
      /*---interpolation---*/
      unsigned long long ns;
      double *b, *c, *d, *x;
      b = malloc(sizeof(double) * N_plus);
      c = malloc(sizeof(double) * N_plus);
      d = malloc(sizeof(double) * N_plus);
      natural_spline(N_plus, CDF, wav, b, c, d);		//wav as a function of CDF
      
      /*---sampling---*/
      if (NS <= pow(10, 7)){
	x = malloc(sizeof(double) * NS);
	for (ns = 0; ns < NS; ns ++)
	    x[ns] = drand48();
	printf("Sampling in progress\n");
	spline_eval(&NS, x, y, &N_plus, CDF, wav, b, c, d);	//returns y to be the sampling wavelength
	/*for (n = 0; n < 500; n++)
	    printf("%le\t%16.14lf\n", x[n], y[n]);
	for (n = 0; n < NS/10; n++)
	    fprintf(inter_43, "%le\t%16.14lf\n", x[n], y[n]);
	fclose(inter_43);      */
	free(x);
      }
      
      else {							//(NS > pow(10, 7))
	  int new_NS = pow(10, 7);
	  int progress, times, TIMES = (int)(NS / new_NS), tail = NS - new_NS * TIMES;
	  double ratio;
	  x	= malloc(sizeof(double) * new_NS);
	  printf("Sampling in progress\n");
	  for (times = 0; times < TIMES; times ++){
	      for (ns = 0; ns < new_NS; ns ++)
		  x[ns] = drand48();
	    spline_eval(&new_NS, x, y, &N_plus, CDF, wav, b, c, d);
	    y += new_NS;
	    // Show the load bar.
	    ratio = (double)(times + 1) / TIMES;
	    printf("%3d%% [", (int)(ratio*100) );
	    for (progress = 0; progress < (int)(ratio * 50) ; progress++)
		printf("=");
	    printf(">");
	    for (progress = (int)(ratio * 50); progress < 50; progress++)
		printf(" ");
	    printf("]\r");
	    fflush(stdout);
	  }
	  free(x);

	  double *x2      = malloc(sizeof(double) * tail);
	  for (ns = 0; ns < tail; ns ++)
	      x2[ns] = drand48();
	  spline_eval(&tail, x2, y, &N_plus, CDF, wav, b, c, d);
	  printf("\n");
	  free(x2);
	  y -= new_NS * TIMES;
    }
    
/*    
    FILE *wavelegnth_sam;
	wavelegnth_sam = fopen("./wavelegnth_sam.dat", "w+");
    for (ns = 0; ns < NS; ns++)
	fprintf(wavelegnth_sam, "%lf\n", y[ns]);
    fclose(wavelegnth_sam);
*/   
    
    /*---deallocate array memory---*/
    
    free(b);
    free(c);
    free(d);
    free(wav);
    free(CDF);
    free(delta_lambda);


  }
  
    clock_t ends = clock();
    printf("%.2f s to return %.2le wavelegnths\n",(double) (ends - start) / CLOCKS_PER_SEC, (double)NS);
    
}