8 #include <boost/property_tree/ptree.hpp>
32 template<
typename EigenType1,
typename EigenType2>
34 EigenType2
const& Lin,
35 Eigen::MatrixXd
const& Qin,
42 template<
typename Type1,
typename Type2>
44 std::shared_ptr<Type2> Lin,
45 Eigen::MatrixXd
const& Qin,
49 LinearSDE(std::shared_ptr<muq::Modeling::LinearOperator> Fin,
50 std::shared_ptr<muq::Modeling::LinearOperator> Lin,
51 Eigen::MatrixXd
const& Qin,
52 boost::property_tree::ptree options);
55 LinearSDE(std::shared_ptr<muq::Modeling::LinearOperator> Fin,
56 boost::property_tree::ptree options);
61 template<
typename EigenRefVector>
65 Eigen::VectorXd fnext(f0.size());
66 EvolveState(f0, T, Eigen::Ref<Eigen::VectorXd>(fnext));
70 template<
typename EigenRefVector1,
typename EigenRefVector2>
73 EigenRefVector2 f)
const
77 if(T<std::numeric_limits<double>::epsilon()){
81 const int numTimes = std::ceil(T/
dt);
86 for(
int i=0; i<numTimes-1; ++i)
90 f +=
dt*
F->Apply(f) +
L->Apply( z );
97 double lastDt = T-(numTimes-1)*
dt;
100 f += lastDt*
F->Apply(f) +
L->Apply( z );
102 f += lastDt*
F->Apply(f);
109 template<
typename EigenRefVector,
typename EigenRefMatrix>
111 EigenRefMatrix
const& gamma0,
114 Eigen::VectorXd mu(mu0.size());
115 Eigen::MatrixXd cov(gamma0.rows(), gamma0.cols());
117 EvolveDistribution(mu0,gamma0, T, Eigen::Ref<Eigen::VectorXd>(mu), Eigen::Ref<Eigen::MatrixXd>(cov));
118 return std::make_pair(mu,cov);
121 template<
typename EigenRefVector1,
typename EigenRefMatrix1,
typename EigenRefVector2,
typename EigenRefMatrix2>
123 EigenRefMatrix1
const& gamma0,
126 EigenRefMatrix2 gamma)
const
129 if(mu0.size()!=mu.size()){
130 throw std::runtime_error(
"In LinearSDE::EvolveDistribution: mu0 and mu have different sizes.");
132 if((gamma0.rows()!=gamma.rows())||(gamma0.cols()!=gamma.cols())){
133 throw std::runtime_error(
"In LinearSDE::EvolveDistribution: gamma0 and gamma have different sizes.");
139 if(T<std::numeric_limits<double>::epsilon()){
143 const int numTimes = std::ceil(T/
dt);
148 Eigen::MatrixXd Fgamma, k1, k2, k3, k4;
151 for(
int i=0; i<numTimes-1; ++i)
154 k2 =
F->Apply(mu + 0.5*
dt*k1);
155 k3 =
F->Apply(mu + 0.5*
dt*k2);
156 k4 =
F->Apply(mu +
dt*k3);
157 mu = mu + (
dt/6.0)*(k1 + 2.0*k2 + 2.0*k3 + k4);
159 Fgamma =
F->Apply(gamma);
160 k1 = Fgamma + Fgamma.transpose() +
LQLT;
161 Fgamma =
F->Apply(gamma + 0.5*
dt*k1);
162 k2 = Fgamma + Fgamma.transpose() +
LQLT;
163 Fgamma =
F->Apply(gamma + 0.5*
dt*k2);
164 k3 = Fgamma + Fgamma.transpose() +
LQLT;
165 Fgamma =
F->Apply(gamma +
dt*k3);
166 k4 = Fgamma + Fgamma.transpose() +
LQLT;
168 gamma = gamma + (
dt/6.0)*(k1 + 2.0*k2 + 2.0*k3 + k4);
172 double lastDt = T-(numTimes-1)*
dt;
175 k2 =
F->Apply(mu + 0.5*lastDt*k1);
176 k3 =
F->Apply(mu + 0.5*lastDt*k2);
177 k4 =
F->Apply(mu + lastDt*k3);
178 mu = mu + (lastDt/6.0)*(k1 + 2.0*k2 + 2.0*k3 + k4);
180 Fgamma =
F->Apply(gamma);
181 k1 = Fgamma + Fgamma.transpose() +
LQLT;
182 Fgamma =
F->Apply(gamma + 0.5*lastDt*k1);
183 k2 = Fgamma + Fgamma.transpose() +
LQLT;
184 Fgamma =
F->Apply(gamma + 0.5*lastDt*k2);
185 k3 = Fgamma + Fgamma.transpose() +
LQLT;
186 Fgamma =
F->Apply(gamma + lastDt*k3);
187 k4 = Fgamma + Fgamma.transpose() +
LQLT;
189 gamma = gamma + (lastDt/6.0)*(k1 + 2.0*k2 + 2.0*k3 + k4);
195 for(
int i=0; i<numTimes-1; ++i){
196 mu +=
dt*
F->Apply(mu);
197 gamma +=
dt*
dt*(
F->Apply(
F->Apply(gamma).transpose().eval()).transpose()) +
dt*
LQLT;
201 double lastDt = T-(numTimes-1)*
dt;
203 mu += lastDt*
F->Apply(mu);
204 gamma += lastDt*lastDt*(
F->Apply(
F->Apply(gamma).transpose().eval()).transpose()) + lastDt*
LQLT;
211 template<
typename EigenRefVector,
typename EigenRefMatrix>
212 std::pair<Eigen::VectorXd, Eigen::MatrixXd>
EvolveDistribution(std::pair<EigenRefVector,EigenRefMatrix>
const& muCov,
221 std::pair<Eigen::MatrixXd, Eigen::MatrixXd>
Discretize(
double deltaT);
235 static std::shared_ptr<LinearSDE>
Concatenate(std::vector<std::shared_ptr<LinearSDE>>
const& sdes,
236 boost::property_tree::ptree options = boost::property_tree::ptree());
243 std::shared_ptr<muq::Modeling::LinearOperator>
GetF()
const{
return F;};
244 std::shared_ptr<muq::Modeling::LinearOperator>
GetL()
const{
return L;};
245 Eigen::MatrixXd
const&
GetQ()
const{
return Q;};
252 std::shared_ptr<muq::Modeling::LinearOperator>
F;
253 std::shared_ptr<muq::Modeling::LinearOperator>
L;
Generic linear operator base class.
Defines a linear time invariant stochastic differential equation with Gaussian process noise.
LinearSDE(std::shared_ptr< Type1 > Fin, std::shared_ptr< Type2 > Lin, Eigen::MatrixXd const &Qin, boost::property_tree::ptree options)
std::shared_ptr< muq::Modeling::LinearOperator > GetL() const
std::shared_ptr< muq::Modeling::LinearOperator > L
void EvolveState(EigenRefVector1 const &f0, double T, EigenRefVector2 f) const
void ExtractOptions(boost::property_tree::ptree options)
std::shared_ptr< muq::Modeling::LinearOperator > F
Eigen::VectorXd EvolveState(EigenRefVector const &f0, double T) const
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > Discretize(double deltaT)
Eigen::MatrixXd const & GetQ() const
static std::shared_ptr< LinearSDE > Concatenate(std::vector< std::shared_ptr< LinearSDE >> const &sdes, boost::property_tree::ptree options=boost::property_tree::ptree())
Combines the states of multiple SDEs into a single monolitch SDE.
std::pair< Eigen::VectorXd, Eigen::MatrixXd > EvolveDistribution(std::pair< EigenRefVector, EigenRefMatrix > const &muCov, double T) const
const int stateDim
The dimension of the state variable .
std::shared_ptr< muq::Modeling::LinearOperator > GetF() const
std::pair< Eigen::VectorXd, Eigen::MatrixXd > EvolveDistribution(EigenRefVector const &mu0, EigenRefMatrix const &gamma0, double T) const
void EvolveDistribution(EigenRefVector1 const &mu0, EigenRefMatrix1 const &gamma0, double T, EigenRefVector2 mu, EigenRefMatrix2 gamma) const
std::string integratorType
LinearSDE(EigenType1 const &Fin, EigenType2 const &Lin, Eigen::MatrixXd const &Qin, boost::property_tree::ptree options)
static double GetNormal()