diff --git a/xbob/measure/main.cpp b/xbob/measure/main.cpp index 8589f07e5d61a757045637403229803662ef2f02..1d2304396e2a0d4a545217f63904d31dd747d7bb 100644 --- a/xbob/measure/main.cpp +++ b/xbob/measure/main.cpp @@ -890,18 +890,51 @@ static PyObject* rocch2eer(PyObject*, PyObject* args, PyObject* kwds) { } -/** -void bind_measure_error() { +PyDoc_STRVAR(s_roc_for_far_str, "roc_for_far"); +PyDoc_STRVAR(s_roc_for_far_doc, +"roc_for_far(negatives, positives, far_list) -> array\n\ +\n\ +Calculates the ROC curve given a set of positive and negative\n\ +scores and the FAR values for which the CAR should be computed.\n\ +The resulting ROC curve holds a copy of the given FAR values (row\n\ +0), and the corresponding FRR values (row 1).\n\ +"); + +static PyObject* roc_for_far(PyObject*, PyObject* args, PyObject* kwds) { + + /* Parses input arguments in a single shot */ + static const char* const_kwlist[] = { + "negatives", + "positives", + "far_list", + 0 /* Sentinel */ + }; + static char** kwlist = const_cast<char**>(const_kwlist); - def( - "roc_for_far", - &bob_roc_for_far, - (arg("negatives"), arg("positives"), arg("far_list")), - "Calculates the ROC curve given a set of positive and negative scores and the FAR values for which the CAR should be computed. The resulting ROC curve holds a copy of the given FAR values (row 0), and the corresponding FRR values (row 1)." - ); + PyBlitzArrayObject* neg = 0; + PyBlitzArrayObject* pos = 0; + PyBlitzArrayObject* list = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O&O&", + kwlist, + &double1d_converter, &neg, + &double1d_converter, &pos, + &double1d_converter, &list + )) return 0; + + auto result = bob::measure::roc_for_far( + *PyBlitzArrayCxx_AsBlitz<double,1>(neg), + *PyBlitzArrayCxx_AsBlitz<double,1>(pos), + *PyBlitzArrayCxx_AsBlitz<double,1>(list) + ); + + Py_DECREF(neg); + Py_DECREF(pos); + Py_DECREF(list); + + return reinterpret_cast<PyObject*>(PyBlitzArrayCxx_NewFromArray(result)); } -**/ static PyMethodDef library_methods[] = { { @@ -1012,6 +1045,12 @@ static PyMethodDef library_methods[] = { METH_VARARGS|METH_KEYWORDS, s_rocch2eer_doc }, + { + s_roc_for_far_str, + (PyCFunction)roc_for_far, + METH_VARARGS|METH_KEYWORDS, + s_roc_for_far_doc + }, {0} /* Sentinel */ };