Commits

Ruben Martinez-Cantin  committed 6862528

Working on new parametric function interface

  • Participants
  • Parent commits 539e5c8

Comments (0)

Files changed (9)

File include/kernel_atomic.hpp

   };
   void setHyperParameters(const vectord &theta) 
   {
-    assert(params.size() == n_params);
+    assert(theta.size() == n_params);
     params = theta;
   };
   vectord getHyperParameters() {return params;};

File include/kernel_combined.hpp

 
     size_t n_lhs = left->nHyperParameters();
     size_t n_rhs = right->nHyperParameters();
-    assert(params.size() == n_lhs + n_rhs);
+    assert(theta.size() == n_lhs + n_rhs);
     left->setHyperParameters(subrange(theta,0,n_lhs));
     right->setHyperParameters(subrange(theta,n_lhs,n_lhs+n_rhs));
   };

File include/mean_atomic.hpp

+/** \file mean_atomic.hpp \brief Atomic (simple) parametric functions */
+/*
+-------------------------------------------------------------------------
+   This file is part of BayesOpt, an efficient C++ library for 
+   Bayesian optimization.
+
+   Copyright (C) 2011-2013 Ruben Martinez-Cantin <rmcantin@unizar.es>
+ 
+   BayesOpt is free software: you can redistribute it and/or modify it 
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   BayesOpt is distributed in the hope that it will be useful, but 
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with BayesOpt.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------
+*/
+
+#ifndef  _MEAN_FUNCTORS_HPP_
+#define  _MEAN_FUNCTORS_HPP_
+
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include "mean_functors.hpp"
+
+/**\addtogroup ParametricFunctions
+ * @{
+ */
+
+/** \brief Abstract class for an atomic kernel */
+class AtomicFunction : public ParametricFunction
+{
+public:
+  virtual int init(size_t input_dim)
+  {
+    n_inputs = input_dim;
+    return 0;
+  };
+  void setParameters(const vectord &theta) 
+  {
+    assert(theta.size() == n_params);
+    mParameters = theta;
+  };
+  vectord getParameters() {return mParameters;};
+  size_t nParameters() {return n_params;};
+
+  virtual ~AtomicKernel(){};
+
+protected:
+  size_t n_params;
+  size_t n_features;
+  vectord mParameters;
+};
+
+
+/** \brief Constant zero function */
+class ZeroFunction: public ParametricFunction
+{
+public:
+  double getMean (const vectord& x) { return 0.0; };
+  vectord getFeatures(const vectord& x) { return zvectord(1); };  
+  size_t getN(const vectord& x) {return 1;}  
+};
+
+/** \brief Constant one function */
+class OneFunction: public ParametricFunction
+{
+public:
+  double getMean (const vectord& x) { return 1.0; };
+  vectord getFeatures(const vectord& x) { return svectord(1,1.0); };  
+  size_t getN(const vectord& x) {return 1;}  
+};
+
+
+/** \brief Constant function. 
+    The first parameter indicates the constant value. */
+class ConstantFunction: public ParametricFunction
+{
+public:
+  double getMean (const vectord& x) { return mParameters(0); };
+  vectord getFeatures(const vectord& x) { return svectord(1,1.0); };  
+  size_t getN(const vectord& x) {return 1;}  
+};
+
+
+/** \brief Linear combination function. 
+    Each parameter indicates the coefficient of each dimension. */
+class LinearFunction: public ParametricFunction
+{
+public:
+  double getMean (const vectord& x)
+  { return boost::numeric::ublas::inner_prod(x,mParameters);  };
+  vectord getFeatures(const vectord& x) { return x; };  
+  size_t getN(const vectord& x) {return x.size();}  
+};
+
+
+/** \brief Linear combination plus constant function. 
+    The first parameter indicates the constant value. */
+class LinearPlusConstantFunction: public ParametricFunction
+{
+public:
+  void setParameters(const vectord& params)
+  { 
+    mConstParam = params(0);
+    mParameters = boost::numeric::ublas::project(params, 
+			boost::numeric::ublas::range(1, params.size())); 
+  };
+  
+  double getMean (const vectord& x)
+  { return boost::numeric::ublas::inner_prod(x,mParameters) + mConstParam;  };
+
+  vectord getFeatures(const vectord& x) 
+  {
+    using boost::numeric::ublas::range;
+    using boost::numeric::ublas::project;
+    vectord res(x.size()+1);
+    res(0) = 1;
+    project(res,range(1,res.size())) = x;
+    return res; 
+  };  
+
+  size_t getN(const vectord& x) {return 1+x.size();}  
+
+protected:
+  double mConstParam;
+};
+
+//@}
+
+#endif

