2 #include <boost/python.hpp> 
    3 #include <numpy/arrayobject.h> 
    4 #include "../nabo/nabo.h" 
    8 using namespace boost::python;
 
   17 static const double infD = std::numeric_limits<double>::infinity();
 
   18 static const Index maxI = std::numeric_limits<Index>::max();
 
   20 #if PY_MAJOR_VERSION >= 3 
   37         assert(PyArray_CHKFLAGS(cloudObj, NPY_C_CONTIGUOUS) || PyArray_CHKFLAGS(cloudObj, NPY_F_CONTIGUOUS));
 
   38         assert(PyArray_NDIM(cloudObj) == 2);
 
   39         const npy_intp *shape = PyArray_DIMS(cloudObj);
 
   40         if (PyArray_CHKFLAGS(cloudObj, NPY_F_CONTIGUOUS))
 
   55         startMsg += paramName;
 
   58         if (!PyArray_Check(cloudObj))
 
   59                 throw std::runtime_error(startMsg + 
"must be a multi-dimensional array");
 
   60         const int nDim = PyArray_NDIM(cloudObj);
 
   62                 throw std::runtime_error(startMsg + 
"must be a two-dimensional array");
 
   63         if (PyArray_TYPE(cloudObj) != NPY_FLOAT64)
 
   64                 throw std::runtime_error(startMsg + 
"must hold doubles");
 
   65         if (!PyArray_CHKFLAGS(cloudObj, NPY_C_CONTIGUOUS) && !PyArray_CHKFLAGS(cloudObj, NPY_F_CONTIGUOUS))
 
   66                 throw std::runtime_error(startMsg + 
"must be a continuous array");
 
   71         int dimCount, pointCount;
 
   72         const PyObject *cloudObj(cloudIn.ptr());
 
   77         double* cloudData(
reinterpret_cast<double*
>(PyArray_DATA(cloudObj)));
 
   84         int dimCount, pointCount;
 
   85         const PyObject *cloudObj(cloudIn.ptr());
 
   90         cloudOut.resize(dimCount, pointCount);
 
   92         memcpy(cloudOut.data(), PyArray_DATA(cloudObj), pointCount*dimCount*
sizeof(
double));
 
  106 #if PY_MAJOR_VERSION >=3 
  107                 object it = params.items();
 
  109                 object it = params.iteritems();
 
  112                 for(
int i = 0; i < len(params); ++i)
 
  114                         const tuple item(it.attr(
"next")());
 
  115                         const std::string key = extract<std::string>(item[0]);
 
  116                         const object val(item[1]);
 
  117                         const std::string valType(val.ptr()->ob_type->tp_name);
 
  118                         if (valType == 
"int")
 
  120                                 const int iVal = extract<int>(val);
 
  122                                         _params[key] = (unsigned)iVal;
 
  137         tuple 
knn(
const object query, 
const Index k = 1, 
const double epsilon = 0, 
const unsigned optionFlags = 0, 
const double maxRadius = 
infD)
 
  145                 nns->knn(*mappedQuery, indexMatrix, dists2Matrix, k, 
epsilon, optionFlags, maxRadius);
 
  148                 npy_intp retDims[2] = { mappedQuery->cols(), k };
 
  149                 const int dataCount(k * mappedQuery->cols());
 
  150                 PyObject* dists2 = PyArray_EMPTY(2, retDims, PyArray_DOUBLE, PyArray_ISFORTRAN(query.ptr()));
 
  151                 memcpy(PyArray_DATA(dists2), dists2Matrix.data(), dataCount*
sizeof(
double));
 
  152                 PyObject* indices = PyArray_EMPTY(2, retDims, PyArray_INT, PyArray_ISFORTRAN(query.ptr()));
 
  153                 memcpy(PyArray_DATA(indices), indexMatrix.data(), dataCount*
sizeof(
int));
 
  157                 return make_tuple(
object(handle<>(indices)), 
object(handle<>(dists2)));
 
  165 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(knn_overloads, knn, 1, 5)
 
  171         enum_<SearchType>(
"SearchType", 
"Type of algorithm used for search.")
 
  177         enum_<SearchOptionFlags>(
"SearchOptionFlags", 
"Flags you can OR when creating search.")
 
  182         class_<NearestNeighbourSearch>(
 
  183                 "NearestNeighbourSearch",
 
  184                 "Nearest-neighbour search object, containing the data, on which you can do the knn(...) query.\n\n" 
  185                 "The data and query must be continuous numpy arrays.\n" 
  186                 "As numpy proposes both C and Fortran data orders, pynabo\n" 
  187                 "will always consider the contiguous dimension to be coordinates\n" 
  188                 "of points, regardless of order, as this provides the fastest\n" 
  189                 "possible execution. The return values of knn(...) will have\n" 
  190                 "the same order as the query and will have the different results\n" 
  191                 "of each point in the contiguous dimension." 
  193                 init<
const object, optional<const SearchType, const Index, const dict> >(
 
  194                         "Create a nearest-neighbour search.\n\n" 
  196                         "    data -- data-point cloud in which to search, must be a numpy array\n" 
  197                         "    searchType -- type of search, default: KDTREE_LINEAR_HEAP\n" 
  198                         "    dim -- number of dimensions to consider, must be lower or equal to cloud.rows(), default: dim of data\n" 
  199                         "    creationOptionFlags -- creation options, a bitwise OR of elements of CreationOptionFlags",
 
  200                         args(
"self", 
"data", 
"searchType", 
"dim", 
"creationOptionFlags, default: 0")
 
  205                         args(
"self", 
"query", 
"k", 
"epsilon", 
"optionFlags", 
"maxRadius"),
 
  206                         "Find the k nearest neighbours of query in data.\n\n" 
  208                         "    query -- query points, must be a numpy array\n" 
  209                         "    k -- number of nearest neighbour requested, default: 1\n" 
  210                         "    epsilon -- maximal ratio of error for approximate search, 0 for exact search; has no effect if the number of neighbour found is smaller than the number requested; default: 0.\n" 
  211                         "    optionFlags -- search options, a bitwise OR of elements of SearchOptionFlags, default: 0\n" 
  212                         "    maxRadius -- maximum radius in which to search, can be used to prune search, is not affected by epsilon, default: inf\n\n" 
  214                         "    A tuple of two 2D numpy arrays, the first containing indices to points in data, the other containing squared distances."