MUQ  0.4.3
KernelImpl.h
Go to the documentation of this file.
1 #ifndef KERNELIMPL_H
2 #define KERNELIMPL_H
3 
5 
6 #include <stan/math/fwd/scal.hpp>
7 
8 namespace muq
9 {
10 namespace Approximation
11 {
12 
24 template<typename ChildType>
25 class KernelImpl : public KernelBase
26 {
27 
28 
29 public:
30 
31  KernelImpl(unsigned inputDimIn,
32  unsigned coDimIn,
33  unsigned numParamsIn) : KernelBase(inputDimIn, coDimIn, numParamsIn){};
34 
35  KernelImpl(unsigned inputDimIn,
36  std::vector<unsigned> dimIndsIn,
37  unsigned coDimIn,
38  unsigned numParamsIn) : KernelBase(inputDimIn, dimIndsIn, coDimIn, numParamsIn){};
39 
40 
41  virtual ~KernelImpl(){};
42 
43  virtual std::shared_ptr<KernelBase> Clone() const override
44  {
45  return std::make_shared<ChildType>(static_cast<ChildType const &>(*this));
46  }
47 
48  virtual void FillBlock(Eigen::Ref<const Eigen::VectorXd> const& x1,
49  Eigen::Ref<const Eigen::VectorXd> const& x2,
50  Eigen::Ref<const Eigen::VectorXd> const& params,
51  Eigen::Ref<Eigen::MatrixXd> block) const override
52  {
53 
54  Eigen::VectorXd x1slice = GetSegment(x1);
55  Eigen::VectorXd x2slice = GetSegment(x2);
56  static_cast<const ChildType*>(this)->FillBlockImpl(Eigen::Ref<const Eigen::VectorXd>(x1slice),Eigen::Ref<const Eigen::VectorXd>(x2slice),params,block);
57  };
58 
59 
60  virtual void FillPosDerivBlock(Eigen::Ref<const Eigen::VectorXd> const& x1,
61  Eigen::Ref<const Eigen::VectorXd> const& x2,
62  Eigen::Ref<const Eigen::VectorXd> const& params,
63  std::vector<int> const& wrts,
64  Eigen::Ref<Eigen::MatrixXd> block) const override
65  {
66  FillPosDerivBlockImpl(x1,x2,params,wrts,block);
67  }
68 
69  void FillPosDerivBlockImpl(Eigen::Ref<const Eigen::VectorXd> const& x1,
70  Eigen::Ref<const Eigen::VectorXd> const& x2,
71  Eigen::Ref<const Eigen::VectorXd> const& params,
72  std::vector<int> const& wrts,
73  Eigen::Ref<Eigen::MatrixXd> block) const
74  {
75  // STAN will sometimes fail with third derivatives
76  //assert(wrts.size()<3);
77 
78  if(wrts.size()==0){
79  Eigen::VectorXd x1slice = GetSegment(x1);
80  Eigen::VectorXd x2slice = GetSegment(x2);
81  static_cast<const ChildType*>(this)->FillBlockImpl(Eigen::Ref<const Eigen::VectorXd>(x1slice), Eigen::Ref<const Eigen::VectorXd>(x2slice), params, block);
82  return;
83  }
84 
85 
86  Eigen::Matrix<stan::math::fvar<double>, Eigen::Dynamic, 1> x1Temp(x1.size());
87  Eigen::Matrix<stan::math::fvar<double>, Eigen::Dynamic, 1> x2Temp(x2.size());
88 
89  for(int i=0; i<x1.size(); ++i){
90  x1Temp(i).val_ = x1(i);
91  x1Temp(i).d_ = 0.0;
92  x2Temp(i).val_ = x2(i);
93  x2Temp(i).d_ = 0.0;
94  }
95  x1Temp(wrts.at(0)).d_ = 1.0;
96 
97  if(wrts.size()==1){
98  Eigen::Matrix<stan::math::fvar<double>, Eigen::Dynamic, Eigen::Dynamic> cov(coDim, coDim);
99  static_cast<const ChildType*>(this)->template FillBlockImpl<stan::math::fvar<double>,double, stan::math::fvar<double>>(x1Temp, x2Temp, params, cov);
100 
101  for(int j=0; j<coDim; ++j){
102  for(int i=0; i<coDim; ++i){
103  block(i,j) = cov(i,j).d_;
104  }
105  }
106  return;
107  }
108 
109 
110  Eigen::Matrix<stan::math::fvar<stan::math::fvar<double>>, Eigen::Dynamic, 1> x1Temp2(x1.size());
111  Eigen::Matrix<stan::math::fvar<stan::math::fvar<double>>, Eigen::Dynamic, 1> x2Temp2(x1.size());
112  for(int i=0; i<x1.size(); ++i){
113  x1Temp2(i).val_ = x1Temp(i);
114  x1Temp2(i).d_ = 0.0;
115  x2Temp2(i).val_ = x2Temp(i);
116  x2Temp2(i).d_ = 0.0;
117  }
118  x1Temp2(wrts.at(1)).d_ = 1.0;
119 
120  if(wrts.size()==2){
121  Eigen::Matrix<stan::math::fvar<stan::math::fvar<double>>, Eigen::Dynamic, Eigen::Dynamic> cov(coDim,coDim);
122  static_cast<const ChildType*>(this)->template FillBlockImpl<stan::math::fvar<stan::math::fvar<double>>,double,stan::math::fvar<stan::math::fvar<double>>>(x1Temp2, x2Temp2, params, cov);
123 
124  for(int j=0; j<coDim; ++j){
125  for(int i=0; i<coDim; ++i){
126  block(i,j) = cov(i,j).d_.d_;
127  }
128  }
129 
130  return;
131  }
132 
133  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>, Eigen::Dynamic, 1> x1Temp3(x1.size());
134  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>, Eigen::Dynamic, 1> x2Temp3(x1.size());
135  for(int i=0; i<x1.size(); ++i){
136  x1Temp3(i).val_ = x1Temp2(i);
137  x1Temp3(i).d_ = 0.0;
138  x2Temp3(i).val_ = x2Temp2(i);
139  x2Temp3(i).d_ = 0.0;
140  }
141  x1Temp3(wrts.at(2)).d_ = 1.0;
142 
143  if(wrts.size()==3){
144 
145  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>, Eigen::Dynamic, Eigen::Dynamic> cov(coDim,coDim);
146  static_cast<const ChildType*>(this)->template FillBlockImpl<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>,double,stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>(x1Temp3, x2Temp3, params, cov);
147 
148  for(int j=0; j<coDim; ++j){
149  for(int i=0; i<coDim; ++i){
150  block(i,j) = cov(i,j).d_.d_.d_;
151  }
152  }
153 
154  return;
155  }
156 
157  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>, Eigen::Dynamic, 1> x1Temp4(x1.size());
158  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>, Eigen::Dynamic, 1> x2Temp4(x1.size());
159  for(int i=0; i<x1.size(); ++i){
160  x1Temp4(i).val_ = x1Temp3(i);
161  x1Temp4(i).d_ = 0.0;
162  x2Temp4(i).val_ = x2Temp3(i);
163  x2Temp4(i).d_ = 0.0;
164  }
165  x1Temp4(wrts.at(3)).d_ = 1.0;
166 
167  if(wrts.size()==4){
168 
169  Eigen::Matrix<stan::math::fvar<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>, Eigen::Dynamic, Eigen::Dynamic> cov(coDim,coDim);
170  static_cast<const ChildType*>(this)->template FillBlockImpl<stan::math::fvar<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>,double,stan::math::fvar<stan::math::fvar<stan::math::fvar<stan::math::fvar<double>>>>>(x1Temp4, x2Temp4, params, cov);
171 
172  for(int j=0; j<coDim; ++j){
173  for(int i=0; i<coDim; ++i){
174  block(i,j) = cov(i,j).d_.d_.d_.d_;
175  }
176  }
177 
178  return;
179  }
180 
181  assert(wrts.size()<=4);
182  };
183 
184  template<typename ScalarType>
185  Eigen::Matrix<ScalarType, Eigen::Dynamic, 1> GetSegment(Eigen::Ref<const Eigen::Matrix<ScalarType, Eigen::Dynamic, 1>> const& input) const
186  {
187  Eigen::Matrix<ScalarType, Eigen::Dynamic, 1> output(dimInds.size());
188  for(int i=0; i<dimInds.size(); ++i)
189  output(i) = input(dimInds.at(i));
190 
191  return output;
192  }
193 };
194 
195 
196 }
197 }
198 
199 #endif
Base class for all covariance kernels.
Definition: KernelBase.h:36
const unsigned int coDim
Definition: KernelBase.h:133
const std::vector< unsigned int > dimInds
Definition: KernelBase.h:126
Base class in CRTP pattern for covariance kernels.
Definition: KernelImpl.h:26
virtual void FillPosDerivBlock(Eigen::Ref< const Eigen::VectorXd > const &x1, Eigen::Ref< const Eigen::VectorXd > const &x2, Eigen::Ref< const Eigen::VectorXd > const &params, std::vector< int > const &wrts, Eigen::Ref< Eigen::MatrixXd > block) const override
Definition: KernelImpl.h:60
KernelImpl(unsigned inputDimIn, unsigned coDimIn, unsigned numParamsIn)
Definition: KernelImpl.h:31
KernelImpl(unsigned inputDimIn, std::vector< unsigned > dimIndsIn, unsigned coDimIn, unsigned numParamsIn)
Definition: KernelImpl.h:35
Eigen::Matrix< ScalarType, Eigen::Dynamic, 1 > GetSegment(Eigen::Ref< const Eigen::Matrix< ScalarType, Eigen::Dynamic, 1 >> const &input) const
Definition: KernelImpl.h:185
virtual void FillBlock(Eigen::Ref< const Eigen::VectorXd > const &x1, Eigen::Ref< const Eigen::VectorXd > const &x2, Eigen::Ref< const Eigen::VectorXd > const &params, Eigen::Ref< Eigen::MatrixXd > block) const override
Definition: KernelImpl.h:48
void FillPosDerivBlockImpl(Eigen::Ref< const Eigen::VectorXd > const &x1, Eigen::Ref< const Eigen::VectorXd > const &x2, Eigen::Ref< const Eigen::VectorXd > const &params, std::vector< int > const &wrts, Eigen::Ref< Eigen::MatrixXd > block) const
Definition: KernelImpl.h:69
virtual std::shared_ptr< KernelBase > Clone() const override
Definition: KernelImpl.h:43