/**
 * Input arguments: dataset (matrix), params (struct)
 * Output arguments: index (pointer to index), params (struct), speedup(double)
 */
static void _build_index(int nOutArray, mxArray* OutArray[], int nInArray, const mxArray* InArray[])
{
    /* Check the number of input arguments */
    if(nInArray != 2) {
        mexErrMsgTxt("Incorrect number of input arguments");
    }
    /* Check the number of output arguments */
    if ((nOutArray == 0)||(nOutArray > 3)) {
        mexErrMsgTxt("Incorrect number of outputs.");
    }
    const mxArray* datasetMat = InArray[0];
    check_allowed_type(datasetMat);

    int dcount = mxGetN(datasetMat);
    int length = mxGetM(datasetMat);


    const mxArray* pStruct = InArray[1];

    /* get index parameters */
    FLANNParameters p;
    matlabStructToFlannStruct(pStruct, p);

    float speedup = -1;

    TypedIndex* typedIndex = new TypedIndex();

    if (mxIsSingle(datasetMat)) {
        float* dataset = (float*) mxGetData(datasetMat);
        typedIndex->index = flann_build_index_float(dataset,dcount,length, &speedup, &p);
        typedIndex->type = FLANN_FLOAT32;
    }
    else if (mxIsDouble(datasetMat)) {
        double* dataset = (double*) mxGetData(datasetMat);
        typedIndex->index = flann_build_index_double(dataset,dcount,length, &speedup, &p);
        typedIndex->type = FLANN_FLOAT64;
    }
    else if (mxIsUint8(datasetMat)) {
        unsigned char* dataset = (unsigned char*) mxGetData(datasetMat);
        typedIndex->index = flann_build_index_byte(dataset,dcount,length, &speedup, &p);
        typedIndex->type = FLANN_UINT8;
    }
    else if (mxIsInt32(datasetMat)) {
        int* dataset = (int*) mxGetData(datasetMat);
        typedIndex->index = flann_build_index_int(dataset,dcount,length, &speedup, &p);
        typedIndex->type = FLANN_INT32;
    }

    mxClassID classID;
    if (sizeof(flann_index_t)==4) {
        classID = mxUINT32_CLASS;
    }
    else if (sizeof(flann_index_t)==8) {
        classID = mxUINT64_CLASS;
    }

    /* Allocate memory for Output Matrix */
    OutArray[0] = mxCreateNumericMatrix(1, 1, classID, mxREAL);

    /* Get pointer to Output matrix and store result*/
    TypedIndex** pOut = (TypedIndex**)mxGetData(OutArray[0]);
    pOut[0] = typedIndex;

    if (nOutArray > 1) {
        OutArray[1] = flannStructToMatlabStruct(p);
    }
    if (nOutArray > 2) {
        OutArray[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
        double* pSpeedup = mxGetPr(OutArray[2]);

        *pSpeedup = speedup;
    }
}
Example #2
0
int NearestNode(MacroMesh *m, real *xphy) {
  int nearest = -1;

#ifdef _WITH_FLANN
  // Use of flann library: faster  ???
  static bool is_ready = false;
  static struct FLANNParameters p;

  static float speedup;
  static flann_index_t findex;

  // at first call: construct the index
  // TO DO free the index when finished
  if (!is_ready) {
    printf("Using flann: build search index...\n");
    p = DEFAULT_FLANN_PARAMETERS;
    p.algorithm = FLANN_INDEX_AUTOTUNED;
    p.target_precision = 0.9; /* want 90% target precision */

#if real == double
      findex = flann_build_index_double(m->node, m->nbnodes, 3, &speedup, &p);
#else
      findex = flann_build_index_float(m->node, m->nbnodes, 3, &speedup, &p);
#endif
    is_ready = true;
  }
  
  // number of nearest neighbors to search 
  int nn = 1;
  int result[nn];
  real dists[nn];

  // compute the nn nearest-neighbors of each point in xphy
  // with index construction
  // flann_find_nearest_neighbors_real(m->node,     // nodes list
  // 				      m->nbnodes,  // number of nodes
  // 				      3,           // space dim
  // 				      xphy,
  // 				      1,           // number of points in xphy
  // 				      result,      // nearest points indices
  // 				      dists,       // distances
  // 				      nn,
  // 				      &p);         // flan struct
  

#if real == double
  flann_find_nearest_neighbors_index_double(findex,// index
					    xphy,
					    1,      // number of points in xphy
					    result, // nearest points indices
					    dists,  // distances
					    nn,
					    &p);     // flan struct
#else
  flann_find_nearest_neighbors_index_float(findex,// index
					   xphy,
					   1,      // number of points in xphy
					   result, // nearest points indices
					   dists,  // distances
					   nn,
					   &p);     // flan struct
#endif

  nearest = result[0];
  // printf("xphy=%f %f %f nearest=%d %f %f %f \n",
  // 	 xphy[0],xphy[1],xphy[2],nearest+1,
  // 	 m->node[0+nearest*3],m->node[1+nearest*3],m->node[2+nearest*3]);

#else // Do not use FLANN library.

  // slow version: loops on all the points
  real d = 1e20;

  for(int ino = 0; ino < m->nbnodes; ino++){
    real d2 = Dist(xphy, m->node + 3 * ino);
    if (d2 < d) {
      nearest = ino;
      d = d2;
    }
  }
#endif

  return nearest;
}