Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_ResponseStatisticModelEvaluator.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
14 #include "Teuchos_Assert.hpp"
15 
18  const Teuchos::Array< Teuchos::RCP<const Epetra_Map> >& base_g_maps_,
19  const Teuchos::RCP<const Stokhos::OrthogPolyBasis<int,double> >& sg_basis_,
21  const Teuchos::RCP<const Epetra_BlockMap>& block_map_) :
22  me(me_),
23  base_g_maps(base_g_maps_),
24  sg_basis(sg_basis_),
25  sg_comm(sg_comm_),
26  block_map(block_map_),
27  num_p(0),
28  num_g(0)
29 {
30  InArgs me_inargs = me->createInArgs();
31  OutArgs me_outargs = me->createOutArgs();
32  num_p = me_inargs.Np();
33  num_g = me_outargs.Ng();
34 }
35 
36 // Overridden from EpetraExt::ModelEvaluator
37 
40 get_x_map() const
41 {
42  return Teuchos::null;
43 }
44 
47 get_f_map() const
48 {
49  return Teuchos::null;
50 }
51 
54 get_p_map(int l) const
55 {
57  l >= num_p || l < 0, std::logic_error,
58  std::endl <<
59  "Error! Stokhos::ResponseStatisticModelEvaluator::get_p_map(): " <<
60  "Invalid parameter index l = " << l << std::endl);
61 
62  return me->get_p_map(l);
63 }
64 
67 get_g_map(int l) const
68 {
70  l >= 3*num_g || l < 0, std::logic_error,
71  std::endl <<
72  "Error! Stokhos::ResponseStatisticModelEvaluator::get_g_map(): " <<
73  "Invalid response index l = " << l << std::endl);
74 
75  if (l < num_g)
76  return me->get_g_map(l);
77  else if (l < 2*num_g)
78  return base_g_maps[l-num_g];
79  else
80  return base_g_maps[l-2*num_g];
81 }
82 
85 get_p_names(int l) const
86 {
88  l >= num_p || l < 0, std::logic_error,
89  std::endl <<
90  "Error! Stokhos::ResponseStatisticModelEvaluator::get_p_names(): " <<
91  "Invalid parameter index l = " << l << std::endl);
92 
93  return me->get_p_names(l);
94 }
95 
98 get_p_init(int l) const
99 {
101  l >= num_p || l < 0, std::logic_error,
102  std::endl <<
103  "Error! Stokhos::ResponseStatisticModelEvaluator::get_p_init(): " <<
104  "Invalid parameter index l = " << l << std::endl);
105 
106  return me->get_p_init(l);
107 }
108 
109 EpetraExt::ModelEvaluator::InArgs
111 {
112  InArgsSetup inArgs;
113  InArgs me_inargs = me->createInArgs();
114 
115  inArgs.setModelEvalDescription(this->description());
116  inArgs.set_Np(num_p);
117 
118  // Support pass-through of sg data
119  inArgs.setSupports(IN_ARG_sg_basis, me_inargs.supports(IN_ARG_sg_basis));
120  inArgs.setSupports(IN_ARG_sg_quadrature,
121  me_inargs.supports(IN_ARG_sg_quadrature));
122  inArgs.setSupports(IN_ARG_sg_expansion,
123  me_inargs.supports(IN_ARG_sg_expansion));
124 
125  return inArgs;
126 }
127 
128 EpetraExt::ModelEvaluator::OutArgs
130 {
131  OutArgsSetup outArgs;
132  OutArgs me_outargs = me->createOutArgs();
133 
134  outArgs.setModelEvalDescription(this->description());
135 
136  outArgs.set_Np_Ng(num_p, 3*num_g);
137  for (int i=0; i<num_g; i++) {
138  for (int j=0; j<num_p; j++) {
139  outArgs.setSupports(OUT_ARG_DgDp, i, j,
140  me_outargs.supports(OUT_ARG_DgDp, i, j));
141 
142  DerivativeSupport ds = me_outargs.supports(OUT_ARG_DgDp, i, j);
143  DerivativeSupport ds_stat;
144  if (ds.supports(DERIV_MV_BY_COL))
145  ds_stat.plus(DERIV_MV_BY_COL);
146  if (ds.supports(DERIV_TRANS_MV_BY_ROW))
147  ds_stat.plus(DERIV_TRANS_MV_BY_ROW);
148  if (ds.supports(DERIV_LINEAR_OP))
149  ds_stat.plus(DERIV_TRANS_MV_BY_ROW);
150  outArgs.setSupports(OUT_ARG_DgDp, i+num_g, j, ds_stat);
151  outArgs.setSupports(OUT_ARG_DgDp, i+2*num_g, j, ds_stat);
152  }
153  }
154 
155  return outArgs;
156 }
157 
158 void
160  const OutArgs& outArgs) const
161 {
162  // Create underlying inargs
163  InArgs me_inargs = me->createInArgs();
164 
165  // Pass parameters
166  for (int i=0; i<num_p; i++)
167  me_inargs.set_p(i, inArgs.get_p(i));
168 
169  // Pass SG data
170  if (me_inargs.supports(IN_ARG_sg_basis))
171  me_inargs.set_sg_basis(inArgs.get_sg_basis());
172  if (me_inargs.supports(IN_ARG_sg_quadrature))
173  me_inargs.set_sg_quadrature(inArgs.get_sg_quadrature());
174  if (me_inargs.supports(IN_ARG_sg_expansion))
175  me_inargs.set_sg_expansion(inArgs.get_sg_expansion());
176 
177  // Create underlying outargs
178  OutArgs me_outargs = me->createOutArgs();
179 
180  Teuchos::Array<bool> need_g_var(num_g);
181 
182  // Responses
183  for (int i=0; i<num_g; i++) {
184 
185  // See if we need g_var for d/dp(g_var) below
186  need_g_var[i] = false;
187  for (int j=0; j<num_p; j++)
188  if (!outArgs.supports(OUT_ARG_DgDp, i, j).none())
189  if (!outArgs.get_DgDp(i+2*num_g,j).isEmpty())
190  need_g_var[i] = true;
191 
192  // g
193  Teuchos::RCP<Epetra_Vector> g = outArgs.get_g(i);
194  Teuchos::RCP<Epetra_Vector> g_mean = outArgs.get_g(i+num_g);
195  Teuchos::RCP<Epetra_Vector> g_var = outArgs.get_g(i+2*num_g);
196  if ((g_mean != Teuchos::null || g_var != Teuchos::null || need_g_var[i]) &&
197  g == Teuchos::null) {
198  g = Teuchos::rcp(new Epetra_Vector(*(me->get_g_map(i))));
199  }
200  me_outargs.set_g(i, g);
201 
202  // dg/dp
203  for (int j=0; j<num_p; j++) {
204  if (!outArgs.supports(OUT_ARG_DgDp, i, j).none()) {
205  Derivative dgdp = outArgs.get_DgDp(i,j);
207  outArgs.get_DgDp(i+num_g,j).getMultiVector();
209  outArgs.get_DgDp(i+2*num_g,j).getMultiVector();
210  if ((dgdp_mean != Teuchos::null || dgdp_var != Teuchos::null) &&
211  dgdp.isEmpty()) {
212  Teuchos::RCP<const Epetra_Map> g_map = me->get_g_map(i);
213  Teuchos::RCP<const Epetra_Map> p_map = me->get_p_map(j);
214  DerivativeSupport ds = me_outargs.supports(OUT_ARG_DgDp,i,j);
215  EDerivativeMultiVectorOrientation mvOrientation;
216  if (dgdp_mean != Teuchos::null)
217  mvOrientation = outArgs.get_DgDp(i+num_g,j).getMultiVectorOrientation();
218  else
219  mvOrientation = outArgs.get_DgDp(i+2*num_g,j).getMultiVectorOrientation();
220  if (mvOrientation == DERIV_TRANS_MV_BY_ROW &&
221  ds.supports(DERIV_LINEAR_OP))
222  dgdp = Derivative(me->create_DgDp_op(i,j));
223  else if (mvOrientation == DERIV_TRANS_MV_BY_ROW)
224  dgdp =
225  Derivative(Teuchos::rcp(new Epetra_MultiVector(
226  *p_map,
227  g_map->NumMyElements())),
228  DERIV_TRANS_MV_BY_ROW);
229  else
230  dgdp =
231  Derivative(Teuchos::rcp(new Epetra_MultiVector(
232  *g_map,
233  p_map->NumMyElements())),
234  DERIV_MV_BY_COL);
235 
236  }
237  me_outargs.set_DgDp(i, j, dgdp);
238 
239  // We need g to compute d/dp(g_var)
240  if (dgdp_var != Teuchos::null && g == Teuchos::null) {
241  g = Teuchos::rcp(new Epetra_Vector(*(me->get_g_map(i))));
242  me_outargs.set_g(i, g);
243  }
244  }
245  }
246 
247  }
248 
249  // Compute the functions
250  me->evalModel(me_inargs, me_outargs);
251 
252  // Compute statistics
253  for (int i=0; i<num_g; i++) {
254 
255  // g
256  Teuchos::RCP<Epetra_Vector> g = me_outargs.get_g(i);
257  Teuchos::RCP<Epetra_Vector> g_mean = outArgs.get_g(i+num_g);
258  Teuchos::RCP<Epetra_Vector> g_var = outArgs.get_g(i+2*num_g);
259  if (need_g_var[i] && g_var == Teuchos::null)
260  g_var = Teuchos::rcp(new Epetra_Vector(*(base_g_maps[i])));
262  if (g_mean != Teuchos::null || g_var != Teuchos::null) {
264  sg_basis, block_map, base_g_maps[i], me->get_g_map(i),
265  sg_comm, View, *g));
266  }
267 
268  if (g_mean != Teuchos::null)
269  g_sg->computeMean(*g_mean);
270  if (g_var != Teuchos::null)
271  g_sg->computeVariance(*g_var);
272 
273  // dg/dp
274  for (int j=0; j<num_p; j++) {
275  if (!outArgs.supports(OUT_ARG_DgDp, i, j).none()) {
276  Derivative dgdp = me_outargs.get_DgDp(i,j);
278  outArgs.get_DgDp(i+num_g,j).getMultiVector();
280  outArgs.get_DgDp(i+2*num_g,j).getMultiVector();
281  if (dgdp_mean != Teuchos::null || dgdp_var != Teuchos::null) {
282  if (dgdp.getLinearOp() != Teuchos::null) {
283  Teuchos::RCP<Epetra_Operator> dgdp_op = dgdp.getLinearOp();
284  int n = base_g_maps[i]->NumMyElements();
285  EpetraMultiVectorOrthogPoly X_sg(sg_basis, block_map,
286  base_g_maps[i], sg_comm, n);
287  dgdp_op->SetUseTranspose(true);
288  if (dgdp_mean != Teuchos::null) {
289  X_sg.init(0.0);
290  for (int l=0; l<n; l++)
291  X_sg[0][l][l] = 1.0;
293  outArgs.get_DgDp(i+num_g,j).getMultiVectorOrientation() == DERIV_MV_BY_COL,
294  std::logic_error,
295  "Error! ResponseStatisticModelEvaluator does not support " <<
296  " dg/dp DERIV_MV_BY_COL for underlying operator dg/dp");
297  dgdp_op->Apply(*(X_sg.getBlockMultiVector()), *dgdp_mean);
298  }
299  if (dgdp_var != Teuchos::null) {
300  X_sg.init(0.0);
301  for (int k=1; k<sg_basis->size(); k++)
302  for (int l=0; l<n; l++)
303  X_sg[k][l][l] = 2.0*(*g_sg)[k][l]*sg_basis->norm_squared(k);
305  outArgs.get_DgDp(i+2*num_g,j).getMultiVectorOrientation() == DERIV_MV_BY_COL,
306  std::logic_error,
307  "Error! ResponseStatisticModelEvaluator does not support " <<
308  " dg/dp DERIV_MV_BY_COL for underlying operator dg/dp");
309  dgdp_op->Apply(*(X_sg.getBlockMultiVector()), *dgdp_var);
310  }
311 
312  }
313  else if (dgdp.getMultiVector() != Teuchos::null) {
315  dgdp.getMultiVector();
317  if (dgdp.getMultiVectorOrientation() == DERIV_MV_BY_COL)
318  row_map = me->get_g_map(i);
319  else
320  row_map = me->get_p_map(j);
322  sg_basis, block_map, row_map, Teuchos::rcpFromRef(dgdp_mv->Map()),
323  sg_comm, View, *dgdp_mv);
324  if (dgdp_mean != Teuchos::null)
325  dgdp_sg.computeMean(*dgdp_mean);
326  if (dgdp_var != Teuchos::null) {
327  dgdp_var->PutScalar(0.0);
328  for (int k=1; k<sg_basis->size(); k++)
329  for (int m=0; m<dgdp_var->NumVectors(); m++)
330  for (int l=0; l<row_map->NumMyElements(); l++)
331  (*dgdp_var)[m][l] += 2.0*(*g_sg)[k][l]*dgdp_sg[k][m][l]*
332  sg_basis->norm_squared(k);
333  }
334  }
335  }
336  }
337  }
338  }
339 }
void computeVariance(Epetra_Vector &v) const
Compute variance.
Teuchos::RCP< const Epetra_Map > get_g_map(int l) const
Return response map.
Teuchos::RCP< const Epetra_Vector > get_p_init(int l) const
Return initial parameters.
virtual int SetUseTranspose(bool UseTranspose)=0
void computeMean(Epetra_MultiVector &v) const
Compute mean.
void computeMean(Epetra_Vector &v) const
Compute mean.
void init(const value_type &val)
Initialize coefficients.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
int NumMyElements() const
virtual int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const =0
void evalModel(const InArgs &inArgs, const OutArgs &outArgs) const
Evaluate model on InArgs.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.
virtual const Epetra_BlockMap & Map() const =0
Teuchos::RCP< EpetraExt::BlockMultiVector > getBlockMultiVector()
Get block vector.
Teuchos::RCP< const Epetra_Map > get_f_map() const
Return residual vector map.
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Return array of parameter names.
Teuchos::RCP< const Epetra_Map > get_p_map(int l) const
Return parameter vector map.
Teuchos::RCP< const Epetra_Map > get_x_map() const
Return solution vector map.
ResponseStatisticModelEvaluator(const Teuchos::RCP< EpetraExt::ModelEvaluator > &me, const Teuchos::Array< Teuchos::RCP< const Epetra_Map > > &base_g_maps, const Teuchos::RCP< const Stokhos::OrthogPolyBasis< int, double > > &sg_basis, const Teuchos::RCP< const EpetraExt::MultiComm > &sg_comm, const Teuchos::RCP< const Epetra_BlockMap > &block_map)
int n
Teuchos::RCP< EpetraExt::ModelEvaluator > me
Underlying model evaluator.
ScalarType g(const Teuchos::Array< ScalarType > &x, const ScalarType &y)
A container class storing an orthogonal polynomial whose coefficients are vectors, operators, or in general any type that would have an expensive copy constructor.