Esempio n. 1
0
/* Finds discrete maxima of the tensor (based on emc) and refines them,
 * storing magnitudes in (malloc'ed) *ls and *vs. Returns the number of
 * distinct maxima, or -1 on error. ls are sorted in descending order.
 */
int elfMaximaFind_d(double **ls, double **vs, const double *ten,
                    elfMaximaContext *emc) {
  unsigned int i;
  int retval;
  double *vals;
  airHeap *heap;
  if (ls==NULL || vs==NULL || ten==NULL || emc==NULL)
    return -1;
  if (emc->vertices_d==NULL) { /* we need to allocate these */
    emc->vertices_d = (double*) malloc(sizeof(double)*3*(emc->num/2));
    for (i=0; i<emc->num/2; i++) {
      ELL_3V_COPY(emc->vertices_d+3*i, emc->vertices_f+3*i);
    }
  }
  /* evaluate all unique directions */
  vals = (double*) malloc(sizeof(double)*(emc->num/2));
  for (i=0; i<emc->num/2; i++) {
    vals[i]=(*emc->type->sym->s_form_d)(ten, emc->vertices_d+3*i);
  }
  heap = airHeapNew(sizeof(double)*3, 20);
  /* identify discrete maxima */
  for (i=0; i<emc->num/2; i++) {
    unsigned int ni=0;
    int ismax=1, nb;
    while (ni<emc->nbstride && (nb=emc->neighbors[emc->nbstride*2*i+ni])!=-1) {
      if (vals[i]<=vals[nb/2]) {
        ismax=0;
        break;
      }
      ni++;
    }
    if (ismax) {
      double s=vals[i], v[3];
      ELL_3V_COPY(v,emc->vertices_d+3*i);
      if (emc->refine) /* refine further */
        tijk_refine_max_3d_d(&s, v, ten, emc->type, emc->parm);
      /* add to heap */
      airHeapInsert(heap, -s, v);
    }
  }
  /* allocate arrays and return what we have found */
  retval=airHeapLength(heap);
  if (retval>0) {
    *ls = (double*) malloc(sizeof(double)*retval);
    *vs = (double*) malloc(sizeof(double)*3*retval);
    for (i=0; i<(unsigned int)retval; i++) {
      (*ls)[i]=-airHeapFrontPop(heap, (*vs)+3*i);
    }
  }
  heap=airHeapNix(heap);
  free(vals);
  return retval;
}
Esempio n. 2
0
/* Same as airHeapNew, but initializes the new heap with the keys from key
 * and the optional data from data. If data is non-NULL, it needs to
 * have the same length as key, or this function will fail. The incr
 * field of the heap is copied from key (rather than data).
 */
airHeap *airHeapFromArray(const airArray *key, const airArray *data) {
  airHeap *h;
  unsigned int i;
  if (key==NULL || (data!=NULL && data->len!=key->len))
    return NULL; /* unusable input */
  h = airHeapNew((data==NULL)?0:data->unit, key->incr);
  if (heapLenIncr (h, key->len)) { /* could not allocate memory */
    airHeapNuke(h);
    return NULL;
  }
  memcpy(h->key, key->data, key->len*sizeof(double));
  if (h->data_a!=NULL) memcpy(h->data, data->data, data->len*data->unit);
  for (i=0; i<key->len; i++) { /* initialize indices to identity */
    h->idx[i]=i;
    h->invidx[i]=i;
  }
  heapify(h);
  return h;
}