Exemplo n.º 1
0
/* maxheap version */
static void fvec_k_min_maxheap (const float *val, int n,
                                     int *idx, int k)
{
  fbinheap_t *mh = fbinheap_new (k);
  int i;

  for (i = 0; i < n; i++)
    fbinheap_add (mh, i, val[i]);    /* -val because we want maxes instead of mins */

  fbinheap_sort_labels (mh, idx);
  fbinheap_delete (mh);
}
Exemplo n.º 2
0
void mexFunction (int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray*prhs[])

{
  if (nrhs != 4) 
    mexErrMsgTxt ("Invalid number of input arguments: either 2 for initialization or 4 for feeding the heap");
  
  if (nlhs != 2)
    mexErrMsgTxt ("2 output arguments are expected");
  
  if (mxGetClassID(ARGIN_VAL) != mxSINGLE_CLASS || mxGetClassID(ARGIN_VALH) != mxSINGLE_CLASS)
    mexErrMsgTxt ("need single precision array for values"); 
  
  if (mxGetClassID(ARGIN_IDS) != mxUINT32_CLASS || mxGetClassID(ARGIN_IDSH) != mxUINT32_CLASS)
    mexErrMsgTxt ("need uint32 arrays for indices"); 
  
  /* Variables defining the heap */
  int k = mxGetM (ARGIN_VALH);               /* Number of neighbors for the heap */
  int nh = mxGetN (ARGIN_VALH);              /* Number of heaps */

  if (mxGetM(ARGIN_IDSH) != k || mxGetN (ARGIN_IDSH) != nh)
    mexErrMsgTxt ("Inconsistent sizes for the heap parameters");
  
  /* Values to be considered for being added in the heap */
  int n = mxGetM (ARGIN_VAL);
  int nh2 = mxGetN (ARGIN_VAL);
  
  if (mxGetM(ARGIN_IDS) != n || mxGetN (ARGIN_IDS) != 1 || nh2 != nh)
    mexErrMsgTxt ("Invalid sizes for the values/indexes to be added");

  /* Pointer to the data to manipulate */  
  float * val = (float*) mxGetPr (ARGIN_VAL);
  int * ids = (int*) mxGetPr (ARGIN_IDS);


  /* Produce output heap and populate it */  
  ARGOUT_VAL = mxCreateNumericMatrix (k, nh, mxSINGLE_CLASS, mxREAL);
  ARGOUT_IDS = mxCreateNumericMatrix (k, nh, mxUINT32_CLASS, mxREAL);

  float * bh_val = (float*) mxGetPr (ARGOUT_VAL);
  int * bh_ids = (int*) mxGetPr (ARGOUT_IDS);

  memcpy (bh_val, mxGetPr (ARGIN_VALH), k * nh * sizeof (*bh_val));
  memcpy (bh_ids, mxGetPr (ARGIN_IDSH), k * nh * sizeof (*bh_ids));
  
  int i, j;
  for (j = 0 ; j < nh ; j++)
    fbinheap_add (k, bh_val + j * k, bh_ids + j * k, n, val + j * n, ids);
} 
Exemplo n.º 3
0
int merge_ordered_sets (const int **labels,const float **vals,
			const int *sizes,int k,
			int **labels_out,float **vals_out) {
  int i,j;
  int n_out = ivec_sum (sizes, k);

  int *all_labels = ivec_new (n_out);
  float *all_vals = fvec_new (n_out);

  /* Maxheap:
   * * maxheap label = index of table in 0..k-1
   * * maxheap val = - (label from labels table)
   *  
   * If maxheap val does not fit in a float (if label>2**24), it
   * triggers an assertion. Time to implement a maxheap with int
   * values...
   */
  fbinheap_t *mh = fbinheap_new(k);

  /* current index on table k */ 
  int indices[k];

  for ( i = 0 ; i < k ; i++) {
    if (sizes[i] == 0) 
      continue;
    indices[i] = 0;
    int label = labels[i][0];
    float mh_val = -label;
    assert ((int)(-mh_val) == label || !"lost precision in int->float conversion");
    fbinheap_add (mh, i, mh_val);
  }
  
  int all_i = 0;
  while (mh->k>0) {    

    /* smallest available label */    
    i = mh->label[1];       /* index of table */
    j = (int)(-mh->val[1]); /* label */

    /* I don't dare compiling with -DNDEBUG */    
    /* assert(j==labels[i][indices[i]]); */

    all_labels[all_i] = j;
    all_vals[all_i] = vals[i][indices[i]];
    all_i++;

    /* remove handled label */
    fbinheap_pop (mh);
    
    indices[i]++;
    if (indices[i] < sizes[i]) { /* push next label from this table */
      int label = labels[i][indices[i]];
      float mh_val = -label;
      assert ((int)(-mh_val) == label || !"lost precision in int->float conversion");
      fbinheap_add (mh, i, mh_val);
    }
  }
  fbinheap_delete (mh);  
  assert (all_i == n_out);

  *labels_out = all_labels;
  *vals_out = all_vals;
  return n_out;
}