1 /* _______________________________________________________________________
2
3 PECOS: Parallel Environment for Creation Of Stochastics
4 Copyright (c) 2011, Sandia National Laboratories.
5 This software is distributed under the GNU Lesser General Public License.
6 For more information, see the README file in the top Pecos directory.
7 _______________________________________________________________________ */
8
9 #ifndef SURROGATE_DATA_HPP
10 #define SURROGATE_DATA_HPP
11
12 #include "pecos_data_types.hpp"
13 #include "DiscrepancyCalculator.hpp"
14 #include <boost/math/special_functions/fpclassify.hpp> //for boostmath::isfinite
15
16
17 namespace Pecos {
18
19 /// The representation of a SurrogateDataVars instance. This representation,
20 /// or body, may be shared by multiple SurrogateDataVars handle instances.
21
22 /** The SurrogateDataVars/SurrogateDataVarsRep pairs utilize a
23 handle-body idiom (Coplien, Advanced C++). */
24
25 class SurrogateDataVarsRep
26 {
27 //
28 //- Heading: Friends
29 //
30
31 /// the handle class can access attributes of the body class directly
32 friend class SurrogateDataVars;
33
34 public:
35 /// destructor
36 ~SurrogateDataVarsRep();
37
38 private:
39
40 //
41 //- Heading: Private member functions
42 //
43
44 /// constructor
45 SurrogateDataVarsRep(const RealVector& c_vars, const IntVector& di_vars,
46 const RealVector& dr_vars, short mode);
47 /// alternate constructor (data sizing only)
48 SurrogateDataVarsRep(size_t num_c_vars, size_t num_di_vars,
49 size_t num_dr_vars);
50
51 /// lightweight constructor (common use case: continuous variables)
52 SurrogateDataVarsRep(const RealVector& c_vars, short mode);
53 /// alternate lightweight constructor (data sizing only)
54 SurrogateDataVarsRep(size_t num_c_vars);
55
56
57 //
58 //- Heading: Private data members
59 //
60
61 RealVector continuousVars; ///< continuous variables
62 IntVector discreteIntVars; ///< discrete integer variables
63 RealVector discreteRealVars; ///< discrete real variables
64 };
65
66
67 inline SurrogateDataVarsRep::
SurrogateDataVarsRep(const RealVector & c_vars,const IntVector & di_vars,const RealVector & dr_vars,short mode)68 SurrogateDataVarsRep(const RealVector& c_vars, const IntVector& di_vars,
69 const RealVector& dr_vars, short mode)
70 {
71 // Note: provided a way to query DataAccess mode for c_vars, could make
72 // greater use of operator= for {DEEP,SHALLOW}_COPY modes
73 if (mode == DEEP_COPY) { // enforce deep vector copy
74 if (!c_vars.empty()) copy_data( c_vars, continuousVars);
75 if (!di_vars.empty()) copy_data(di_vars, discreteIntVars);
76 if (!dr_vars.empty()) copy_data(dr_vars, discreteRealVars);
77 }
78 else if (mode == SHALLOW_COPY) { // enforce shallow vector copy
79 if (!c_vars.empty())
80 continuousVars
81 = RealVector(Teuchos::View, c_vars.values(), c_vars.length());
82 if (!di_vars.empty())
83 discreteIntVars
84 = IntVector(Teuchos::View, di_vars.values(), di_vars.length());
85 if (!dr_vars.empty())
86 discreteRealVars
87 = RealVector(Teuchos::View, dr_vars.values(), dr_vars.length());
88 }
89 else { // default: assume existing Copy/View state
90 if (!c_vars.empty()) continuousVars = c_vars;
91 if (!di_vars.empty()) discreteIntVars = di_vars;
92 if (!dr_vars.empty()) discreteRealVars = dr_vars;
93 }
94 }
95
96
97 inline SurrogateDataVarsRep::
SurrogateDataVarsRep(size_t num_c_vars,size_t num_di_vars,size_t num_dr_vars)98 SurrogateDataVarsRep(size_t num_c_vars, size_t num_di_vars, size_t num_dr_vars)
99 {
100 continuousVars.sizeUninitialized(num_c_vars);
101 discreteIntVars.sizeUninitialized(num_di_vars);
102 discreteRealVars.sizeUninitialized(num_dr_vars);
103 }
104
105
106 inline SurrogateDataVarsRep::
SurrogateDataVarsRep(const RealVector & c_vars,short mode)107 SurrogateDataVarsRep(const RealVector& c_vars, short mode)
108 {
109 // Note: provided a way to query DataAccess mode for c_vars, could make
110 // greater use of operator= for {DEEP,SHALLOW}_COPY modes
111 if (!c_vars.empty())
112 switch (mode) {
113 case DEEP_COPY:
114 copy_data(c_vars, continuousVars); break;
115 case SHALLOW_COPY:
116 continuousVars
117 = RealVector(Teuchos::View, c_vars.values(), c_vars.length());
118 break;
119 default: // assume existing Copy/View state
120 continuousVars = c_vars; break;
121 }
122 }
123
124
125 inline SurrogateDataVarsRep::
SurrogateDataVarsRep(size_t num_c_vars)126 SurrogateDataVarsRep(size_t num_c_vars)
127 { continuousVars.sizeUninitialized(num_c_vars); }
128
129
~SurrogateDataVarsRep()130 inline SurrogateDataVarsRep::~SurrogateDataVarsRep()
131 { }
132
133
134 /// Container class encapsulating basic parameter data for defining a
135 /// "truth" data point.
136
137 /** A set of these input data points is contained in SurrogateData and
138 provides the data to build the approximation. A handle-body idiom
139 is used to avoid excessive data copying overhead. */
140
141 class SurrogateDataVars
142 {
143 public:
144
145 //
146 //- Heading: Constructors, destructor, and operators
147 //
148
149 /// default constructor
150 SurrogateDataVars();
151
152 /// standard constructor
153 SurrogateDataVars(const RealVector& c_vars, const IntVector& di_vars,
154 const RealVector& dr_vars, short mode = DEFAULT_COPY);
155 /// alternate constructor (data sizing only)
156 SurrogateDataVars(size_t num_c_vars, size_t num_di_vars, size_t num_dr_vars);
157
158 /// lightweight constructor
159 SurrogateDataVars(const RealVector& c_vars, short mode = DEFAULT_COPY);
160 /// alternate lightweight constructor (data sizing only)
161 SurrogateDataVars(size_t num_c_vars);
162
163 /// copy constructor
164 SurrogateDataVars(const SurrogateDataVars& sdv);
165 /// destructor
166 ~SurrogateDataVars();
167
168 /// assignment operator
169 SurrogateDataVars& operator=(const SurrogateDataVars& sdv);
170 // equality operator
171 //bool operator==(const SurrogateDataVars& sdv) const;
172
173 //
174 //- Heading: member functions
175 //
176
177 /// instantiate a sdvRep
178 void create_rep(size_t num_vars);
179
180 /// return number of continuous variables
181 size_t cv() const;
182 /// return number of discrete integer variables
183 size_t div() const;
184 /// return number of discrete real variables
185 size_t drv() const;
186
187 /// return deep copy of SurrogateDataVars instance
188 SurrogateDataVars copy() const;
189
190 /// set i^{th} entry within continuousVars
191 void continuous_variable(Real c_var, size_t i);
192 /// set continuousVars
193 void continuous_variables(const RealVector& c_vars,
194 short mode = DEFAULT_COPY);
195 /// get continuousVars
196 const RealVector& continuous_variables() const;
197 /// get view of continuousVars for updating in place
198 RealVector continuous_variables_view();
199
200 /// set i^{th} entry within discreteIntVars
201 void discrete_int_variable(int di_var, size_t i);
202 /// set discreteIntVars
203 void discrete_int_variables(const IntVector& di_vars,
204 short mode = DEFAULT_COPY);
205 /// get discreteIntVars
206 const IntVector& discrete_int_variables() const;
207 /// get view of discreteIntVars for updating in place
208 IntVector discrete_int_variables_view();
209
210 /// set i^{th} entry within discreteRealVars
211 void discrete_real_variable(Real dr_var, size_t i);
212 /// set discreteRealVars
213 void discrete_real_variables(const RealVector& dr_vars,
214 short mode = DEFAULT_COPY);
215 /// get discreteRealVars
216 const RealVector& discrete_real_variables() const;
217 /// get view of discreteRealVars for updating in place
218 RealVector discrete_real_variables_view();
219
220 /// function to check sdvRep (does this handle contain a body)
221 bool is_null() const;
222
223 private:
224
225 //
226 //- Heading: Private data members
227 //
228
229 /// pointer to the body (handle-body idiom)
230 std::shared_ptr<SurrogateDataVarsRep> sdvRep;
231 };
232
233
SurrogateDataVars()234 inline SurrogateDataVars::SurrogateDataVars()
235 { }
236
237
238 // BMA NOTE: The following don't use make_shared<SurrogateDataVarsRep>()
239 // due to private ctors
240
241 inline SurrogateDataVars::
SurrogateDataVars(const RealVector & c_vars,const IntVector & di_vars,const RealVector & dr_vars,short mode)242 SurrogateDataVars(const RealVector& c_vars, const IntVector& di_vars,
243 const RealVector& dr_vars, short mode):
244 sdvRep(new SurrogateDataVarsRep(c_vars, di_vars, dr_vars, mode))
245 { }
246
247
248 inline SurrogateDataVars::
SurrogateDataVars(size_t num_c_vars,size_t num_di_vars,size_t num_dr_vars)249 SurrogateDataVars(size_t num_c_vars, size_t num_di_vars, size_t num_dr_vars):
250 sdvRep(new SurrogateDataVarsRep(num_c_vars, num_di_vars, num_dr_vars))
251 { }
252
253
254 inline SurrogateDataVars::
SurrogateDataVars(const RealVector & c_vars,short mode)255 SurrogateDataVars(const RealVector& c_vars, short mode):
256 sdvRep(new SurrogateDataVarsRep(c_vars, mode))
257 { }
258
259
SurrogateDataVars(size_t num_c_vars)260 inline SurrogateDataVars::SurrogateDataVars(size_t num_c_vars):
261 sdvRep(new SurrogateDataVarsRep(num_c_vars))
262 { }
263
264
SurrogateDataVars(const SurrogateDataVars & sdv)265 inline SurrogateDataVars::SurrogateDataVars(const SurrogateDataVars& sdv):
266 sdvRep(sdv.sdvRep)
267 { }
268
269
~SurrogateDataVars()270 inline SurrogateDataVars::~SurrogateDataVars()
271 { }
272
273
274 inline SurrogateDataVars& SurrogateDataVars::
operator =(const SurrogateDataVars & sdv)275 operator=(const SurrogateDataVars& sdv)
276 {
277 sdvRep = sdv.sdvRep;
278 return *this;
279 }
280
281
282 //inline bool SurrogateDataVars::operator==(const SurrogateDataVars& sdv) const
283 //{
284 // return (sdvRep->continuousVars == sdv.sdvRep->continuousVars &&
285 // sdvRep->discreteIntVars == sdv.sdvRep->discreteIntVars &&
286 // sdvRep->discreteRealVars == sdv.sdvRep->discreteRealVars) ?
287 // true : false;
288 //}
289
290
create_rep(size_t num_vars)291 inline void SurrogateDataVars::create_rep(size_t num_vars)
292 { sdvRep.reset(new SurrogateDataVarsRep(num_vars)); }
293
294
295 /// deep copy of SurrogateDataVars instance
copy() const296 inline SurrogateDataVars SurrogateDataVars::copy() const
297 {
298 SurrogateDataVars sdv(sdvRep->continuousVars, sdvRep->discreteIntVars,
299 sdvRep->discreteRealVars, DEEP_COPY);
300 return sdv;
301 }
302
303
continuous_variable(Real c_var,size_t i)304 inline void SurrogateDataVars::continuous_variable(Real c_var, size_t i)
305 { sdvRep->continuousVars[i] = c_var; }
306
307
308 inline void SurrogateDataVars::
continuous_variables(const RealVector & c_vars,short mode)309 continuous_variables(const RealVector& c_vars, short mode)
310 {
311 if (mode == DEEP_COPY) // enforce deep vector copy
312 copy_data(c_vars, sdvRep->continuousVars);
313 else if (mode == SHALLOW_COPY) // enforce shallow vector copy
314 sdvRep->continuousVars
315 = RealVector(Teuchos::View, c_vars.values(), c_vars.length());
316 else // default: assume existing Copy/View state
317 sdvRep->continuousVars = c_vars;
318 }
319
320
cv() const321 inline size_t SurrogateDataVars::cv() const
322 { return sdvRep->continuousVars.length(); }
323
324
div() const325 inline size_t SurrogateDataVars::div() const
326 { return sdvRep->discreteIntVars.length(); }
327
328
drv() const329 inline size_t SurrogateDataVars::drv() const
330 { return sdvRep->discreteRealVars.length(); }
331
332
continuous_variables() const333 inline const RealVector& SurrogateDataVars::continuous_variables() const
334 { return sdvRep->continuousVars; }
335
336
continuous_variables_view()337 inline RealVector SurrogateDataVars::continuous_variables_view()
338 {
339 return RealVector(Teuchos::View, sdvRep->continuousVars.values(),
340 sdvRep->continuousVars.length());
341 }
342
343
discrete_int_variable(int di_var,size_t i)344 inline void SurrogateDataVars::discrete_int_variable(int di_var, size_t i)
345 { sdvRep->discreteIntVars[i] = di_var; }
346
347
348 inline void SurrogateDataVars::
discrete_int_variables(const IntVector & di_vars,short mode)349 discrete_int_variables(const IntVector& di_vars, short mode)
350 {
351 if (mode == DEEP_COPY) // enforce deep vector copy
352 copy_data(di_vars, sdvRep->discreteIntVars);
353 else if (mode == SHALLOW_COPY) // enforce shallow vector copy
354 sdvRep->discreteIntVars
355 = IntVector(Teuchos::View, di_vars.values(), di_vars.length());
356 else // default: assume existing Copy/View state
357 sdvRep->discreteIntVars = di_vars;
358 }
359
360
discrete_int_variables() const361 inline const IntVector& SurrogateDataVars::discrete_int_variables() const
362 { return sdvRep->discreteIntVars; }
363
364
discrete_int_variables_view()365 inline IntVector SurrogateDataVars::discrete_int_variables_view()
366 {
367 return IntVector(Teuchos::View, sdvRep->discreteIntVars.values(),
368 sdvRep->discreteIntVars.length());
369 }
370
371
discrete_real_variable(Real dr_var,size_t i)372 inline void SurrogateDataVars::discrete_real_variable(Real dr_var, size_t i)
373 { sdvRep->discreteRealVars[i] = dr_var; }
374
375
376 inline void SurrogateDataVars::
discrete_real_variables(const RealVector & dr_vars,short mode)377 discrete_real_variables(const RealVector& dr_vars, short mode)
378 {
379 if (mode == DEEP_COPY) // enforce deep vector copy
380 copy_data(dr_vars, sdvRep->discreteRealVars);
381 else if (mode == SHALLOW_COPY) // enforce shallow vector copy
382 sdvRep->discreteRealVars
383 = RealVector(Teuchos::View, dr_vars.values(), dr_vars.length());
384 else // default: assume existing Copy/View state
385 sdvRep->discreteRealVars = dr_vars;
386 }
387
388
discrete_real_variables() const389 inline const RealVector& SurrogateDataVars::discrete_real_variables() const
390 { return sdvRep->discreteRealVars; }
391
392
discrete_real_variables_view()393 inline RealVector SurrogateDataVars::discrete_real_variables_view()
394 {
395 return RealVector(Teuchos::View, sdvRep->discreteRealVars.values(),
396 sdvRep->discreteRealVars.length());
397 }
398
399
is_null() const400 inline bool SurrogateDataVars::is_null() const
401 { return (sdvRep) ? false : true; }
402
403
404 /// The representation of a surrogate data response. This representation,
405 /// or body, may be shared by multiple SurrogateDataResp handle instances.
406
407 /** The SurrogateDataResp/SurrogateDataRespRep pairs utilize a
408 handle-body idiom (Coplien, Advanced C++). */
409
410 class SurrogateDataRespRep
411 {
412 //
413 //- Heading: Friends
414 //
415
416 /// the handle class can access attributes of the body class directly
417 friend class SurrogateDataResp;
418
419 public:
420 /// destructor
421 ~SurrogateDataRespRep();
422
423 private:
424
425 //
426 //- Heading: Private member functions
427 //
428
429 /// constructor
430 SurrogateDataRespRep(Real fn_val, const RealVector& fn_grad,
431 const RealSymMatrix& fn_hess, short bits, short mode);
432 /// lightweight constructor (common use case)
433 SurrogateDataRespRep(Real fn_val);
434 /// alternate constructor (data sizing only)
435 SurrogateDataRespRep(short bits, size_t num_vars);
436
437 //
438 //- Heading: Private data members
439 //
440
441 short activeBits; ///< active data bits: 1 (fn), 2 (grad), 4 (hess)
442 Real responseFn; ///< truth response function value
443 RealVector responseGrad; ///< truth response function gradient
444 RealSymMatrix responseHess; ///< truth response function Hessian
445 };
446
447
448 inline SurrogateDataRespRep::
SurrogateDataRespRep(Real fn_val,const RealVector & fn_grad,const RealSymMatrix & fn_hess,short bits,short mode)449 SurrogateDataRespRep(Real fn_val, const RealVector& fn_grad,
450 const RealSymMatrix& fn_hess, short bits, short mode):
451 responseFn(fn_val), // always deep copy for scalars
452 activeBits(bits)
453 {
454 // Note: provided a way to query incoming grad/hess DataAccess modes,
455 // could make greater use of operator= for {DEEP,SHALLOW}_COPY modes
456 if (mode == DEEP_COPY) { // enforce vector/matrix deep copy
457 if (activeBits & 2) copy_data(fn_grad, responseGrad);
458 if (activeBits & 4) copy_data(fn_hess, responseHess);
459 }
460 else if (mode == SHALLOW_COPY) { // enforce vector/matrix shallow copy
461 if (activeBits & 2)
462 responseGrad = RealVector(Teuchos::View, fn_grad.values(),
463 fn_grad.length());
464 if (activeBits & 4)
465 responseHess = RealSymMatrix(Teuchos::View, fn_hess, fn_hess.numRows());
466 }
467 else { // default: assume existing Copy/View state
468 if (activeBits & 2) responseGrad = fn_grad;
469 if (activeBits & 4) responseHess = fn_hess;
470 }
471 }
472
473
SurrogateDataRespRep(Real fn_val)474 inline SurrogateDataRespRep::SurrogateDataRespRep(Real fn_val):
475 responseFn(fn_val), // always deep copy for scalars
476 activeBits(1)
477 { }
478
479
480 inline SurrogateDataRespRep::
SurrogateDataRespRep(short bits,size_t num_vars)481 SurrogateDataRespRep(short bits, size_t num_vars):
482 activeBits(bits)
483 {
484 if (bits & 2)
485 responseGrad.sizeUninitialized(num_vars);
486 if (bits & 4)
487 responseHess.shapeUninitialized(num_vars);
488 }
489
490
~SurrogateDataRespRep()491 inline SurrogateDataRespRep::~SurrogateDataRespRep()
492 { }
493
494
495 /// Container class encapsulating basic parameter and response data
496 /// for defining a "truth" data point.
497
498 /** A list of these data points is contained in Approximation instances
499 (e.g., Dakota::Approximation::currentPoints) and provides the data
500 to build the approximation. A handle-body idiom is used to avoid
501 excessive data copying overhead. */
502
503 class SurrogateDataResp
504 {
505 public:
506
507 //
508 //- Heading: Constructors, destructor, and operators
509 //
510
511 /// default constructor
512 SurrogateDataResp();
513 /// standard constructor
514 SurrogateDataResp(Real fn_val, const RealVector& fn_grad,
515 const RealSymMatrix& fn_hess, short bits,
516 short mode = DEFAULT_COPY);
517 /// lightweight constructor
518 SurrogateDataResp(Real fn_val);
519 /// alternate constructor (data sizing only)
520 SurrogateDataResp(short bits, size_t num_vars);
521 /// copy constructor
522 SurrogateDataResp(const SurrogateDataResp& sdr);
523 /// destructor
524 ~SurrogateDataResp();
525
526 /// assignment operator
527 SurrogateDataResp& operator=(const SurrogateDataResp& sdr);
528 // equality operator
529 //bool operator==(const SurrogateDataResp& sdr) const;
530
531 //
532 //- Heading: member functions
533 //
534
535 /// instantiate a sdvRep
536 void create_rep(short bits, size_t num_vars);
537
538 /// return deep copy of SurrogateDataResp instance
539 SurrogateDataResp copy() const;
540
541 /// set activeBits
542 void active_bits(short val);
543 /// get activeBits
544 short active_bits() const;
545
546 /// size response{Grad,Hess}
547 void derivative_variables(size_t num_v);
548 /// return size of response{Grad,Hess} (0 if inactive)
549 size_t derivative_variables() const;
550
551 /// set responseFn
552 void response_function(Real fn);
553 /// get responseFn
554 Real response_function() const;
555 /// get "view" of responseFn for updating in place
556 Real& response_function_view();
557
558 /// set i^{th} entry within responseGrad
559 void response_gradient(Real grad_i, size_t i);
560 /// set responseGrad
561 void response_gradient(const RealVector& grad, short mode = DEFAULT_COPY);
562 /// get responseGrad
563 const RealVector& response_gradient() const;
564 /// get view of responseGrad for updating in place
565 RealVector response_gradient_view();
566
567 /// set i-j^{th} entry within responseHess
568 void response_hessian(Real hess_ij, size_t i, size_t j);
569 /// set responseHess
570 void response_hessian(const RealSymMatrix& hess, short mode = DEFAULT_COPY);
571 /// get responseHess
572 const RealSymMatrix& response_hessian() const;
573 /// get view of responseHess for updating in place
574 RealSymMatrix response_hessian_view();
575
576 /// function to check sdrRep (does this handle contain a body)
577 bool is_null() const;
578 /// output response function, gradient, and Hessian data
579 void write(std::ostream& s) const;
580
581 private:
582
583 //
584 //- Heading: Private data members
585 //
586
587 /// pointer to the body (handle-body idiom)
588 std::shared_ptr<SurrogateDataRespRep> sdrRep;
589 };
590
591
SurrogateDataResp()592 inline SurrogateDataResp::SurrogateDataResp()
593 { }
594
595 // BMA NOTE: The following don't use make_shared<SurrogateDataRespRep>()
596 // due to private ctors
597
598 inline SurrogateDataResp::
SurrogateDataResp(Real fn_val,const RealVector & fn_grad,const RealSymMatrix & fn_hess,short bits,short mode)599 SurrogateDataResp(Real fn_val, const RealVector& fn_grad,
600 const RealSymMatrix& fn_hess, short bits, short mode):
601 sdrRep(new SurrogateDataRespRep(fn_val, fn_grad, fn_hess, bits, mode))
602 { }
603
604
SurrogateDataResp(Real fn_val)605 inline SurrogateDataResp::SurrogateDataResp(Real fn_val):
606 sdrRep(new SurrogateDataRespRep(fn_val))
607 { }
608
609
610 inline SurrogateDataResp::
SurrogateDataResp(short bits,size_t num_vars)611 SurrogateDataResp(short bits, size_t num_vars):
612 sdrRep(new SurrogateDataRespRep(bits, num_vars))
613 { }
614
615
SurrogateDataResp(const SurrogateDataResp & sdr)616 inline SurrogateDataResp::SurrogateDataResp(const SurrogateDataResp& sdr):
617 sdrRep(sdr.sdrRep)
618 { }
619
620
~SurrogateDataResp()621 inline SurrogateDataResp::~SurrogateDataResp()
622 { }
623
624
625 inline SurrogateDataResp& SurrogateDataResp::
operator =(const SurrogateDataResp & sdr)626 operator=(const SurrogateDataResp& sdr)
627 {
628 sdrRep = sdr.sdrRep;
629 return *this;
630 }
631
632
633 //inline bool SurrogateDataResp::operator==(const SurrogateDataResp& sdr) const
634 //{
635 // return ( sdrRep->responseFn == sdr.sdrRep->responseFn &&
636 // sdrRep->responseGrad == sdr.sdrRep->responseGrad &&
637 // sdrRep->responseHess == sdr.sdrRep->responseHess ) ? true : false;
638 //}
639
640
create_rep(short bits,size_t num_vars)641 inline void SurrogateDataResp::create_rep(short bits, size_t num_vars)
642 { sdrRep.reset(new SurrogateDataRespRep(bits, num_vars)); }
643
644
645 /// deep copy of SurrogateDataResp instance
copy() const646 inline SurrogateDataResp SurrogateDataResp::copy() const
647 {
648 SurrogateDataResp sdr(sdrRep->responseFn, sdrRep->responseGrad,
649 sdrRep->responseHess, sdrRep->activeBits, DEEP_COPY);
650 return sdr;
651 }
652
653
active_bits(short val)654 inline void SurrogateDataResp::active_bits(short val)
655 { sdrRep->activeBits = val; }
656
657
active_bits() const658 inline short SurrogateDataResp::active_bits() const
659 { return sdrRep->activeBits; }
660
661
derivative_variables(size_t num_v)662 inline void SurrogateDataResp::derivative_variables(size_t num_v)
663 {
664 if (sdrRep->activeBits & 2)
665 sdrRep->responseGrad.sizeUninitialized(num_v);
666 if (sdrRep->activeBits & 4)
667 sdrRep->responseHess.shapeUninitialized(num_v);
668 }
669
670
derivative_variables() const671 inline size_t SurrogateDataResp::derivative_variables() const
672 {
673 return std::max(sdrRep->responseGrad.length(),
674 sdrRep->responseHess.numRows());
675 }
676
677
response_function(Real fn)678 inline void SurrogateDataResp::response_function(Real fn)
679 { sdrRep->responseFn = fn; }
680
681
response_function() const682 inline Real SurrogateDataResp::response_function() const
683 { return sdrRep->responseFn; }
684
685
response_function_view()686 inline Real& SurrogateDataResp::response_function_view()
687 { return sdrRep->responseFn; }
688
689
response_gradient(Real grad_i,size_t i)690 inline void SurrogateDataResp::response_gradient(Real grad_i, size_t i)
691 { sdrRep->responseGrad[i] = grad_i; }
692
693
694 inline void SurrogateDataResp::
response_gradient(const RealVector & grad,short mode)695 response_gradient(const RealVector& grad, short mode)
696 {
697 if (mode == DEEP_COPY) // enforce vector deep copy
698 copy_data(grad, sdrRep->responseGrad);
699 else if (mode == SHALLOW_COPY) // enforce vector shallow copy
700 sdrRep->responseGrad
701 = RealVector(Teuchos::View, grad.values(), grad.length());
702 else // default: assume existing Copy/View state
703 sdrRep->responseGrad = grad;
704 }
705
706
response_gradient() const707 inline const RealVector& SurrogateDataResp::response_gradient() const
708 { return sdrRep->responseGrad; }
709
710
response_gradient_view()711 inline RealVector SurrogateDataResp::response_gradient_view()
712 {
713 return RealVector(Teuchos::View, sdrRep->responseGrad.values(),
714 sdrRep->responseGrad.length());
715 }
716
717
718 inline void SurrogateDataResp::
response_hessian(Real hess_ij,size_t i,size_t j)719 response_hessian(Real hess_ij, size_t i, size_t j)
720 { sdrRep->responseHess(i,j) = hess_ij; }
721
722
723 inline void SurrogateDataResp::
response_hessian(const RealSymMatrix & hess,short mode)724 response_hessian(const RealSymMatrix& hess, short mode)
725 {
726 if (mode == DEEP_COPY) // enforce matrix deep copy
727 copy_data(hess, sdrRep->responseHess);
728 else if (mode == SHALLOW_COPY) // enforce matrix shallow copy
729 sdrRep->responseHess = RealSymMatrix(Teuchos::View, hess, hess.numRows());
730 else // default: assume existing Copy/View state
731 sdrRep->responseHess = hess;
732 }
733
734
response_hessian() const735 inline const RealSymMatrix& SurrogateDataResp::response_hessian() const
736 { return sdrRep->responseHess; }
737
738
response_hessian_view()739 inline RealSymMatrix SurrogateDataResp::response_hessian_view()
740 {
741 return RealSymMatrix(Teuchos::View, sdrRep->responseHess,
742 sdrRep->responseHess.numRows());
743 }
744
745
is_null() const746 inline bool SurrogateDataResp::is_null() const
747 { return (sdrRep) ? false : true; }
748
749
write(std::ostream & s) const750 inline void SurrogateDataResp::write(std::ostream& s) const
751 {
752 if (sdrRep->activeBits & 1)
753 s << "function value = " << std::setw(WRITE_PRECISION+7)
754 << sdrRep->responseFn << '\n';
755 if (sdrRep->activeBits & 2) {
756 s << "function gradient =\n";
757 write_data_trans(s, sdrRep->responseGrad, true, true, true);
758 }
759 if (sdrRep->activeBits & 4)
760 s << "function Hessian =\n" << sdrRep->responseHess;
761 }
762
763
764 /// std::ostream insertion operator for SurrogateDataResp
operator <<(std::ostream & s,const SurrogateDataResp & sdr)765 inline std::ostream& operator<<(std::ostream& s, const SurrogateDataResp& sdr)
766 { sdr.write(s); return s; }
767
768
769 /// Representation of management class for surrogate data defined from
770 /// input variable data and output response data.
771
772 /** Response sets are generally unique for each approximated response
773 function, but variable sets are often (but not always) replicated.
774 Thus the design accommodates the case where inputs and/or outputs
775 involve either shallow or deep copies. */
776
777 class SurrogateDataRep
778 {
779 //
780 //- Heading: Friends
781 //
782
783 /// the handle class can access attributes of the body class directly
784 friend class SurrogateData;
785
786 public:
787 ~SurrogateDataRep(); ///< destructor
788
789 private:
790
791 //
792 //- Heading: Constructors and destructor
793 //
794
795 SurrogateDataRep(); ///< constructor
796
797 //
798 //- Heading: Member functions
799 //
800
801 /// update {varsData,respData}Iter from activeKey
802 void update_active_iterators();
803
804 //
805 //- Heading: Private data members
806 //
807
808 /// database of reference variable data sets, with lookup by model/level index
809 std::map<UShortArray, SDVArray> varsData;
810 /// iterator to active entry within varsData
811 std::map<UShortArray, SDVArray>::iterator varsDataIter;
812 /// filtered database of variable data sets, a subset drawn from varsData
813 std::map<UShortArray, SDVArray> filteredVarsData;
814
815 /// database of reference response data sets, with lookup by model/level index
816 std::map<UShortArray, SDRArray> respData;
817 /// iterator to active entry within respData
818 std::map<UShortArray, SDRArray>::iterator respDataIter;
819 /// filtered database of response data sets, a subset drawn from respData
820 std::map<UShortArray, SDRArray> filteredRespData;
821
822 /// sets of popped variables data sets, with lookup by model/level index.
823 /// Each popped set is an SDVArray extracted from varsData.
824 std::map<UShortArray, SDVArrayDeque> poppedVarsData;
825 /// sets of popped response data sets, with lookup by model/level index.
826 /// Each popped set is an SDRArray extracted from respData.
827 std::map<UShortArray, SDRArrayDeque> poppedRespData;
828 /// a stack managing the number of points previously appended that
829 /// can be removed by calls to pop()
830 std::map<UShortArray, SizetArray> popCountStack;
831
832 /// database key indicating the currently active {SDV,SDR}Arrays.
833 /// the key is a multi-index managing multiple modeling dimensions
834 /// such as model form, doscretization level, etc.
835 UShortArray activeKey;
836
837 /// index of anchor point within {vars,resp}Data, _NPOS if none; for now,
838 /// we restrict anchor to reference data to simplify bookkeeping (assume
839 /// anchor does not migrate within pushed/popped data)
840 std::map<UShortArray, size_t> anchorIndex;
841
842 /// map from failed respData indices to failed data bits; defined
843 /// in sample_checks() and used for fault tolerance
844 std::map<UShortArray, SizetShortMap> failedRespData;
845 };
846
847
SurrogateDataRep()848 inline SurrogateDataRep::SurrogateDataRep()
849 { }
850
851
~SurrogateDataRep()852 inline SurrogateDataRep::~SurrogateDataRep()
853 { }
854
855
update_active_iterators()856 inline void SurrogateDataRep::update_active_iterators()
857 {
858 varsDataIter = varsData.find(activeKey);
859 if (varsDataIter == varsData.end()) {
860 std::pair<UShortArray, SDVArray> sdv_pair(activeKey, SDVArray());
861 varsDataIter = varsData.insert(sdv_pair).first;
862 }
863 respDataIter = respData.find(activeKey);
864 if (respDataIter == respData.end()) {
865 std::pair<UShortArray, SDRArray> sdr_pair(activeKey, SDRArray());
866 respDataIter = respData.insert(sdr_pair).first;
867 }
868 }
869
870
871 /// Management class for surrogate data defined from input variable
872 /// data and output response data.
873
874 /** Response sets are generally unique for each approximated response
875 function, but variable sets are often (but not always) replicated.
876 Thus the design accommodates the case where inputs and/or outputs
877 involve either shallow or deep copies. */
878
879 class SurrogateData
880 {
881 public:
882
883 //
884 //- Heading: Constructors, destructor, and operators
885 //
886
887 SurrogateData(); ///< default handle ctor (no body)
888 SurrogateData(bool handle); ///< handle + body constructor
889 SurrogateData(const UShortArray& key); ///< handle + body constructor
890 SurrogateData(const SurrogateData& sd); ///< copy constructor
891 ~SurrogateData(); ///< destructor
892
893 /// assignment operator
894 SurrogateData& operator=(const SurrogateData& sdv);
895
896 //
897 //- Heading: Member functions
898 //
899
900 /// copy incoming sd instance with options for shallow or deep copies
901 /// of the SurrogateData{Vars,Resp} objects
902 void copy(const SurrogateData& sd, short sdv_mode = DEEP_COPY,
903 short sdr_mode = DEEP_COPY) const;
904 /// returns a new SurrogateData instance with options for shallow or
905 /// deep copies of the SurrogateData{Vars,Resp} objects
906 SurrogateData copy(short sdv_mode = DEEP_COPY,
907 short sdr_mode = DEEP_COPY) const;
908 /// copy active data for incoming sd instance with options for
909 /// shallow or deep copies of the SurrogateData{Vars,Resp} objects
910 void copy_active(const SurrogateData& sd, short sdv_mode,
911 short sdr_mode) const;
912
913 void size_active_sdv(const SurrogateData& sd) const;
914 void copy_active_sdv(const SurrogateData& sd, short sdv_mode) const;
915 void copy_active_pop_sdv(const SurrogateData& sd, short sdv_mode) const;
916 void size_active_sdr(const SDRArray& sdr_array) const;
917 void size_active_sdr(const SurrogateData& sd) const;
918 void copy_active_sdr(const SurrogateData& sd, short sdr_mode) const;
919 void copy_active_pop_sdr(const SurrogateData& sd, short sdr_mode) const;
920
921 /// resize {vars,resp}Data
922 void resize(size_t num_pts, short bits, size_t num_vars);
923
924 /// augment {vars,resp}Data and define anchorIndex
925 void anchor_point(const SurrogateDataVars& sdv, const SurrogateDataResp& sdr);
926 /// set {vars,resp}Data
927 void data_points(const SDVArray& sdv_array, const SDRArray& sdr_array);
928
929 /// augment varsData and define anchorIndex
930 void anchor_variables(const SurrogateDataVars& sdv);
931 /// get varsData instance corresponding to anchorIndex
932 const SurrogateDataVars& anchor_variables() const;
933 /// augment respData and define anchorIndex
934 void anchor_response(const SurrogateDataResp& sdr);
935 /// get respData instance corresponding to anchorIndex
936 const SurrogateDataResp& anchor_response() const;
937
938 /// set varsData[activeKey]
939 void variables_data(const SDVArray& sdv_array);
940 /// get varsData[activeKey]
941 const SDVArray& variables_data() const;
942 /// get varsData[key]
943 const SDVArray& variables_data(const UShortArray& key) const;
944 /// get varsData[activeKey]
945 SDVArray& variables_data();
946
947 /// set respData[activeKey]
948 void response_data(const SDRArray& sdr_array);
949 /// get respData[activeKey]
950 const SDRArray& response_data() const;
951 /// get respData[key]
952 const SDRArray& response_data(const UShortArray& key) const;
953 /// get respData[activeKey]
954 SDRArray& response_data();
955
956 /// get varsData
957 const std::map<UShortArray, SDVArray>& variables_data_map() const;
958 /// build/return filteredVarsData, pulling aggregated/nonaggregated
959 /// keys from varsData
960 const std::map<UShortArray, SDVArray>&
961 filtered_variables_data_map(short mode) const;
962 /// set varsData
963 void variables_data_map(const std::map<UShortArray, SDVArray>& vars_map);
964
965 /// get respData
966 const std::map<UShortArray, SDRArray>& response_data_map() const;
967 /// build/return filteredRespData, pulling aggregated/synthetic/raw data
968 /// sets from respData
969 const std::map<UShortArray, SDRArray>&
970 filtered_response_data_map(short mode) const;
971 /// set respData
972 void response_data_map(const std::map<UShortArray, SDRArray>& resp_map);
973
974 /// return a particular key instance present within the
975 /// aggregated/synthetic/raw data subset (respData is used)
976 const UShortArray& filtered_key(short mode, size_t index) const;
977
978 /// push sdv onto end of varsData
979 void push_back(const SurrogateDataVars& sdv);
980 /// push sdr onto end of respData
981 void push_back(const SurrogateDataResp& sdr);
982 /// push {sdv,sdr} onto ends of {vars,resp}Data
983 void push_back(const SurrogateDataVars& sdv, const SurrogateDataResp& sdr);
984
985 /// remove the first entry from {vars,resp}Data, managing anchorIndex
986 /// Note: inefficient for std::vector's, but needed in rare cases.
987 void pop_front(size_t num_pop = 1);
988 /// remove the last entry from {vars,resp}Data, managing anchorIndex
989 void pop_back(size_t num_pop = 1);
990
991 /// remove num_pop_pts entries from ends of active entry in {vars,resp}Data
992 void pop(bool save_data = true);
993 /// remove num_pop_pts entries from ends of keyed entries in {vars,resp}Data
994 void pop(const UShort2DArray& keys, bool save_data);
995 /// return a previously popped data set (identified by index) to the
996 /// ends of active entry in {vars,resp}Data
997 void push(size_t index, bool erase_popped = true);
998 /// return previously popped data sets (identified by index) to the
999 /// ends of keyed entries in {vars,resp}Data
1000 void push(const UShort2DArray& keys, size_t index, bool erase_popped = true);
1001
1002 /// append count to popCountStack[activeKey]
1003 void pop_count(size_t count) const;
1004 /// return popCountStack[activeKey].back()
1005 size_t pop_count() const;
1006 /// assign popCountStack[activeKey]
1007 void pop_count_stack(const SizetArray& pop_count) const;
1008 /// return popCountStack[key]
1009 const SizetArray& pop_count_stack(const UShortArray& key) const;
1010 /// return popCountStack[activeKey]
1011 const SizetArray& pop_count_stack() const;
1012 /// assign popCountStack
1013 void pop_count_stack_map(
1014 const std::map<UShortArray, SizetArray>& pcs_map) const;
1015 /// return popCountStack
1016 const std::map<UShortArray, SizetArray>& pop_count_stack_map() const;
1017
1018 /// pop records from front of {vars,resp}Data to achieve target length,
1019 /// for each key in passed set
1020 void history_target(size_t target, const UShort2DArray& keys);
1021
1022 /// query presence of anchor indexed within {vars,resp}Data
1023 bool anchor() const;
1024 /// assign anchorIndex[activeKey] to incoming index
1025 void anchor_index(size_t index) const;
1026 /// assign anchorIndex[key] to incoming index
1027 void anchor_index(size_t index, const UShortArray& key) const;
1028 /// return anchorIndex[activeKey], if defined
1029 size_t anchor_index() const;
1030 /// return anchorIndex[key], if defined
1031 size_t anchor_index(const UShortArray& key) const;
1032 /// assign anchorIndex
1033 void anchor_index_map(const std::map<UShortArray, size_t>& ai_map) const;
1034 /// return anchorIndex
1035 const std::map<UShortArray, size_t>& anchor_index_map() const;
1036 /// erase anchorIndex[activeKey]
1037 void clear_anchor_index();
1038 /// erase anchorIndex[key]
1039 void clear_anchor_index(const UShortArray& key);
1040 /// erase anchorIndex for each key within passed set
1041 void clear_anchor_index(const UShort2DArray& keys);
1042
1043 /// return size of active key within {vars,resp}Data
1044 size_t points() const;
1045 /// return size of {vars,resp}Data instance corresponding to key
1046 size_t points(const UShortArray& key) const;
1047
1048 /// return total number of available data components
1049 size_t response_size() const;
1050 /// return number of failed data components
1051 size_t failed_response_size() const;
1052 /// return net number of active data components (total minus failed)
1053 size_t active_response_size() const;
1054
1055 /// return number of 1D arrays within popped{Vars,Resp}Data 2D arrays
1056 /// identified by key
1057 size_t popped_sets(const UShortArray& key) const;
1058 /// return number of 1D arrays within popped{Vars,Resp}Data 2D arrays
1059 /// identified by activeKey
1060 size_t popped_sets() const;
1061
1062 /// return number of gradient variables from size of gradient arrays
1063 size_t num_gradient_variables() const;
1064 /// return number of Hessian variables from size of Hessian arrays
1065 size_t num_hessian_variables() const;
1066 /// return number of derivative variables as indicated by size of
1067 /// gradient/Hessian arrays
1068 size_t num_derivative_variables() const;
1069
1070 /// convenience function used by data_checks() for respData
1071 void response_check(const SurrogateDataResp& sdr, short& failed_data) const;
1072 /// screen data sets for samples with Inf/Nan that should be excluded;
1073 /// defines failedRespData
1074 void data_checks() const;
1075 /// return failedRespData corresponding to active anchorIndex
1076 short failed_anchor_data() const;
1077 /// assign active failedRespData
1078 void failed_response_data(const SizetShortMap& fail_data) const;
1079 /// return failedRespData[key]
1080 const SizetShortMap& failed_response_data(const UShortArray& key) const;
1081 /// return failedRespData[activeKey]
1082 const SizetShortMap& failed_response_data() const;
1083
1084 /// assign activeKey and update active iterators
1085 void active_key(const UShortArray& key) const;
1086 /// return activeKey
1087 const UShortArray& active_key() const;
1088 /// searches for key and updates {vars,resp}DataIter only if found
1089 bool contains(const UShortArray& key);
1090
1091 /// clear active key within {vars,resp}Data
1092 void clear_active_data();
1093 /// clear a set of keys within {vars,resp}Data
1094 void clear_active_data(const UShort2DArray& keys);
1095 /// clear all inactive data within {vars,resp}Data
1096 void clear_inactive_data();
1097
1098 /// clear filtered{Vars,Resp}Data (shallow copy subsets of {vars,resp}Data)
1099 void clear_filtered();
1100
1101 /// clear active key within popped{Vars,Resp}Data
1102 void clear_active_popped();
1103 /// clear a set of keys within popped{Vars,Resp}Data
1104 void clear_active_popped(const UShort2DArray& keys);
1105 /// clear popped{Vars,Resp}Data and restore to initial popped state
1106 void clear_popped();
1107
1108 /// clear {vars,resp}Data and restore to initial data state
1109 void clear_data(bool initialize = true);
1110
1111 /// clear all keys for all maps and optionally restore to initial state
1112 void clear_all(bool initialize = true);
1113 /// invokes both clear_active_data() and clear_active_popped()
1114 void clear_all_active();
1115 /// invokes both clear_active_data(keys) and clear_active_popped(keys)
1116 void clear_all_active(const UShort2DArray& keys);
1117
1118 /// return sdRep
1119 std::shared_ptr<SurrogateDataRep> data_rep() const;
1120
1121 /// function to check sdRep (does this handle contain a body)
1122 bool is_null() const;
1123
1124 private:
1125
1126 //
1127 //- Heading: Member functions
1128 //
1129
1130 /// define or update anchorIndex[activeKey]
1131 size_t assign_anchor_index();
1132 /// retrieve anchorIndex[activeKey]
1133 size_t retrieve_anchor_index(bool hard_fail = false) const;
1134 /// retrieve anchorIndex[key]
1135 size_t retrieve_anchor_index(const UShortArray& key,
1136 bool hard_fail = false) const;
1137
1138 /// assign sdv within varsData[activeKey] at indicated index
1139 void assign_variables(const SurrogateDataVars& sdv, size_t index);
1140 /// assign sdr within respData[activeKey] at indicated index
1141 void assign_response(const SurrogateDataResp& sdr, size_t index);
1142
1143 /// set failedRespData
1144 void failed_response_data_map(
1145 const std::map<UShortArray, SizetShortMap>& fail_resp) const;
1146 /// get failedRespData
1147 const std::map<UShortArray, SizetShortMap>& failed_response_data_map() const;
1148
1149 /// set active poppedVarsData
1150 void popped_variables(const SDVArrayDeque& popped_vars);
1151 /// get active poppedVarsData
1152 const SDVArrayDeque& popped_variables() const;
1153 /// set active poppedRespData
1154 void popped_response(const SDRArrayDeque& popped_resp);
1155 /// get active poppedRespData
1156 const SDRArrayDeque& popped_response() const;
1157
1158 /// set poppedVarsData
1159 void popped_variables_map(
1160 const std::map<UShortArray, SDVArrayDeque>& popped_vars);
1161 /// get poppedVarsData
1162 const std::map<UShortArray, SDVArrayDeque>& popped_variables_map() const;
1163 /// set poppedRespData
1164 void popped_response_map(
1165 const std::map<UShortArray, SDRArrayDeque>& popped_resp);
1166 /// get poppedRespData
1167 const std::map<UShortArray, SDRArrayDeque>& popped_response_map() const;
1168
1169 /// helper function for an individual key
1170 void pop(SDVArray& sdv_array_ref, SDRArray& sdr_array_ref,
1171 const UShortArray& key, bool save_data);
1172 /// helper function for an individual key
1173 void push(SDVArray& sdv_array_ref, SDRArray& sdr_array_ref,
1174 const UShortArray& key, size_t index, bool erase_popped);
1175
1176 //
1177 //- Heading: Private data members
1178 //
1179
1180 /// pointer to the body (handle-body idiom)
1181 std::shared_ptr<SurrogateDataRep> sdRep;
1182 };
1183
1184
SurrogateData()1185 inline SurrogateData::SurrogateData()
1186 { }
1187
1188
1189 // BMA NOTE: The following don't use make_shared<SurrogateDataRep>()
1190 // due to private ctors
1191
SurrogateData(bool handle)1192 inline SurrogateData::SurrogateData(bool handle):
1193 sdRep(new SurrogateDataRep())
1194 { sdRep->update_active_iterators(); } // default activeKey is empty array
1195
1196
SurrogateData(const UShortArray & key)1197 inline SurrogateData::SurrogateData(const UShortArray& key):
1198 sdRep(new SurrogateDataRep())
1199 { active_key(key); }
1200
1201
SurrogateData(const SurrogateData & sd)1202 inline SurrogateData::SurrogateData(const SurrogateData& sd):
1203 sdRep(sd.sdRep)
1204 { }
1205
1206
~SurrogateData()1207 inline SurrogateData::~SurrogateData()
1208 { }
1209
1210
operator =(const SurrogateData & sd)1211 inline SurrogateData& SurrogateData::operator=(const SurrogateData& sd)
1212 {
1213 sdRep = sd.sdRep;
1214 return *this;
1215 }
1216
1217
active_key(const UShortArray & key) const1218 inline void SurrogateData::active_key(const UShortArray& key) const
1219 {
1220 if (sdRep->activeKey != key) {
1221 sdRep->activeKey = key;
1222 sdRep->update_active_iterators();
1223 }
1224 }
1225
1226
active_key() const1227 inline const UShortArray& SurrogateData::active_key() const
1228 { return sdRep->activeKey; }
1229
1230
contains(const UShortArray & key)1231 inline bool SurrogateData::contains(const UShortArray& key)
1232 {
1233 return (sdRep->varsData.find(key) == sdRep->varsData.end() ||
1234 sdRep->respData.find(key) == sdRep->respData.end()) ? false : true;
1235 }
1236
1237
1238 inline void SurrogateData::
data_points(const SDVArray & sdv_array,const SDRArray & sdr_array)1239 data_points(const SDVArray& sdv_array, const SDRArray& sdr_array)
1240 {
1241 sdRep->varsDataIter->second = sdv_array;
1242 sdRep->respDataIter->second = sdr_array;
1243 }
1244
1245
anchor_index(size_t index) const1246 inline void SurrogateData::anchor_index(size_t index) const
1247 {
1248 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1249 const UShortArray& key = sdRep->activeKey;
1250 std::map<UShortArray, size_t>::iterator anchor_it = anchor_index.find(key);
1251 if (anchor_it == anchor_index.end()) { // conditionally insert new record
1252 if (index != _NPOS)
1253 anchor_index[key] = index;
1254 }
1255 else // update existing record
1256 anchor_it->second = index;
1257 }
1258
1259
1260 inline void SurrogateData::
anchor_index(size_t index,const UShortArray & key) const1261 anchor_index(size_t index, const UShortArray& key) const
1262 {
1263 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1264 std::map<UShortArray, size_t>::iterator anchor_it = anchor_index.find(key);
1265 if (anchor_it == anchor_index.end()) { // conditionally insert new record
1266 if (index != _NPOS)
1267 anchor_index[key] = index;
1268 }
1269 else // update existing record
1270 anchor_it->second = index;
1271 }
1272
1273
anchor_index() const1274 inline size_t SurrogateData::anchor_index() const
1275 { return retrieve_anchor_index(false); }
1276
1277
anchor_index(const UShortArray & key) const1278 inline size_t SurrogateData::anchor_index(const UShortArray& key) const
1279 { return retrieve_anchor_index(key, false); }
1280
1281
1282 inline const std::map<UShortArray, size_t>& SurrogateData::
anchor_index_map() const1283 anchor_index_map() const
1284 { return sdRep->anchorIndex; }
1285
1286
1287 inline void SurrogateData::
anchor_index_map(const std::map<UShortArray,size_t> & ai_map) const1288 anchor_index_map(const std::map<UShortArray, size_t>& ai_map) const
1289 { sdRep->anchorIndex = ai_map; }
1290
1291
clear_anchor_index()1292 inline void SurrogateData::clear_anchor_index()
1293 { sdRep->anchorIndex.erase(sdRep->activeKey); }
1294
1295
clear_anchor_index(const UShortArray & key)1296 inline void SurrogateData::clear_anchor_index(const UShortArray& key)
1297 { sdRep->anchorIndex.erase(key); }
1298
1299
clear_anchor_index(const UShort2DArray & keys)1300 inline void SurrogateData::clear_anchor_index(const UShort2DArray& keys)
1301 {
1302 size_t k, num_k = keys.size();
1303 for (k=0; k<num_k; ++k)
1304 sdRep->anchorIndex.erase(keys[k]);
1305 }
1306
1307
assign_anchor_index()1308 inline size_t SurrogateData::assign_anchor_index()
1309 {
1310 // This is often called in sequence of assign_anchor_variables() and
1311 // assign_anchor_response() --> use points() for consistent indexing
1312 size_t index = points(); // push_back() to follow
1313 // This approach reassigns an existing anchor index to freshly appended
1314 // anchor data --> previous anchor data is preserved but demoted
1315 sdRep->anchorIndex[sdRep->activeKey] = index;
1316
1317 /*
1318 // This approach preserves a previously assigned anchor index, which is good
1319 // for a pair of assign_anchor_{variables,response}() calls, but bad if a
1320 // previous sdv/sdr anchor assignment has not been cleared --> a subsequent
1321 // assign_{variables,response}() will overwrite the previous data, corrupting
1322 // the history for multipoint approximations.
1323 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1324 const UShortArray& key = sdRep->activeKey;
1325 std::map<UShortArray, size_t>::iterator anchor_it = anchor_index.find(key);
1326 size_t index;
1327 if (anchor_it == anchor_index.end()) // no anchor defined
1328 anchor_index[key] = index = points();
1329 else {
1330 index = anchor_it->second;
1331 if (index == _NPOS) // reassign only if undefined, else preserve
1332 anchor_it->second = index = points();
1333 }
1334 */
1335
1336 return index;
1337 }
1338
1339
retrieve_anchor_index(bool hard_fail) const1340 inline size_t SurrogateData::retrieve_anchor_index(bool hard_fail) const
1341 {
1342 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1343 std::map<UShortArray, size_t>::iterator anchor_it
1344 = anchor_index.find(sdRep->activeKey);
1345 if (anchor_it == anchor_index.end() || anchor_it->second == _NPOS) {
1346 if (hard_fail) {
1347 PCerr << "Error: lookup failure in SurrogateData::retrieve_anchor_index"
1348 << "()." << std::endl;
1349 abort_handler(-1);
1350 }
1351 return _NPOS;
1352 }
1353 else
1354 return anchor_it->second;
1355 }
1356
1357
1358 inline size_t SurrogateData::
retrieve_anchor_index(const UShortArray & key,bool hard_fail) const1359 retrieve_anchor_index(const UShortArray& key, bool hard_fail) const
1360 {
1361 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1362 std::map<UShortArray, size_t>::iterator anchor_it = anchor_index.find(key);
1363 if (anchor_it == anchor_index.end() || anchor_it->second == _NPOS) {
1364 if (hard_fail) {
1365 PCerr << "Error: lookup failure in SurrogateData::retrieve_anchor_index"
1366 << "()." << std::endl;
1367 abort_handler(-1);
1368 }
1369 return _NPOS;
1370 }
1371 else
1372 return anchor_it->second;
1373 }
1374
1375
1376 inline void SurrogateData::
assign_variables(const SurrogateDataVars & sdv,size_t index)1377 assign_variables(const SurrogateDataVars& sdv, size_t index)
1378 {
1379 SDVArray& sdv_array = sdRep->varsDataIter->second;
1380 if (index == sdv_array.size() || index == _NPOS) sdv_array.push_back(sdv);
1381 else sdv_array[index] = sdv;
1382 }
1383
1384
1385 inline void SurrogateData::
assign_response(const SurrogateDataResp & sdr,size_t index)1386 assign_response(const SurrogateDataResp& sdr, size_t index)
1387 {
1388 SDRArray& sdr_array = sdRep->respDataIter->second;
1389 if (index == sdr_array.size() || index == _NPOS) sdr_array.push_back(sdr);
1390 else sdr_array[index] = sdr;
1391 }
1392
1393
1394 inline void SurrogateData::
anchor_point(const SurrogateDataVars & sdv,const SurrogateDataResp & sdr)1395 anchor_point(const SurrogateDataVars& sdv, const SurrogateDataResp& sdr)
1396 {
1397 size_t index = assign_anchor_index();
1398 assign_variables(sdv, index);
1399 assign_response(sdr, index);
1400 }
1401
1402
anchor_variables(const SurrogateDataVars & sdv)1403 inline void SurrogateData::anchor_variables(const SurrogateDataVars& sdv)
1404 {
1405 size_t index = assign_anchor_index();
1406 assign_variables(sdv, index);
1407 }
1408
1409
anchor_variables() const1410 inline const SurrogateDataVars& SurrogateData::anchor_variables() const
1411 {
1412 size_t index = retrieve_anchor_index(true); // abort on index error
1413 return sdRep->varsDataIter->second[index];
1414 }
1415
1416
anchor_response(const SurrogateDataResp & sdr)1417 inline void SurrogateData::anchor_response(const SurrogateDataResp& sdr)
1418 {
1419 size_t index = assign_anchor_index();
1420 assign_response(sdr, index);
1421 }
1422
1423
anchor_response() const1424 inline const SurrogateDataResp& SurrogateData::anchor_response() const
1425 {
1426 size_t index = retrieve_anchor_index(true); // abort on index error
1427 return sdRep->respDataIter->second[index];
1428 }
1429
1430
variables_data(const SDVArray & sdv_array)1431 inline void SurrogateData::variables_data(const SDVArray& sdv_array)
1432 { sdRep->varsDataIter->second = sdv_array; }
1433
1434
variables_data() const1435 inline const SDVArray& SurrogateData::variables_data() const
1436 { return sdRep->varsDataIter->second; }
1437
1438
1439 inline const SDVArray& SurrogateData::
variables_data(const UShortArray & key) const1440 variables_data(const UShortArray& key) const
1441 { return sdRep->varsData[key]; }
1442
1443
variables_data()1444 inline SDVArray& SurrogateData::variables_data()
1445 { return sdRep->varsDataIter->second; }
1446
1447
response_data(const SDRArray & sdr_array)1448 inline void SurrogateData::response_data(const SDRArray& sdr_array)
1449 { sdRep->respDataIter->second = sdr_array; }
1450
1451
response_data() const1452 inline const SDRArray& SurrogateData::response_data() const
1453 { return sdRep->respDataIter->second; }
1454
1455
1456 inline const SDRArray& SurrogateData::
response_data(const UShortArray & key) const1457 response_data(const UShortArray& key) const
1458 { return sdRep->respData[key]; }
1459
1460
response_data()1461 inline SDRArray& SurrogateData::response_data()
1462 { return sdRep->respDataIter->second; }
1463
1464
1465 inline const std::map<UShortArray, SDVArray>& SurrogateData::
variables_data_map() const1466 variables_data_map() const
1467 { return sdRep->varsData; }
1468
1469
1470 inline const std::map<UShortArray, SDVArray>& SurrogateData::
filtered_variables_data_map(short mode) const1471 filtered_variables_data_map(short mode) const
1472 {
1473 const std::map<UShortArray, SDVArray>& vars_map = sdRep->varsData;
1474 std::map<UShortArray, SDVArray>& filt_vars_map = sdRep->filteredVarsData;
1475 std::map<UShortArray, SDVArray>::const_iterator cit;
1476
1477 filt_vars_map.clear();
1478 switch (mode) {
1479 case AGGREGATED_DATA_FILTER:
1480 for (cit=vars_map.begin(); cit!=vars_map.end(); ++cit)
1481 if (DiscrepancyCalculator::aggregated_key(cit->first))
1482 filt_vars_map.insert(*cit);
1483 break;
1484 case SYNTHETIC_DATA_FILTER:
1485 for (cit=vars_map.begin(); cit!=vars_map.end(); ++cit)
1486 if (DiscrepancyCalculator::synthetic_key(cit->first))
1487 filt_vars_map.insert(*cit);
1488 break;
1489 case RAW_DATA_FILTER:
1490 for (cit=vars_map.begin(); cit!=vars_map.end(); ++cit)
1491 if (DiscrepancyCalculator::raw_data_key(cit->first))
1492 filt_vars_map.insert(*cit);
1493 break;
1494 case NO_FILTER:
1495 filt_vars_map = vars_map;
1496 break;
1497 }
1498 return filt_vars_map;
1499 }
1500
1501
1502 inline void SurrogateData::
variables_data_map(const std::map<UShortArray,SDVArray> & vars_map)1503 variables_data_map(const std::map<UShortArray, SDVArray>& vars_map)
1504 { sdRep->varsData = vars_map; }
1505
1506
1507 inline const std::map<UShortArray, SDRArray>& SurrogateData::
response_data_map() const1508 response_data_map() const
1509 { return sdRep->respData; }
1510
1511
1512 inline const std::map<UShortArray, SDRArray>& SurrogateData::
filtered_response_data_map(short mode) const1513 filtered_response_data_map(short mode) const
1514 {
1515 const std::map<UShortArray, SDRArray>& resp_map = sdRep->respData;
1516 std::map<UShortArray, SDRArray>& filt_resp_map = sdRep->filteredRespData;
1517 std::map<UShortArray, SDRArray>::const_iterator cit;
1518
1519 filt_resp_map.clear();
1520 switch (mode) {
1521 case AGGREGATED_DATA_FILTER:
1522 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit)
1523 if (DiscrepancyCalculator::aggregated_key(cit->first))
1524 filt_resp_map.insert(*cit);
1525 break;
1526 case SYNTHETIC_DATA_FILTER:
1527 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit)
1528 if (DiscrepancyCalculator::synthetic_key(cit->first))
1529 filt_resp_map.insert(*cit);
1530 break;
1531 case RAW_DATA_FILTER:
1532 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit)
1533 if (DiscrepancyCalculator::raw_data_key(cit->first))
1534 filt_resp_map.insert(*cit);
1535 break;
1536 case NO_FILTER:
1537 filt_resp_map = resp_map;
1538 break;
1539 }
1540 return filt_resp_map;
1541 }
1542
1543
1544 inline void SurrogateData::
response_data_map(const std::map<UShortArray,SDRArray> & resp_map)1545 response_data_map(const std::map<UShortArray, SDRArray>& resp_map)
1546 { sdRep->respData = resp_map; }
1547
1548
1549 inline const UShortArray& SurrogateData::
filtered_key(short mode,size_t index) const1550 filtered_key(short mode, size_t index) const
1551 {
1552 const std::map<UShortArray, SDRArray>& resp_map = sdRep->respData;
1553 std::map<UShortArray, SDRArray>::const_iterator cit;
1554
1555 size_t cntr = 0;
1556 switch (mode) {
1557 case AGGREGATED_DATA_FILTER:
1558 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit) {
1559 const UShortArray& key = cit->first;
1560 if (DiscrepancyCalculator::aggregated_key(key)) {
1561 if (cntr == index) return key;
1562 else ++cntr;
1563 }
1564 }
1565 break;
1566 case SYNTHETIC_DATA_FILTER:
1567 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit) {
1568 const UShortArray& key = cit->first;
1569 if (DiscrepancyCalculator::synthetic_key(key)) {
1570 if (cntr == index) return key;
1571 else ++cntr;
1572 }
1573 }
1574 break;
1575 case RAW_DATA_FILTER:
1576 for (cit=resp_map.begin(); cit!=resp_map.end(); ++cit) {
1577 const UShortArray& key = cit->first;
1578 if (DiscrepancyCalculator::raw_data_key(key)) {
1579 if (cntr == index) return key;
1580 else ++cntr;
1581 }
1582 }
1583 break;
1584 case NO_FILTER:
1585 cit = resp_map.begin();
1586 std::advance(cit, index);
1587 return cit->first;
1588 break;
1589 }
1590
1591 PCerr << "Error: index not reached in SurrogateData::filtered_key(mode,index)"
1592 << std::endl;
1593 abort_handler(-1);
1594 return resp_map.begin()->first; // dummy return for compiler
1595 }
1596
1597
push_back(const SurrogateDataVars & sdv)1598 inline void SurrogateData::push_back(const SurrogateDataVars& sdv)
1599 { sdRep->varsDataIter->second.push_back(sdv); }
1600
1601
push_back(const SurrogateDataResp & sdr)1602 inline void SurrogateData::push_back(const SurrogateDataResp& sdr)
1603 { sdRep->respDataIter->second.push_back(sdr); }
1604
1605
1606 inline void SurrogateData::
push_back(const SurrogateDataVars & sdv,const SurrogateDataResp & sdr)1607 push_back(const SurrogateDataVars& sdv, const SurrogateDataResp& sdr)
1608 {
1609 sdRep->varsDataIter->second.push_back(sdv);
1610 sdRep->respDataIter->second.push_back(sdr);
1611 }
1612
1613
pop_back(size_t num_pop)1614 inline void SurrogateData::pop_back(size_t num_pop)
1615 {
1616 SDVArray& sdv_array = sdRep->varsDataIter->second;
1617 SDRArray& sdr_array = sdRep->respDataIter->second;
1618 size_t len = std::min(sdv_array.size(), sdr_array.size());
1619 if (len < num_pop) {
1620 PCerr << "Error: insufficient size (" << len << ") for pop_back("
1621 << num_pop << ")." << std::endl;
1622 abort_handler(-1);
1623 }
1624
1625 size_t start = len - num_pop;
1626 SDVArray::iterator v_it = sdv_array.begin() + start;
1627 SDRArray::iterator r_it = sdr_array.begin() + start;
1628 sdv_array.erase(v_it, sdv_array.end());
1629 sdr_array.erase(r_it, sdr_array.end());
1630
1631 if (retrieve_anchor_index() >= start) // popped point was anchor
1632 clear_anchor_index();
1633 }
1634
1635
pop_front(size_t num_pop)1636 inline void SurrogateData::pop_front(size_t num_pop)
1637 {
1638 SDVArray& sdv_array = sdRep->varsDataIter->second;
1639 SDRArray& sdr_array = sdRep->respDataIter->second;
1640 size_t len = std::min(sdv_array.size(), sdr_array.size());
1641 if (len < num_pop) {
1642 PCerr << "Error: insufficient size (" << len << ") for pop_front("
1643 << num_pop << ")." << std::endl;
1644 abort_handler(-1);
1645 }
1646
1647 SDVArray::iterator v_it = sdv_array.begin();
1648 SDRArray::iterator r_it = sdr_array.begin();
1649 sdv_array.erase(v_it, v_it + num_pop);
1650 sdr_array.erase(r_it, r_it + num_pop);
1651
1652 size_t index = retrieve_anchor_index();
1653 if (index < num_pop) // anchor has been popped
1654 clear_anchor_index();
1655 else if (index != _NPOS) // anchor (still) exists, decrement its index
1656 anchor_index(index - num_pop);
1657 }
1658
1659
1660 inline void SurrogateData::
history_target(size_t target,const UShort2DArray & keys)1661 history_target(size_t target, const UShort2DArray& keys)
1662 {
1663 size_t k, num_k = keys.size(), len, num_pops;
1664 SDVArray::iterator v_start, v_end; SDRArray::iterator r_start, r_end;
1665 for (k=0; k<num_k; ++k) {
1666 const UShortArray& key_k = keys[k];
1667 SDVArray& sdv_array = sdRep->varsData[key_k];
1668 SDRArray& sdr_array = sdRep->respData[key_k];
1669 len = std::min(sdv_array.size(), sdr_array.size());
1670 if (len > target) {
1671 // erase oldest data (pop from front of array)
1672 num_pops = len - target;
1673 v_start = v_end = sdv_array.begin(); std::advance(v_end, num_pops);
1674 r_start = r_end = sdr_array.begin(); std::advance(r_end, num_pops);
1675 sdv_array.erase(v_start, v_end); sdr_array.erase(r_start, r_end);
1676
1677 // Avoid multiple lookups
1678 std::map<UShortArray, size_t>& anchor_index = sdRep->anchorIndex;
1679 std::map<UShortArray, size_t>::iterator anchor_it
1680 = anchor_index.find(key_k);
1681 if (anchor_it != anchor_index.end() && anchor_it->second != _NPOS) {
1682 if (anchor_it->second < num_pops) // a popped point was anchor
1683 anchor_index.erase(anchor_it);//(key_k);
1684 else // anchor still exists, decrement its index
1685 anchor_it->second -= num_pops;
1686 }
1687 /*
1688 anch_index = retrieve_anchor_index(key_k);
1689 if (anch_index < num_pops) // a popped point was anchor
1690 clear_anchor_index(key_k);
1691 else if (anch_index != _NPOS) // anchor still exists, decrement its index
1692 anchor_index(anch_index - num_pops, key_k);
1693 */
1694 }
1695 }
1696 }
1697
1698
1699 inline void SurrogateData::
pop(SDVArray & sdv_array_ref,SDRArray & sdr_array_ref,const UShortArray & key,bool save_data)1700 pop(SDVArray& sdv_array_ref, SDRArray& sdr_array_ref, const UShortArray& key,
1701 bool save_data)
1702 {
1703 size_t num_ref_pts = std::min(sdv_array_ref.size(), sdr_array_ref.size());
1704
1705 // harden logic for case of an empty SurrogateData (e.g.,
1706 // distinct discrepancy at level 0)
1707 std::map<UShortArray, SizetArray>::iterator it
1708 = sdRep->popCountStack.find(key);
1709 if (it == sdRep->popCountStack.end()) {
1710 if (num_ref_pts == 0)
1711 return; // assume inactive SurrogateData -> ignore pop request
1712 else {
1713 PCerr << "\nError: active count stack not found in SurrogateData::pop() "
1714 << "for key:\n" << key << std::flush;
1715 abort_handler(-1);
1716 }
1717 }
1718
1719 SizetArray& pop_count_stack = it->second;
1720 if (pop_count_stack.empty()) {
1721 PCerr << "\nError: empty count stack in SurrogateData::pop() for key:\n"
1722 << key << std::flush;
1723 abort_handler(-1);
1724 }
1725 size_t num_pop_pts = pop_count_stack.back();
1726 if (num_pop_pts) {
1727 if (num_ref_pts < num_pop_pts) {
1728 PCerr << "Error: pop count (" << num_pop_pts << ") exceeds data size ("
1729 << num_ref_pts << ") in SurrogateData::pop(size_t) for key:\n"
1730 << key << std::flush;
1731 abort_handler(-1);
1732 }
1733 SDVArrayDeque& popped_sdv_arrays = sdRep->poppedVarsData[key];
1734 SDRArrayDeque& popped_sdr_arrays = sdRep->poppedRespData[key];
1735 if (save_data) {
1736 // append empty arrays and then update them in place
1737 popped_sdv_arrays.push_back(SDVArray());
1738 popped_sdr_arrays.push_back(SDRArray());
1739 SDVArray& last_popped_sdv_array = popped_sdv_arrays.back();
1740 SDRArray& last_popped_sdr_array = popped_sdr_arrays.back();
1741 SDVArray::iterator v_end = sdv_array_ref.end();
1742 SDRArray::iterator r_end = sdr_array_ref.end();
1743 last_popped_sdv_array.insert(last_popped_sdv_array.begin(),
1744 v_end - num_pop_pts, v_end);
1745 last_popped_sdr_array.insert(last_popped_sdr_array.begin(),
1746 r_end - num_pop_pts, r_end);
1747 }
1748 size_t new_size = num_ref_pts - num_pop_pts;
1749 sdv_array_ref.resize(new_size); sdr_array_ref.resize(new_size);
1750
1751 // TO DO: prune failedRespData[key] or leave in map ?
1752 data_checks(); // from scratch for now...
1753 }
1754 pop_count_stack.pop_back();
1755 }
1756
1757
pop(bool save_data)1758 inline void SurrogateData::pop(bool save_data)
1759 {
1760 pop(sdRep->varsDataIter->second, sdRep->respDataIter->second,
1761 sdRep->activeKey, save_data);
1762 }
1763
1764
pop(const UShort2DArray & keys,bool save_data)1765 inline void SurrogateData::pop(const UShort2DArray& keys, bool save_data)
1766 {
1767 size_t k, num_k = keys.size();
1768 for (k=0; k<num_k; ++k) {
1769 const UShortArray& key_k = keys[k];
1770 pop(sdRep->varsData[key_k], sdRep->respData[key_k], key_k, save_data);
1771 }
1772 }
1773
1774
1775 inline void SurrogateData::
push(SDVArray & sdv_array_ref,SDRArray & sdr_array_ref,const UShortArray & key,size_t index,bool erase_popped)1776 push(SDVArray& sdv_array_ref, SDRArray& sdr_array_ref, const UShortArray& key,
1777 size_t index, bool erase_popped)
1778 {
1779 std::map<UShortArray, SDVArrayDeque>::iterator pvd_it
1780 = sdRep->poppedVarsData.find(key);
1781 std::map<UShortArray, SDRArrayDeque>::iterator prd_it
1782 = sdRep->poppedRespData.find(key);
1783 size_t num_popped
1784 = (pvd_it != sdRep->poppedVarsData.end() &&
1785 prd_it != sdRep->poppedRespData.end()) ?
1786 std::min(pvd_it->second.size(), prd_it->second.size()) : 0;
1787
1788 // harden logic for case of an empty SurrogateData (e.g.,
1789 // distinct discrepancy at level 0)
1790 if (num_popped > index) {
1791 SDVArrayDeque& popped_sdv_arrays = pvd_it->second;
1792 SDRArrayDeque& popped_sdr_arrays = prd_it->second;
1793 SDVArrayDeque::iterator vit = popped_sdv_arrays.begin();
1794 SDRArrayDeque::iterator rit = popped_sdr_arrays.begin();
1795 std::advance(vit, index); std::advance(rit, index);
1796 size_t num_pts = std::min(vit->size(), rit->size());
1797
1798 sdv_array_ref.insert(sdv_array_ref.end(), vit->begin(), vit->end());
1799 sdr_array_ref.insert(sdr_array_ref.end(), rit->begin(), rit->end());
1800
1801 // TO DO: update failedRespData[activeKey] ?
1802 data_checks(); // from scratch for now...
1803
1804 if (erase_popped)
1805 { popped_sdv_arrays.erase(vit); popped_sdr_arrays.erase(rit); }
1806
1807 sdRep->popCountStack[key].push_back(num_pts);
1808 }
1809 else if (num_popped) { // not empty
1810 PCerr << "Error: index out of range for active popped arrays in "
1811 << "SurrogateData::push()." << std::endl;
1812 abort_handler(-1);
1813 }
1814 // else ignore push request for empty popped (SurrogateData assumed inactive)
1815 }
1816
1817
push(size_t index,bool erase_popped)1818 inline void SurrogateData::push(size_t index, bool erase_popped)
1819 {
1820 push(sdRep->varsDataIter->second, sdRep->respDataIter->second,
1821 sdRep->activeKey, index, erase_popped);
1822 }
1823
1824
1825 inline void SurrogateData::
push(const UShort2DArray & keys,size_t index,bool erase_popped)1826 push(const UShort2DArray& keys, size_t index, bool erase_popped)
1827 {
1828 size_t k, num_k = keys.size();
1829 for (k=0; k<num_k; ++k) {
1830 const UShortArray& key_k = keys[k];
1831 push(sdRep->varsData[key_k], sdRep->respData[key_k], key_k,
1832 index, erase_popped);
1833 }
1834 }
1835
1836
pop_count(size_t count) const1837 inline void SurrogateData::pop_count(size_t count) const
1838 { sdRep->popCountStack[sdRep->activeKey].push_back(count); }
1839
1840
pop_count() const1841 inline size_t SurrogateData::pop_count() const
1842 {
1843 std::map<UShortArray, SizetArray>::iterator pop_it
1844 = sdRep->popCountStack.find(sdRep->activeKey);
1845 return (pop_it == sdRep->popCountStack.end() || pop_it->second.empty()) ?
1846 _NPOS : pop_it->second.back();
1847 }
1848
1849
1850 inline const SizetArray& SurrogateData::
pop_count_stack(const UShortArray & key) const1851 pop_count_stack(const UShortArray& key) const
1852 { return sdRep->popCountStack[key]; }
1853
1854
pop_count_stack() const1855 inline const SizetArray& SurrogateData::pop_count_stack() const
1856 { return pop_count_stack(sdRep->activeKey); }
1857
1858
pop_count_stack(const SizetArray & pop_count) const1859 inline void SurrogateData::pop_count_stack(const SizetArray& pop_count) const
1860 { sdRep->popCountStack[sdRep->activeKey] = pop_count; }
1861
1862
1863 inline void SurrogateData::
pop_count_stack_map(const std::map<UShortArray,SizetArray> & pcs_map) const1864 pop_count_stack_map(const std::map<UShortArray, SizetArray>& pcs_map) const
1865 { sdRep->popCountStack = pcs_map; }
1866
1867
1868 inline const std::map<UShortArray, SizetArray>& SurrogateData::
pop_count_stack_map() const1869 pop_count_stack_map() const
1870 { return sdRep->popCountStack; }
1871
1872
anchor() const1873 inline bool SurrogateData::anchor() const
1874 {
1875 std::map<UShortArray, size_t>::iterator anchor_it
1876 = sdRep->anchorIndex.find(sdRep->activeKey);
1877 return (anchor_it == sdRep->anchorIndex.end() || anchor_it->second == _NPOS)
1878 ? false : true;
1879 }
1880
1881
points() const1882 inline size_t SurrogateData::points() const
1883 {
1884 return std::min(sdRep->varsDataIter->second.size(),
1885 sdRep->respDataIter->second.size());
1886 }
1887
1888
points(const UShortArray & key) const1889 inline size_t SurrogateData::points(const UShortArray& key) const
1890 {
1891 std::map<UShortArray, SDVArray>::const_iterator sdv_it
1892 = sdRep->varsData.find(key);
1893 std::map<UShortArray, SDRArray>::const_iterator sdr_it
1894 = sdRep->respData.find(key);
1895 return (sdv_it == sdRep->varsData.end() || sdr_it == sdRep->respData.end()) ?
1896 0 : std::min(sdv_it->second.size(), sdr_it->second.size());
1897 }
1898
1899
response_size() const1900 inline size_t SurrogateData::response_size() const
1901 {
1902 const SDRArray& sdr_array = sdRep->respDataIter->second;
1903 size_t i, data_size = 0, num_resp = sdr_array.size(), nh;
1904 short active_bits;
1905 for (i=0; i<num_resp; ++i) {
1906 const SurrogateDataResp& sdr = sdr_array[i];
1907 active_bits = sdr.active_bits();
1908 if (active_bits & 1) ++data_size;
1909 if (active_bits & 2) data_size += sdr.response_gradient().length();
1910 if (active_bits & 4) {
1911 nh = sdr.response_hessian().numRows();
1912 if (nh) data_size += nh * (nh + 1) / 2;
1913 }
1914 }
1915 return data_size;
1916 }
1917
1918
failed_response_size() const1919 inline size_t SurrogateData::failed_response_size() const
1920 {
1921 const SDRArray& sdr_array = sdRep->respDataIter->second;
1922 size_t failed_size = 0, nh; short fail_bits;
1923 const SizetShortMap& failed_resp = failed_response_data();
1924 for (StShMCIter cit=failed_resp.begin(); cit!=failed_resp.end(); ++cit) {
1925 fail_bits = cit->second;
1926 const SurrogateDataResp& sdr = sdr_array[cit->first];
1927 if (fail_bits & 1) ++failed_size;
1928 if (fail_bits & 2) failed_size += sdr.response_gradient().length();
1929 if (fail_bits & 4) {
1930 nh = sdr.response_hessian().numRows();
1931 if (nh) failed_size += nh * (nh + 1) / 2;
1932 }
1933 }
1934 return failed_size;
1935 }
1936
1937
active_response_size() const1938 inline size_t SurrogateData::active_response_size() const
1939 { return response_size() - failed_response_size(); }
1940
1941
popped_sets(const UShortArray & key) const1942 inline size_t SurrogateData::popped_sets(const UShortArray& key) const
1943 {
1944 return std::min(sdRep->poppedVarsData[key].size(),
1945 sdRep->poppedRespData[key].size());
1946 }
1947
1948
popped_sets() const1949 inline size_t SurrogateData::popped_sets() const
1950 { return popped_sets(sdRep->activeKey); }
1951
1952
num_gradient_variables() const1953 inline size_t SurrogateData::num_gradient_variables() const
1954 {
1955 const SDRArray& sdr_array = sdRep->respDataIter->second;
1956 return (sdr_array.empty()) ? 0 : sdr_array[0].response_gradient().length();
1957 }
1958
1959
num_hessian_variables() const1960 inline size_t SurrogateData::num_hessian_variables() const
1961 {
1962 const SDRArray& sdr_array = sdRep->respDataIter->second;
1963 return (sdr_array.empty()) ? 0 : sdr_array[0].response_hessian().numRows();
1964 }
1965
1966
num_derivative_variables() const1967 inline size_t SurrogateData::num_derivative_variables() const
1968 {
1969 size_t num_grad_vars = num_gradient_variables();
1970 if (num_grad_vars) return num_grad_vars; // precedence
1971 else return num_hessian_variables(); // fall-back
1972 }
1973
1974
1975 inline void SurrogateData::
response_check(const SurrogateDataResp & sdr,short & failed_data) const1976 response_check(const SurrogateDataResp& sdr, short& failed_data) const
1977 {
1978 // We take a conservative approach of rejecting all data of derivative
1979 // order greater than or equal to a detected failure:
1980
1981 short resp_bits = sdr.active_bits();
1982 failed_data = 0;
1983 if (resp_bits & 1) {
1984 if (!boost::math::isfinite<Real>(sdr.response_function()))
1985 failed_data = resp_bits; // all data for this & higher deriv orders
1986 }
1987 if ( (resp_bits & 2) && !failed_data ) {
1988 const RealVector& grad = sdr.response_gradient();
1989 size_t j, num_deriv_vars = grad.length();
1990 for (j=0; j<num_deriv_vars; ++j)
1991 if (!boost::math::isfinite<Real>(grad[j]))
1992 { failed_data = (resp_bits & 6); break; } // this & higher deriv orders
1993 }
1994 if ( (resp_bits & 4) && !failed_data ) {
1995 const RealSymMatrix& hess = sdr.response_hessian();
1996 size_t j, k, num_deriv_vars = hess.numRows();
1997 for (j=0; j<num_deriv_vars; ++j)
1998 for (k=0; k<=j; ++k)
1999 if (!boost::math::isfinite<Real>(hess(j,k)))
2000 { failed_data = 4; break; } // this & higher deriv orders
2001 }
2002 }
2003
2004
data_checks() const2005 inline void SurrogateData::data_checks() const
2006 {
2007 const SDRArray& resp_data = sdRep->respDataIter->second;
2008 SizetShortMap& failed_resp = sdRep->failedRespData[sdRep->activeKey];
2009 failed_resp.clear();
2010 size_t i, num_resp = resp_data.size(); short failed_data;
2011 for (i=0; i<num_resp; ++i) {
2012 response_check(resp_data[i], failed_data);
2013 if (failed_data)
2014 failed_resp[i] = failed_data; // include in map
2015 }
2016
2017 #ifdef DEBUG
2018 PCout << "failedRespData:\n";
2019 for (SizetShortMap::iterator it=failed_resp.begin();
2020 it!=failed_resp.end(); ++it)
2021 PCout << "index: " << std::setw(6) << it->first
2022 << " data: " << it->second << '\n';
2023 #endif // DEBUG
2024 }
2025
2026
failed_anchor_data() const2027 inline short SurrogateData::failed_anchor_data() const
2028 {
2029 std::map<UShortArray, SizetShortMap>::const_iterator cit1
2030 = sdRep->failedRespData.find(sdRep->activeKey);
2031 if (cit1 == sdRep->failedRespData.end()) return 0;
2032 else {
2033 const SizetShortMap& failed_resp_data = cit1->second;
2034 SizetShortMap::const_iterator cit2 = failed_resp_data.find(anchor_index());
2035 return (cit2 == failed_resp_data.end()) ? 0 : cit2->second;
2036 }
2037 }
2038
2039
2040 inline void SurrogateData::
failed_response_data(const SizetShortMap & fail_data) const2041 failed_response_data(const SizetShortMap& fail_data) const
2042 { sdRep->failedRespData[sdRep->activeKey] = fail_data; }
2043
2044
2045 inline const SizetShortMap& SurrogateData::
failed_response_data(const UShortArray & key) const2046 failed_response_data(const UShortArray& key) const
2047 { return sdRep->failedRespData[key]; }
2048
2049
failed_response_data() const2050 inline const SizetShortMap& SurrogateData::failed_response_data() const
2051 { return failed_response_data(sdRep->activeKey); }
2052
2053
2054 inline void SurrogateData::
failed_response_data_map(const std::map<UShortArray,SizetShortMap> & fail_resp) const2055 failed_response_data_map(const std::map<UShortArray, SizetShortMap>& fail_resp)
2056 const
2057 { sdRep->failedRespData = fail_resp; }
2058
2059
2060 inline const std::map<UShortArray, SizetShortMap>& SurrogateData::
failed_response_data_map() const2061 failed_response_data_map() const
2062 { return sdRep->failedRespData; }
2063
2064
popped_variables() const2065 inline const SDVArrayDeque& SurrogateData::popped_variables() const
2066 {
2067 std::map<UShortArray, SDVArrayDeque>& pop_vars = sdRep->poppedVarsData;
2068 const UShortArray& key = sdRep->activeKey;
2069 std::map<UShortArray, SDVArrayDeque>::iterator cit = pop_vars.find(key);
2070 if (cit == pop_vars.end()) {
2071 std::pair<UShortArray, SDVArrayDeque> sdv_pair(key, SDVArrayDeque());
2072 cit = pop_vars.insert(sdv_pair).first; // create empty array for key
2073 }
2074 return cit->second;
2075 }
2076
2077
popped_variables(const SDVArrayDeque & popped_vars)2078 inline void SurrogateData::popped_variables(const SDVArrayDeque& popped_vars)
2079 { sdRep->poppedVarsData[sdRep->activeKey] = popped_vars; }
2080
2081
popped_response() const2082 inline const SDRArrayDeque& SurrogateData::popped_response() const
2083 {
2084 std::map<UShortArray, SDRArrayDeque>& pop_resp = sdRep->poppedRespData;
2085 const UShortArray& key = sdRep->activeKey;
2086 std::map<UShortArray, SDRArrayDeque>::iterator cit = pop_resp.find(key);
2087 if (cit == pop_resp.end()) {
2088 std::pair<UShortArray, SDRArrayDeque> sdr_pair(key, SDRArrayDeque());
2089 cit = pop_resp.insert(sdr_pair).first; // create empty array for key
2090 }
2091 return cit->second;
2092 }
2093
2094
2095 inline void SurrogateData::
popped_response(const SDRArrayDeque & popped_resp)2096 popped_response(const SDRArrayDeque& popped_resp)
2097 { sdRep->poppedRespData[sdRep->activeKey] = popped_resp; }
2098
2099
2100 inline const std::map<UShortArray, SDVArrayDeque>& SurrogateData::
popped_variables_map() const2101 popped_variables_map() const
2102 { return sdRep->poppedVarsData; }
2103
2104
2105 inline void SurrogateData::
popped_variables_map(const std::map<UShortArray,SDVArrayDeque> & popped_vars)2106 popped_variables_map(const std::map<UShortArray, SDVArrayDeque>& popped_vars)
2107 { sdRep->poppedVarsData = popped_vars; }
2108
2109
2110 inline const std::map<UShortArray, SDRArrayDeque>& SurrogateData::
popped_response_map() const2111 popped_response_map() const
2112 { return sdRep->poppedRespData; }
2113
2114
2115 inline void SurrogateData::
popped_response_map(const std::map<UShortArray,SDRArrayDeque> & popped_resp)2116 popped_response_map(const std::map<UShortArray, SDRArrayDeque>& popped_resp)
2117 { sdRep->poppedRespData = popped_resp; }
2118
2119
2120 inline void SurrogateData::
copy(const SurrogateData & sd,short sdv_mode,short sdr_mode) const2121 copy(const SurrogateData& sd, short sdv_mode, short sdr_mode) const
2122 {
2123 if (sdv_mode == DEEP_COPY) {
2124 size_t i, j, num_pts, num_sdva;
2125 const std::map<UShortArray, SDVArray>& vars_map = sd.variables_data_map();
2126 std::map<UShortArray, SDVArray>::const_iterator v_cit;
2127 std::map<UShortArray, SDVArray>& new_vars_map = sdRep->varsData;
2128 new_vars_map.clear();
2129 for (v_cit = vars_map.begin(); v_cit != vars_map.end(); ++v_cit) {
2130 const SDVArray& sdv_array = v_cit->second;
2131 num_pts = sdv_array.size();
2132 SDVArray new_sdv_array(num_pts);
2133 for (i=0; i<num_pts; ++i)
2134 new_sdv_array[i] = sdv_array[i].copy();
2135 new_vars_map[v_cit->first] = sdv_array;
2136 }
2137
2138 const std::map<UShortArray, SDVArrayDeque>& popped_vars_map
2139 = sd.popped_variables_map();
2140 std::map<UShortArray, SDVArrayDeque>::const_iterator v2_cit;
2141 std::map<UShortArray, SDVArrayDeque>& new_popped_vars_map
2142 = sdRep->poppedVarsData;
2143 new_popped_vars_map.clear();
2144 for (v2_cit = popped_vars_map.begin(); v2_cit != popped_vars_map.end();
2145 ++v2_cit) {
2146 const SDVArrayDeque& sdv_2d_array = v2_cit->second;
2147 num_sdva = sdv_2d_array.size();
2148 SDVArrayDeque new_popped_sdv_2d(num_sdva);
2149 for (i=0; i<num_sdva; ++i) {
2150 const SDVArray& sdva_i = sdv_2d_array[i];
2151 num_pts = sdva_i.size();
2152 new_popped_sdv_2d[i].resize(num_pts);
2153 for (j=0; j<num_pts; ++j)
2154 new_popped_sdv_2d[i][j] = sdva_i[j].copy();
2155 }
2156 new_popped_vars_map[v2_cit->first] = new_popped_sdv_2d;
2157 }
2158 }
2159 else { // shallow SDV copies based on operator=
2160 sdRep->varsData = sd.variables_data_map();
2161 sdRep->poppedVarsData = sd.popped_variables_map();
2162 }
2163
2164 if (sdr_mode == DEEP_COPY) {
2165 size_t i, j, num_pts, num_sdra;
2166 const std::map<UShortArray, SDRArray>& resp_map = sd.response_data_map();
2167 std::map<UShortArray, SDRArray>::const_iterator r_cit;
2168 std::map<UShortArray, SDRArray>& new_resp_map = sdRep->respData;
2169 new_resp_map.clear();
2170 for (r_cit = resp_map.begin(); r_cit != resp_map.end(); ++r_cit) {
2171 const SDRArray& sdr_array = r_cit->second;
2172 num_pts = sdr_array.size();
2173 SDRArray new_sdr_array(num_pts);
2174 for (i=0; i<num_pts; ++i)
2175 new_sdr_array[i] = sdr_array[i].copy();
2176 new_resp_map[r_cit->first] = new_sdr_array;
2177 }
2178
2179 const std::map<UShortArray, SDRArrayDeque>& popped_resp_map
2180 = sd.popped_response_map();
2181 std::map<UShortArray, SDRArrayDeque>::const_iterator r2_cit;
2182 std::map<UShortArray, SDRArrayDeque>& new_popped_resp_map
2183 = sdRep->poppedRespData;
2184 new_popped_resp_map.clear();
2185 for (r2_cit = popped_resp_map.begin(); r2_cit != popped_resp_map.end();
2186 ++r2_cit) {
2187 const SDRArrayDeque& sdr_2d_array = r2_cit->second;
2188 num_sdra = sdr_2d_array.size();
2189 SDRArrayDeque new_popped_sdr_2d(num_sdra);
2190 for (i=0; i<num_sdra; ++i) {
2191 const SDRArray& sdra_i = sdr_2d_array[i];
2192 num_pts = sdra_i.size();
2193 new_popped_sdr_2d[i].resize(num_pts);
2194 for (j=0; j<num_pts; ++j)
2195 new_popped_sdr_2d[i][j] = sdra_i[j].copy();
2196 }
2197 new_popped_resp_map[r2_cit->first] = new_popped_sdr_2d;
2198 }
2199 }
2200 else { // shallow SDR copies based on operator=
2201 sdRep->respData = sd.response_data_map();
2202 sdRep->poppedRespData = sd.popped_response_map();
2203 }
2204
2205 active_key(sd.active_key());
2206 pop_count_stack_map(sd.pop_count_stack_map());
2207 anchor_index_map(sd.anchor_index_map());
2208 failed_response_data_map(sd.failed_response_data_map());
2209 }
2210
2211
copy(short sdv_mode,short sdr_mode) const2212 inline SurrogateData SurrogateData::copy(short sdv_mode, short sdr_mode) const
2213 {
2214 SurrogateData sd;
2215 sd.copy(*this, sdv_mode, sdr_mode);
2216 return sd;
2217 }
2218
2219
2220 inline void SurrogateData::
copy_active(const SurrogateData & sd,short sdv_mode,short sdr_mode) const2221 copy_active(const SurrogateData& sd, short sdv_mode, short sdr_mode) const
2222 {
2223 const UShortArray& key = sd.active_key();
2224 if (sdRep->activeKey != key) active_key(key);
2225 copy_active_sdv(sd, sdv_mode);
2226 copy_active_pop_sdv(sd, sdv_mode);
2227 copy_active_sdr(sd, sdr_mode);
2228 copy_active_pop_sdr(sd, sdr_mode);
2229
2230 // deep copies of bookkeeping arrays
2231 anchor_index(sd.anchor_index());
2232 pop_count_stack(sd.pop_count_stack());
2233 failed_response_data(sd.failed_response_data());
2234 }
2235
2236
size_active_sdv(const SurrogateData & sd) const2237 inline void SurrogateData::size_active_sdv(const SurrogateData& sd) const
2238 {
2239 const UShortArray& key = sd.active_key();
2240 if (sdRep->activeKey != key) active_key(key);
2241
2242 const SDVArray& sdv_array = sd.variables_data();
2243 size_t num_pts = sdv_array.size();
2244 if (num_pts) {
2245 const SurrogateDataVars& sdv0 = sdv_array[0];
2246 size_t i, num_cv = sdv0.cv(), num_div = sdv0.div(), num_drv = sdv0.drv();
2247 SDVArray& new_sdv_array = sdRep->varsDataIter->second;
2248 new_sdv_array.resize(num_pts);
2249 for (i=0; i<num_pts; ++i)
2250 new_sdv_array[i] = SurrogateDataVars(num_cv, num_div, num_drv);
2251 }
2252 }
2253
2254
2255 inline void SurrogateData::
copy_active_sdv(const SurrogateData & sd,short sdv_mode) const2256 copy_active_sdv(const SurrogateData& sd, short sdv_mode) const
2257 {
2258 const UShortArray& key = sd.active_key();
2259 if (sdRep->activeKey != key) active_key(key);
2260
2261 SDVArray& new_sdv_array = sdRep->varsDataIter->second;
2262 if (sdv_mode == DEEP_COPY) {
2263 const SDVArray& sdv_array = sd.variables_data();
2264 size_t i, num_pts = sdv_array.size();
2265 new_sdv_array.resize(num_pts);
2266 for (i=0; i<num_pts; ++i)
2267 new_sdv_array[i] = sdv_array[i].copy();
2268 }
2269 else // shallow SDV copies based on operator=
2270 new_sdv_array = sd.variables_data();
2271 }
2272
2273
2274 inline void SurrogateData::
copy_active_pop_sdv(const SurrogateData & sd,short sdv_mode) const2275 copy_active_pop_sdv(const SurrogateData& sd, short sdv_mode) const
2276 {
2277 const UShortArray& key = sd.active_key();
2278 if (sdRep->activeKey != key) active_key(key);
2279
2280 SDVArrayDeque& new_pop_sdv_array = sdRep->poppedVarsData[key];
2281 if (sdv_mode == DEEP_COPY) {
2282 const SDVArrayDeque& pop_sdv_array = sd.popped_variables();
2283 size_t i, j, num_pts, num_sdva = pop_sdv_array.size();
2284 new_pop_sdv_array.resize(num_sdva);
2285 for (i=0; i<num_sdva; ++i) {
2286 const SDVArray& sdva_i = pop_sdv_array[i];
2287 num_pts = sdva_i.size();
2288 new_pop_sdv_array[i].resize(num_pts);
2289 for (j=0; j<num_pts; ++j)
2290 new_pop_sdv_array[i][j] = sdva_i[j].copy();
2291 }
2292 }
2293 else // shallow SDV copies based on operator=
2294 new_pop_sdv_array = sd.popped_variables();
2295 }
2296
2297
size_active_sdr(const SDRArray & sdr_array) const2298 inline void SurrogateData::size_active_sdr(const SDRArray& sdr_array) const
2299 {
2300 size_t num_pts = sdr_array.size();
2301 SDRArray& new_sdr_array = sdRep->respDataIter->second;
2302 new_sdr_array.resize(num_pts);
2303 if (num_pts) {
2304 const SurrogateDataResp& sdr0 = sdr_array[0];
2305 short bits = sdr0.active_bits(); // assume homogeneity in deriv data
2306 size_t i, num_deriv_v = sdr0.derivative_variables();
2307 for (i=0; i<num_pts; ++i)
2308 new_sdr_array[i] = SurrogateDataResp(bits, num_deriv_v);
2309 }
2310 }
2311
2312
size_active_sdr(const SurrogateData & sd) const2313 inline void SurrogateData::size_active_sdr(const SurrogateData& sd) const
2314 {
2315 const UShortArray& key = sd.active_key();
2316 if (sdRep->activeKey != key) active_key(key);
2317 size_active_sdr(sd.response_data());
2318 }
2319
2320
2321 inline void SurrogateData::
copy_active_sdr(const SurrogateData & sd,short sdr_mode) const2322 copy_active_sdr(const SurrogateData& sd, short sdr_mode) const
2323 {
2324 const UShortArray& key = sd.active_key();
2325 if (sdRep->activeKey != key) active_key(key);
2326
2327 SDRArray& new_sdr_array = sdRep->respDataIter->second;
2328 if (sdr_mode == DEEP_COPY) {
2329 const SDRArray& sdr_array = sd.response_data();
2330 size_t i, num_pts = sdr_array.size();
2331 new_sdr_array.resize(num_pts);
2332 for (i=0; i<num_pts; ++i)
2333 new_sdr_array[i] = sdr_array[i].copy();
2334 }
2335 else // shallow SDR copies based on operator=
2336 new_sdr_array = sd.response_data();
2337 }
2338
2339
2340 inline void SurrogateData::
copy_active_pop_sdr(const SurrogateData & sd,short sdr_mode) const2341 copy_active_pop_sdr(const SurrogateData& sd, short sdr_mode) const
2342 {
2343 const UShortArray& key = sd.active_key();
2344 if (sdRep->activeKey != key) active_key(key);
2345
2346 SDRArrayDeque& new_pop_sdr_array = sdRep->poppedRespData[key];
2347 if (sdr_mode == DEEP_COPY) {
2348 const SDRArrayDeque& pop_sdr_array = sd.popped_response();
2349 size_t i, j, num_pts, num_sdra = pop_sdr_array.size();
2350 new_pop_sdr_array.resize(num_sdra);
2351 for (i=0; i<num_sdra; ++i) {
2352 const SDRArray& sdra_i = pop_sdr_array[i];
2353 num_pts = sdra_i.size();
2354 new_pop_sdr_array[i].resize(num_pts);
2355 for (j=0; j<num_pts; ++j)
2356 new_pop_sdr_array[i][j] = sdra_i[j].copy();
2357 }
2358 }
2359 else // shallow SDR copies based on operator=
2360 new_pop_sdr_array = sd.popped_response();
2361 }
2362
2363
resize(size_t new_pts,short bits,size_t num_vars)2364 inline void SurrogateData::resize(size_t new_pts, short bits, size_t num_vars)
2365 {
2366 size_t i, pts = points();
2367 SDVArray& sdv_array = sdRep->varsDataIter->second;
2368 SDRArray& sdr_array = sdRep->respDataIter->second;
2369
2370 sdv_array.resize(new_pts); sdr_array.resize(new_pts);
2371 for (i=pts; i<new_pts; ++i) {
2372 // minimal ctors that define a rep and size arrays
2373 sdv_array[i].create_rep(num_vars);
2374 sdr_array[i].create_rep(bits, num_vars);
2375 }
2376 }
2377
2378
clear_active_data()2379 inline void SurrogateData::clear_active_data()
2380 {
2381 /*
2382 // Too aggressive due to DataFitSurrModel::build_approximation() call to
2383 // approxInterface.clear_current_active_data();
2384 const UShortArray& key = sdRep->activeKey;
2385 sdRep->varsData.erase(key);
2386 sdRep->varsDataIter = sdRep->varsData.end();
2387 sdRep->respData.erase(key);
2388 sdRep->respDataIter = sdRep->respData.end();
2389 sdRep->anchorIndex.erase(key);
2390 sdRep->failedRespData.erase(key);
2391 */
2392
2393 // Retain valid {vars,Resp}DataIter when clearing {vars,resp}Data:
2394 sdRep->varsDataIter->second.clear();
2395 sdRep->respDataIter->second.clear();
2396 // anchorIndex and failedRespData can be pruned:
2397 const UShortArray& key = sdRep->activeKey;
2398 sdRep->anchorIndex.erase(key); //sdRep->anchorIndex[key] = _NPOS;
2399 sdRep->failedRespData.erase(key);//sdRep->failedRespData[key].clear();
2400 }
2401
2402
clear_active_data(const UShort2DArray & keys)2403 inline void SurrogateData::clear_active_data(const UShort2DArray& keys)
2404 {
2405 // clear each passed key without disturbing the active key
2406 size_t k, num_k = keys.size();
2407 for (k=0; k<num_k; ++k) {
2408 const UShortArray& key_k = keys[k];
2409 // clear instead of erase
2410 sdRep->varsData[key_k].clear();
2411 sdRep->respData[key_k].clear();
2412 // can erase
2413 sdRep->anchorIndex.erase(key_k);
2414 sdRep->failedRespData.erase(key_k);
2415 }
2416 }
2417
2418
clear_inactive_data()2419 inline void SurrogateData::clear_inactive_data()
2420 {
2421 std::map<UShortArray, SDVArray>::iterator vd_it = sdRep->varsData.begin();
2422 std::map<UShortArray, SDRArray>::iterator rd_it = sdRep->respData.begin();
2423 while (vd_it != sdRep->varsData.end())
2424 if (vd_it == sdRep->varsDataIter) // preserve active
2425 { ++vd_it; ++rd_it; }
2426 else { // clear inactive
2427 const UShortArray& key = vd_it->first;
2428 // anchorIndex and failedRespData can be pruned:
2429 sdRep->anchorIndex.erase(key); // if it exists
2430 sdRep->failedRespData.erase(key); // if it exists
2431 // Be more conservative with clearing {vars,resp}Data:
2432 vd_it->second.clear(); ++vd_it;
2433 rd_it->second.clear(); ++rd_it;
2434 // Too aggressive. Note: postfix increments manage iterator invalidations
2435 //sdRep->varsData.erase(vd_it++); sdRep->respData.erase(rd_it++);
2436 }
2437 }
2438
2439
clear_filtered()2440 inline void SurrogateData::clear_filtered()
2441 {
2442 sdRep->filteredVarsData.clear();
2443 sdRep->filteredRespData.clear();
2444 }
2445
2446
clear_active_popped()2447 inline void SurrogateData::clear_active_popped()
2448 {
2449 const UShortArray& key = sdRep->activeKey;
2450 // can erase as will be recreated in pop() if needed:
2451 sdRep->poppedVarsData.erase(key);//sdRep->poppedVarsData[key].clear();
2452 sdRep->poppedRespData.erase(key);//sdRep->poppedRespData[key].clear();
2453 sdRep->popCountStack.erase(key); //sdRep->popCountStack[key].clear();
2454 }
2455
2456
clear_active_popped(const UShort2DArray & keys)2457 inline void SurrogateData::clear_active_popped(const UShort2DArray& keys)
2458 {
2459 // clear each passed key without disturbing the active key
2460 size_t k, num_k = keys.size();
2461 for (k=0; k<num_k; ++k) {
2462 const UShortArray& key_k = keys[k];
2463 // can erase as will be recreated in pop() if needed
2464 sdRep->poppedVarsData.erase(key_k);
2465 sdRep->poppedRespData.erase(key_k);
2466 sdRep->popCountStack.erase(key_k);
2467 }
2468 }
2469
2470
clear_popped()2471 inline void SurrogateData::clear_popped()
2472 {
2473 sdRep->poppedVarsData.clear();
2474 sdRep->poppedRespData.clear();
2475 sdRep->popCountStack.clear();
2476 }
2477
2478
clear_data(bool initialize)2479 inline void SurrogateData::clear_data(bool initialize)
2480 {
2481 sdRep->varsData.clear();
2482 sdRep->respData.clear();
2483 clear_filtered();
2484
2485 sdRep->anchorIndex.clear();
2486 sdRep->failedRespData.clear();
2487
2488 if (initialize) // preserve activeKey and restore to initialization state
2489 sdRep->update_active_iterators();
2490 else {
2491 sdRep->activeKey.clear();
2492 sdRep->varsDataIter = sdRep->varsData.end();
2493 sdRep->respDataIter = sdRep->respData.end();
2494 }
2495 }
2496
2497
clear_all(bool initialize)2498 inline void SurrogateData::clear_all(bool initialize)
2499 { clear_data(initialize); clear_popped(); }
2500
2501
clear_all_active()2502 inline void SurrogateData::clear_all_active()
2503 { clear_active_data(); clear_active_popped(); }
2504
2505
clear_all_active(const UShort2DArray & keys)2506 inline void SurrogateData::clear_all_active(const UShort2DArray& keys)
2507 { clear_active_data(keys); clear_active_popped(keys); }
2508
2509
data_rep() const2510 inline std::shared_ptr<SurrogateDataRep> SurrogateData::data_rep() const
2511 { return sdRep; }
2512
2513
is_null() const2514 inline bool SurrogateData::is_null() const
2515 { return (sdRep) ? false : true; }
2516
2517 } // namespace Pecos
2518
2519 #endif
2520