MUQ  0.4.3
BasicModPiece.cpp
Go to the documentation of this file.
1 #include <vector>
2 #include <Eigen/Core>
3 
5 
6 
7 class SimpleModel : public muq::Modeling::ModPiece
8 {
9 public:
10  SimpleModel(int numPts) : muq::Modeling::ModPiece({numPts,2},{numPts}) {};
11 
12 protected:
13  void EvaluateImpl(muq::Modeling::ref_vector<Eigen::VectorXd> const& inputs) override
14  {
15  Eigen::VectorXd const& x = inputs.at(0).get();
16  Eigen::VectorXd const& c = inputs.at(1).get();
17 
18  Eigen::VectorXd y = c(0)*x + c(1)*Eigen::VectorXd::Ones(x.size());
19 
20  outputs.resize(1);
21  outputs.at(0) = y;
22  };
23 
24  virtual void JacobianImpl(unsigned int outWrt,
25  unsigned int inWrt,
26  muq::Modeling::ref_vector<Eigen::VectorXd> const& inputs) override
27  {
28  Eigen::VectorXd const& x = inputs.at(0).get();
29  Eigen::VectorXd const& c = inputs.at(1).get();
30 
31  // Jacobian wrt x
32  if(inWrt==0){
33  jacobian = c(0)*Eigen::VectorXd::Identity(x.size(), x.size());
34 
35  // Jacobian wrt c
36  }else{
37  jacobian = Eigen::MatrixXd::Ones(outputSizes(0), inputSizes(inWrt));
38  jacobian.col(0) = x;
39  }
40  }
41 
42  virtual void GradientImpl(unsigned int outWrt,
43  unsigned int inWrt,
45  Eigen::VectorXd const& sens) override
46  {
47  Eigen::VectorXd const& x = inputs.at(0).get();
48  Eigen::VectorXd const& c = inputs.at(1).get();
49 
50  // Gradient wrt x
51  if(inWrt==0){
52  gradient = c(0) * sens;
53 
54  // Gradient wrt c
55  }else{
56  gradient.resize(2);
57  gradient(0) = x.dot(sens);
58  gradient(1) = sens.sum();
59  }
60  }
61 
62  virtual void ApplyJacobianImpl(unsigned int outWrt,
63  unsigned int inWrt,
65  Eigen::VectorXd const& vec) override
66  {
67  Eigen::VectorXd const& x = inputs.at(0).get();
68  Eigen::VectorXd const& c = inputs.at(1).get();
69 
70  // Jacobian wrt x
71  if(inWrt==0){
72  jacobianAction = c(0)*vec;
73 
74  // Jacobian wrt c
75  }else{
76  jacobianAction = vec(0)*x + vec(1)*Eigen::VectorXd::Ones(x.size());
77  }
78  }
79 
80  virtual void ApplyHessianImpl(unsigned int outWrt,
81  unsigned int inWrt1,
82  unsigned int inWrt2,
84  Eigen::VectorXd const& sens,
85  Eigen::VectorXd const& vec) override
86  {
87  Eigen::VectorXd const& x = inputs.at(0).get();
88  Eigen::VectorXd const& c = inputs.at(1).get();
89 
90  // Apply d^2 / dxdc
91  if((inWrt1==0)&&(inWrt2==1)){
92  hessAction = vec(0) * sens;
93 
94  // Apply d^2 / dcdx
95  }else if((inWrt2==0)&&(inWrt1==1)){
96  hessAction.resize(2);
97  hessAction(0) = sens.dot(vec);
98  hessAction(1) = 0;
99 
100  // Apply d^2 / dxds
101  }else if((inWrt1==0)&&(inWrt2==2)){
102  hessAction = c(0) * vec;
103 
104  // Apply d^2 / dcds
105  }else if((inWrt1==1)&&(inWrt2==2)){
106 
107  hessAction.resize(2);
108  hessAction(0) = x.dot(vec);
109  hessAction(1) = vec.sum();
110 
111  // Apply d^2/dx^2 or d^2/dc^2 or d^2/ds^2 or d^2 / dsdx or d^2 / dsdc
112  }else{
113  hessAction = Eigen::VectorXd::Zero(inputSizes(inWrt1));
114  }
115  }
116 }; // end of class SimpleModel
117 
118 
119 int main(){
120 
121  unsigned int numPts = 10;
122  Eigen::VectorXd x = Eigen::VectorXd::Random(numPts);
123 
124  Eigen::VectorXd c(2);
125  c << 1.0, 0.5;
126 
127  auto mod = std::make_shared<SimpleModel>(numPts);
128 
129  Eigen::VectorXd y = mod->Evaluate(x,c).at(0);
130 
131  std::cout << "c = " << c.transpose() << std::endl;
132  std::cout << "x = " << x.transpose() << std::endl;
133  std::cout << "y = " << y.transpose() << std::endl;
134 
135  int wrt1=0, wrt2=0;
136 
137  Eigen::VectorXd grad, gradFd, vec;
138  Eigen::VectorXd hessAct, hessActFd;
139  Eigen::VectorXd sens = Eigen::VectorXd::Random(mod->outputSizes(0));
140 
141 
142  grad = mod->Gradient(0,wrt1, x,c,sens);
143  gradFd = mod->GradientByFD(0,wrt1,std::vector<Eigen::VectorXd>{x,c},sens);
144  std::cout << "Gradient Comparison:\n" << grad.transpose() << "\nvs\n" << gradFd.transpose() << std::endl << std::endl;
145 
146  vec = Eigen::VectorXd::Random(mod->inputSizes(wrt2));
147  hessAct = mod->ApplyHessian(0, wrt1, wrt2, std::vector<Eigen::VectorXd>{x,c}, sens, vec);
148  hessActFd = mod->ApplyHessianByFD(0,wrt1,wrt2,std::vector<Eigen::VectorXd>{x,c},sens,vec);
149 
150  std::cout << "Hessian Comparison:\n" << hessAct.transpose() << "\nvs\n" << hessActFd.transpose() << std::endl << std::endl;
151 
152  wrt1 = 1;
153  grad = mod->Gradient(0,wrt1, x,c,sens);
154  gradFd = mod->GradientByFD(0,wrt1,std::vector<Eigen::VectorXd>{x,c},sens);
155  std::cout << "Gradient Comparison:\n" << grad.transpose() << "\nvs\n" << gradFd.transpose() << std::endl << std::endl;
156 
157  vec = Eigen::VectorXd::Random(mod->inputSizes(wrt2));
158  hessAct = mod->ApplyHessian(0, wrt1, wrt2, std::vector<Eigen::VectorXd>{x,c}, sens, vec);
159  hessActFd = mod->ApplyHessianByFD(0,wrt1,wrt2,std::vector<Eigen::VectorXd>{x,c},sens,vec);
160 
161  std::cout << "Hessian Comparison:\n" << hessAct.transpose() << "\nvs\n" << hessActFd.transpose() << std::endl << std::endl;
162 
163  wrt1 = 0;
164  wrt2 = 1;
165 
166  grad = mod->Gradient(0,wrt1, x,c,sens);
167  gradFd = mod->GradientByFD(0,wrt1,std::vector<Eigen::VectorXd>{x,c},sens);
168  std::cout << "Gradient Comparison:\n" << grad.transpose() << "\nvs\n" << gradFd.transpose() << std::endl << std::endl;
169 
170  vec = Eigen::VectorXd::Random(mod->inputSizes(wrt2));
171  hessAct = mod->ApplyHessian(0, wrt1, wrt2, std::vector<Eigen::VectorXd>{x,c}, sens, vec);
172  hessActFd = mod->ApplyHessianByFD(0,wrt1,wrt2,std::vector<Eigen::VectorXd>{x,c},sens,vec);
173 
174  std::cout << "Hessian Comparison:\n" << hessAct.transpose() << "\nvs\n" << hessActFd.transpose() << std::endl << std::endl;
175 
176  wrt2 = 2;
177 
178  vec = Eigen::VectorXd::Random(mod->outputSizes(0));
179  hessAct = mod->ApplyHessian(0, wrt1, wrt2, std::vector<Eigen::VectorXd>{x,c}, sens, vec);
180  hessActFd = mod->ApplyHessianByFD(0,wrt1,wrt2,std::vector<Eigen::VectorXd>{x,c},sens,vec);
181 
182  std::cout << "Hessian Comparison:\n" << hessAct.transpose() << "\nvs\n" << hessActFd.transpose() << std::endl << std::endl;
183 
184 
185  return 0;
186 }
int main()
Provides an abstract interface for defining vector-valued model components.
Definition: ModPiece.h:148
Eigen::MatrixXd jacobian
Definition: ModPiece.h:506
virtual void GradientImpl(unsigned int const outputDimWrt, unsigned int const inputDimWrt, ref_vector< Eigen::VectorXd > const &input, Eigen::VectorXd const &sensitivity)
Definition: ModPiece.cpp:237
virtual void ApplyJacobianImpl(unsigned int const outputDimWrt, unsigned int const inputDimWrt, ref_vector< Eigen::VectorXd > const &input, Eigen::VectorXd const &vec)
Definition: ModPiece.cpp:262
const Eigen::VectorXi inputSizes
Definition: ModPiece.h:469
std::vector< Eigen::VectorXd > outputs
Definition: ModPiece.h:503
ModPiece(std::vector< int > const &inputSizes, std::vector< int > const &outputSizes)
Definition: ModPiece.cpp:9
virtual void EvaluateImpl(ref_vector< boost::any > const &inputs) override
User-implemented function that determines the behavior of this muq::Modeling::WorkPiece.
Definition: ModPiece.cpp:179
Eigen::VectorXd gradient
Definition: ModPiece.h:504
virtual void JacobianImpl(unsigned int const outputDimWrt, unsigned int const inputDimWrt, ref_vector< Eigen::VectorXd > const &input)
Definition: ModPiece.cpp:245
const Eigen::VectorXi outputSizes
Definition: ModPiece.h:472
Eigen::VectorXd hessAction
Definition: ModPiece.h:507
Eigen::VectorXd jacobianAction
Definition: ModPiece.h:505
virtual void ApplyHessianImpl(unsigned int const outWrt, unsigned int const inWrt1, unsigned int const inWrt2, ref_vector< Eigen::VectorXd > const &input, Eigen::VectorXd const &sens, Eigen::VectorXd const &vec)
Definition: ModPiece.cpp:436
std::vector< std::reference_wrapper< const T > > ref_vector
A vector of references to something ...
Definition: WorkPiece.h:37