MUQ  0.4.3
ConcatenateKernel.cpp
Go to the documentation of this file.
5 
6 using namespace muq::Approximation;
7 using namespace muq::Modeling;
8 
9 ConcatenateKernel::ConcatenateKernel(std::vector<std::shared_ptr<KernelBase>> const& kernelsIn) : KernelBase(kernelsIn.at(0)->inputDim,
10  CountCoDims(kernelsIn),
11  CountParams(kernelsIn)),
12  kernels(kernelsIn)
13 {
14  // Make sure all the input sizes are the same
15  for(int i=1; i<kernels.size(); ++i)
16  assert(kernels.at(i)->inputDim == kernels.at(0)->inputDim);
17 
18  // Set all the parameters from what was in the kernels before
19  cachedParams.resize(numParams);
20  int paramCnt = 0;
21  for(int i=0; i<kernels.size(); ++i){
22  cachedParams.segment(paramCnt, kernels.at(i)->numParams) = kernels.at(i)->GetParams();
23  paramCnt += kernels.at(i)->numParams;
24  }
25 }
26 
27 
28 void ConcatenateKernel::FillBlock(Eigen::Ref<const Eigen::VectorXd> const& x1,
29  Eigen::Ref<const Eigen::VectorXd> const& x2,
30  Eigen::Ref<const Eigen::VectorXd> const& params,
31  Eigen::Ref<Eigen::MatrixXd> block) const
32 {
33  block = Eigen::MatrixXd::Zero(coDim, coDim);
34  int paramCnt = 0;
35  int codimCnt = 0;
36 
37  for(int i=0; i<kernels.size(); ++i){
38 
39  kernels.at(i)->FillBlock(x1,
40  x2,
41  params.segment(paramCnt, kernels.at(i)->numParams),
42  block.block(codimCnt,codimCnt,kernels.at(i)->coDim, kernels.at(i)->coDim));
43 
44  codimCnt += kernels.at(i)->coDim;
45  paramCnt += kernels.at(i)->numParams;
46  }
47 }
48 
49 void ConcatenateKernel::FillPosDerivBlock(Eigen::Ref<const Eigen::VectorXd> const& x1,
50  Eigen::Ref<const Eigen::VectorXd> const& x2,
51  Eigen::Ref<const Eigen::VectorXd> const& params,
52  std::vector<int> const& wrts,
53  Eigen::Ref<Eigen::MatrixXd> block) const
54 {
55  block = Eigen::MatrixXd::Zero(coDim, coDim);
56 
57  int paramCnt = 0;
58  int codimCnt = 0;
59  for(int i=0; i<kernels.size(); ++i){
60 
61  kernels.at(i)->FillPosDerivBlock(x1,
62  x2,
63  params.segment(paramCnt, kernels.at(i)->numParams),
64  wrts,
65  block.block(codimCnt,codimCnt,kernels.at(i)->coDim, kernels.at(i)->coDim));
66 
67  codimCnt += kernels.at(i)->coDim;
68  paramCnt += kernels.at(i)->numParams;
69  }
70 }
71 
72 unsigned int ConcatenateKernel::CountCoDims(std::vector<std::shared_ptr<KernelBase>> kernelsIn)
73 {
74  int cnt = 0;
75  for(auto& kernel : kernelsIn)
76  cnt += kernel->coDim;
77  return cnt;
78 }
79 unsigned int ConcatenateKernel::CountParams(std::vector<std::shared_ptr<KernelBase>> kernelsIn)
80 {
81  int cnt = 0;
82  for(auto& kernel : kernelsIn)
83  cnt += kernel->numParams;
84  return cnt;
85 }
86 
87 
88 std::tuple<std::shared_ptr<muq::Modeling::LinearSDE>, std::shared_ptr<muq::Modeling::LinearOperator>, Eigen::MatrixXd> ConcatenateKernel::GetStateSpace(boost::property_tree::ptree sdeOptions) const
89 {
90  unsigned int numKernels = kernels.size();
91  std::vector<std::shared_ptr<muq::Modeling::LinearSDE>> sdes(numKernels); // SDE definition for each kernel
92  std::vector<std::shared_ptr<muq::Modeling::LinearOperator>> obsOps(numKernels); // Observation operators for each kernel
93  std::vector<Eigen::MatrixXd> statCovs(numKernels); // Stationary coveriances for each kernel
94 
95  unsigned int totalStatSize = 0; // Size of concatenated stationary covariance matrix
96  unsigned int totalProcSize = 0; // Size of concatenated process noise covariance matrix
97  for(unsigned int i=0; i<numKernels; ++i){
98  std::tie(sdes.at(i), obsOps.at(i), statCovs.at(i)) = kernels.at(i)->GetStateSpace(sdeOptions);
99  totalStatSize += statCovs.at(i).rows();
100  if(sdes.at(i)->GetL())
101  totalProcSize += sdes.at(i)->GetL()->cols();
102  }
103 
104  std::shared_ptr<muq::Modeling::LinearOperator> combinedObsOp = std::make_shared<BlockDiagonalOperator>(obsOps);
105 
106  // Create a new SDE:
107  std::vector<std::shared_ptr<muq::Modeling::LinearOperator>> allFs;
108  std::vector<std::shared_ptr<muq::Modeling::LinearOperator>> allLs;
109  Eigen::MatrixXd newProcessCov = Eigen::MatrixXd::Zero(totalProcSize, totalProcSize);
110  Eigen::MatrixXd newStatCov = Eigen::MatrixXd::Zero(totalStatSize, totalStatSize);
111 
112  unsigned int currStatRow = 0;
113  unsigned int currProcRow = 0;
114  for(unsigned int i=0; i<numKernels; ++i){
115 
116  // Collect stochastic parts
117  if(sdes.at(i)->GetL()){
118  allLs.push_back(sdes.at(i)->GetL());
119 
120  newProcessCov.block(currProcRow,currProcRow, allLs.back()->cols(), allLs.back()->cols()) = sdes.at(i)->GetQ();
121  currProcRow += allLs.back()->cols();
122  }else{
123  allLs.push_back(std::make_shared<ZeroOperator>(sdes.at(i)->GetF()->rows(),0));
124  }
125 
126  // Collect deterministic parts
127  allFs.push_back( sdes.at(i)->GetF() );
128  newStatCov.block(currStatRow,currStatRow, statCovs.at(i).rows(), statCovs.at(i).cols()) = statCovs.at(i);
129  currStatRow += statCovs.at(i).rows();
130  }
131 
132  std::shared_ptr<muq::Modeling::LinearOperator> combinedF = std::make_shared<BlockDiagonalOperator>(allFs);
133  std::shared_ptr<muq::Modeling::LinearOperator> combinedL = std::make_shared<BlockDiagonalOperator>(allLs);
134 
135 
136  auto combinedSDE = std::make_shared<muq::Modeling::LinearSDE>(combinedF, combinedL, newProcessCov, sdeOptions);
137 
138  return std::make_tuple(combinedSDE, combinedObsOp, newStatCov);
139 }
140 
std::vector< std::shared_ptr< KernelBase > > kernels
static unsigned int CountParams(std::vector< std::shared_ptr< KernelBase >> kernels)
ConcatenateKernel(std::shared_ptr< KernelBase > const &kernel1In, std::shared_ptr< KernelBase > const &kernel2In)
virtual std::tuple< std::shared_ptr< muq::Modeling::LinearSDE >, std::shared_ptr< muq::Modeling::LinearOperator >, Eigen::MatrixXd > GetStateSpace(boost::property_tree::ptree sdeOptions=boost::property_tree::ptree()) const override
Returns a state space representation of the covariance kernel.
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
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
static unsigned int CountCoDims(std::vector< std::shared_ptr< KernelBase >> kernels)
Base class for all covariance kernels.
Definition: KernelBase.h:36
const unsigned int coDim
Definition: KernelBase.h:133
const unsigned int numParams
Definition: KernelBase.h:134
Eigen::VectorXd cachedParams
Definition: KernelBase.h:156