--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore Thu Jun 11 12:52:30 2009 -0700
@@ -0,0 +1,3 @@
+syntax: glob
+
+*.so
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Thu Jun 11 12:52:30 2009 -0700
@@ -0,0 +1,22 @@
+all: pyANN.so
+
+PYTHON_INCLUDE=/usr/include/python2.6
+LIBRARIES=-lANN -lpython2.6 -lboost_python
+FLAGS=-O3 -fPIC
+# FLAGS=-fPIC -g
+INSTALL_PATH=~/.local/lib/python2.6/site-packages/
+
+ann-kd-tree.o: ann-kd-tree.cpp
+ g++ -c $< -o $@ -I${PYTHON_INCLUDE} ${FLAGS}
+
+pyann.o: pyann.cpp
+ g++ -c $< -o $@ -I${PYTHON_INCLUDE} ${FLAGS}
+
+pyANN.so: pyann.o ann-kd-tree.o
+ g++ -shared -o $@ pyann.o ann-kd-tree.o ${LIBRARIES} ${FLAGS}
+
+install: pyANN.so
+ install -m644 pyANN.so ${INSTALL_PATH}
+
+clean:
+ rm *.o *.so
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ann-kd-tree.cpp Thu Jun 11 12:52:30 2009 -0700
@@ -0,0 +1,65 @@
+#include <boost/python.hpp>
+#include <boost/python/stl_iterator.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/functional/hash.hpp>
+namespace bp = boost::python;
+
+#include <ANN/ANN.h>
+#include <iostream>
+
+// Constructor from list TODO: change to iterator
+boost::shared_ptr<ANNkd_tree> init_from_list(bp::list lst)
+{
+ int dimension = bp::len(lst[0]);
+ int npts = bp::len(lst);
+ ANNpointArray dataPts = annAllocPts(npts, dimension);
+
+ // Convert points from Python list to ANNpointArray
+ for (unsigned p = 0; p < bp::len(lst); ++p)
+ {
+ ANNpoint& pt = dataPts[p];
+ for (unsigned c = 0; c < dimension; ++c)
+ pt[c] = bp::extract<ANNcoord>(lst[p][c]);
+ }
+
+ boost::shared_ptr<ANNkd_tree> p(new ANNkd_tree(dataPts, npts, dimension));
+ return p;
+}
+
+bp::tuple ksearch(ANNkd_tree& kdtree, bp::list q, int k, double eps)
+{
+ ANNpointArray pts = kdtree.thePoints();
+ // for (unsigned i = 0; i < kdtree.nPoints(); ++i)
+ // std::cout << pts[i][0] << " " << pts[i][1] << " " << pts[i][2] << std::endl;
+
+ ANNpoint annq = annAllocPt(bp::len(q));
+ for (unsigned c = 0; c < bp::len(q); ++c)
+ annq[c] = bp::extract<ANNcoord>(q[c]);
+
+ ANNidxArray nn_idx = new ANNidx[k];
+ ANNdistArray dists = new ANNdist[k];
+
+ kdtree.annkSearch(annq, k, nn_idx, dists, eps);
+
+ bp::list indices, distances;
+ for (unsigned i = 0; i < k; ++i)
+ {
+ indices.append(nn_idx[i]);
+ distances.append(dists[i]);
+ }
+
+ delete nn_idx; delete dists;
+ return bp::make_tuple(indices, distances);
+}
+
+
+void export_ann_kd_tree()
+{
+ bp::class_<ANNkd_tree>("KDTree")
+ .def("__init__", bp::make_constructor(&init_from_list))
+
+ .def("ksearch", &ksearch)
+ .def("__len__", &ANNkd_tree::nPoints)
+ .def("dim", &ANNkd_tree::theDim)
+ ;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pyann.cpp Thu Jun 11 12:52:30 2009 -0700
@@ -0,0 +1,11 @@
+#include <boost/python.hpp>
+namespace bp = boost::python;
+
+
+void export_ann_kd_tree();
+
+
+BOOST_PYTHON_MODULE(pyANN)
+{
+ export_ann_kd_tree();
+};