File include/mean_combined.hpp

+/** \file mean_combined.hpp 
+    \brief Parametric functions that combine other functions */
+/*
+-------------------------------------------------------------------------
+   This file is part of BayesOpt, an efficient C++ library for 
+   Bayesian optimization.
+
+   Copyright (C) 2011-2013 Ruben Martinez-Cantin <rmcantin@unizar.es>
+ 
+   BayesOpt is free software: you can redistribute it and/or modify it 
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   BayesOpt is distributed in the hope that it will be useful, but 
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with BayesOpt.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------
+*/
+
+#ifndef  _MEAN_COMBINED_HPP_
+#define  _MEAN_COMBINED_HPP_
+
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include "kernel_functors.hpp"
+
+/**\addtogroup ParametricFunction
+ * @{
+ */
+
+
+
+/** \brief Abstract class for combined functions.
+ *  It allows combinations of other functions (addition, product, etc.)
+ */
+class CombinedFunction : public ParametricFunction
+{
+public:
+  virtual int init(size_t input_dim, 
+		   ParametricFunction* left, 
+		   ParametricFunction* right)
+  {
+    n_inputs = input_dim;
+    this->left = left;
+    this->right = right;
+    return 0;
+  };
+  void setParameters(const vectord &theta) 
+  {
+    using boost::numeric::ublas::subrange;
+
+    size_t n_lhs = left->nParameters();
+    size_t n_rhs = right->nParameters();
+    assert(theta.size() == n_lhs + n_rhs);
+    left->setParameters(subrange(theta,0,n_lhs));
+    right->setParameters(subrange(theta,n_lhs,n_lhs+n_rhs));
+  };
+
+  vectord getParameters() 
+  {
+    using boost::numeric::ublas::subrange;
+
+    size_t n_lhs = left->nParameters();
+    size_t n_rhs = right->nParameters();
+    vectord par(n_lhs + n_rhs);
+    subrange(par,0,n_lhs) = left->getParameters();
+    subrange(par,n_lhs,n_lhs+n_rhs) = right->getParameters();
+    return par;
+  };
+
+  size_t nParameters() 
+  {
+    size_t n_lhs = left->nParameters();
+    size_t n_rhs = right->nParameters();
+    return n_lhs + n_rhs;
+  };
+
+  virtual ~CombinedKernel()
+  {
+    delete left;
+    delete right;
+  };
+
+protected:
+  ParametricFunction* left;
+  ParametricFunction* right;
+};
+
+
+/** \brief Sum of two kernels */
+class KernelSum: public CombinedKernel
+{
+public:
+  double operator()(const vectord &x1, const vectord &x2)
+  {
+    return (*left)(x1,x2) + (*right)(x1,x2);
+  };
+
+  double gradient(const vectord &x1, const vectord &x2,
+		  size_t component)
+  {
+    return left->gradient(x1,x2,component) + right->gradient(x1,x2,component);
+  };
+};
+
+
+/** \brief Product of two kernels */
+class KernelProd: public CombinedKernel
+{
+public:
+  double operator()(const vectord &x1, const vectord &x2)
+  {
+    return (*left)(x1,x2) * (*right)(x1,x2);
+  };
+
+  double gradient(const vectord &x1, const vectord &x2,
+		  size_t component)
+  {
+    return 0.0; //TODO: Not implemented
+  };
+};
+
+
+
+//@}
+
+#endif

