diff --git a/c/interaction/interaction.c b/c/interaction/interaction.c index 9048dee..efb50a0 100644 --- a/c/interaction/interaction.c +++ b/c/interaction/interaction.c @@ -134,7 +134,7 @@ static PyTypeObject interaction_UFuncWrapperType { PyTypeObject_HEAD_INIT(NULL, 0) .tp_name = "brown.interaction.UFuncWrapper", - .tp_doc = "A wrapper that wraps the ufuncs for interaction and force, storing the coeficients", + .tp_doc = "A wrapper that wraps the ufuncs for interaction and force, storing the coefficients", .tp_basicsize = sizeof(interaction_UFuncWrapper), .tp_itemsize = 0, .tp_flags = Py_TPFLAGS_DEFAULT, @@ -142,6 +142,12 @@ static PyTypeObject interaction_UFuncWrapperType }; + +static char interaction_types[] = + { NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT}; +static char force_types[] = + { NPY_FLOAT, NPY_FLOAT}; + static int interaction_UFuncWrapper_init ( interaction_UFuncWrapper * self @@ -152,6 +158,8 @@ interaction_UFuncWrapper_init // 1: interaction2D char type; PyObject * coefficients; + int i; + PyObject * this_coefficient; if(!PyArgs_ParseTupleAndKeywords(args, kwds, "BO!", &type, &PyList_Type, &coefficients)) { @@ -164,35 +172,76 @@ interaction_UFuncWrapper_init return -1; } + // copy the coefficients. + for(i = 0; i < 19; i++) + { + this_coefficient = PyList_GetItem(coefficients, i); + // XXX: PyFloat_AsDouble might call python code, + // so make sure that nothing bad can happen. + Py_INCREF(this_coefficient); + self->coefficients[i] = PyFloat_AsDouble(this_coefficient); + Py_DECREF(this_coefficient); + if(PyErr_Occurred()) + { + return -1; + } + } + switch(type) + { + case 0: + { + self->ufunc = PyUFunc_FromFuncAndData( + force_funcs + , self->coefficients + , force_types + , 1 + , 2 + , 1 + , PyUFunc_None + , "force_function" + , "computes the scalar force between two particles with given coefficients" + , 0); + break; + } + case 1: + { + self->ufunc = PyUFunc_FromFuncAndData( + interaction_funcs + , interaction_data + , interaction_types + , 1 + , 5 + , 2 + , PyUFunc_None + , "interaction2D" + , "Update the momenta according to the given coefficients and positions" + , 0); + break; + } + default: + { + PyErr_SetString(PyExc_ValueError, "unknown ufunc type, must be 0 or 1"); + return -1 + } + + } } static PyObject * interaction_UFuncWrapper_call - (interaction_UFuncWrapper * self, - PyObject * data) + (interaction_UFuncWrapper * self + , PyObject * args + , PyObject * kwargs) { - return + return PyObject_Call(self->ufunc, args, kwargs); } static PyMethodDef InteractionMethods[] = { {NULL, NULL, 0, NULL} }; -// FIXME -PyUFuncGenericFunction interaction_funcs[] = - { &interaction_ufunc_float2D}; -PyUFuncGenericFunction force_funcs[] = - { &interaction_ufunc_force}; - -static char interaction_types[] = - { NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT}; -static char force_types[] = - { NPY_FLOAT, NPY_FLOAT, NPY_FLOAT}; - -static void *interaction_data[] = {NULL}; -static void *force_data[] = {NULL}; static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT @@ -223,29 +272,7 @@ PyInit_interaction(void) import_ufunc(); ufunc_interaction = PyUFunc_FromFuncAndDataAndSignature( - interaction_funcs - , interaction_data - , interaction_types - , 1 - , 5 - , 2 - , PyUFunc_None - , "interaction2D" - , "Update the momenta according to the given coefficients and positions" - , 0 - , "(n),(n),(n),(n),(19)->(n),(n)"); ufunc_force = PyUFunc_FromFuncAndDataAndSignature( - force_funcs - , force_data - , force_types - , 1 - , 2 - , 1 - , PyUFunc_None - , "force_function" - , "computes the scalar force between two particles with given coefficients" - , 0 - , "(n),(19)->(n)"); dct = PyModule_GetDict(module); PyDict_SetItemString(dct, "interaction2D", ufunc_interaction);