Commit 7b374776 authored by Manuel Günther's avatar Manuel Günther
Browse files

Removed dependency on bob by adding C++ Library to this package.

parent f3eeaaf9
......@@ -3,11 +3,6 @@ from . import version
from .version import module as __version__
from .version import api as __api_version__
def get_include():
"""Returns the directory containing the C/C++ API include directives"""
return __import__('pkg_resources').resource_filename(__name__, 'include')
def get_config():
"""Returns a string containing the configuration information.
"""
......
......@@ -2,7 +2,7 @@
* @author Andre Anjos <andre.anjos@idiap.ch>
* @date Fri 10 Jan 2014 14:26:25 CET
*
* @brief Python bindings for the machine activation
* @brief Python bindings for bob::learn::activation
*
* Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland
*/
......@@ -12,7 +12,7 @@
#include <bob.io.base/api.h>
#include <bob.blitz/cppapi.h>
#include <bob.blitz/cleanup.h>
#include <bob/machine/Activation.h>
#include <bob.learn.activation/Activation.h>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <structmember.h>
......@@ -37,7 +37,7 @@ PyDoc_STRVAR(s_activation_doc,
expect them to work fine with the C++ code, as no hook is\n\
implemented as of this time to allow for this. You must create\n\
a class that inherits from the C++\n\
:cpp:type:`bob::machine::Activation` in C++ and then bind it to\n\
:cpp:type:`bob::learn::activation::Activation` in C++ and then bind it to\n\
Python like we have done for the classes available in these\n\
bindings.\n\
\n\
......@@ -57,7 +57,7 @@ static PyObject* PyBobLearnActivation_new
}
PyObject* PyBobLearnActivation_NewFromActivation
(boost::shared_ptr<bob::machine::Activation> a) {
(boost::shared_ptr<bob::learn::activation::Activation> a) {
PyBobLearnActivationObject* retval = (PyBobLearnActivationObject*)PyBobLearnActivation_new(&PyBobLearnActivation_Type, 0, 0);
......@@ -131,7 +131,7 @@ static int apply(boost::function<double (double)> function,
}
static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* self,
double (bob::machine::Activation::*method) (double) const,
double (bob::learn::activation::Activation::*method) (double) const,
PyObject* args, PyObject* kwds) {
/* Parses input arguments in a single shot */
......@@ -195,7 +195,7 @@ static PyObject* PyBobLearnActivation_call1(PyBobLearnActivationObject* self,
}
static PyObject* PyBobLearnActivation_call2(PyBobLearnActivationObject* self,
double (bob::machine::Activation::*method) (double) const,
double (bob::learn::activation::Activation::*method) (double) const,
PyObject* args, PyObject* kwds) {
/* Parses input arguments in a single shot */
......@@ -289,12 +289,12 @@ static PyObject* PyBobLearnActivation_call(PyBobLearnActivationObject* self,
case 1:
return PyBobLearnActivation_call1
(self, &bob::machine::Activation::f, args, kwds);
(self, &bob::learn::activation::Activation::f, args, kwds);
break;
case 2:
return PyBobLearnActivation_call2
(self, &bob::machine::Activation::f, args, kwds);
(self, &bob::learn::activation::Activation::f, args, kwds);
break;
default:
......@@ -341,12 +341,12 @@ static PyObject* PyBobLearnActivation_f_prime(PyBobLearnActivationObject* self,
case 1:
return PyBobLearnActivation_call1
(self, &bob::machine::Activation::f_prime, args, kwds);
(self, &bob::learn::activation::Activation::f_prime, args, kwds);
break;
case 2:
return PyBobLearnActivation_call2
(self, &bob::machine::Activation::f_prime, args, kwds);
(self, &bob::learn::activation::Activation::f_prime, args, kwds);
break;
default:
......@@ -393,12 +393,12 @@ static PyObject* PyBobLearnActivation_f_prime_from_f
case 1:
return PyBobLearnActivation_call1
(self, &bob::machine::Activation::f_prime_from_f, args, kwds);
(self, &bob::learn::activation::Activation::f_prime_from_f, args, kwds);
break;
case 2:
return PyBobLearnActivation_call2
(self, &bob::machine::Activation::f_prime_from_f, args, kwds);
(self, &bob::learn::activation::Activation::f_prime_from_f, args, kwds);
break;
default:
......
/**
* @author Andre Anjos <andre.anjos@idiap.ch>
* @date Fri 17 May 2013 16:02:05 CEST
*
* @brief Implementation of the activation registry
*
* Copyright (C) Idiap Research Institute, Martigny, Switzerland
*/
#include <bob.learn.activation/Activation.h>
boost::shared_ptr<bob::learn::activation::ActivationRegistry> bob::learn::activation::ActivationRegistry::instance() {
static boost::shared_ptr<bob::learn::activation::ActivationRegistry> s_instance(new ActivationRegistry());
return s_instance;
}
void bob::learn::activation::ActivationRegistry::deregisterFactory(const std::string& id) {
s_id2factory.erase(id);
}
void bob::learn::activation::ActivationRegistry::registerActivation(const std::string& id,
bob::learn::activation::activation_factory_t factory) {
auto it = s_id2factory.find(id);
if (it == s_id2factory.end()) {
s_id2factory[id] = factory;
}
else {
if (s_id2factory[id] != factory) {
boost::format m("replacing factory for activation functor `%s' with a different one is not allowed at this point");
m % id;
throw std::runtime_error(m.str());
}
//replacing with the same factory may be the result of multiple python
//modules being loaded.
}
}
bool bob::learn::activation::ActivationRegistry::isRegistered(const std::string& id) {
return (s_id2factory.find(id) != s_id2factory.end());
}
bob::learn::activation::activation_factory_t bob::learn::activation::ActivationRegistry::find
(const std::string& id) {
auto it = s_id2factory.find(id);
if (it == s_id2factory.end()) {
boost::format m("unregistered activation function: %s");
m % id;
throw std::runtime_error(m.str());
}
return it->second;
}
......@@ -28,7 +28,7 @@ static int PyBobLearnIdentityActivation_init
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1;
try {
self->cxx.reset(new bob::machine::IdentityActivation());
self->cxx.reset(new bob::learn::activation::IdentityActivation());
}
catch (std::exception& ex) {
PyErr_SetString(PyExc_RuntimeError, ex.what());
......
/**
* @date Thu Jul 7 16:49:35 2011 +0200
* @author Andre Anjos <andre.anjos@idiap.ch>
*
* @brief Activation functions for linear and MLP machines.
*
* Copyright (C) Idiap Research Institute, Martigny, Switzerland
*/
#ifndef BOB_LEARN_ACTIVATION_ACTIVATION_H
#define BOB_LEARN_ACTIVATION_ACTIVATION_H
#include <string>
#include <boost/shared_ptr.hpp>
#include <bob.io.base/HDF5File.h>
namespace bob { namespace learn { namespace activation {
/**
* Base class for activation functions. All activation functions must derive
* from this one.
*/
class Activation {
public: // api
/**
* Computes activated value, given an input.
*/
virtual double f (double z) const =0;
/**
* Computes the derivative of the current activation - i.e., the same
* input as for f().
*/
virtual double f_prime (double z) const { return f_prime_from_f(f(z)); }
/**
* Computes the derivative of the activated value, given the activated
* value - that is, the output of Activation::f() above.
*/
virtual double f_prime_from_f (double a) const =0;
/**
* Saves itself to an HDF5File
*/
virtual void save(bob::io::base::HDF5File& f) const { f.set("id", unique_identifier()); }
/**
* Loads itself from an HDF5File
*/
virtual void load(bob::io::base::HDF5File& f) {}
/**
* Returns a unique identifier, used by this class in connection to the
* Activation registry.
*/
virtual std::string unique_identifier() const =0;
/**
* Returns a stringified representation for this Activation function
*/
virtual std::string str() const =0;
};
/**
* Generic interface for Activation object factories
*/
typedef boost::shared_ptr<Activation> (*activation_factory_t) (bob::io::base::HDF5File& f);
/**
* Loads an activation function from file using the new API
*/
boost::shared_ptr<Activation> load_activation(bob::io::base::HDF5File& f);
/**
* Loads an activation function using the old API
*
* @param e The old enumeration value for activation functions:
* (0) - linear; (1) - tanh; (2) - logistic
*/
boost::shared_ptr<Activation> make_deprecated_activation(uint32_t e);
/**
* Implements the activation function f(z) = z
*/
class IdentityActivation: public Activation {
public: // api
virtual ~IdentityActivation() {}
virtual double f (double z) const { return z; }
virtual double f_prime (double z) const { return 1.; }
virtual double f_prime_from_f (double a) const { return 1.; }
virtual std::string unique_identifier() const { return "bob.machine.Activation.Identity"; }
virtual std::string str() const { return "f(z) = z"; }
};
/**
* Implements the activation function f(z) = C*z
*/
class LinearActivation: public Activation {
public: // api
LinearActivation(double C=1.) : m_C(C) {}
virtual ~LinearActivation() {}
virtual double f (double z) const { return m_C * z; }
virtual double f_prime (double z) const { return m_C; }
virtual double f_prime_from_f (double a) const { return m_C; }
double C() const { return m_C; }
virtual void save(bob::io::base::HDF5File& f) const { Activation::save(f); f.set("C", m_C); }
virtual void load(bob::io::base::HDF5File& f) { m_C = f.read<double>("C"); }
virtual std::string unique_identifier() const { return "bob.machine.Activation.Linear"; }
virtual std::string str() const { return (boost::format("f(z) = %.5e * z") % m_C).str(); }
private: // representation
double m_C; ///< multiplication factor
};
/**
* Implements the activation function f(z) = std::tanh(z)
*/
class HyperbolicTangentActivation: public Activation {
public: // api
virtual ~HyperbolicTangentActivation() {}
virtual double f (double z) const { return std::tanh(z); }
virtual double f_prime_from_f (double a) const { return (1. - (a*a)); }
virtual std::string unique_identifier() const { return "bob.machine.Activation.HyperbolicTangent"; }
virtual std::string str() const { return "f(z) = tanh(z)"; }
};
/**
* Implements the activation function f(z) = C*tanh(M*z)
*/
class MultipliedHyperbolicTangentActivation: public Activation {
public: // api
MultipliedHyperbolicTangentActivation(double C=1., double M=1.) : m_C(C), m_M(M) {}
virtual ~MultipliedHyperbolicTangentActivation() {}
virtual double f (double z) const { return m_C * std::tanh(m_M * z); }
virtual double f_prime_from_f (double a) const { return m_C * m_M * (1. - std::pow(a/m_C,2)); }
double C() const { return m_C; }
double M() const { return m_M; }
virtual void save(bob::io::base::HDF5File& f) const { Activation::save(f); f.set("C", m_C); f.set("M", m_C); }
virtual void load(bob::io::base::HDF5File& f) {m_C = f.read<double>("C"); m_M = f.read<double>("M"); }
virtual std::string unique_identifier() const { return "bob.machine.Activation.MultipliedHyperbolicTangent"; }
virtual std::string str() const { return (boost::format("f(z) = %.5e * tanh(%.5e * z)") % m_C % m_M).str(); }
private: // representation
double m_C; ///< multiplication factor
double m_M; ///< internal multiplication factor
};
/**
* Implements the activation function f(z) = 1. / ( 1. + e^(-z) )
*/
class LogisticActivation: public Activation {
public: // api
virtual ~LogisticActivation() {}
virtual double f (double z) const { return 1. / ( 1. + std::exp(-z) ); }
virtual double f_prime_from_f (double a) const { return a * (1. - a); }
virtual std::string unique_identifier() const { return "bob.machine.Activation.Logistic"; }
virtual std::string str() const { return "f(z) = 1./(1. + e^-z)"; }
};
/**
* The ActivationRegistry holds registered loaders for different types of
* Activation functions.
*/
class ActivationRegistry {
public: //static access
/**
* Returns the singleton
*/
static boost::shared_ptr<ActivationRegistry> instance();
static const std::map<std::string, activation_factory_t>& getFactories ()
{
boost::shared_ptr<ActivationRegistry> ptr = instance();
return ptr->s_id2factory;
}
public: //object access
void registerActivation(const std::string& unique_identifier,
activation_factory_t factory);
void deregisterFactory(const std::string& unique_identifier);
activation_factory_t find(const std::string& unique_identifier);
bool isRegistered(const std::string& unique_identifier);
private:
ActivationRegistry (): s_id2factory() {}
// Not implemented
ActivationRegistry (const ActivationRegistry&);
std::map<std::string, activation_factory_t> s_id2factory;
};
} } }
#endif /* BOB_LEARN_ACTIVATION_ACTIVATION_H */
......@@ -2,7 +2,7 @@
* @author Andre Anjos <andre.anjos@idiap.ch>
* @date Wed 15 Jan 2014 10:15:21 CET
*
* @brief C/C++ Python API for activation functors in bob::machine
* @brief C/C++ Python API for activation functors in bob::learn::activation
*/
#ifndef BOB_LEARN_ACTIVATION_H
......@@ -10,8 +10,7 @@
#include <Python.h>
#include <bob.learn.activation/config.h>
#include <bob/machine/Activation.h>
#include <bob/machine/LinearMachine.h>
#include <bob.learn.activation/Activation.h>
#define BOB_LEARN_ACTIVATION_MODULE_PREFIX bob.learn.activation
#define BOB_LEARN_ACTIVATION_MODULE_NAME _library
......@@ -53,7 +52,7 @@ enum _PyBobLearnActivation_ENUM{
typedef struct {
PyObject_HEAD
boost::shared_ptr<bob::machine::Activation> cxx;
boost::shared_ptr<bob::learn::activation::Activation> cxx;
} PyBobLearnActivationObject;
#define PyBobLearnActivation_Type_TYPE PyTypeObject
......@@ -62,7 +61,7 @@ typedef struct {
#define PyBobLearnActivation_Check_PROTO (PyObject* o)
#define PyBobLearnActivation_NewFromActivation_RET PyObject*
#define PyBobLearnActivation_NewFromActivation_PROTO (boost::shared_ptr<bob::machine::Activation> a)
#define PyBobLearnActivation_NewFromActivation_PROTO (boost::shared_ptr<bob::learn::activation::Activation> a)
/***********************************************
* Bindings for bob.learn.activation.Identity *
......@@ -70,7 +69,7 @@ typedef struct {
typedef struct {
PyBobLearnActivationObject parent;
boost::shared_ptr<bob::machine::IdentityActivation> cxx;
boost::shared_ptr<bob::learn::activation::IdentityActivation> cxx;
} PyBobLearnIdentityActivationObject;
#define PyBobLearnIdentityActivation_Type_TYPE PyTypeObject
......@@ -81,7 +80,7 @@ typedef struct {
typedef struct {
PyBobLearnActivationObject parent;
boost::shared_ptr<bob::machine::LinearActivation> cxx;
boost::shared_ptr<bob::learn::activation::LinearActivation> cxx;
} PyBobLearnLinearActivationObject;
#define PyBobLearnLinearActivation_Type_TYPE PyTypeObject
......@@ -92,7 +91,7 @@ typedef struct {
typedef struct {
PyBobLearnActivationObject parent;
boost::shared_ptr<bob::machine::LogisticActivation> cxx;
boost::shared_ptr<bob::learn::activation::LogisticActivation> cxx;
} PyBobLearnLogisticActivationObject;
#define PyBobLearnLogisticActivation_Type_TYPE PyTypeObject
......@@ -103,7 +102,7 @@ typedef struct {
typedef struct {
PyBobLearnActivationObject parent;
boost::shared_ptr<bob::machine::HyperbolicTangentActivation> cxx;
boost::shared_ptr<bob::learn::activation::HyperbolicTangentActivation> cxx;
} PyBobLearnHyperbolicTangentActivationObject;
#define PyBobLearnHyperbolicTangentActivation_Type_TYPE PyTypeObject
......@@ -114,7 +113,7 @@ typedef struct {
typedef struct {
PyBobLearnActivationObject parent;
boost::shared_ptr<bob::machine::MultipliedHyperbolicTangentActivation> cxx;
boost::shared_ptr<bob::learn::activation::MultipliedHyperbolicTangentActivation> cxx;
} PyBobLearnMultipliedHyperbolicTangentActivationObject;
#define PyBobLearnMultipliedHyperbolicTangentActivation_Type_TYPE PyTypeObject
......
......@@ -33,7 +33,7 @@ static int PyBobLearnLinearActivation_init
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|d", kwlist, &C)) return -1;
try {
self->cxx.reset(new bob::machine::LinearActivation(C));
self->cxx.reset(new bob::learn::activation::LinearActivation(C));
}
catch (std::exception& ex) {
PyErr_SetString(PyExc_RuntimeError, ex.what());
......
......@@ -27,7 +27,7 @@ static int PyBobLearnLogisticActivation_init
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1;
try {
self->cxx.reset(new bob::machine::LogisticActivation());
self->cxx.reset(new bob::learn::activation::LogisticActivation());
}
catch (std::exception& ex) {
PyErr_SetString(PyExc_RuntimeError, ex.what());
......
......@@ -21,7 +21,7 @@ Builds a new hyperbolic tangent activation function with a given\n\
constant for the inner and outter products. Don't use this if you\n\
just want to set the constants to the default values (1.0). In\n\
such a case, prefer to use the more efficient\n\
:py:class:`bob.machine.HyperbolicTangentActivation`.\n\
:py:class:`bob.learn.activation.HyperbolicTangentActivation`.\n\
");
static int PyBobLearnMultipliedHyperbolicTangentActivation_init
......@@ -38,7 +38,7 @@ static int PyBobLearnMultipliedHyperbolicTangentActivation_init
return -1;
try {
self->cxx.reset(new bob::machine::MultipliedHyperbolicTangentActivation(C, M));
self->cxx.reset(new bob::learn::activation::MultipliedHyperbolicTangentActivation(C, M));
}
catch (std::exception& ex) {
PyErr_SetString(PyExc_RuntimeError, ex.what());
......
......@@ -29,7 +29,7 @@ static int PyBobLearnHyperbolicTangentActivation_init
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist)) return -1;
try {
self->cxx.reset(new bob::machine::HyperbolicTangentActivation());
self->cxx.reset(new bob::learn::activation::HyperbolicTangentActivation());
}
catch (std::exception& ex) {
PyErr_SetString(PyExc_RuntimeError, ex.what());
......
......@@ -5,9 +5,11 @@
* @brief Binds configuration information available from bob
*/
#include <Python.h>
#include <bob/config.h>
#ifdef NO_IMPORT_ARRAY
#undef NO_IMPORT_ARRAY
#endif
#include <bob.blitz/capi.h>
#include <bob.blitz/cleanup.h>
#include <string>
#include <cstdlib>
......@@ -16,11 +18,7 @@
#include <boost/version.hpp>
#include <boost/format.hpp>
#ifdef NO_IMPORT_ARRAY
#undef NO_IMPORT_ARRAY
#endif
#include <bob.blitz/capi.h>
#include <bob.blitz/cleanup.h>
#include <bob.core/config.h>
#include <bob.io.base/config.h>
#include <bob.learn.activation/config.h>
......@@ -82,13 +80,6 @@ static PyObject* python_version() {
return Py_BuildValue("s", f.str().c_str());
}
/**
* Bob version, API version and platform
*/
static PyObject* bob_version() {
return Py_BuildValue("sis", BOB_VERSION, BOB_API_VERSION, BOB_PLATFORM);
}
/**
* Numpy version
*/
......@@ -104,6 +95,13 @@ static PyObject* bob_blitz_version() {
return Py_BuildValue("{ss}", "api", BOOST_PP_STRINGIZE(BOB_BLITZ_API_VERSION));
}
/**
* bob.core c/c++ api version
*/
static PyObject* bob_core_version() {
return Py_BuildValue("{ss}", "api", BOOST_PP_STRINGIZE(BOB_CORE_API_VERSION));
}
/**
* bob.io.base c/c++ api version
*/
......@@ -117,14 +115,15 @@ static PyObject* build_version_dictionary() {
if (!retval) return 0;
auto retval_ = make_safe(retval);
if (!dict_steal(retval, "Bob", bob_core_version())) return 0;
if (!dict_set(retval, "Blitz++", BZ_VERSION)) return 0;
if (!dict_steal(retval, "Boost", boost_version())) return 0;
if (!dict_steal(retval, "Compiler", compiler_version())) return 0;
if (!dict_steal(retval, "Python", python_version())) return 0;
if (!dict_steal(retval, "NumPy", numpy_version())) return 0;
if (!dict_steal(retval, "bob.blitz", bob_blitz_version())) return 0;
if (!dict_steal(retval, "bob.core", bob_core_version())) return 0;
if (!dict_steal(retval, "bob.io.base", bob_io_base_version())) return 0;
if (!dict_steal(retval, "Bob", bob_version())) return 0;