Beispiel #1
0
void sort_mask_pixnum(gsl_vector_ulong *pixnum_array, 
		      gsl_vector_int *resolution_array, unsigned long n_mask,
		      gsl_vector_int *resolution_region_array, 
		      gsl_vector_ulong *resolution_start_array,
		      gsl_vector_ulong *resolution_finish_array, int n_res)
{
  unsigned long i, j, k, n, n_sub_mask;
  gsl_vector_ulong *tmp_pixnum_array, *total_pixnum_array;
  gsl_permutation *pixel_index;

  /* This routine prepares a list of masks and resolutions to be put into
     the resolution struct; it will rarely be called by the user.
  */

  total_pixnum_array = gsl_vector_ulong_alloc(n_mask);

  for (k=0;k<n_res;k++) {
    if (resolution_start_array->data[k] == resolution_finish_array->data[k]) {
      j = resolution_start_array->data[k];
      total_pixnum_array->data[j] = pixnum_array->data[j];
    } else {
      n_sub_mask = resolution_finish_array->data[k] - 
	resolution_start_array->data[k] + 1;
      
      tmp_pixnum_array = gsl_vector_ulong_alloc(n_sub_mask);
      pixel_index = gsl_permutation_alloc(n_sub_mask);
      
      j = resolution_start_array->data[k];
      for (i=0;i<n_sub_mask;i++) {
	tmp_pixnum_array->data[i] = pixnum_array->data[j];
	j++;
      }
  
      gsl_sort_vector_ulong_index(pixel_index,tmp_pixnum_array);

      j = resolution_start_array->data[k];
      for (i=0;i<n_sub_mask;i++) {
	n = pixel_index->data[i];
	total_pixnum_array->data[j] = tmp_pixnum_array->data[n];
	j++;
      }
      
      gsl_vector_ulong_free(tmp_pixnum_array);
      gsl_permutation_free(pixel_index);
    }
  }
   
  for (i=0;i<n_mask;i++) 
    pixnum_array->data[i] = total_pixnum_array->data[i];

  gsl_vector_ulong_free(total_pixnum_array);

}
Beispiel #2
0
void make_resolution_struct(gsl_vector_ulong *pixnum_array, 
			    gsl_vector_int *resolution_array, 
			    unsigned long n_pixel, 
			    resolution_struct *res_struct, int n_res)
{
  unsigned long i,j;
  gsl_vector_ulong *resolution_start_array, *resolution_finish_array;
  gsl_vector_int *resolution_region_array;
  int k; 

  /* Given input arrays of resolutions and masks, this routine puts 
     together the resolution structure.  Each element of this structure
     contains an array of masks at the same resolution as well as information
     about the number of masks and the common resolution.  This allows for
     efficient searching of the masks at the desired resolution, while 
     avoiding those of different resolution.
  */

  resolution_region_array = gsl_vector_int_alloc(n_res);
  resolution_start_array = gsl_vector_ulong_alloc(n_res);
  resolution_finish_array = gsl_vector_ulong_alloc(n_res);

  find_resolution_bounds(resolution_array,n_pixel,resolution_region_array,
			 resolution_start_array,resolution_finish_array);

  sort_mask_pixnum(pixnum_array,resolution_array,n_pixel,
		   resolution_region_array,resolution_start_array,
		   resolution_finish_array,n_res);
  
  for (k=0;k<n_res;k++) {
    res_struct[k].start = resolution_start_array->data[k];
    res_struct[k].finish = resolution_finish_array->data[k];
    res_struct[k].n_pixel = 
      res_struct[k].finish - res_struct[k].start + 1;
    res_struct[k].resolution = resolution_region_array->data[k];
    res_struct[k].area = pix_area(res_struct[k].resolution,
				  pixnum_array->data[res_struct[k].start]);
    /* printf("%u pixels with resolution of %i\n",res_struct[k].n_pixel,
       res_struct[k].resolution);  */
    res_struct[k].pixnum = gsl_vector_ulong_alloc(res_struct[k].n_pixel);
    j = res_struct[k].start;
    for (i=0;i<res_struct[k].n_pixel;i++) {
      res_struct[k].pixnum->data[i] = pixnum_array->data[j];
      j++;
    }
  }

  gsl_vector_int_free(resolution_region_array);
  gsl_vector_ulong_free(resolution_start_array);
  gsl_vector_ulong_free(resolution_finish_array);

}
Beispiel #3
0
void sort_mask_resolution(gsl_vector_int *resolution_array, 
			  gsl_vector_ulong *pixnum_array, unsigned long n_mask)
{
  gsl_permutation *pixel_index;
  gsl_vector_ulong *tmp_pixnum_array; 
  gsl_vector_int *tmp_resolution_array;
  unsigned long i, j;
  
  /* Given a list of masks and resolutions, return each list sorted by the 
     resolution.  This routine is needed to make the resolution structure. */

  tmp_pixnum_array = gsl_vector_ulong_alloc(n_mask);
  tmp_resolution_array = gsl_vector_int_alloc(n_mask);
  pixel_index = gsl_permutation_alloc(n_mask);

  gsl_sort_vector_int_index(pixel_index,resolution_array);

  for (i=0;i<n_mask;i++) {
    j = pixel_index->data[i];
    tmp_pixnum_array->data[i] = pixnum_array->data[j];
    tmp_resolution_array->data[i] = resolution_array->data[j];
  }

  for (i=0;i<n_mask;i++) {
    pixnum_array->data[i] = tmp_pixnum_array->data[i];
    resolution_array->data[i] = tmp_resolution_array->data[i];
  }

  gsl_vector_int_free(tmp_resolution_array);
  gsl_vector_ulong_free(tmp_pixnum_array);
  gsl_permutation_free(pixel_index);

}
Beispiel #4
0
/*
 * Frees p
 *
 * Note that the distance matrix p->M is *not* freed by this function.
 */
