MUQ  0.4.3
PeriodicKernel.cpp
Go to the documentation of this file.
2 
7 
9 
10 
13 
14 #include "MUQ/Modeling/LinearSDE.h"
15 
16 
17 #include <unsupported/Eigen/Polynomials>
18 #include <Eigen/SparseCore>
19 
20 #include <boost/math/special_functions/bessel.hpp>
21 #include <boost/property_tree/ptree.hpp>
22 
23 using namespace muq::Approximation;
24 using namespace muq::Modeling;
25 
26 
28 class PeriodicKernel_F_block : public muq::Modeling::LinearOperator
29 {
30 public:
31  PeriodicKernel_F_block(const double wjIn) : muq::Modeling::LinearOperator(2,2), wj(wjIn){};
32 
33  virtual Eigen::MatrixXd Apply(Eigen::Ref<const Eigen::MatrixXd> const& x) override
34  {
35  Eigen::MatrixXd output(2,x.cols());
36  output.row(0) = -wj*x.row(1);
37  output.row(1) = wj*x.row(0);
38  return output;
39  }
40 
41  virtual Eigen::MatrixXd ApplyTranspose(Eigen::Ref<const Eigen::MatrixXd> const& x) override
42  {
43  Eigen::MatrixXd output(2,x.cols());
44  output.row(0) = wj*x.row(1);
45  output.row(1) = -wj*x.row(0);
46  return output;
47  }
48 
49  virtual Eigen::MatrixXd GetMatrix() override
50  {
51  Eigen::MatrixXd output(2,2);
52  output << 0.0, -wj,
53  wj, 0.0;
54 
55  return output;
56  }
57 
58 private:
59  const double wj;
60 
61 };
62 
63 std::tuple<std::shared_ptr<muq::Modeling::LinearSDE>, std::shared_ptr<muq::Modeling::LinearOperator>, Eigen::MatrixXd> PeriodicKernel::GetStateSpace(boost::property_tree::ptree sdeOptions) const
64 {
65 
66  const double sigma2 = cachedParams(0);
67  const double length = cachedParams(1);
68  const double period = cachedParams(2);
69 
70  // This is the same as J in the paper
71  const int numTerms = sdeOptions.get("PeriodicKernel.StateSpace.NumTerms",4);
72 
73  const double w0 = 2.0*pi/period;
74 
75  const double l2 = std::pow(length, 2.0);
76 
77 
78  Eigen::VectorXd q2s(numTerms+1); // holds all of the q_j^2 values from eqn 27 in "Explicit Link Between Periodic Covariance Functions and State Space Models"
79 
80  q2s(0) = boost::math::cyl_bessel_i(0, 1.0/l2) / exp(1.0/l2);
81  for(int i=1; i<numTerms+1; ++i)
82  q2s(i) = 2.0 * boost::math::cyl_bessel_i(i, 1.0/l2) / exp(1.0/l2);
83 
84 
85  // SET UP F
86  std::vector<std::shared_ptr<LinearOperator>> fBlocks(numTerms+1);
87  for(int i=0; i<numTerms+1; ++i)
88  fBlocks.at(i) = std::make_shared<PeriodicKernel_F_block>(w0*i);
89 
90  auto F = std::make_shared<BlockDiagonalOperator>(fBlocks);
91 
92  // SET UP L
93  std::vector<std::shared_ptr<LinearOperator>> lBlocks(numTerms+1);
94  for(int i=0; i<numTerms+1; ++i)
95  lBlocks.at(i) = std::make_shared<IdentityOperator>(2);
96 
97  auto L = std::make_shared<BlockDiagonalOperator>(lBlocks);
98 
99  // Set up Pinf
100  Eigen::MatrixXd Pinf = Eigen::MatrixXd::Zero(2*(numTerms+1), 2*(numTerms+1));
101  for(int i=0; i<numTerms+1; ++i)
102  Pinf.block(2*i, 2*i, 2, 2) = q2s(i) * Eigen::MatrixXd::Identity(2,2);
103 
104  // Set up Q
105  Eigen::MatrixXd Q = Eigen::MatrixXd::Zero(2*(numTerms+1), 2*(numTerms+1));
106 
107  // SET UP H
108  std::vector<Eigen::Triplet<double>> Hcoeffs;
109  for(int i=0; i<numTerms+1; ++i)
110  Hcoeffs.push_back(Eigen::Triplet<double>(0, 2*i, 1.0));
111 
112  Eigen::SparseMatrix<double> Hmat(1, 2*(numTerms+1));
113  Hmat.setFromTriplets(Hcoeffs.begin(), Hcoeffs.end());
114 
115  auto H = muq::Modeling::LinearOperator::Create(Hmat);
116 
117  // Create the SDE
118  auto sde = std::make_shared<muq::Modeling::LinearSDE>(F,L,Q,sdeOptions);
119 
120  return std::make_tuple(sde, H, Pinf);
121 
122 }
123 
124 
125 
126 
127 PeriodicKernel::PeriodicKernel(unsigned dim,
128  std::vector<unsigned> dimInds,
129  const double sigma2In,
130  const double lengthIn,
131  const double periodIn,
132  const Eigen::Vector2d sigmaBounds,
133  const Eigen::Vector2d lengthBounds,
134  const Eigen::Vector2d periodBounds) : KernelImpl<PeriodicKernel>(dim, dimInds, 1 , 3)
135 {
136  SetupBounds(sigmaBounds, lengthBounds, periodBounds);
137 
138  cachedParams.resize(3);
139  cachedParams(0) = sigma2In;
140  cachedParams(1) = lengthIn;
141  cachedParams(2) = periodIn;
142 };
143 
144 
145 PeriodicKernel::PeriodicKernel(unsigned dim,
146  const double sigma2In,
147  const double lengthIn,
148  const double periodIn,
149  const Eigen::Vector2d sigmaBounds,
150  const Eigen::Vector2d lengthBounds,
151  const Eigen::Vector2d periodBounds) : KernelImpl<PeriodicKernel>(dim, 1 , 3)
152 {
153  SetupBounds(sigmaBounds, lengthBounds, periodBounds);
154 
155  cachedParams.resize(3);
156  cachedParams(0) = sigma2In;
157  cachedParams(1) = lengthIn;
158  cachedParams(2) = periodIn;
159 };
160 
161 void PeriodicKernel::SetupBounds(Eigen::Vector2d const& sigmaBounds,
162  Eigen::Vector2d const& lengthBounds,
163  Eigen::Vector2d const& periodBounds)
164 {
165  paramBounds.resize(2,3);
166 
167  paramBounds(0,0) = sigmaBounds(0);
168  paramBounds(1,0) = sigmaBounds(1);
169 
170  paramBounds(0,1) = lengthBounds(0);
171  paramBounds(1,1) = lengthBounds(1);
172 
173  paramBounds(0,2) = periodBounds(0);
174  paramBounds(1,2) = periodBounds(1);
175 };
Base class in CRTP pattern for covariance kernels.
Definition: KernelImpl.h:26
Generic linear operator base class.