#include #include #include "lsh.h" #include /* Docstrings */ static char module_docstring[] = "This module implements fast nearest-neighbor retrieval using LSH."; static char lsh_docstring[] = "Calculate the closest neightbours with distances given a query window."; /* Available functions */ static PyObject* lsh_lsh(PyObject *self, PyObject *args); /* Module specification */ static PyMethodDef module_methods[] = { { "lsh", lsh_lsh, METH_VARARGS, lsh_docstring }, { NULL, NULL, 0, NULL } }; /* Initialize the module */ #if PY_MAJOR_VERSION >= 3 #define MOD_ERROR_VAL NULL #define MOD_SUCCESS_VAL(val) val #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) #define MOD_DEF(ob, name, doc, methods) \ static struct PyModuleDef moduledef = { \ PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \ ob = PyModule_Create(&moduledef); #else #define MOD_ERROR_VAL #define MOD_SUCCESS_VAL(val) #define MOD_INIT(name) void init##name(void) #define MOD_DEF(ob, name, doc, methods) \ ob = Py_InitModule3(name, methods, doc); #endif MOD_INIT(_lsh) { PyObject *m; MOD_DEF(m, "_lsh", module_docstring, module_methods) if (m == NULL) return MOD_ERROR_VAL; import_array(); return MOD_SUCCESS_VAL(m); } static PyObject* lsh_lsh(PyObject* self, PyObject* args) { PyObject* data_obj = NULL; PyObject* query_obj = NULL; PyObject* hash_obj = NULL; double **** hashFunctions; double ** weights = NULL; double*** data; double ** query; int * candidates; double * distances; int nrOfCandidates; double r; double a; double sd; PyArray_Descr *descr; descr = PyArray_DescrFromType(NPY_DOUBLE); PyArray_Descr *descr_float; descr_float = PyArray_DescrFromType(NPY_FLOAT64); /// Parse the input tuple if (!PyArg_ParseTuple(args, "OOddd|O", &data_obj, &query_obj, &r, &a, &sd, &hash_obj)) { return NULL; } /// Get the dimensions of the data and query int data_size = (long) PyArray_DIM(data_obj, 0); int channel_size = (long) PyArray_DIM(data_obj, 2); int query_size = (int) PyArray_DIM(query_obj, 0); /// Convert data, query and weights to C array npy_intp dims0[3]; if (PyArray_AsCArray(&query_obj, (void **)&query, dims0, 2, descr) < 0 || PyArray_AsCArray(&data_obj, (void ***)&data, dims0, 3, descr) < 0) { PyErr_SetString(PyExc_TypeError, "error converting to c array"); return NULL; } if (hash_obj != NULL) { printf("Using weights"); if (PyArray_AsCArray(&hash_obj, (void **)&weights, dims0, 2, descr) < 0) { PyErr_SetString(PyExc_TypeError, "error converting weights to c array"); return NULL; } } int K = ceil(log((log(0.5))/log(1-exp(-2*(0.1)*(0.1)*query_size)))/log((1-exp(-2*(0.1)*(0.1)*query_size))/(0.5))); int L = ceil(log(0.05)/(log(1-pow(1-exp(-2*(0.1)*(0.1)*query_size), K)))); printf("K: %d\n", K); printf("L: %d\n", L); printf("Dim: %d\n", channel_size); /// Initialize output parameters hashFunctions = (double ****)malloc(L*sizeof(double***)); for (int l=0;l