diff --git a/doc/c_cpp_api.rst b/doc/c_cpp_api.rst index b5c37a3014584109b417be00d24cccd7de80735a..0d702f7d121ffddde2f269ce5f6f1bd4e7e7b657 100644 --- a/doc/c_cpp_api.rst +++ b/doc/c_cpp_api.rst @@ -74,6 +74,14 @@ Activation Functors Returns ``1`` if it is, and ``0`` otherwise. +.. cpp:function:: PyObject* PyBobLearnActivation_NewFromActivation(boost::shared_ptr<bob::machine::Activation> a) + + Constructs a new :c:type:`PyBobLearnActivationObject` starting from a shared + pointer to a pre-allocated `bob::machine::Activation` instance. This API is + available so that return values from actuall C++ machines can be mapped into + Python. It is the sole way to build an object of type :py:class:`Activation` + without recurring to the derived classes. + .. note:: Other object definitions exist for each of the specializations for diff --git a/xbob/learn/activation/activation.cpp b/xbob/learn/activation/activation.cpp index df0b413dfd90e8406b75705d671a707bbad3cf5e..7829bddc76d373325820ab3eb9d79367eef3d693 100644 --- a/xbob/learn/activation/activation.cpp +++ b/xbob/learn/activation/activation.cpp @@ -43,10 +43,41 @@ PyDoc_STRVAR(s_activation_doc, \n\ "); +static PyObject* PyBobLearnActivation_new +(PyTypeObject* type, PyObject*, PyObject*) { + + /* Allocates the python object itself */ + PyBobLearnActivationObject* self = + (PyBobLearnActivationObject*)type->tp_alloc(type, 0); + + self->cxx.reset(); + + return reinterpret_cast<PyObject*>(self); + +} + +PyObject* PyBobLearnActivation_NewFromActivation +(boost::shared_ptr<bob::machine::Activation> a) { + + PyBobLearnActivationObject* retval = (PyBobLearnActivationObject*)PyBobLearnActivation_new(&PyBobLearnActivation_Type, 0, 0); + + retval->cxx = a; + + return reinterpret_cast<PyObject*>(retval); + +} + +static void PyBobLearnActivation_delete (PyBobLearnActivationObject* self) { + + self->cxx.reset(); + self->ob_type->tp_free((PyObject*)self); + +} + static int PyBobLearnActivation_init(PyBobLearnActivationObject* self, PyObject*, PyObject*) { - PyErr_Format(PyExc_NotImplementedError, "cannot initialize object of base type `%s' - use one of the inherited classes", s_activation_str); + PyErr_Format(PyExc_NotImplementedError, "cannot initialize object of base type `%s' - use one of the inherited classes", self->ob_type->tp_name); return -1; } @@ -99,7 +130,7 @@ static int apply(boost::function<double (double)> function, } -static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* o, +static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* self, double (bob::machine::Activation::*method) (double) const, PyObject* args, PyObject* kwds) { @@ -120,12 +151,12 @@ static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* o, auto z_converted_ = make_safe(z_converted); if (z_converted->type_num != NPY_FLOAT64) { - PyErr_SetString(PyExc_TypeError, "Activation function only supports 64-bit float arrays for input array `z'"); + PyErr_Format(PyExc_TypeError, "`%s' function only supports 64-bit float arrays for input array `z'", self->ob_type->tp_name); return 0; } if (z_converted->ndim < 1 || z_converted->ndim > 4) { - PyErr_Format(PyExc_TypeError, "Activation function only accepts 1, 2, 3 or 4-dimensional arrays (not %" PY_FORMAT_SIZE_T "dD arrays)", z_converted->ndim); + PyErr_Format(PyExc_TypeError, "`%s' function only accepts 1, 2, 3 or 4-dimensional arrays (not %" PY_FORMAT_SIZE_T "dD arrays)", self->ob_type->tp_name, z_converted->ndim); return 0; } @@ -135,11 +166,11 @@ static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* o, auto res_ = make_safe(res); // processes the data - int ok = apply(boost::bind(method, o->base, _1), + int ok = apply(boost::bind(method, self->cxx, _1), z_converted, reinterpret_cast<PyBlitzArrayObject*>(res)); if (!ok) { - PyErr_SetString(PyExc_RuntimeError, "unexpected error occurred applying C++ activation function to input array (DEBUG ME)"); + PyErr_Format(PyExc_RuntimeError, "unexpected error occurred applying `%s' to input array (DEBUG ME)", self->ob_type->tp_name); return 0; } @@ -152,18 +183,18 @@ static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* o, PyObject* z_float = PyNumber_Float(z); auto z_float_ = make_safe(z_float); - auto bound_method = boost::bind(method, o->base, _1); + auto bound_method = boost::bind(method, self->cxx, _1); double res_c = bound_method(PyFloat_AsDouble(z_float)); return PyFloat_FromDouble(res_c); } - PyErr_Format(PyExc_TypeError, "Activation function is not capable to process input objects of type `%s'", z->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "`%s' is not capable to process input objects of type `%s'", self->ob_type->tp_name, z->ob_type->tp_name); return 0; } -static PyObject* PyBobLearnActivation_call2(PyBobLearnActivationObject* o, +static PyObject* PyBobLearnActivation_call2(PyBobLearnActivationObject* self, double (bob::machine::Activation::*method) (double) const, PyObject* args, PyObject* kwds) { @@ -184,17 +215,17 @@ static PyObject* PyBobLearnActivation_call2(PyBobLearnActivationObject* o, auto res_ = make_safe(res); if (z->type_num != NPY_FLOAT64) { - PyErr_SetString(PyExc_TypeError, "Activation function only supports 64-bit float arrays for input array `z'"); + PyErr_Format(PyExc_TypeError, "`%s' function only supports 64-bit float arrays for input array `z'", self->ob_type->tp_name); return 0; } if (res->type_num != NPY_FLOAT64) { - PyErr_SetString(PyExc_TypeError, "Activation function only supports 64-bit float arrays for output array `res'"); + PyErr_Format(PyExc_TypeError, "`%s' function only supports 64-bit float arrays for output array `res'", self->ob_type->tp_name); return 0; } if (z->ndim < 1 || z->ndim > 4) { - PyErr_Format(PyExc_TypeError, "Activation function only accepts 1, 2, 3 or 4-dimensional arrays (not %" PY_FORMAT_SIZE_T "dD arrays)", z->ndim); + PyErr_Format(PyExc_TypeError, "`%s' function only accepts 1, 2, 3 or 4-dimensional arrays (not %" PY_FORMAT_SIZE_T "dD arrays)", self->ob_type->tp_name, z->ndim); return 0; } @@ -213,10 +244,10 @@ static PyObject* PyBobLearnActivation_call2(PyBobLearnActivationObject* o, } //at this point all checks are done, we can proceed into calling C++ - int ok = apply(boost::bind(method, o->base, _1), z, res); + int ok = apply(boost::bind(method, self->cxx, _1), z, res); if (!ok) { - PyErr_SetString(PyExc_RuntimeError, "unexpected error occurred applying C++ activation function to input array (DEBUG ME)"); + PyErr_Format(PyExc_RuntimeError, "unexpected error occurred applying C++ `%s' to input array (DEBUG ME)", self->ob_type->tp_name); return 0; } @@ -249,7 +280,7 @@ error otherwise.\n\ \n\ "); -static PyObject* PyBobLearnActivation_call(PyBobLearnActivationObject* o, +static PyObject* PyBobLearnActivation_call(PyBobLearnActivationObject* self, PyObject* args, PyObject* kwds) { Py_ssize_t nargs = args?PyTuple_Size(args):0 + kwds?PyDict_Size(kwds):0; @@ -258,12 +289,12 @@ static PyObject* PyBobLearnActivation_call(PyBobLearnActivationObject* o, case 1: return PyBobLearnActivation_call1 - (o, &bob::machine::Activation::f, args, kwds); + (self, &bob::machine::Activation::f, args, kwds); break; case 2: return PyBobLearnActivation_call2 - (o, &bob::machine::Activation::f, args, kwds); + (self, &bob::machine::Activation::f, args, kwds); break; default: @@ -301,7 +332,7 @@ error otherwise.\n\ \n\ "); -static PyObject* PyBobLearnActivation_f_prime(PyBobLearnActivationObject* o, +static PyObject* PyBobLearnActivation_f_prime(PyBobLearnActivationObject* self, PyObject* args, PyObject* kwds) { Py_ssize_t nargs = args?PyTuple_Size(args):0 + kwds?PyDict_Size(kwds):0; @@ -310,12 +341,12 @@ static PyObject* PyBobLearnActivation_f_prime(PyBobLearnActivationObject* o, case 1: return PyBobLearnActivation_call1 - (o, &bob::machine::Activation::f_prime, args, kwds); + (self, &bob::machine::Activation::f_prime, args, kwds); break; case 2: return PyBobLearnActivation_call2 - (o, &bob::machine::Activation::f_prime, args, kwds); + (self, &bob::machine::Activation::f_prime, args, kwds); break; default: @@ -353,8 +384,8 @@ error otherwise.\n\ \n\ "); -static PyObject* PyBobLearnActivation_f_prime_from_f(PyBobLearnActivationObject* o, - PyObject* args, PyObject* kwds) { +static PyObject* PyBobLearnActivation_f_prime_from_f +(PyBobLearnActivationObject* self, PyObject* args, PyObject* kwds) { Py_ssize_t nargs = args?PyTuple_Size(args):0 + kwds?PyDict_Size(kwds):0; @@ -362,12 +393,12 @@ static PyObject* PyBobLearnActivation_f_prime_from_f(PyBobLearnActivationObject* case 1: return PyBobLearnActivation_call1 - (o, &bob::machine::Activation::f_prime_from_f, args, kwds); + (self, &bob::machine::Activation::f_prime_from_f, args, kwds); break; case 2: return PyBobLearnActivation_call2 - (o, &bob::machine::Activation::f_prime_from_f, args, kwds); + (self, &bob::machine::Activation::f_prime_from_f, args, kwds); break; default: @@ -389,8 +420,9 @@ in connection with the Activation registry.\n\ \n\ "); -static PyObject* PyBobLearnActivation_UniqueIdentifier (PyBobLearnActivationObject* o) { - return Py_BuildValue("s", o->base->unique_identifier().c_str()); +static PyObject* PyBobLearnActivation_UniqueIdentifier +(PyBobLearnActivationObject* self) { + return Py_BuildValue("s", self->cxx->unique_identifier().c_str()); } PyDoc_STRVAR(s_load_str, "load"); @@ -401,18 +433,18 @@ Loads itself from a :py:class:`xbob.io.HDF5File`\n\ \n\ "); -static PyObject* PyBobLearnActivation_Load(PyBobLearnActivationObject* o, +static PyObject* PyBobLearnActivation_Load(PyBobLearnActivationObject* self, PyObject* f) { if (!PyBobIoHDF5File_Check(f)) { - PyErr_Format(PyExc_TypeError, "Activation function cannot load itself from `%s', only from an HDF5 file", f->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "`%s' cannot load itself from `%s', only from an HDF5 file", self->ob_type->tp_name, f->ob_type->tp_name); return 0; } auto h5f = reinterpret_cast<PyBobIoHDF5FileObject*>(f); try { - o->base->load(*h5f->f); + self->cxx->load(*h5f->f); } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); @@ -431,22 +463,22 @@ PyDoc_STRVAR(s_save_str, "save"); PyDoc_STRVAR(s_save_doc, "o.save(f) -> None\n\ \n\ -Loads itself from a :py:class:`xbob.io.HDF5File`\n\ +Saves itself to a :py:class:`xbob.io.HDF5File`\n\ \n\ "); -static PyObject* PyBobLearnActivation_Save(PyBobLearnActivationObject* o, - PyObject* f) { +static PyObject* PyBobLearnActivation_Save +(PyBobLearnActivationObject* self, PyObject* f) { if (!PyBobIoHDF5File_Check(f)) { - PyErr_Format(PyExc_TypeError, "Activation function cannot write itself to `%s', only to an HDF5 file", f->ob_type->tp_name); + PyErr_Format(PyExc_TypeError, "`%s' cannot write itself to `%s', only to an HDF5 file", self->ob_type->tp_name, f->ob_type->tp_name); return 0; } auto h5f = reinterpret_cast<PyBobIoHDF5FileObject*>(f); try { - o->base->save(*h5f->f); + self->cxx->save(*h5f->f); } catch (std::exception& e) { PyErr_SetString(PyExc_RuntimeError, e.what()); @@ -509,7 +541,7 @@ static PyObject* PyBobLearnActivation_RichCompare (PyBobLearnActivationObject* s if (!PyBobLearnActivation_Check(other)) { PyErr_Format(PyExc_TypeError, "cannot compare `%s' with `%s'", - s_activation_str, other->ob_type->tp_name); + self->ob_type->tp_name, other->ob_type->tp_name); return 0; } @@ -517,11 +549,11 @@ static PyObject* PyBobLearnActivation_RichCompare (PyBobLearnActivationObject* s switch (op) { case Py_EQ: - if (self->base->str() == other_->base->str()) Py_RETURN_TRUE; + if (self->cxx->str() == other_->cxx->str()) Py_RETURN_TRUE; Py_RETURN_FALSE; break; case Py_NE: - if (self->base->str() != other_->base->str()) Py_RETURN_TRUE; + if (self->cxx->str() != other_->cxx->str()) Py_RETURN_TRUE; Py_RETURN_FALSE; break; default: @@ -531,8 +563,8 @@ static PyObject* PyBobLearnActivation_RichCompare (PyBobLearnActivationObject* s } -static PyObject* PyBobLearnActivation_Str (PyBobLearnActivationObject* o) { - return Py_BuildValue("s", o->base->str().c_str()); +static PyObject* PyBobLearnActivation_Str (PyBobLearnActivationObject* self) { + return Py_BuildValue("s", self->cxx->str().c_str()); } PyTypeObject PyBobLearnActivation_Type = { @@ -541,7 +573,7 @@ PyTypeObject PyBobLearnActivation_Type = { s_activation_str, /* tp_name */ sizeof(PyBobLearnActivationObject), /* tp_basicsize */ 0, /* tp_itemsize */ - 0, /* tp_dealloc */ + (destructor)PyBobLearnActivation_delete, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -574,5 +606,5 @@ PyTypeObject PyBobLearnActivation_Type = { 0, /* tp_dictoffset */ (initproc)PyBobLearnActivation_init, /* tp_init */ 0, /* tp_alloc */ - 0, /* tp_new */ + PyBobLearnActivation_new /* tp_new */ }; diff --git a/xbob/learn/activation/identity.cpp b/xbob/learn/activation/identity.cpp index 32072b01b891166a19196921958b8280a8e80275..0463d42b3bc8d27fd19a7c915f66d367d298a188 100644 --- a/xbob/learn/activation/identity.cpp +++ b/xbob/learn/activation/identity.cpp @@ -28,7 +28,7 @@ static int PyBobLearnIdentityActivation_init if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1; try { - self->base = new bob::machine::IdentityActivation(); + self->cxx.reset(new bob::machine::IdentityActivation()); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); @@ -37,7 +37,7 @@ static int PyBobLearnIdentityActivation_init PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_identityactivation_str); } - self->parent.base = self->base; + self->parent.cxx = self->cxx; if (PyErr_Occurred()) return -1; @@ -48,9 +48,8 @@ static int PyBobLearnIdentityActivation_init static void PyBobLearnIdentityActivation_delete (PyBobLearnIdentityActivationObject* self) { - delete self->base; - self->parent.base = 0; - self->base = 0; + self->parent.cxx.reset(); + self->cxx.reset(); self->parent.ob_type->tp_free((PyObject*)self); } diff --git a/xbob/learn/activation/include/xbob.learn.activation/api.h b/xbob/learn/activation/include/xbob.learn.activation/api.h index c737cb2d0991983563d04f0e82a8eaa5602c3545..34383078ed135819abae27ba3d73223eff282bd7 100644 --- a/xbob/learn/activation/include/xbob.learn.activation/api.h +++ b/xbob/learn/activation/include/xbob.learn.activation/api.h @@ -33,7 +33,7 @@ typedef struct { PyObject_HEAD - bob::machine::Activation* base; + boost::shared_ptr<bob::machine::Activation> cxx; } PyBobLearnActivationObject; #define PyBobLearnActivation_Type_NUM 1 @@ -43,16 +43,20 @@ typedef struct { #define PyBobLearnActivation_Check_RET int #define PyBobLearnActivation_Check_PROTO (PyObject* o) +#define PyBobLearnActivation_NewFromActivation_NUM 3 +#define PyBobLearnActivation_NewFromActivation_RET PyObject* +#define PyBobLearnActivation_NewFromActivation_PROTO (boost::shared_ptr<bob::machine::Activation> a) + /*********************************************** * Bindings for xbob.learn.activation.Identity * ***********************************************/ typedef struct { PyBobLearnActivationObject parent; - bob::machine::IdentityActivation* base; + boost::shared_ptr<bob::machine::IdentityActivation> cxx; } PyBobLearnIdentityActivationObject; -#define PyBobLearnIdentityActivation_Type_NUM 3 +#define PyBobLearnIdentityActivation_Type_NUM 4 #define PyBobLearnIdentityActivation_Type_TYPE PyTypeObject /********************************************* @@ -61,10 +65,10 @@ typedef struct { typedef struct { PyBobLearnActivationObject parent; - bob::machine::LinearActivation* base; + boost::shared_ptr<bob::machine::LinearActivation> cxx; } PyBobLearnLinearActivationObject; -#define PyBobLearnLinearActivation_Type_NUM 4 +#define PyBobLearnLinearActivation_Type_NUM 5 #define PyBobLearnLinearActivation_Type_TYPE PyTypeObject /*********************************************** @@ -73,10 +77,10 @@ typedef struct { typedef struct { PyBobLearnActivationObject parent; - bob::machine::LogisticActivation* base; + boost::shared_ptr<bob::machine::LogisticActivation> cxx; } PyBobLearnLogisticActivationObject; -#define PyBobLearnLogisticActivation_Type_NUM 5 +#define PyBobLearnLogisticActivation_Type_NUM 6 #define PyBobLearnLogisticActivation_Type_TYPE PyTypeObject /******************************************************** @@ -85,10 +89,10 @@ typedef struct { typedef struct { PyBobLearnActivationObject parent; - bob::machine::HyperbolicTangentActivation* base; + boost::shared_ptr<bob::machine::HyperbolicTangentActivation> cxx; } PyBobLearnHyperbolicTangentActivationObject; -#define PyBobLearnHyperbolicTangentActivation_Type_NUM 6 +#define PyBobLearnHyperbolicTangentActivation_Type_NUM 7 #define PyBobLearnHyperbolicTangentActivation_Type_TYPE PyTypeObject /****************************************************************** @@ -97,14 +101,14 @@ typedef struct { typedef struct { PyBobLearnActivationObject parent; - bob::machine::MultipliedHyperbolicTangentActivation* base; + boost::shared_ptr<bob::machine::MultipliedHyperbolicTangentActivation> cxx; } PyBobLearnMultipliedHyperbolicTangentActivationObject; -#define PyBobLearnMultipliedHyperbolicTangentActivation_Type_NUM 7 +#define PyBobLearnMultipliedHyperbolicTangentActivation_Type_NUM 8 #define PyBobLearnMultipliedHyperbolicTangentActivation_Type_TYPE PyTypeObject /* Total number of C API pointers */ -#define PyXbobLearnActivation_API_pointers 8 +#define PyXbobLearnActivation_API_pointers 9 #ifdef XBOB_LEARN_ACTIVATION_MODULE @@ -124,6 +128,8 @@ typedef struct { PyBobLearnActivation_Check_RET PyBobLearnActivation_Check PyBobLearnActivation_Check_PROTO; + PyBobLearnActivation_NewFromActivation_RET PyBobLearnActivation_NewFromActivation PyBobLearnActivation_NewFromActivation_PROTO; + /*********************************************** * Bindings for xbob.learn.activation.Identity * ***********************************************/ @@ -194,6 +200,8 @@ typedef struct { # define PyBobLearnActivation_Check (*(PyBobLearnActivation_Check_RET (*)PyBobLearnActivation_Check_PROTO) PyXbobLearnActivation_API[PyBobLearnActivation_Check_NUM]) +# define PyBobLearnActivation_NewFromActivation (*(PyBobLearnActivation_NewFromActivation_RET (*)PyBobLearnActivation_NewFromActivation_PROTO) PyXbobLearnActivation_API[PyBobLearnActivation_NewFromActivation_NUM]) + /*********************************************** * Bindings for xbob.learn.activation.Identity * ***********************************************/ diff --git a/xbob/learn/activation/linear.cpp b/xbob/learn/activation/linear.cpp index 491ebd6b06af7e571ae294878b710bbf77a4237a..bb338052e4dc75afb19e0c5b136a5487bfb9f2ce 100644 --- a/xbob/learn/activation/linear.cpp +++ b/xbob/learn/activation/linear.cpp @@ -33,7 +33,7 @@ static int PyBobLearnLinearActivation_init if (!PyArg_ParseTupleAndKeywords(args, kwds, "|d", kwlist, &C)) return -1; try { - self->base = new bob::machine::LinearActivation(C); + self->cxx.reset(new bob::machine::LinearActivation(C)); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); @@ -42,7 +42,7 @@ static int PyBobLearnLinearActivation_init PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_linearactivation_str); } - self->parent.base = self->base; + self->parent.cxx = self->cxx; if (PyErr_Occurred()) return -1; @@ -53,9 +53,8 @@ static int PyBobLearnLinearActivation_init static void PyBobLearnLinearActivation_delete (PyBobLearnLinearActivationObject* self) { - delete self->base; - self->parent.base = 0; - self->base = 0; + self->parent.cxx.reset(); + self->cxx.reset(); self->parent.ob_type->tp_free((PyObject*)self); } @@ -68,7 +67,7 @@ PyDoc_STRVAR(s_C_doc, static PyObject* PyBobLearnLinearActivation_C (PyBobLearnLinearActivationObject* self) { - return Py_BuildValue("d", self->base->C()); + return Py_BuildValue("d", self->cxx->C()); } diff --git a/xbob/learn/activation/logistic.cpp b/xbob/learn/activation/logistic.cpp index 34c223347c3cac89a193730a02abb70e2a9793ed..ba5af66f730fa8b90a6cace9c6beb7e0eb8c12c9 100644 --- a/xbob/learn/activation/logistic.cpp +++ b/xbob/learn/activation/logistic.cpp @@ -27,7 +27,7 @@ static int PyBobLearnLogisticActivation_init if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1; try { - self->base = new bob::machine::LogisticActivation(); + self->cxx.reset(new bob::machine::LogisticActivation()); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); @@ -36,7 +36,7 @@ static int PyBobLearnLogisticActivation_init PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_logisticactivation_str); } - self->parent.base = self->base; + self->parent.cxx = self->cxx; if (PyErr_Occurred()) return -1; @@ -47,9 +47,8 @@ static int PyBobLearnLogisticActivation_init static void PyBobLearnLogisticActivation_delete (PyBobLearnLogisticActivationObject* self) { - delete self->base; - self->parent.base = 0; - self->base = 0; + self->parent.cxx.reset(); + self->cxx.reset(); self->parent.ob_type->tp_free((PyObject*)self); } diff --git a/xbob/learn/activation/main.cpp b/xbob/learn/activation/main.cpp index 053230940119bbf84ddb90ffaaac788a945d95e8..7e25978753261f6f166ed0fc69f6bc3606ab59f8 100644 --- a/xbob/learn/activation/main.cpp +++ b/xbob/learn/activation/main.cpp @@ -89,6 +89,8 @@ PyMODINIT_FUNC XBOB_EXT_ENTRY_NAME (void) { PyXbobLearnActivation_API[PyBobLearnActivation_Check_NUM] = (void *)&PyBobLearnActivation_Check; + PyXbobLearnActivation_API[PyBobLearnActivation_NewFromActivation_NUM] = (void *)&PyBobLearnActivation_NewFromActivation; + /*********************************************** * Bindings for xbob.learn.activation.Identity * ***********************************************/ diff --git a/xbob/learn/activation/mult_tanh.cpp b/xbob/learn/activation/mult_tanh.cpp index 72038bb3ed12e8880c4348876f16befcd7c43053..95e4acc10bfa02a34bbb108f30f124cd682dc52f 100644 --- a/xbob/learn/activation/mult_tanh.cpp +++ b/xbob/learn/activation/mult_tanh.cpp @@ -38,7 +38,7 @@ static int PyBobLearnMultipliedHyperbolicTangentActivation_init return -1; try { - self->base = new bob::machine::MultipliedHyperbolicTangentActivation(C, M); + self->cxx.reset(new bob::machine::MultipliedHyperbolicTangentActivation(C, M)); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); @@ -47,7 +47,7 @@ static int PyBobLearnMultipliedHyperbolicTangentActivation_init PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_multtanhactivation_str); } - self->parent.base = self->base; + self->parent.cxx = self->cxx; if (PyErr_Occurred()) return -1; @@ -58,9 +58,8 @@ static int PyBobLearnMultipliedHyperbolicTangentActivation_init static void PyBobLearnMultipliedHyperbolicTangentActivation_delete (PyBobLearnMultipliedHyperbolicTangentActivationObject* self) { - delete self->base; - self->parent.base = 0; - self->base = 0; + self->parent.cxx.reset(); + self->cxx.reset(); self->parent.ob_type->tp_free((PyObject*)self); } @@ -74,7 +73,7 @@ tangent function (read-only).\n\ static PyObject* PyBobLearnMultipliedHyperbolicTangentActivation_C (PyBobLearnMultipliedHyperbolicTangentActivationObject* self) { - return Py_BuildValue("d", self->base->C()); + return Py_BuildValue("d", self->cxx->C()); } @@ -88,7 +87,7 @@ tangent function (read-only).\n\ static PyObject* PyBobLearnMultipliedHyperbolicTangentActivation_M (PyBobLearnMultipliedHyperbolicTangentActivationObject* self) { - return Py_BuildValue("d", self->base->M()); + return Py_BuildValue("d", self->cxx->M()); } diff --git a/xbob/learn/activation/tanh.cpp b/xbob/learn/activation/tanh.cpp index d310a7ac37a439a39f28cb76f1ecedc6a44053b0..866a713e98d4fd457adbde647b74fae9e6fd9997 100644 --- a/xbob/learn/activation/tanh.cpp +++ b/xbob/learn/activation/tanh.cpp @@ -29,7 +29,7 @@ static int PyBobLearnHyperbolicTangentActivation_init if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1; try { - self->base = new bob::machine::HyperbolicTangentActivation(); + self->cxx.reset(new bob::machine::HyperbolicTangentActivation()); } catch (std::exception& ex) { PyErr_SetString(PyExc_RuntimeError, ex.what()); @@ -38,7 +38,7 @@ static int PyBobLearnHyperbolicTangentActivation_init PyErr_Format(PyExc_RuntimeError, "cannot create new object of type `%s' - unknown exception thrown", s_hyperbolictangentactivation_str); } - self->parent.base = self->base; + self->parent.cxx = self->cxx; if (PyErr_Occurred()) return -1; @@ -49,9 +49,8 @@ static int PyBobLearnHyperbolicTangentActivation_init static void PyBobLearnHyperbolicTangentActivation_delete (PyBobLearnHyperbolicTangentActivationObject* self) { - delete self->base; - self->parent.base = 0; - self->base = 0; + self->parent.cxx.reset(); + self->cxx.reset(); self->parent.ob_type->tp_free((PyObject*)self); }