File include/mean_functors.hpp

 #ifndef  _MEAN_FUNCTORS_HPP_
 #define  _MEAN_FUNCTORS_HPP_
 
-#include <boost/numeric/ublas/vector_proxy.hpp>
 #include "parameters.h"
 #include "specialtypes.hpp"
 
 class ParametricFunction
 {
 public:
-  static ParametricFunction* create(mean_name name, const vectord& params);
-  virtual void setParameters(const vectord& params){ mParameters = params; };
+  virtual int init(size_t input_dim) {return 0;};
+  virtual int init(size_t input_dim, Kernel* left, Kernel* right) {return 0;};
+
+  virtual void setParameters(const vectord& params) = 0;
+  virtual vectord getParameters() = 0;
+  virtual size_t nParameters() = 0;
+
   virtual double getMean(const vectord& x) = 0;
-  virtual vectord getFeatures(const vectord& x) = 0;  
-  virtual size_t getN(const vectord& x) = 0;  
-  
   virtual vectord operator()(const vecOfvec& x)
   {
     vectord result(x.size());
     return result;
   };
 
+
+  virtual size_t nFeatures() = 0;
+  virtual vectord getFeatures(const vectord& x) = 0;  
   virtual matrixd getAllFeatures(const vecOfvec& x)
   {
-    size_t nf = getN(x[0]);
+    size_t nf = nFeatures();
     matrixd result(nf,x.size());
 
     for(size_t ii=0; ii< x.size(); ++ii)
   virtual ~ParametricFunction(){};
 
 protected:
-  vectord mParameters;
+  size_t n_input;
 };
 
 
-/** \brief Constant zero function */
-class ZeroFunction: public ParametricFunction
+template <typename ParametricType> ParametricFunction * create_func()
+{
+  return new ParametricType();
+}
+
+
+/** 
+ * \brief Factory model for parametric functions
+ * This factory is based on the libgp library by Manuel Blum
+ *      https://bitbucket.org/mblum/libgp
+ * which follows the squeme of GPML by Rasmussen and Nickisch
+ *     http://www.gaussianprocess.org/gpml/code/matlab/doc/
+ */
+class MeanFactory
 {
 public:
-  double getMean (const vectord& x) { return 0.0; };
-  vectord getFeatures(const vectord& x) { return zvectord(1); };  
-  size_t getN(const vectord& x) {return 1;}  
+  MeanFactory ();
+  virtual ~MeanFactory () {};
+  
+  ParametricType* create(mean_name name, size_t input_dim);
+  ParametricType* create(std::string name, size_t input_dim);
+    
+private:
+  typedef ParametricType* (*create_func_definition)();
+  std::map<std::string , MeanFactory::create_func_definition> registry;
 };
 
 
-/** \brief Constant one function */
-class OneFunction: public ParametricFunction
-{
-public:
-  double getMean (const vectord& x) { return 1.0; };
-  vectord getFeatures(const vectord& x) { return svectord(1,1.0); };  
-  size_t getN(const vectord& x) {return 1;}  
-};
-
-
-/** \brief Constant function. 
-    The first parameter indicates the constant value. */
-class ConstantFunction: public ParametricFunction
-{
-public:
-  double getMean (const vectord& x) { return mParameters(0); };
-  vectord getFeatures(const vectord& x) { return svectord(1,1.0); };  
-  size_t getN(const vectord& x) {return 1;}  
-};
-
-
-/** \brief Linear combination function. 
-    Each parameter indicates the coefficient of each dimension. */
-class LinearFunction: public ParametricFunction
-{
-public:
-  double getMean (const vectord& x)
-  { return boost::numeric::ublas::inner_prod(x,mParameters);  };
-  vectord getFeatures(const vectord& x) { return x; };  
-  size_t getN(const vectord& x) {return x.size();}  
-};
-
-
-/** \brief Linear combination plus constant function. 
-    The first parameter indicates the constant value. */
-class LinearPlusConstantFunction: public ParametricFunction
-{
-public:
-  void setParameters(const vectord& params)
-  { 
-    mConstParam = params(0);
-    mParameters = boost::numeric::ublas::project(params, 
-			boost::numeric::ublas::range(1, params.size())); 
-  };
-  
-  double getMean (const vectord& x)
-  { return boost::numeric::ublas::inner_prod(x,mParameters) + mConstParam;  };
-
-  vectord getFeatures(const vectord& x) 
-  {
-    using boost::numeric::ublas::range;
-    using boost::numeric::ublas::project;
-    vectord res(x.size()+1);
-    res(0) = 1;
-    project(res,range(1,res.size())) = x;
-    return res; 
-  };  
-
-  size_t getN(const vectord& x) {return 1+x.size();}  
-
-protected:
-  double mConstParam;
-};
-
 //@}
 
 #endif

File include/mixture_distribution.hpp

+/** \file mixture_distribution.hpp 
+    \brief Mixture of gaussians probability distribution */
+/*
+-------------------------------------------------------------------------
+   This file is part of BayesOpt, an efficient C++ library for 
+   Bayesian optimization.
+
+   Copyright (C) 2011-2013 Ruben Martinez-Cantin <rmcantin@unizar.es>
+ 
+   BayesOpt is free software: you can redistribute it and/or modify it 
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   BayesOpt is distributed in the hope that it will be useful, but 
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with BayesOpt.  If not, see <http://www.gnu.org/licenses/>.
+------------------------------------------------------------------------
+*/
+
+
+#ifndef __MIXTURE_DISTRIBUTION_HPP__
+#define __MIXTURE_DISTRIBUTION_HPP__
+
+#include "gauss_distribution.hpp" 
+
+class MixtureDistribution: public ProbabilityDistribution
+{
+public:
+  MixtureDistribution(size_t n);
+  virtual ~MixtureDistribution();
+
+  /** 
+   * \brief Sets the mean and std of the distribution
+   */
+  void setMeanAndStd(double mean, double std)
+  { assert(false) };
+
+  /** 
+   * \brief Expected Improvement algorithm for minimization
+   * @param min  minimum value found
+   * @param g exponent (used for annealing)
+   *
+   * @return negative value of the expected improvement
+   */
+  double negativeExpectedImprovement(double min, size_t g);
+
+  /** 
+   * \brief Lower confindence bound. Can be seen as the inverse of the Upper 
+   * confidence bound
+   * @param beta std coefficient (used for annealing)
+   * @return value of the lower confidence bound
+   */
+  double lowerConfidenceBound(double beta);
+
+  /** 
+   * Probability of improvement algorithm for minimization
+   * @param min  minimum value found
+   * @param epsilon minimum improvement margin
+   * 
+   * @return negative value of the probability of improvement
+   */
+  double negativeProbabilityOfImprovement(double min,
+					  double epsilon);
+
+  /** 
+   * Sample outcome acording to the marginal distribution at the query point.
+   * @param eng boost.random engine
+   * 
+   * @return outcome
+   */
+  double sample_query(randEngine& eng);
+
+  double getMean() {return mean_;};
+  double getStd()  {return std_;};
+
+
+private:
+  std::vector<GaussianDistribution*> mComponents; 
+  vectord mW; 
+};
+
+
+
+#endif

File include/specialtypes.hpp

 #include <boost/numeric/ublas/matrix_proxy.hpp>
 #include <boost/numeric/ublas/vector.hpp>
 #include <boost/numeric/ublas/io.hpp>
-#include <boost/numeric/ublas/symmetric.hpp>
 
 typedef boost::numeric::ublas::vector<double>                   vectord;
 typedef boost::numeric::ublas::zero_vector<double>             zvectord;
 typedef boost::numeric::ublas::scalar_vector<double>           svectord;
 typedef boost::numeric::ublas::matrix<double>                   matrixd;
-typedef boost::numeric::ublas::triangular_matrix<double,
-	      boost::numeric::ublas::lower>                   ltmatrixd;
-typedef boost::numeric::ublas::identity_matrix<double>             eyed;
 
 typedef std::vector<vectord>                                   vecOfvec;
 typedef std::vector<vectord>::iterator                 vecOfvecIterator;

File python/bayesopt.cpp

-/* Generated by Cython 0.16 on Thu Feb 28 17:49:42 2013 */
+/* Generated by Cython 0.16 on Fri Mar  1 17:20:58 2013 */
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
 static char __pyx_k_8[] = "unknown dtype code in numpy.pxd (%d)";
 static char __pyx_k_9[] = "Format string allocated too short, see comment in numpy.pxd";
 static char __pyx_k_12[] = "Format string allocated too short.";
-static char __pyx_k_16[] = "/home/rmcantin/code/bayesian-optimization/python/bayesopt.pyx";
+static char __pyx_k_16[] = "/home/rmcantin/code/bayesopt/python/bayesopt.pyx";
 static char __pyx_k__B[] = "B";
 static char __pyx_k__H[] = "H";
 static char __pyx_k__I[] = "I";

File src/mean_functors.cpp

+#include <sstream>
+
 #include "log.hpp"
 #include "mean_functors.hpp"
+#include "mean_atomic.hpp"
+#include "mean_combined.hpp"
 
-ParametricFunction* ParametricFunction::create(mean_name name, const vectord& params)
+
+
+MeanFactory::MeanFactory()
+{
+  registry["mZero"] = & create_func<ZeroFunction>;
+  registry["mOne"] = & create_func<OneFunction>;
+  registry["mConst"] = & create_func<ConstantFunction>;
+  registry["mLinear"] = & create_func<LinearFunction>;
+  registry["mSum"] = & create_func<SumFunction>;
+  registry["mProd"] = & create_func<ProdFuntion>;
+}
+
+
+/** \brief Factory method for kernels. */
+ParametricFunction* ParametricFunction::create(mean_name name, 
+					       size_t input_dim)
 {
   ParametricFunction* m_ptr;
 
       return NULL;
     }
 
-  m_ptr->setParameters(params);
+  m_ptr->init(input_dim);
   return m_ptr;
 };
 
