示例#1
0
文件: ABC.c 项目: JZorrilla/camelus
void free_SMC_ABC_t(SMC_ABC_t *ABC)
{
  if (ABC->oldPart)      {free_particle_arr(ABC->oldPart);    ABC->oldPart = NULL;}
  if (ABC->newPart)      {free_particle_arr(ABC->newPart);    ABC->newPart = NULL;}
  if (ABC->diffList)     {free_double_arr(ABC->diffList);     ABC->diffList = NULL;}
  
  if (ABC->obsSummary)   {free_double_arr(ABC->obsSummary);   ABC->obsSummary = NULL;}
  if (ABC->simulSummary) {free_double_arr(ABC->simulSummary); ABC->simulSummary = NULL;}
  if (ABC->peakHist)     {free_hist_t(ABC->peakHist);         ABC->peakHist = NULL;}
  
  if (ABC->sampArr)      {free_sampler_arr(ABC->sampArr);     ABC->sampArr = NULL;}
  if (ABC->hMap)         {free_halo_map(ABC->hMap);           ABC->hMap = NULL;}
  if (ABC->gMap)         {free_gal_map(ABC->gMap);            ABC->gMap = NULL;}
  if (ABC->kMap)         {free_map_t(ABC->kMap);              ABC->kMap = NULL;}
  if (ABC->nMap)         {free_map_t(ABC->nMap);              ABC->nMap = NULL;}
  if (ABC->transformer)  {free_FFT_t(ABC->transformer);       ABC->transformer = NULL;}
  if (ABC->peakList)     {free_double_arr(ABC->peakList);     ABC->peakList = NULL;}
  free(ABC); ABC = NULL;
  return;
}
示例#2
0
文件: ABC.c 项目: JZorrilla/camelus
void free_particle_arr(particle_arr *part)
{
  int i;
  if (part->array) {
    for (i=0; i<part->p; i++) {free_particle_t(part->array[i]); part->array[i] = NULL;}
  }
  if (part->mean) {free_double_arr(part->mean); part->mean = NULL;}
  gsl_matrix_free(part->cov);
  gsl_matrix_free(part->cov2);
  gsl_matrix_free(part->invCov);
  gsl_permutation_free(part->perm);
  free(part);
  return;
}
/*
 * Finds the constant required to normalise the function to the given set of event
 * data. The check limit specifies the range of values that will be checked to find
 * the constant. Starts from 1 and goes up to check_limit with the given step.
 * Returns a negative value if something goes wrong. To get a good normaliser for
 * the actual function, it is probably best to use the number of subintervals equivalent
 * to the length of the interval divided by the time steps that lambda represents.
 * This is usually one time step. As an example, if lambda represents the number of 
 * events in one second, and your interval time is 100 seconds, you should use 100
 * intervals. A normaliser is required for functions estimated using the gaussian
 * kernel method due to the way that gaussians are summed. Dividing the values of
 * the estimated function by the return value of this function will give a function
 * that is on the same scale as the generating function.
 */
double _find_normaliser(void* f1, double_arr* events, double interval_start,
		       double interval_end, double check_start, double check_limit,
		       double step, int subintervals, char* type)
{
    double normaliser = check_start;
    double best = -INFINITY;
    double best_normaliser = -INFINITY;

    int* bin_counts = sum_events_in_interval(events->data, events->len, interval_start,
					     interval_end, subintervals);

    double* midpoints = get_interval_midpoints(interval_start, interval_end, subintervals);

    double_arr* function_values;

    if (strcmp(type, "gauss") == 0){
	function_values = sum_gaussians_at_points((gauss_vector*) f1, midpoints, subintervals);
    } else if (strcmp(type, "base") == 0){
	function_values = estimate_at_points((est_arr*) f1, midpoints, subintervals);
    } else {
	printf("Unknown type \"%s\"when finding normalisation constant.\n", type);
	exit(1);
    }

    while(normaliser <= check_limit){
	double pmf_sum = sum_log_pdfs(bin_counts, function_values->data, normaliser, subintervals);
//	printf("Sum with normaliser %lf: %lf, current best %lf (%lf).\n", normaliser, pmf_sum, best, best_normaliser);
	if (pmf_sum > best) {
	    best = pmf_sum;
	    best_normaliser = normaliser;
//	    printf("New best normaliser is %lf with a sum of %lf\n", best_normaliser, best);
	}
//		printf("total pmf is %lf, normaliser is %lf\n", pmf_sum, normaliser);
	normaliser += step;
    }

    free(midpoints);
    free(bin_counts);
    free_double_arr(function_values);
    return best_normaliser;
}
/*
 * Computes the time delay between two functions f1 and f2. Requires data about the
 * event streams of which each of the functions is an estimate. f1 is the base function,
 * if there are more than two functions. This function is taken as the baseline against
 * which all other functions are compared, and so the time delay will be given relative to
 * it. The function splits the interval specified in the parameter file into a number of
 * bins, and calculates the number of events that fall into each bin. To calculate the time delay,
 * f2 is shifted relative to f1, starting at a negative shift and moving to a positive one.
 * The process is iterative, and the granularity of the estimate is defined by the step
 * specified in the parameter file. The estimate of the time delay is the point at which the
 * sum of the probability mass functions taken at a number of points along the combination of
 * the base function and the shifted function is minimised. In other words, the shift at
 * which the bin counts most closely match the lambda values taken from the functions
 * is the estimate returned. The functions are combined such that for all possible delays
 * in the range [-max_delay, max_delay], the same amount of data is gathered.
 */
