MUQ  0.4.3
GaussianProcess.h
Go to the documentation of this file.
1 #ifndef GAUSSIANPROCESS_H_
2 #define GAUSSIANPROCESS_H_
3 
5 
7 
8 #include <Eigen/Core>
9 
11 
12 #include <set>
13 
14 //#include <nlopt.h>
15 
16 
17 namespace muq
18 {
19 
20  namespace Approximation
21  {
22 
23 
64  class GaussianProcess;
65  class ObservationInformation;
66 
67  struct OptInfo
68  {
70  };
71 
72  double nlopt_obj(unsigned n, const double *x, double *nlopt_grad, void *opt_info);
73 
80  class MeanFunctionBase : public std::enable_shared_from_this<MeanFunctionBase>
81  {
82 
83  public:
84  MeanFunctionBase(unsigned dimIn,
85  unsigned coDimIn) : inputDim(dimIn), coDim(coDimIn){}
86 
87  virtual ~MeanFunctionBase() = default;
88 
89  virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const& xs) const = 0;
90 
91  virtual std::shared_ptr<MeanFunctionBase> Clone() const = 0;
92 
93  virtual std::shared_ptr<MeanFunctionBase> GetPtr()
94  {
95  return shared_from_this();
96  };
97 
98  virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const& xs, std::vector<std::vector<int>> const& derivCoords) const = 0;
99 
100  const unsigned inputDim;
101  const unsigned coDim;
102 
103  };
104 
105 
109  class ZeroMean : public MeanFunctionBase
110  {
111 
112  public:
113  ZeroMean(unsigned dim, unsigned coDim) : MeanFunctionBase(dim,coDim){};
114 
115  virtual ~ZeroMean() = default;
116 
117  virtual std::shared_ptr<MeanFunctionBase> Clone() const override
118  {
119  return std::make_shared<ZeroMean>(*this);
120  }
121 
122  virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const& xs) const override
123  {
124  return Eigen::MatrixXd::Zero(coDim, xs.cols());
125  }
126 
127  virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const& xs, std::vector<std::vector<int>> const& derivCoords) const override
128  {
129  return Eigen::MatrixXd::Zero(coDim*derivCoords.size(), xs.cols());
130  }
131  };
132 
134  {
135 
136  public:
137  LinearMean(double slope, double intercept) : LinearMean(slope*Eigen::MatrixXd::Ones(1,1), intercept*Eigen::VectorXd::Ones(1)){};
138 
139  virtual ~LinearMean() = default;
140 
141  LinearMean(Eigen::MatrixXd const& slopesIn,
142  Eigen::VectorXd const& interceptsIn) : MeanFunctionBase(slopesIn.cols(),slopesIn.rows()),
143  slopes(slopesIn),
144  intercepts(interceptsIn){};
145 
146  virtual std::shared_ptr<MeanFunctionBase> Clone() const override
147  {
148  return std::make_shared<LinearMean>(*this);
149  }
150 
151  virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const& xs) const override
152  {
153  return (slopes*xs).colwise() + intercepts;
154  }
155 
156  virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const& xs, std::vector<std::vector<int>> const& derivCoords) const override
157  {
158  Eigen::MatrixXd output = Eigen::VectorXd::Zero(coDim*derivCoords.size(), xs.cols());
159  for(int j=0; j<xs.cols(); ++j){
160  for(int i=0; i<derivCoords.size(); ++i)
161  {
162  if(derivCoords.at(i).size()==1){
163  output.col(j).segment(i*coDim, coDim) = slopes.col(derivCoords.at(i).at(0));
164  }else if(derivCoords.at(i).size()==1){
165  output.col(j).segment(i*coDim, coDim) = Evaluate(xs.col(j)).col(0);
166  }
167  }
168  }
169  return output;
170  }
171 
172  private:
173  Eigen::MatrixXd slopes;
174  Eigen::VectorXd intercepts;
175 
176  };
177 
178 
182  template<typename LinearOperator>
184  {
185 
186  public:
187  template<typename MeanType>
188  LinearTransformMean(LinearOperator const& Ain,
189  MeanType const& meanIn) :
190  MeanFunctionBase(meanIn.inputDim, A.rows()),
191  A(Ain),
192  otherMean(meanIn.Clone())
193  {
194  assert(A.cols() == otherMean->coDim);
195  };
196 
197  virtual ~LinearTransformMean() = default;
198 
199  virtual std::shared_ptr<MeanFunctionBase> Clone() const override
200  {
201  return std::make_shared<LinearTransformMean>(*this);
202  }
203 
204  virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const& xs) const override
205  {
206  return A * otherMean->Evaluate(xs);
207  }
208 
209  virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const& xs, std::vector<std::vector<int>> const& derivCoords) const override
210  {
211  // TODO
212  std::cerr << "Derivatives in linear transform mean have not been implemented yet..." << std::endl;
213  assert(false);
214  }
215 
216  private:
217  LinearOperator A;
218  std::shared_ptr<MeanFunctionBase> otherMean;
219 
220  };
221 
222 
224  LinearTransformMean<MeanType> operator*(Eigen::MatrixXd const& A, MeanType const&K)
225  {
227  }
228 
232  class SumMean : public MeanFunctionBase
233  {
234 
235  public:
236  template<typename MeanType1, typename MeanType2>
237  SumMean(MeanType1 const& mu1In,
238  MeanType2 const& mu2In) :
239  MeanFunctionBase(mu1In.inputDim, mu1In.coDim),
240  mu1(mu1In),
241  mu2(mu2In)
242  {
243  assert(mu1->inputDim == mu2->inputDim);
244  assert(mu1->coDim == mu2->coDim);
245  };
246 
247  virtual ~SumMean() = default;
248 
249  virtual std::shared_ptr<MeanFunctionBase> Clone() const override
250  {
251  return std::make_shared<SumMean>(*this);
252  }
253 
254  virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const& xs) const override
255  {
256  return mu1->Evaluate(xs) + mu2->Evaluate(xs);
257  }
258 
259  virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const& xs, std::vector<std::vector<int>> const& derivCoords) const override
260  {
261  return mu1->GetDerivative(xs, derivCoords) + mu2->GetDerivative(xs, derivCoords);
262  }
263 
264  private:
265  std::shared_ptr<MeanFunctionBase> mu1, mu2;
266 
267  };
268 
270  SumMean operator+(MeanType1 const& mu1, MeanType2 const& mu2)
271  {
272  return SumMean(mu1, mu2);
273  }
274 
275 
276 
281  {
282 
283  public:
284 
286  {
290  NoCov
291  };
292 
294  KernelBase& kernelIn) : GaussianProcess(meanIn.Clone(), kernelIn.Clone()){};
295 
296  GaussianProcess(std::shared_ptr<MeanFunctionBase> meanIn,
297  std::shared_ptr<KernelBase> covKernelIn);
298 
299  virtual ~GaussianProcess() = default;
300 
302  virtual GaussianProcess& Condition(Eigen::Ref<const Eigen::MatrixXd> const& loc,
303  Eigen::Ref<const Eigen::MatrixXd> const& vals)
304  {return Condition(loc,vals,0.0);};
305 
306  virtual GaussianProcess& Condition(Eigen::Ref<const Eigen::MatrixXd> const& loc,
307  Eigen::Ref<const Eigen::MatrixXd> const& vals,
308  double obsVar);
309 
310  virtual GaussianProcess& Condition(std::shared_ptr<ObservationInformation> obs);
311 
316  std::shared_ptr<muq::Modeling::Gaussian> Discretize(Eigen::MatrixXd const& pts);
317 
319  virtual void Optimize();
320 
324  virtual std::pair<Eigen::MatrixXd, Eigen::MatrixXd> Predict(Eigen::MatrixXd const& newLocs,
325  CovarianceType covType);
326 
330  virtual Eigen::MatrixXd PredictMean(Eigen::MatrixXd const& newPts);
331 
335  virtual Eigen::MatrixXd Sample(Eigen::MatrixXd const& newPts);
336 
337 
338  virtual double LogLikelihood(Eigen::MatrixXd const& xs,
339  Eigen::MatrixXd const& vals);
340 
341  // Evaluates the log marginal likelihood needed when fitting hyperparameters
342  virtual double MarginalLogLikelihood();
343  virtual double MarginalLogLikelihood(Eigen::Ref<Eigen::VectorXd> grad){return MarginalLogLikelihood(grad, true);};
344  virtual double MarginalLogLikelihood(Eigen::Ref<Eigen::VectorXd> grad,
345  bool computeGrad);
346 
347  std::shared_ptr<MeanFunctionBase> Mean(){return mean;};
348  std::shared_ptr<KernelBase> Kernel(){return covKernel;};
349 
350  protected:
351 
352  Eigen::MatrixXd BuildCrossCov(Eigen::MatrixXd const& newLocs);
353 
354  Eigen::MatrixXd SolveFromEig(Eigen::MatrixXd const& b) const;
355 
356  void ProcessObservations();
357 
358 
359  std::shared_ptr<MeanFunctionBase> mean;
360  std::shared_ptr<KernelBase> covKernel;
361 
362  std::vector<std::shared_ptr<ObservationInformation>> observations;
363 
364 
365  Eigen::VectorXd trainDiff;
366  Eigen::VectorXd sigmaTrainDiff;
367 
368  Eigen::LDLT<Eigen::MatrixXd> covSolver;
369 
370  Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> covSolverEig;
371  bool useEig = false; // If the ldlt decomposition fails, we'll try the eigenvalue solver
372 
373  int obsDim;
374  const int inputDim;
375  const int coDim;
376 
377  // Have new observations been added since the covariance was inverted?
378  bool hasNewObs;
379 
380  const double pi = 4.0 * atan(1.0); //boost::math::constants::pi<double>();
381  const double nugget = 1e-14; // added to the covariance diagonal to ensure eigenvalues are positive
382  };
383 
384  // class GaussianProcess
385 
388  template<typename MeanType, typename KernelType>
389  GaussianProcess ConstructGP(MeanType const& mean,
390  KernelType const& kernel)
391  {
392  return GaussianProcess(mean.Clone(),kernel.Clone());
393  }
394 
395  } // namespace Approximation
396 } // namespace muq
397 
398 #endif // #ifndef GAUSSIANPROCESS_H_
Eigen::LDLT< Eigen::MatrixXd > covSolver
virtual Eigen::MatrixXd Sample(Eigen::MatrixXd const &newPts)
GaussianProcess(MeanFunctionBase &meanIn, KernelBase &kernelIn)
std::shared_ptr< KernelBase > covKernel
virtual Eigen::MatrixXd PredictMean(Eigen::MatrixXd const &newPts)
Eigen::MatrixXd BuildCrossCov(Eigen::MatrixXd const &newLocs)
Eigen::SelfAdjointEigenSolver< Eigen::MatrixXd > covSolverEig
virtual GaussianProcess & Condition(Eigen::Ref< const Eigen::MatrixXd > const &loc, Eigen::Ref< const Eigen::MatrixXd > const &vals)
virtual double MarginalLogLikelihood(Eigen::Ref< Eigen::VectorXd > grad)
std::shared_ptr< muq::Modeling::Gaussian > Discretize(Eigen::MatrixXd const &pts)
Eigen::MatrixXd SolveFromEig(Eigen::MatrixXd const &b) const
virtual std::pair< Eigen::MatrixXd, Eigen::MatrixXd > Predict(Eigen::MatrixXd const &newLocs, CovarianceType covType)
std::shared_ptr< MeanFunctionBase > mean
std::vector< std::shared_ptr< ObservationInformation > > observations
std::shared_ptr< MeanFunctionBase > Mean()
virtual double LogLikelihood(Eigen::MatrixXd const &xs, Eigen::MatrixXd const &vals)
std::shared_ptr< KernelBase > Kernel()
Base class for all covariance kernels.
Definition: KernelBase.h:36
virtual ~LinearMean()=default
virtual std::shared_ptr< MeanFunctionBase > Clone() const override
LinearMean(double slope, double intercept)
LinearMean(Eigen::MatrixXd const &slopesIn, Eigen::VectorXd const &interceptsIn)
virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const &xs, std::vector< std::vector< int >> const &derivCoords) const override
virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const &xs) const override
virtual std::shared_ptr< MeanFunctionBase > Clone() const override
LinearTransformMean(LinearOperator const &Ain, MeanType const &meanIn)
virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const &xs, std::vector< std::vector< int >> const &derivCoords) const override
std::shared_ptr< MeanFunctionBase > otherMean
virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const &xs) const override
virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const &xs, std::vector< std::vector< int >> const &derivCoords) const =0
MeanFunctionBase(unsigned dimIn, unsigned coDimIn)
virtual std::shared_ptr< MeanFunctionBase > Clone() const =0
virtual std::shared_ptr< MeanFunctionBase > GetPtr()
virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const &xs) const =0
virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const &xs, std::vector< std::vector< int >> const &derivCoords) const override
std::shared_ptr< MeanFunctionBase > mu1
SumMean(MeanType1 const &mu1In, MeanType2 const &mu2In)
virtual ~SumMean()=default
virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const &xs) const override
std::shared_ptr< MeanFunctionBase > mu2
virtual std::shared_ptr< MeanFunctionBase > Clone() const override
virtual Eigen::MatrixXd Evaluate(Eigen::MatrixXd const &xs) const override
ZeroMean(unsigned dim, unsigned coDim)
virtual std::shared_ptr< MeanFunctionBase > Clone() const override
virtual Eigen::MatrixXd GetDerivative(Eigen::MatrixXd const &xs, std::vector< std::vector< int >> const &derivCoords) const override
virtual ~ZeroMean()=default
GaussianProcess ConstructGP(MeanType const &mean, KernelType const &kernel)
LinearTransformMean< MeanType > operator*(Eigen::MatrixXd const &A, MeanType const &K)
double nlopt_obj(unsigned n, const double *x, double *nlopt_grad, void *opt_info)
SumMean operator+(MeanType1 const &mu1, MeanType2 const &mu2)
int int FloatType value
Definition: json.h:15223