+/** 
+ * \brief Factory model for kernel functions
+ * This function is based on the libgp library by Manuel Blum
+ *      https://bitbucket.org/mblum/libgp
+ * which follows the squeme of GPML by Rasmussen and Nickisch
+ *     http://www.gaussianprocess.org/gpml/code/matlab/doc/
+ * @param name string with the kernel structure
+ * @param imput_dim number of input dimensions
+ * @return kernel pointer
+ */
+ParametricFunction* MeanFactory::create(std::string name, size_t input_dim)
+{
+  ParametricFunction *mFunc;
+  std::stringstream is(name);
+  std::stringstream os(std::stringstream::out);
+  std::stringstream os1(std::stringstream::out);
+  std::stringstream os2(std::stringstream::out);
+  char c;
+  int i = 0, j = 0;
+  while (is >> c) 
+    {
+      if (c == '(') i++;
+      else if (c == ')') i--;
+      else if (c == ',') j++;
+      else 
+	{
+	  if (i == 0) os << c;
+	  else if (j == 0) os1 << c;
+	  else os2 << c;
+	}
+    }
+  std::map<std::string,MeanFactory::create_func_definition>::iterator it = registry.find(os.str());
+  if (it == registry.end()) 
+    {
+      FILE_LOG(logERROR) << "Error: Fatal error while parsing mean function: "
+			 << os.str() << " not found" << std::endl;
+      return NULL;
+    } 
+  mFunc = registry.find(os.str())->second();
+  if (os1.str().length() == 0 && os2.str().length() == 0) 
+    {
+      mFunc->init(input_dim);
+    } 
+  else 
+    {
+      mFunc->init(input_dim, create(os1.str(),input_dim), 
+		  create(os2.str(),input_dim));
+    }
+  return mFunc;
+
+};
+
+
+