double _estimate_delay_pmf(char* outfile, double_arr* base_events, double_arr* f2_events, void* f1, 
			   void* f2, double combine_start, double combine_interval,
			   double combine_step, int num_bins, double start_delta,
			   double end_delta, double max_delay, double delta_step, double normaliser,
			   char* type, int output_switch)
{
    // Always work on two streams
    int num_streams = 2;
    double combine_end = combine_start + combine_interval;

    double bin_length = (combine_end - combine_start)/num_bins;
    double current_delta = start_delta;

    // Set the initial values for our estimate
    double best_delta = -INFINITY;
    double best_value = -INFINITY;
    
    // We don't know which type we will get, so use a void pointer to store
    // it and cast later.
    void** store = NULL;

    if (strcmp(type, "gauss") == 0){
	store = malloc(sizeof(gauss_vector*) * 2);
	store[0] = (gauss_vector*)f1;
	store[1] = (gauss_vector*)f2;
    } else if (strcmp(type, "base") == 0){
	store = malloc(sizeof(est_arr*) * 2);
	store[0] = (est_arr*)f1;
	store[1] = (est_arr*)f2;
    }

#ifdef VERBOSE
    printf("cstart %lf cend %lf cint %lf cstep %lf nbins %d startd %lf endd %lf maxd %lf dstep %lf norm %lf\n",
    	   combine_start, combine_end, combine_interval, combine_step, num_bins, start_delta, end_delta, max_delay, delta_step, normaliser);
#endif

    double_arr* time_delay = init_double_arr(2);
    time_delay->data[0] = 0;
    double_multi_arr* combined = NULL;
    double_multi_arr* delay_pmfs = init_multi_array(2, (int)((end_delta - start_delta)/delta_step)+1);

    // PMF sums will be calculated for both streams.
    int* bin_counts1 = sum_events_in_interval(base_events->data, base_events->len, combine_start,
					     combine_end, num_bins);
    int* bin_counts2 = sum_events_in_interval(f2_events->data, f2_events->len, combine_start,
					     combine_end, num_bins);
    
    double* midpoints = get_interval_midpoints(combine_start, combine_end,
					       num_bins);
    double* lambda_sums = malloc(sizeof(double) * num_bins);
    double* best_lambda_sums = malloc(sizeof(double) * num_bins);

    // How many bins need to be skipped to ensure that only the bins that are present in 
    int skip_bins = (int) max_delay/bin_length;
    int i, j = 0;

    while (current_delta <= end_delta){
	// get the combined function with the delay applied
	// compare the combined function to the bin counts of the stream by calculating the pmf for each interval
	// to do this, first get the bin counts. These will remain constant for the function.
	// then, calculate the interval times for each bin, which will be the same for each
	// sum the values of lambda within this interval at each time. This will be one lambda per second, probably,
	// since each lambda represents the number of arrivals per single time step
	// finally, find the poisson pmf of the two values - gsl_ran_poisson_pdf(bin count, lambda sum for bin)
	//	printf("current delta %lf\n", current_delta);
	time_delay->data[1] = current_delta;
	if (strcmp(type, "gauss") == 0){
      	    combined = combine_gauss_vectors((gauss_vector**)store, time_delay,
					     combine_start, combine_end, combine_step,
					     normaliser, num_streams);
    	} else if (strcmp(type, "base") == 0){
    	    combined = combine_functions((est_arr**)store, time_delay, combine_start,
					 combine_interval, combine_step, num_streams);
    	} else {
	    printf("Unknown type for estimate \"%s\" when estimating delta.\n", type);
	    exit(1);
	}

	for (i = 0; i < num_bins; ++i) {
	    // find the sum of lambda values for each subinterval

	    // The lambda sums must be normalised so that they are on the same scale as the bin counts.
	    lambda_sums[i] = sum_array_interval(combined->data[0], combined->data[1],
					     i * bin_length, (i + 1) * bin_length,
						1, combined->lengths[0]);
#ifdef VERBOSE
	    printf("subinterval start %lf, subinterval end %lf\n", i * bin_length, (i + 1) * bin_length);
	    printf("sum of lambdas in interval %lf\n", lambda_sums[i]);
#endif
	}

	int s2_shift = (int)(ceil((max_delay - current_delta)/bin_length));
//	printf("s2 shift is %d. Number of bins being checked %d\n", s2_shift, num_bins - 2 * skip_bins);

#ifdef VERBOSE2
	for (i = 0; i < num_bins - 2 * skip_bins; ++i) {
	    printf("Counts 1 %d counts 2 %d, comparing %lf from 1 with %lf from 2, lambda is %lf\n",
		   (bin_counts1+skip_bins)[i], (bin_counts2+s2_shift)[i],
		   (midpoints+skip_bins)[i], (midpoints+s2_shift)[i],
		   (lambda_sums+skip_bins)[i]);
	}
#endif

	double total1 = sum_log_pdfs(bin_counts1 + skip_bins, lambda_sums + skip_bins, 1, num_bins - 2 * skip_bins);
	// need to shift bin_counts2 so that the correct intervals line up for the given delay
	double total2 = sum_log_pdfs(bin_counts2 + s2_shift, lambda_sums + skip_bins, 1, num_bins - 2 * skip_bins);
	double cumulative = total1 + total2;
	delay_pmfs->data[0][j] = current_delta;
	delay_pmfs->data[1][j] = cumulative;

//	printf("pmf sum is %lf\n", total);
	if (cumulative > best_value){
	    //	    printf("New value %lf is less than old %lf. guess updated to %lf\n", cumulative, best_value, current_delta);
	    best_value = cumulative;
	    best_delta = current_delta;
	    memcpy(best_lambda_sums, lambda_sums, sizeof(double) * num_bins);
	} else {
	    //	    printf("New value %lf is larger than old %lf. guess remains at %lf\n", cumulative, best_value, best_delta);
	}

	current_delta += delta_step;
	free_double_multi_arr(combined);
	j++;
    }

    if (outfile != NULL && output_switch != 0){
	char* out = malloc(strlen(outfile) + strlen("_pmf_lambda.dat") + 5);
	if (output_switch >= 1){
	    sprintf(out, "%s_pmf_delay.dat", outfile);
	    output_double_multi_arr(out, "w", delay_pmfs);
	}

	if (output_switch >= 2){
	    sprintf(out, "%s_pmf_lambda.dat", outfile);
	    FILE *fp = fopen(out, "w");
		
	    for (i = 0; i < num_bins; ++i) {
		fprintf(fp, "%lf %lf\n", midpoints[i], best_lambda_sums[i]);
	    }
	    fclose(fp);


	    sprintf(out, "%s_pmf_bins.dat", outfile);
	    fp = fopen(out, "w");
	    for (i = 0; i < num_bins; ++i) {
		fprintf(fp, "%lf %d %d\n", midpoints[i], bin_counts1[i], bin_counts2[i]);
	    }
	    fclose(fp);
	}
	
	free(out);
    }

    free(midpoints);
    free(lambda_sums);
    free(best_lambda_sums);
    free(bin_counts1);
    free(bin_counts2);
    free(store);
    free_double_arr(time_delay);
    free_double_multi_arr(delay_pmfs);
    
    return best_delta;
}