void pam_partition_free(const pam_partition p)
{
  gsl_vector_uchar_free(p->in_set);
  gsl_vector_ulong_free(p->cl_index);
  gsl_vector_free(p->cl_dist);

  free(p);
}
Beispiel #5
0
void make_superpix_struct(int superpix_resolution,
			  gsl_vector_ulong *pixnum_array, 
			  gsl_vector_int *resolution_array, 
			  unsigned long n_pixel, 
			  superpixnum_struct *superpix_struct, 
			  unsigned long n_superpix)
{
  unsigned long i,j, k;
  gsl_vector_ulong *superpix_start_array, *superpix_finish_array;
  gsl_vector_ulong *superpix_region_array, *tmp_pixnum_array, *superpix_array;
  gsl_vector_ulong *tmp_superpix_array;
  gsl_vector_int *tmp_resolution_array;
  gsl_permutation *pixel_index;

  /* Similar to the resolution structure, the superpix structure groups a
     list of masks by common superpixel index.  These masks are then stored
     in a resolution structure, futher sorting them by resolution.  The 
     combination of these two structures allows one to quickly exclude the
     vast majority of the masks for any sort of filtering algorithm and check
     only those masks most likely to contain a given point.
     
     This routine serves as a wrapper for the various steps required to fill
     in the superpixel structure, requiring only that the user call
     find_n_superpix first (in order to allocate the superpixel structure),
     and then call this routine.
  */

  superpix_region_array = gsl_vector_ulong_alloc(n_superpix);
  superpix_start_array = gsl_vector_ulong_alloc(n_superpix);
  superpix_finish_array = gsl_vector_ulong_alloc(n_superpix);
  superpix_array = gsl_vector_ulong_alloc(n_pixel);
  tmp_superpix_array = gsl_vector_ulong_alloc(n_pixel);
  tmp_pixnum_array = gsl_vector_ulong_alloc(n_pixel);
  tmp_resolution_array = gsl_vector_int_alloc(n_pixel);
  pixel_index = gsl_permutation_alloc(n_pixel);


  for (i=0;i<n_pixel;i++) {
    superpix(resolution_array->data[i],pixnum_array->data[i],
	     superpix_resolution,&superpix_array->data[i]);
    /* printf("%d\n",superpix_array->data[i]); */
  }

  gsl_sort_vector_ulong_index(pixel_index,superpix_array);
  
  for (i=0;i<n_pixel;i++) {
    k = pixel_index->data[i];
    tmp_resolution_array->data[i] = resolution_array->data[k];
    tmp_pixnum_array->data[i] = pixnum_array->data[k];
    tmp_superpix_array->data[i] = superpix_array->data[k];
  }
    
  for (i=0;i<n_pixel;i++) {
    resolution_array->data[i] = tmp_resolution_array->data[i];
    pixnum_array->data[i] = tmp_pixnum_array->data[i];
    superpix_array->data[i] = tmp_superpix_array->data[i];
  }

  gsl_vector_ulong_free(tmp_superpix_array);
  gsl_vector_ulong_free(tmp_pixnum_array);
  gsl_vector_int_free(tmp_resolution_array);
  gsl_permutation_free(pixel_index);

  /* printf("Finding superpix bounds...\n"); */
  
  find_superpix_bounds(superpix_array,n_pixel,superpix_region_array,
		       superpix_start_array,superpix_finish_array);

  for (k=0;k<n_superpix;k++) {
    /* printf("%d %d %d\n",superpix_start_array->data[k],
       superpix_finish_array->data[k],superpix_region_array->data[k]); */
    superpix_struct[k].n_pixel = 
      superpix_finish_array->data[k] - superpix_start_array->data[k] + 1;
    superpix_struct[k].resolution = superpix_resolution;
    superpix_struct[k].superpixnum = superpix_region_array->data[k];

    tmp_pixnum_array = gsl_vector_ulong_alloc(superpix_struct[k].n_pixel);
    tmp_resolution_array = gsl_vector_int_alloc(superpix_struct[k].n_pixel);
    pixel_index = gsl_permutation_alloc(superpix_struct[k].n_pixel);

    j = 0;
    for (i=superpix_start_array->data[k];
	 i<=superpix_finish_array->data[k];i++) {
      tmp_resolution_array->data[j] = resolution_array->data[i];
      j++;
    }

    gsl_sort_vector_int_index(pixel_index,tmp_resolution_array);
    
    for (i=0;i<superpix_struct[k].n_pixel;i++) {
      j = pixel_index->data[i] + superpix_start_array->data[k];
      tmp_pixnum_array->data[i] = pixnum_array->data[j];
      tmp_resolution_array->data[i] = resolution_array->data[j];
      /* printf("%i %u\n",tmp_resolution_array->data[i],
	 tmp_pixnum_array->data[i]); */
    }

    superpix_struct[k].n_res = 
      find_n_res(tmp_resolution_array, superpix_struct[k].n_pixel);
    
    /* printf("Found %i resolutions in superpixel %u\n",
       superpix_struct[k].n_res,k); */

    if (!(superpix_struct[k].res_struct=
	  malloc(superpix_struct[k].n_res*sizeof(resolution_struct)))) {
      printf("Couldn't allocate memory...\n");
      exit(1);
    }

    make_resolution_struct(tmp_pixnum_array, tmp_resolution_array, 
			   superpix_struct[k].n_pixel, 
			   superpix_struct[k].res_struct,
			   superpix_struct[k].n_res);

    gsl_vector_ulong_free(tmp_pixnum_array);
    gsl_vector_int_free(tmp_resolution_array);
    gsl_permutation_free(pixel_index);
  }

  gsl_vector_ulong_free(superpix_region_array);
  gsl_vector_ulong_free(superpix_start_array);
  gsl_vector_ulong_free(superpix_finish_array);
  gsl_vector_ulong_free(superpix_array);
}
Beispiel #6
0
/* Run PAM */
static void pam_run(pam_partition p, size_t max_iters)
{
  if (p->k == p->M->size1) {
    /* Simple case */
    return;
  }

  size_t i, j, k, m, n, trimmed_size = p->M->size1 - p->k,
         any_swaps = 0,
         iter = 0;
  size_t *medoids, *trimmed;
  double c, current_cost;
  gsl_vector *cost = gsl_vector_alloc(trimmed_size);
  gsl_vector_ulong *cl_index = gsl_vector_ulong_alloc(p->cl_index->size);
  gsl_vector *cl_dist = gsl_vector_alloc(p->cl_dist->size);

  medoids = malloc(sizeof(size_t) * p->k);
  trimmed = malloc(sizeof(size_t) * (p->M->size1 - p->k));

  j = 0;
  k = 0;
  for (i = 0; i < p->M->size1; i++) {
    if (gsl_vector_uchar_get(p->in_set, i))
      medoids[j++] = i;
    else {
      assert(!pam_always_select(p, i));
      trimmed[k++] = i;
    }
  }

  assert(j == p->k);
  assert(k == p->M->size1 - p->k);

  do {
    if (PAM_VERBOSE)
      fprintf(stderr, "Iteration %lu\n", iter);

    any_swaps = 0;

    /* For every medoid, m, swap with every non-medoid, compute cost */
    for (i = 0; i < p->k; i++) {
      m = medoids[i];

      /* If medoid is in the always_select set, no action. */
      if (pam_always_select(p, m))
        continue;

      current_cost = pam_total_cost(p);

      /* Try every non-medoid */
      gsl_vector_set_all(cost, FLT_MAX);

      for (j = 0; j < trimmed_size; j++) {
        n = trimmed[j];
        c = pam_swap_update_cost(p, m, n, cl_index, cl_dist);
        gsl_vector_set(cost, j, c);
      }

      /* Find the minimum cost from all swaps */
      j = gsl_vector_min_index(cost);
      if (gsl_vector_get(cost, j) < current_cost) {
        /* Current cost beaten */
        any_swaps = 1;
        n = trimmed[j];
        assert(n != m);
        assert(!gsl_vector_uchar_get(p->in_set, n));
        assert(gsl_vector_uchar_get(p->in_set, m));
        if (PAM_VERBOSE)
          fprintf(stderr, "SWAP: %lu->%lu [%f -> %f]\n", m, n,
                  current_cost, gsl_vector_get(cost, j));
        gsl_vector_uchar_swap_elements(p->in_set, m, n);

        /* Move n to medoids, m to trimmed */
        trimmed[j] = m;
        medoids[i] = n;

        /* Recalculate cached values */
        pam_swap_cost(p, m, n);
      }
    }
  }
  while (any_swaps && ++iter < max_iters);

  if (PAM_VERBOSE) {
    fprintf(stderr, "Done in %lu iterations. Final config:\n", iter);
    gsl_vector_uchar_fprintf(stderr, p->in_set, "%d");
    fprintf(stderr, "Final cost: %f\n", pam_total_cost(p));
  }

  gsl_vector_free(cost);
  gsl_vector_ulong_free(cl_index);
  gsl_vector_free(cl_dist);
  free(medoids);
  free(trimmed);
}
Beispiel #7
0
int main(int argc, char *argv[])
{
    extern long n_masks, n_bbox, n_superpix, n_bbox, bbox_iter;
    extern superpixnum_struct *mask_struct;
    extern bbox_struct *bbox;
    extern int superpix_resolution;
    extern gsl_rng *mt19937_rand;
    double LAM, ETA,dLAM,mag,LAMMIN,ETAMAX,LAMMAX,ETAMIN;
    double ra, dec, temp_lam, temp_eta, temp_r, temp_abs_r, temp_z, temp_type;
    double temp_covar_zz, temp_covar_tz, temp_covar_tt, temp_prob;
    double tmp_lammin, tmp_lammax, tmp_etamin, tmp_etamax;
    double upper_mag, lower_mag, prob,LAM_length,ETA_length;
    double z_min, z_max, z_length, z, temp_u, temp_g, temp_i;
    double temp_redshift, temp_redshifterr, temp_red, max_seg, x, y;
    double lammin, lammax, etamin, etamax;
    long run, col, fld, id, bit, i, j, k, c, not_masked, nkeep, n;
    gsl_vector_int *stripe_array, *mask_resolution_array;
    gsl_vector_ulong *mask_pixnum_array, *mask_superpixnum_array;
    long idum1, idum2, southern_stripe, n_stripe, pixnum;
    long bbox_finder, n_masks_old, jlo, ilo, stripe_iter;
    int resolution;
    gsl_vector_char *output_type;
    FILE *MaskFile;

    assign_parameters();

    superpix_resolution = 4;

    if (argc < 2) {
        fprintf(stderr,"example usage:\n");
        fprintf(stderr,"    ./filter maskfile < radec_file > output\n");
        fprintf(stderr,"    cat radec_file | ./filter maskfile > output\n");
        fprintf(stderr,"radec_file should be columns of ra dec\n");
        fprintf(stderr,"only rows that pass the mask are output\n");
        fprintf(stderr,"output columns are ra dec\n");
        exit(1);
    }
    MaskFile = fopen(argv[1],"r");

    n_masks = 0;

    while ((c = getc(MaskFile)) != EOF) {
        if (c == '\n') n_masks++;
    }
    rewind(MaskFile);

    n_stripe = 0;
    bbox_finder = 1;
    n_masks_old = n_masks;
    while ((bbox_finder == 1) && (n_stripe < n_masks_old)) {
        fscanf(MaskFile,"%ld %i\n", &pixnum, &resolution);
        if (resolution < 0) {
            n_stripe++;
            n_masks--;
        } else {
            bbox_finder = 0;
        }
    }

    rewind(MaskFile);

    stripe_array = gsl_vector_int_alloc(n_stripe);

    for (i=0;i<n_stripe;i++)
        fscanf(MaskFile,"%i %i\n",&stripe_array->data[i],&resolution);

    gsl_sort_vector_int(stripe_array);

    n_bbox = 1;

    for (i=1;i<n_stripe;i++) {
        if ((stripe_array->data[i] < 50) || (stripe_array->data[i-1] < 50)) {
            if (stripe_array->data[i] > stripe_array->data[i-1]+1) n_bbox++;
        }
    }

    if (!(bbox=malloc(n_bbox*sizeof(bbox_struct)))) {
        fprintf(stderr,"Couldn't allocate bbox_struct memory...\n");
        exit(1);
    }

    fprintf(stderr,"Found %ld bounding regions...\n",n_bbox);

    for (i=0;i<n_bbox;i++) bbox[i].n_stripe = 1;

    j = 0;
    for (i=1;i<n_stripe;i++) {
        if ((stripe_array->data[i] < 50) || (stripe_array->data[i-1] < 50)) {
            if (stripe_array->data[i] == stripe_array->data[i-1]+1) {
                bbox[j].n_stripe++;
            } else {
                j++;
            }
        } else {
            bbox[j].n_stripe++;
        }
    }

    for (i=0;i<n_bbox;i++) {
        if (!(bbox[i].stripe_bound=
                    malloc(bbox[i].n_stripe*sizeof(stripe_struct)))) {
            fprintf(stderr,"Couldn't allocate stripe_struct memory...\n");
            exit(1);
        }
        bbox[i].n_obj = bbox[i].n_keep = 0;
    }

    j = k = 0;
    bbox[0].stripe_bound[0].stripe = stripe_array->data[0];
    for (i=1;i<n_stripe;i++) {
        if ((stripe_array->data[i] < 50) || (stripe_array->data[i-1] < 50)) {
            if (stripe_array->data[i] == stripe_array->data[i-1]+1) {
                k++;
                bbox[j].stripe_bound[k].stripe = stripe_array->data[i];
            } else {
                j++;
                k = 0;
                bbox[j].stripe_bound[k].stripe = stripe_array->data[i];
            }
        } else {
            k++;
            bbox[j].stripe_bound[k].stripe = stripe_array->data[i];
        }
    }

    for (i=0;i<n_bbox;i++) {
        fprintf(stderr,"BBOX %ld:\n\t",i+1);
        primary_bound(bbox[i].stripe_bound[0].stripe,
                &lammin,&lammax,&etamin,&etamax);
        bbox[i].stripe_bound[0].lammin = lammin; 
        bbox[i].stripe_bound[0].lammax = lammax; 
        bbox[i].stripe_bound[0].etamin = etamin; 
        bbox[i].stripe_bound[0].etamax = etamax; 
        bbox[i].lammin = lammin;
        bbox[i].lammax = lammax;
        bbox[i].etamin = etamin;
        bbox[i].etamax = etamax;
        for (j=0;j<bbox[i].n_stripe;j++) {
            fprintf(stderr,"%i ",bbox[i].stripe_bound[j].stripe);
            primary_bound(bbox[i].stripe_bound[j].stripe,
                    &lammin,&lammax,&etamin,&etamax);
            bbox[i].stripe_bound[j].lammin = lammin; 
            bbox[i].stripe_bound[j].lammax = lammax; 
            bbox[i].stripe_bound[j].etamin = etamin; 
            bbox[i].stripe_bound[j].etamax = etamax; 
            if (lammax > bbox[i].lammax) bbox[i].lammax = lammax;
            if (lammin < bbox[i].lammin) bbox[i].lammin = lammin;
            if (etamax > bbox[i].etamax) bbox[i].etamax = etamax;
            if (etamin < bbox[i].etamin) bbox[i].etamin = etamin;
        }
        fprintf(stderr,"\n");
    }

    fprintf(stderr,"There are %ld masks\n",n_masks);

    mask_pixnum_array = gsl_vector_ulong_alloc(n_masks);
    mask_resolution_array = gsl_vector_int_alloc(n_masks);

    for (i=0;i<n_masks;i++) 
        fscanf(MaskFile,"%lu %i\n",&mask_pixnum_array->data[i],
                &mask_resolution_array->data[i]);

    fclose(MaskFile);

    n_superpix = find_n_superpix(superpix_resolution, mask_pixnum_array, 
            mask_resolution_array, n_masks);

    if (!(mask_struct=malloc(n_superpix*sizeof(superpixnum_struct)))) {
        fprintf(stderr,"Couldn't allocate superpixnum_struct memory...\n");
        exit(1);
    }

    mask_superpixnum_array = gsl_vector_ulong_alloc(n_superpix);

    make_superpix_struct(superpix_resolution,mask_pixnum_array,
            mask_resolution_array,n_masks,mask_struct,n_superpix);

    for (i=0;i<n_superpix;i++) 
        mask_superpixnum_array->data[i] = mask_struct[i].superpixnum;

    gsl_vector_ulong_free(mask_pixnum_array);
    gsl_vector_int_free(mask_resolution_array);

    nkeep = 0;

    while (2==fscanf(stdin,"%lf %lf\n",&ra,&dec)) {

        eq2csurvey(ra, dec, &temp_lam, &temp_eta);
        not_masked = 0;
        bbox_iter = -1;
        stripe_iter = -1;
        for (j=0;j<n_bbox;j++) {
            if ((temp_lam <= bbox[j].lammax) && 
                    (temp_lam >= bbox[j].lammin) &&
                    (temp_eta <= bbox[j].etamax) && 
                    (temp_eta >= bbox[j].etamin)) {
                bbox_iter = j;
                j = n_bbox;
            }
        }

        if (bbox_iter >= 0) {
            bbox[bbox_iter].n_obj++;
            for (k=0;k<bbox[bbox_iter].n_stripe;k++) {
                if ((temp_eta <= bbox[bbox_iter].stripe_bound[k].etamax) && 
                        (temp_eta >= bbox[bbox_iter].stripe_bound[k].etamin)) {
                    stripe_iter = k;
                    k = bbox[bbox_iter].n_stripe;
                }
            }

            if (stripe_iter >= 0) {
                if ((temp_lam <= 
                            bbox[bbox_iter].stripe_bound[stripe_iter].lammax) && 
                        (temp_lam >= bbox[bbox_iter].stripe_bound[stripe_iter].lammin)) 
                    not_masked = 1;
            }
        }

        if (not_masked == 1) {
            ang2pix(superpix_resolution,temp_lam,temp_eta,&pixnum);

            lhunt(mask_superpixnum_array,pixnum,&jlo);

            if (jlo <= n_superpix-1) {
                if (pixnum == mask_superpixnum_array->data[jlo]) { 
                    for (k=0;k<mask_struct[jlo].n_res;k++) {
                        ang2pix(mask_struct[jlo].res_struct[k].resolution,
                                temp_lam,temp_eta,&pixnum);
                        if (mask_struct[jlo].res_struct[k].n_pixel == 1) {
                            ilo = 0;
                        } else {
                            lhunt(mask_struct[jlo].res_struct[k].pixnum,pixnum,&ilo);
                        }
                        if (ilo < mask_struct[jlo].res_struct[k].n_pixel) {
                            if (mask_struct[jlo].res_struct[k].pixnum->data[ilo] ==
                                    pixnum) not_masked = 0;
                        }
                    }
                }
            }
        }


        if (not_masked == 1) {
            bbox[bbox_iter].n_keep++;
            printf("%.16g %.16g\n", ra, dec);  
            nkeep++;
        }
    }

    fprintf(stderr,"Kept %ld points\n",nkeep);
    return 0;

}
Beispiel #8
0
static void
dvine_select_order(dml_vine_t *vine,
                   const gsl_matrix *data,
                   dml_vine_weight_t weight,
                   dml_measure_t ***measure_matrix,
                   const gsl_rng *rng)
{
    int n = (int) vine->dim;
    double **weight_matrix;
    size_t selected_node;
    gsl_vector_ulong *tour;
    gsl_vector_short *in_tour;
    double selected_cost, current_cost;
    size_t current_pos = 0, selected_pos = 0; // Initialized to avoid GCC warnings.
    double dik, dkj, dij;
    size_t i, j;
    int cut_index;

    // Compute the weights. The weights are minimized.
    weight_matrix = g_malloc_n(n, sizeof(double *));
    for (size_t i = 0; i < n; i++) {
        weight_matrix[i] = g_malloc_n(n, sizeof(double));
        for (size_t j = 0; j < i; j++) {
            switch (weight) {
            case DML_VINE_WEIGHT_TAU:
                weight_matrix[i][j] = 1
                        - fabs(dml_measure_tau_coef(measure_matrix[i][j]));
                break;
            case DML_VINE_WEIGHT_CVM:
                weight_matrix[i][j] = measure_matrix[i][j]->x->size
                        - dml_measure_cvm_stat(measure_matrix[i][j]);
                break;
            default:
                weight_matrix[i][j] = 0;
                break;
            }
            weight_matrix[j][i] = weight_matrix[i][j];
        }
    }

    // Compute an approximate solution for the TSP instance using the
    // Cheapest insertion heuristic. The dummy node has index n.
    tour = gsl_vector_ulong_alloc(n + 1);
    in_tour = gsl_vector_short_alloc(n + 1);
    gsl_vector_short_set_all(in_tour, FALSE);

    for (size_t node_count = 0; node_count < n + 1; node_count++) {
        // Select the node to be inserted.
        if (node_count == 0) {
            // Initial node (randomly selected).
            selected_node = floor((n + 1) * gsl_rng_uniform(rng));
            gsl_vector_ulong_set(tour, node_count, selected_node);
            gsl_vector_short_set(in_tour, selected_node, TRUE);
        } else {
            selected_cost = GSL_DBL_MAX;

            // Rest of the nodes. Choose the nodes with the minimal insertion cost.
            for (size_t k = 0; k < n + 1; k++) {
                if (!gsl_vector_short_get(in_tour, k)) {
                    if (node_count == 1) {
                        i = gsl_vector_ulong_get(tour, 0);
                        current_cost = (i == n || k == n) ? 0: weight_matrix[i][k];
                        current_pos = 0;
                    } else {
                        current_cost = GSL_DBL_MAX;
                        for (size_t pos = 0; pos < node_count - 1; pos++) {
                            i = gsl_vector_ulong_get(tour, pos);
                            j = gsl_vector_ulong_get(tour, pos + 1);
                            dik = (i == n || k == n) ? 0: weight_matrix[i][k];
                            dkj = (k == n || j == n) ? 0: weight_matrix[k][j];
                            dij = (i == n || j == n) ? 0: weight_matrix[i][j];

                            if (dik + dkj + dij < current_cost) {
                                current_cost = dik + dkj + dij;
                                current_pos = pos;
                            }
                        }
                    }

                    // Check the last position.
                    i = gsl_vector_ulong_get(tour, node_count - 1);
                    j = gsl_vector_ulong_get(tour, 0);
                    dik = (i == n || k == n) ? 0: weight_matrix[i][k];
                    dkj = (k == n || j == n) ? 0: weight_matrix[k][j];
                    dij = (i == n || j == n) ? 0: weight_matrix[i][j];

                    if (dik + dkj + dij < current_cost) {
                        current_cost = dik + dkj + dij;
                        current_pos = node_count - 1;
                    }

                    if (current_cost < selected_cost) {
                        selected_node = k;
                        selected_cost = current_cost;
                        selected_pos = current_pos;
                    }

                }
            }

            // Add the selected node to the tour.
            for (size_t pos = selected_pos; pos < node_count; pos++) {
                i = gsl_vector_ulong_get(tour, pos + 1);
                if (pos == selected_pos) {
                    gsl_vector_ulong_set(tour, pos + 1, selected_node);
                } else {
                    gsl_vector_ulong_set(tour, pos + 1, j);
                }
                j = i;
            }
            gsl_vector_short_set(in_tour, selected_node, TRUE);
        }
    }

    // Cut the tour at the dummy node.
    cut_index = -1;
    for (int i = 0; i < n + 1; i++) {
        if (cut_index >= 0) {
            vine->order[i - cut_index - 1] = gsl_vector_ulong_get(tour, i);
        } else if (gsl_vector_ulong_get(tour, i) == n) {
            cut_index = i;
        }
    }
    for (int i = 0; i < cut_index; i++) {
        vine->order[n - cut_index + i] = gsl_vector_ulong_get(tour, i);
    }

    gsl_vector_ulong_free(tour);
    gsl_vector_short_free(in_tour);
    for (size_t i = 0; i < n; i++) {
        g_free(weight_matrix[i]);
    }
    g_free(weight_matrix);
}