1 /* _______________________________________________________________________
2
3 DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4 Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5 This software is distributed under the GNU Lesser General Public License.
6 For more information, see the README file in the top Dakota directory.
7 _______________________________________________________________________ */
8
9 //- Non-class: PRPMultiIndex
10 //- Description: Global funcs, types, etc. for lookup of PRPairs in eval cache
11 //- Checked by:
12 //- Version: $Id$
13
14 #ifndef PRP_MULTI_INDEX_H
15 #define PRP_MULTI_INDEX_H
16
17 #include "dakota_system_defs.hpp"
18 #include "dakota_data_types.hpp"
19 #include "ParamResponsePair.hpp"
20
21 #include <boost/multi_index_container.hpp>
22 #include <boost/multi_index/hashed_index.hpp>
23 #include <boost/multi_index/mem_fun.hpp>
24 #include <boost/multi_index/ordered_index.hpp>
25
26 #include <algorithm>
27
28 namespace bmi = boost::multi_index;
29
30 namespace Dakota {
31
32 // --------------------------------------------------------
33 // Comparison functions shared by PRPCache/PRPQueue
34 // --------------------------------------------------------
35
36 /// search function for a particular ParamResponsePair within a PRPList based
37 /// on ActiveSet content (request vector and derivative variables vector)
38
39 /** a global function to compare the ActiveSet of a particular database_pr
40 (presumed to be in the global history list) with a passed in ActiveSet
41 (search_set). */
42 inline bool
set_compare(const ParamResponsePair & database_pr,const ActiveSet & search_set)43 set_compare(const ParamResponsePair& database_pr, const ActiveSet& search_set)
44 {
45 // Check each entry of ASV for presence of all requests in the stored data.
46 // A match is now detected when the search_asv is a SUBSET of the stored_asv
47 // (only exact matches were interpreted as duplicates previously). This
48 // extension is widely applicable, but was first implemented to eliminate
49 // duplication in Model::estimate_derivatives() when the gradient evaluation
50 // contains inactive fns. whereas a previous line search evaluation at the
51 // same X had no inactive fns.
52 const ActiveSet& stored_set = database_pr.active_set();
53 const ShortArray& stored_asv = stored_set.request_vector();
54 const ShortArray& search_asv = search_set.request_vector();
55 size_t i, asv_len = search_asv.size();
56 if ( stored_asv.size() != asv_len )
57 return false;
58 bool deriv_flag = false;
59 for (i=0; i<asv_len; ++i) {
60 short search_bits = search_asv[i];
61 if (search_bits & 6)
62 deriv_flag = true;
63 // bit-wise AND used to check if each of the search bits is
64 // present in the stored_asv value
65 if ( (stored_asv[i] & search_bits) != search_bits )
66 return false;
67 }
68
69 // check if each of the search derivative variables is present in stored_dvv
70 if (deriv_flag) {
71 const SizetArray& stored_dvv = stored_set.derivative_vector();
72 const SizetArray& search_dvv = search_set.derivative_vector();
73 size_t dvv_len = search_dvv.size();
74 for (i=0; i<dvv_len; ++i)
75 if ( std::find(stored_dvv.begin(), stored_dvv.end(), search_dvv[i])
76 == stored_dvv.end() )
77 return false;
78 }
79
80 return true;
81 }
82
83
84 // ------------------------------------------------------
85 // Comparison and hashing functions for PRPCache/PRPQueue
86 // ------------------------------------------------------
87
88 /// search function for a particular ParamResponsePair within a PRPMultiIndex
89
90 /** a global function to compare the interface id and variables of a
91 particular database_pr (presumed to be in the global history list) with
92 a passed in key of interface id and variables provided by search_pr. */
id_vars_exact_compare(const ParamResponsePair & database_pr,const ParamResponsePair & search_pr)93 inline bool id_vars_exact_compare(const ParamResponsePair& database_pr,
94 const ParamResponsePair& search_pr)
95 {
96 // First check interface id strings. If a different interface was used, then
97 // we must assume that the results are not interchangeable (differing model
98 // fidelity).
99 if ( search_pr.interface_id() != database_pr.interface_id() )
100 return false;
101
102 // For Boost hashing, need exact binary equality (not tolerance-based)
103 if ( search_pr.variables() != database_pr.variables() )
104 return false;
105
106 // For Boost hashing, a post-processing step is used to manage the ActiveSet
107 // logic as shown in set_compare()
108
109 return true;
110 }
111
112
113 /// hash_value for ParamResponsePairs stored in a PRPMultiIndex
hash_value(const ParamResponsePair & prp)114 inline std::size_t hash_value(const ParamResponsePair& prp)
115 {
116 // hash using interface ID string.
117 std::size_t seed = 0;
118 boost::hash_combine(seed, prp.interface_id());
119
120 // Now, hash values of variables using Variables hash_value friend function
121 boost::hash_combine(seed, prp.variables());
122
123 return seed;
124 }
125
126
127 // --------------------------------------
128 // structs and typedefs for PRPMultiIndex
129 // --------------------------------------
130 // define structs used below in PRPMultiIndex typedef
131
132 /// wrapper to delegate to the ParamResponsePair hash_value function
133 struct partial_prp_hash {
134 /// access operator
operator ()Dakota::partial_prp_hash135 std::size_t operator()(const ParamResponsePair& prp) const
136 { return hash_value(prp); } // ONLY interfaceId & Vars used for hash_value
137 };
138
139 /// predicate for comparing ONLY the interfaceId and Vars attributes of PRPair
140 struct partial_prp_equality {
141 /// access operator
operator ()Dakota::partial_prp_equality142 bool operator()(const ParamResponsePair& database_pr,
143 const ParamResponsePair& search_pr) const
144 { return id_vars_exact_compare(database_pr, search_pr); }
145 };
146
147
148 // tags
149 struct ordered {};
150 struct hashed {};
151 //struct random {};
152
153
154 /// Boost Multi-Index Container for globally caching ParamResponsePairs
155
156 /** For a global cache, both evaluation and interface id's are used for
157 tagging ParamResponsePair records. */
158 typedef bmi::multi_index_container<Dakota::ParamResponsePair, bmi::indexed_by<
159 // sorted by increasing evalId/interfaceId value; can be non-unique due to
160 // restart database and restarted run having different evals with the same
161 // evalId/interfaceId (due to modified execution settings)
162 bmi::ordered_non_unique<bmi::tag<ordered>,
163 bmi::const_mem_fun<Dakota::ParamResponsePair,
164 const IntStringPair&,
165 &Dakota::ParamResponsePair::eval_interface_ids> >,
166 // hashed using partial_prp_hash and compared using partial_prp_equality;
167 // can be non-unique due to multiple evals with same interfaceId/variables
168 // but distinct active set
169 bmi::hashed_non_unique<bmi::tag<hashed>,
170 bmi::identity<Dakota::ParamResponsePair>,
171 partial_prp_hash, partial_prp_equality> > >
172 PRPMultiIndexCache;
173
174 typedef PRPMultiIndexCache PRPCache;
175 typedef PRPCache::index_iterator<ordered>::type PRPCacheOIter;
176 typedef PRPCache::index_const_iterator<ordered>::type PRPCacheOCIter;
177 typedef PRPCache::index_iterator<hashed>::type PRPCacheHIter;
178 typedef PRPCache::index_const_iterator<hashed>::type PRPCacheHCIter;
179 typedef PRPCacheOIter PRPCacheIter; ///< default cache iterator <0>
180 typedef PRPCacheOCIter PRPCacheCIter; ///< default cache const iterator <0>
181 /// default cache const reverse iterator <0>
182 typedef boost::reverse_iterator<PRPCacheCIter> PRPCacheCRevIter;
183
184 // begin()/end() default to index 0. These macros support other indices.
185
186 /// hashed definition of cache begin
hashedCacheBegin(PRPCache & prp_cache)187 inline PRPCacheHIter hashedCacheBegin(PRPCache& prp_cache)
188 { return prp_cache.get<hashed>().begin(); }
189 /// hashed definition of cache end
hashedCacheEnd(PRPCache & prp_cache)190 inline PRPCacheHIter hashedCacheEnd(PRPCache& prp_cache)
191 { return prp_cache.get<hashed>().end(); }
192
193
194 /// Boost Multi-Index Container for locally queueing ParamResponsePairs
195
196 /** For a local queue, interface id's are expected to be consistent,
197 such that evaluation id's are sufficient for tracking particular
198 evaluations. */
199 typedef bmi::multi_index_container<Dakota::ParamResponsePair, bmi::indexed_by<
200 /* random access for index-based operator[] access
201 bmi::random_access<bmi::tag<random> >, */
202 // sorted by unique/increasing evaluation id for fast key-based lookups
203 bmi::ordered_unique<bmi::tag<ordered>,
204 bmi::const_mem_fun<Dakota::ParamResponsePair, int,
205 &Dakota::ParamResponsePair::eval_id> >,
206 // hashed using partial_prp_hash and compared using partial_prp_equality;
207 // can be non-unique due to multiple evals with same interfaceId/variables
208 // but distinct active set
209 bmi::hashed_non_unique<bmi::tag<hashed>,
210 bmi::identity<Dakota::ParamResponsePair>,
211 partial_prp_hash, partial_prp_equality> > >
212 PRPMultiIndexQueue;
213
214 typedef PRPMultiIndexQueue PRPQueue;
215 //typedef PRPQueue::index_iterator<random>::type PRPQueueRIter;
216 //typedef PRPQueue::index_const_iterator<random>::type PRPQueueRCIter;
217 typedef PRPQueue::index_iterator<ordered>::type PRPQueueOIter;
218 typedef PRPQueue::index_const_iterator<ordered>::type PRPQueueOCIter;
219 typedef PRPQueue::index_iterator<hashed>::type PRPQueueHIter;
220 typedef PRPQueue::index_const_iterator<hashed>::type PRPQueueHCIter;
221 typedef PRPQueueOIter PRPQueueIter; // default queue iterator <0>
222 typedef PRPQueueOCIter PRPQueueCIter; // default queue const iterator <0>
223
224 // begin()/end() default to index 0. These macros support other indices.
225
226 /// hashed definition of queue begin
hashedQueueBegin(PRPQueue & prp_queue)227 inline PRPQueueHIter hashedQueueBegin(PRPQueue& prp_queue)
228 { return prp_queue.get<hashed>().begin(); }
229 /// hashed definition of queue end
hashedQueueEnd(PRPQueue & prp_queue)230 inline PRPQueueHIter hashedQueueEnd(PRPQueue& prp_queue)
231 { return prp_queue.get<hashed>().end(); }
232
233
234 // ------------------------------------
235 // lookup_by_val for PRPMultiIndexCache
236 // ------------------------------------
237
238 /// find a ParamResponsePair based on the interface id, variables, and
239 /// ActiveSet search data within search_pr.
240
241 /** Lookup occurs in two steps: (1) PRPMultiIndexCache lookup based on
242 strict equality in interface id and variables, and (2) set_compare()
243 post-processing based on ActiveSet subset logic. */
244 inline PRPCacheHIter
lookup_by_val(PRPMultiIndexCache & prp_cache,const ParamResponsePair & search_pr)245 lookup_by_val(PRPMultiIndexCache& prp_cache, const ParamResponsePair& search_pr)
246 {
247 PRPCacheHIter prp_hash_it0, prp_hash_it1;
248 boost::tuples::tie(prp_hash_it0, prp_hash_it1)
249 = prp_cache.get<hashed>().equal_range(search_pr);
250
251 // equal_range returns a small sequence of possibilities resulting from
252 // hashing with ONLY interfaceId and variables. Post-processing is then
253 // applied to this sequence using set_compare().
254 while (prp_hash_it0 != prp_hash_it1) {
255 if (set_compare(*prp_hash_it0, search_pr.active_set()))
256 return prp_hash_it0;
257 ++prp_hash_it0;
258 }
259 return prp_cache.get<hashed>().end();
260 }
261
262
263 /// find a ParamResponsePair within a PRPMultiIndexCache based on the
264 /// interface id, variables, and ActiveSet search data
265 inline PRPCacheHIter
lookup_by_val(PRPMultiIndexCache & prp_cache,const String & search_interface_id,const Variables & search_vars,const ActiveSet & search_set)266 lookup_by_val(PRPMultiIndexCache& prp_cache, const String& search_interface_id,
267 const Variables& search_vars, const ActiveSet& search_set)
268 {
269 Response search_resp(SIMULATION_RESPONSE, search_set);
270 ParamResponsePair search_pr(search_vars, search_interface_id, search_resp);
271 return lookup_by_val(prp_cache, search_pr);
272 }
273
274
275 /* Better to use cache iterators and avoid extra shallow copies if not needed
276
277 /// alternate overloaded form returns bool and sets found_pr by wrapping
278 /// lookup_by_val(PRPMultiIndexCache&, ParamResponsePair&)
279 inline bool
280 lookup_by_val(PRPMultiIndexCache& prp_cache, const ParamResponsePair& search_pr,
281 ParamResponsePair& found_pr)
282 {
283 PRPCacheHIter prp_hash_it = lookup_by_val(prp_cache, search_pr);
284 if (prp_hash_it != prp_cache.get<hashed>().end()) {
285 found_pr = *prp_hash_it;
286 return true;
287 }
288 else
289 return false;
290 }
291
292
293 /// alternate overloaded form returns bool and sets found_pr by wrapping
294 /// lookup_by_val(PRPMultiIndexCache&, String&, Variables&, ActiveSet&)
295 inline bool
296 lookup_by_val(PRPMultiIndexCache& prp_cache, const String& search_interface_id,
297 const Variables& search_vars, const ActiveSet& search_set,
298 ParamResponsePair& found_pr)
299 {
300 PRPCacheHIter prp_hash_it
301 = lookup_by_val(prp_cache, search_interface_id, search_vars, search_set);
302 if (prp_hash_it != prp_cache.get<hashed>().end()) {
303 found_pr = *prp_hash_it;
304 return true;
305 }
306 else
307 return false;
308 }
309
310
311 /// find the response of a ParamResponsePair within a PRPMultiIndexCache
312 /// based on interface id, variables, and ActiveSet search data
313 inline bool
314 lookup_by_val(PRPMultiIndexCache& prp_cache, const String& search_interface_id,
315 const Variables& search_vars, const ActiveSet& search_set,
316 Response& found_resp)
317 {
318 PRPCacheHIter prp_hash_it
319 = lookup_by_val(prp_cache, search_interface_id, search_vars, search_set);
320 if (prp_hash_it != prp_cache.get<hashed>().end()) {
321 found_resp = prp_hash_it->response();
322 return true;
323 }
324 else
325 return false;
326 }
327 */
328
329
330 inline PRPCacheOIter
lookup_by_nearby_val(PRPMultiIndexCache & prp_cache,const String & search_interface_id,const Variables & search_vars,const ActiveSet & search_set,Real tol)331 lookup_by_nearby_val(PRPMultiIndexCache& prp_cache,
332 const String& search_interface_id,
333 const Variables& search_vars, const ActiveSet& search_set,
334 Real tol)
335 {
336 PRPCacheOIter cache_it;
337 for (cache_it=prp_cache.begin(); cache_it!=prp_cache.end(); ++cache_it)
338 if (cache_it->interface_id() == search_interface_id && // exact
339 nearby(cache_it->variables(), search_vars, tol) && // tolerance
340 set_compare(*cache_it, search_set)) // subset
341 return cache_it; // Duplication detected.
342 return prp_cache.end();
343 }
344
345
346 // ------------------------------------
347 // lookup_by_ids for PRPMultiIndexCache
348 // ------------------------------------
349 /// find a ParamResponsePair within a PRPMultiIndexCache based on search_ids
350 /// (i.e. std::pair<eval_id,interface_id>) search data
351 inline PRPCacheOIter
lookup_by_ids(PRPMultiIndexCache & prp_cache,const IntStringPair & search_ids)352 lookup_by_ids(PRPMultiIndexCache& prp_cache, const IntStringPair& search_ids)
353 {
354 // sign of eval id indicates different dataset sources:
355 // eval id > 0 for unique evals from current execution (in data_pairs)
356 // eval id = 0 for evals from file import (not in data_pairs)
357 // eval id < 0 for non-unique evals from restart (in data_pairs)
358 if (search_ids.first > 0) // positive ids (evals from current exec) are unique
359 return prp_cache.get<ordered>().find(search_ids);
360 else { // negative (restart) and 0 (file import) ids are non-unique in general
361
362 /*
363 // could allow lookup if only one item found, but still a misuse of the fn
364 PRPCacheOIter prp_it0, prp_it1;
365 boost::tuples::tie(prp_it0, prp_it1)
366 = prp_cache.get<ordered>().equal_range(search_ids);
367 switch (std::distance(prp_it0, prp_it1)) {
368 case 0: return prp_cache.get<ordered>().end(); break;
369 case 1: return prp_it0; break;
370 default:
371 Cerr << "Error: duplicate entries in PRPCache lookup_by_ids()."
372 << std::endl;
373 abort_handler(-1); break;
374 }
375 */
376
377 Cerr << "Error: lookup_by_ids(PRPCache&) used for lookup with non-positive "
378 << "evaluation id, which may be non-unique." << std::endl;
379 abort_handler(-1);
380 }
381 }
382
383
384 inline PRPCacheOIter
lookup_by_ids(PRPMultiIndexCache & prp_cache,const IntStringPair & search_ids,const ParamResponsePair & search_pr)385 lookup_by_ids(PRPMultiIndexCache& prp_cache, const IntStringPair& search_ids,
386 const ParamResponsePair& search_pr)
387 {
388 // sign of eval id indicates different dataset sources:
389 // eval id > 0 for unique evals from current execution (in data_pairs)
390 // eval id = 0 for evals from file import (not in data_pairs)
391 // eval id < 0 for non-unique evals from restart (in data_pairs)
392 if (search_ids.first > 0) // positive ids (evals from current exec) are unique
393 return prp_cache.get<ordered>().find(search_ids);
394 else { // negative (restart) and 0 (file import) ids are non-unique in general
395
396 // equal_range returns a small sequence of possibilities resulting from
397 // ordered lookup with ONLY search_ids. Post-processing can then be
398 // applied to this sequence if needed using vars_compare().
399 PRPCacheOIter prp_it0, prp_it1;
400 boost::tuples::tie(prp_it0, prp_it1)
401 = prp_cache.get<ordered>().equal_range(search_ids);
402 switch (std::distance(prp_it0, prp_it1)) {
403 case 0: return prp_cache.get<ordered>().end(); break;
404 case 1: return prp_it0; break;
405 default:
406 while (prp_it0 != prp_it1) {
407 if (prp_it0->variables() == search_pr.variables() && // exact
408 set_compare(*prp_it0, search_pr.active_set())) // subset
409 return prp_it0;
410 ++prp_it0;
411 }
412 return prp_cache.get<ordered>().end(); break;
413 }
414 }
415 }
416
417
418 /* Better to use cache iterators and avoid extra shallow copies if not needed
419
420 /// find a ParamResponsePair within a PRPMultiIndexCache based on
421 /// eval_interface_ids
422 inline bool
423 lookup_by_ids(PRPMultiIndexCache& prp_cache,
424 const IntStringPair& search_eval_interface_ids,
425 ParamResponsePair& found_pr)
426 {
427 PRPCacheOIter prp_iter = lookup_by_ids(prp_cache, search_eval_interface_ids);
428 if (prp_iter != prp_cache.get<ordered>().end()) {
429 found_pr = *prp_iter;
430 return true;
431 }
432 else
433 return false;
434 }
435
436
437 /// find a ParamResponsePair within a PRPMultiIndexCache based on
438 /// eval_interface_ids from the ParamResponsePair search data
439 inline bool
440 lookup_by_ids(PRPMultiIndexCache& prp_cache, const ParamResponsePair& search_pr,
441 ParamResponsePair& found_pr)
442 { return lookup_by_ids(prp_cache, search_pr.eval_interface_ids(), found_pr); }
443 */
444
445
446 // ------------------------------------
447 // lookup_by_val for PRPMultiIndexQueue
448 // ------------------------------------
449
450 /// find a ParamResponsePair based on the interface id, variables, and
451 /// ActiveSet search data within search_pr.
452
453 /** Lookup occurs in two steps: (1) PRPMultiIndexQueue lookup based on
454 strict equality in interface id and variables, and (2) set_compare()
455 post-processing based on ActiveSet subset logic. */
456 inline PRPQueueHIter
lookup_by_val(PRPMultiIndexQueue & prp_queue,const ParamResponsePair & search_pr)457 lookup_by_val(PRPMultiIndexQueue& prp_queue, const ParamResponsePair& search_pr)
458 {
459 PRPQueueHIter prp_hash_it0, prp_hash_it1;
460 boost::tuples::tie(prp_hash_it0, prp_hash_it1)
461 = prp_queue.get<hashed>().equal_range(search_pr);
462
463 // equal_range returns a small sequence of possibilities resulting from
464 // hashing with ONLY interfaceId and variables. Post-processing is then
465 // applied to this sequence using set_compare().
466 while (prp_hash_it0 != prp_hash_it1) {
467 if (set_compare(*prp_hash_it0, search_pr.active_set()))
468 return prp_hash_it0;
469 ++prp_hash_it0;
470 }
471 return prp_queue.get<hashed>().end();
472 }
473
474
475 /// find a ParamResponsePair within a PRPMultiIndexQueue based on
476 /// interface id, variables, and ActiveSet search data
477 inline PRPQueueHIter
lookup_by_val(PRPMultiIndexQueue & prp_queue,const String & search_interface_id,const Variables & search_vars,const ActiveSet & search_set)478 lookup_by_val(PRPMultiIndexQueue& prp_queue, const String& search_interface_id,
479 const Variables& search_vars, const ActiveSet& search_set)
480 {
481 Response search_resp(SIMULATION_RESPONSE, search_set);
482 ParamResponsePair search_pr(search_vars, search_interface_id, search_resp);
483 return lookup_by_val(prp_queue, search_pr);
484 }
485
486
487 /* Better to use cache iterators and avoid extra shallow copies if not needed
488
489 /// alternate overloaded form returns bool and sets found_pr by wrapping
490 /// lookup_by_val(PRPMultiIndexQueue&, ParamResponsePair&)
491 inline bool
492 lookup_by_val(PRPMultiIndexQueue& prp_queue, const ParamResponsePair& search_pr,
493 ParamResponsePair& found_pr)
494 {
495 PRPQueueHIter prp_hash_it = lookup_by_val(prp_queue, search_pr);
496 if (prp_hash_it != prp_queue.get<hashed>().end()) {
497 found_pr = *prp_hash_it;
498 return true;
499 }
500 else
501 return false;
502 }
503
504
505 /// alternate overloaded form returns bool and sets found_pr by wrapping
506 /// lookup_by_val(PRPMultiIndexQueue&, String&, Variables&, ActiveSet&)
507 inline bool
508 lookup_by_val(PRPMultiIndexQueue& prp_queue, const String& search_interface_id,
509 const Variables& search_vars, const ActiveSet& search_set,
510 ParamResponsePair& found_pr)
511 {
512 PRPQueueHIter prp_hash_it
513 = lookup_by_val(prp_queue, search_interface_id, search_vars, search_set);
514 if (prp_hash_it != prp_queue.get<hashed>().end()) {
515 found_pr = *prp_hash_it;
516 return true;
517 }
518 else
519 return false;
520 }
521
522
523 /// find the response of a ParamResponsePair within a PRPMultiIndexQueue
524 /// based on interface id, variables, and ActiveSet search data
525 inline bool
526 lookup_by_val(PRPMultiIndexQueue& prp_queue, const String& search_interface_id,
527 const Variables& search_vars, const ActiveSet& search_set,
528 Response& found_resp)
529 {
530 PRPQueueHIter prp_hash_it
531 = lookup_by_val(prp_queue, search_interface_id, search_vars, search_set);
532 if (prp_hash_it != prp_queue.get<hashed>().end()) {
533 found_resp = prp_hash_it->response();
534 return true;
535 }
536 else
537 return false;
538 }
539 */
540
541
542 // ----------------------------------------
543 // lookup_by_eval_id for PRPMultiIndexQueue
544 // ----------------------------------------
545 /// find a ParamResponsePair within a PRPMultiIndexQueue based on search_id
546 /// (i.e. integer eval_id) search data
547 inline PRPQueueOIter
lookup_by_eval_id(PRPMultiIndexQueue & prp_queue,int search_id)548 lookup_by_eval_id(PRPMultiIndexQueue& prp_queue, int search_id)
549 { return prp_queue.get<ordered>().find(search_id); }
550
551
552 /* Better to use cache iterators and avoid extra shallow copies if not needed
553
554 /// find a ParamResponsePair within a PRPMultiIndexQueue based on eval_id
555 inline bool
556 lookup_by_eval_id(PRPMultiIndexQueue& prp_queue, int search_id,
557 ParamResponsePair& found_pr)
558 {
559 PRPQueueOIter prp_iter = lookup_by_eval_id(prp_queue, search_id);
560 if (prp_iter != prp_queue.get<ordered>().end()) {
561 found_pr = *prp_iter;
562 return true;
563 }
564 else
565 return false;
566 }
567
568
569 /// find a ParamResponsePair within a PRPMultiIndexQueue based on
570 /// eval_id from the ParamResponsePair search data
571 inline bool
572 lookup_by_eval_id(PRPMultiIndexQueue& prp_queue,
573 const ParamResponsePair& search_pr,
574 ParamResponsePair& found_pr)
575 { return lookup_by_eval_id(prp_queue, search_pr.eval_id(), found_pr); }
576 */
577
578 } // namespace Dakota
579
580 #endif // PRP_MULTI_INDEX_H
581
582