BayesOpt
kernel_functors.cpp
1 /*
2 -------------------------------------------------------------------------
3  This file is part of BayesOpt, an efficient C++ library for
4  Bayesian optimization.
5 
6  Copyright (C) 2011-2015 Ruben Martinez-Cantin <rmcantin@unizar.es>
7 
8  BayesOpt is free software: you can redistribute it and/or modify it
9  under the terms of the GNU Affero General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  BayesOpt is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU Affero General Public License for more details.
17 
18  You should have received a copy of the GNU Affero General Public License
19  along with BayesOpt. If not, see <http://www.gnu.org/licenses/>.
20 ------------------------------------------------------------------------
21 */
22 
23 #include <stdexcept>
24 #include "log.hpp"
25 #include "parser.hpp"
26 #include "ublas_extra.hpp"
27 #include "kernel_functors.hpp"
28 
30 #include "kernels/kernel_const.hpp"
31 #include "kernels/kernel_linear.hpp"
32 #include "kernels/kernel_hamming.hpp"
33 #include "kernels/kernel_matern.hpp"
34 #include "kernels/kernel_polynomial.hpp"
35 #include "kernels/kernel_gaussian.hpp"
36 #include "kernels/kernel_rq.hpp"
37 
39 #include "kernels/kernel_sum.hpp"
40 #include "kernels/kernel_prod.hpp"
41 
42 namespace bayesopt
43 {
44 
45  KernelFactory::KernelFactory()
46  {
47  registry["kConst"] = & create_func<ConstKernel>;
48  registry["kLinear"] = & create_func<LinKernel>;
49  registry["kLinearARD"] = & create_func<LinKernelARD>;
50 
51  registry["kHamming"] = & create_func<HammingKernel>;
52 
53  registry["kMaternISO1"] = & create_func<MaternIso1>;
54  registry["kMaternISO3"] = & create_func<MaternIso3>;
55  registry["kMaternISO5"] = & create_func<MaternIso5>;
56  registry["kMaternARD1"] = & create_func<MaternARD1>;
57  registry["kMaternARD3"] = & create_func<MaternARD3>;
58  registry["kMaternARD5"] = & create_func<MaternARD5>;
59 
60  registry["kPoly1"] = & create_func<Polynomial>;
61  registry["kPoly2"] = & create_func<Polynomial2>;
62  registry["kPoly3"] = & create_func<Polynomial3>;
63  registry["kPoly4"] = & create_func<Polynomial4>;
64  registry["kPoly5"] = & create_func<Polynomial5>;
65  registry["kPoly6"] = & create_func<Polynomial6>;
66 
67  registry["kSEARD"] = & create_func<SEArd>;
68  registry["kSEISO"] = & create_func<SEIso>;
69 
70  registry["kRQISO"] = & create_func<RQIso>;
71 
72  registry["kSum"] = & create_func<KernelSum>;
73  registry["kProd"] = & create_func<KernelProd>;
74  }
75 
76 
87  Kernel* KernelFactory::create(std::string name, size_t input_dim)
88  {
89  Kernel *kFunc;
90  std::string os, os1, os2;
91  utils::parseExpresion(name,os,os1,os2);
92 
93  std::map<std::string,KernelFactory::create_func_definition>::iterator it = registry.find(os);
94  if (it == registry.end())
95  {
96  throw std::invalid_argument("Error while parsing kernel function: "
97  "Kernel not found " + os);
98  return NULL;
99  }
100  kFunc = it->second();
101  if (os1.length() == 0 && os2.length() == 0)
102  {
103  kFunc->init(input_dim);
104  }
105  else // Combined kernel
106  {
107  kFunc->init(input_dim, create(os1,input_dim), create(os2,input_dim));
108  }
109  return kFunc;
110  };
111 
112 
114 
115  KernelModel::KernelModel(size_t dim, Parameters parameters)
116  { setKernel(parameters.kernel,dim); }
117 
118  void KernelModel::setKernel (const vectord &thetav,
119  const vectord &stheta,
120  std::string k_name,
121  size_t dim)
122  {
123  KernelFactory mKFactory;
124 
125  mKernel.reset(mKFactory.create(k_name, dim));
126 
127  if ((thetav.size() == 1) && (stheta.size() == 1) && (mKernel->nHyperParameters() != 1))
128  {
129  // We assume isotropic prior, so we replicate the vectors for all dimensions
130  size_t n = mKernel->nHyperParameters();
131 
132  FILE_LOG(logINFO) << "Expected " << n << " hyperparameters."
133  << " Replicating parameters and prior.";
134 
135  vectord newthetav = svectord(n,thetav(0));
136  vectord newstheta = svectord(n,stheta(0));
137 
138  setKernelPrior(newthetav,newstheta);
139  mKernel->setHyperParameters(newthetav);
140  }
141  else
142  {
143  setKernelPrior(thetav,stheta);
144  mKernel->setHyperParameters(thetav);
145  }
146  }
147 
149  size_t dim)
150  {
151  size_t n = kernel.hp_mean.size();
152  vectord th = kernel.hp_mean;
153  vectord sth = kernel.hp_std;
154  setKernel(th, sth, kernel.name, dim);
155  };
156 
157 
158  void KernelModel::computeCorrMatrix(const vecOfvec& XX, matrixd& corrMatrix,
159  double nugget)
160  {
161  assert(corrMatrix.size1() == XX.size());
162  assert(corrMatrix.size2() == XX.size());
163  const size_t nSamples = XX.size();
164 
165  for (size_t ii=0; ii< nSamples; ++ii)
166  {
167  for (size_t jj=0; jj < ii; ++jj)
168  {
169  corrMatrix(ii,jj) = (*mKernel)(XX[ii], XX[jj]);
170  corrMatrix(jj,ii) = corrMatrix(ii,jj);
171  }
172  corrMatrix(ii,ii) = (*mKernel)(XX[ii],XX[ii]) + nugget;
173  }
174  }
175 
176  void KernelModel::computeDerivativeCorrMatrix(const vecOfvec& XX,
177  matrixd& corrMatrix,
178  int dth_index)
179  {
180  assert(corrMatrix.size1() == XX.size());
181  assert(corrMatrix.size2() == XX.size());
182  const size_t nSamples = XX.size();
183 
184  for (size_t ii=0; ii< nSamples; ++ii)
185  {
186  for (size_t jj=0; jj < ii; ++jj)
187  {
188  corrMatrix(ii,jj) = mKernel->gradient(XX[ii],XX[jj],
189  dth_index);
190  corrMatrix(jj,ii) = corrMatrix(ii,jj);
191  }
192  corrMatrix(ii,ii) = mKernel->gradient(XX[ii],XX[ii],dth_index);
193  }
194  }
195 
196 
197  double KernelModel::kernelLogPrior()
198  {
199  double prior = 0.0;
200  vectord th = mKernel->getHyperParameters();
201  for(size_t i = 0; i<th.size();++i)
202  {
203  if (priorKernel[i].standard_deviation() > 0)
204  {
205  prior += std::log(boost::math::pdf(priorKernel[i],th(i)));
206  }
207  }
208  return prior;
209  }
210 } //namespace bayesopt
KernelParameters kernel
Kernel parameters.
Definition: parameters.hpp:107
Kernel functions that combine other kernels.
Kernel (covariance) functions.
void setKernel(const vectord &thetav, const vectord &stheta, std::string k_name, size_t dim)
Select kernel (covariance function) for the surrogate process.
vectord hp_mean
Kernel hyperparameters prior (mean, log space)
Definition: parameters.hpp:43
Namespace of the library interface.
Definition: using.dox:1
Factory model for kernel functions This factory is based on the libgp library by Manuel Blum https://...
Functions to parse strings.
vectord hp_std
Kernel hyperparameters prior (st dev, log space)
Definition: parameters.hpp:44
Interface for kernel functors.
Extra functions for Ublas library.
void parseExpresion(std::string input, std::string &parent, std::string &child1, std::string &child2)
Parse expresions of the form Parent(Child1, Child2).
Definition: parser.cpp:35
Kernel * create(std::string name, size_t input_dim)
Factory model for kernel functions This function is based on the libgp library by Manuel Blum https:/...
Modules and helper macros for logging.
std::string name
Name of the kernel function.
Definition: parameters.hpp:42
Atomic (simple) kernel functions.