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 #include "RandomFieldModel.hpp"
10 #include "MarginalsCorrDistribution.hpp"
11 #include "ParallelLibrary.hpp"
12 #include "Teuchos_SerialDenseHelpers.hpp"
13
14 namespace Dakota {
15
16 /// initialization of static needed by RecastModel
17 RandomFieldModel* RandomFieldModel::rfmInstance(NULL);
18
19
RandomFieldModel(ProblemDescDB & problem_db)20 RandomFieldModel::RandomFieldModel(ProblemDescDB& problem_db):
21 RecastModel(problem_db, get_sub_model(problem_db)),
22 // LPS TODO: initialize other class data members off problemDB
23 numObservations(0),
24 expansionForm(problem_db.get_ushort("model.rf.expansion_form")),
25 covarianceForm(problem_db.get_ushort("model.rf.analytic_covariance")),
26 requestedReducedRank(problem_db.get_int("model.rf.expansion_bases")),
27 percentVariance(problem_db.get_real("model.truncation_tolerance")),
28 actualReducedRank(5)
29 {
30 modelType = "random_field";
31 modelId = RecastModel::recast_model_id(root_model_id(), "RANDOM_FIELD");
32 init_dace_iterator(problem_db);
33
34 validate_inputs();
35 }
36
37
~RandomFieldModel()38 RandomFieldModel::~RandomFieldModel()
39 { /* empty dtor */ }
40
41
get_sub_model(ProblemDescDB & problem_db)42 Model RandomFieldModel::get_sub_model(ProblemDescDB& problem_db)
43 {
44 Model sub_model;
45
46 const String& propagation_model_pointer
47 = problem_db.get_string("model.rf.propagation_model_pointer");
48 size_t model_index = problem_db.get_db_model_node(); // for restoration
49 problem_db.set_db_model_nodes(propagation_model_pointer);
50 sub_model = problem_db.get_model();
51 //check_submodel_compatibility(actualModel);
52 problem_db.set_db_model_nodes(model_index); // restore
53
54 return sub_model;
55 }
56
57
init_dace_iterator(ProblemDescDB & problem_db)58 void RandomFieldModel::init_dace_iterator(ProblemDescDB& problem_db)
59 {
60 const String& dace_method_pointer
61 = problem_db.get_string("model.dace_method_pointer");
62
63 if (!dace_method_pointer.empty()) { // global DACE approximations
64 size_t method_index = problem_db.get_db_method_node(); // for restoration
65 size_t model_index = problem_db.get_db_model_node(); // for restoration
66 problem_db.set_db_list_nodes(dace_method_pointer);
67
68 // instantiate the DACE iterator, which instantiates the actual model
69 daceIterator = problem_db.get_iterator();
70 daceIterator.sub_iterator_flag(true);
71
72 // retrieve the actual model from daceIterator (invalid for selected
73 // meta-iterators, e.g., hybrids)
74 Model& rf_generating_model = daceIterator.iterated_model();
75 // BMA TODO: review
76 // check_submodel_compatibility(actualModel);
77 // if outer level output is verbose/debug and actualModel verbosity is
78 // defined by the DACE method spec, request fine-grained evaluation
79 // reporting for purposes of the final output summary. This allows verbose
80 // final summaries without verbose output on every dace-iterator completion.
81 if (outputLevel > NORMAL_OUTPUT)
82 rf_generating_model.fine_grained_evaluation_counters();
83
84 problem_db.set_db_method_node(method_index); // restore method only
85 problem_db.set_db_model_nodes(model_index); // restore all model nodes
86
87
88 // TODO: may want to make this a quieter, lighter iterator?
89 daceIterator.sub_iterator_flag(true);
90 }
91 }
92
93
validate_inputs()94 void RandomFieldModel::validate_inputs()
95 {
96 //if (buildField) {
97 if (rfDataFilename.empty() && daceIterator.is_null() && (covarianceForm == NOCOVAR)) {
98 Cerr << "\nError: Random field model requires data_file or "
99 << "dace_method_pointer or specification of an analytic covariance"
100 << std::endl;
101 abort_handler(MODEL_ERROR);
102 }
103
104 // }
105 }
106
107
108 /** May eventually take on init_comms and related operations. Also
109 may want ide of build/update like DataFitSurrModel, eventually. */
initialize_mapping(ParLevLIter pl_iter)110 bool RandomFieldModel::initialize_mapping(ParLevLIter pl_iter)
111 {
112 bool sub_model_resize = RecastModel::initialize_mapping(pl_iter);
113
114 // TODO: create modes to switch between generating, accepting, and
115 // underlying model
116 fieldRealizationId=0;
117
118 // runtime operation to identify the random field approximation
119 if (covarianceForm != NOCOVAR) {
120 rf_suite_identify_field_model();
121 expansionForm = RF_KARHUNEN_LOEVE;
122 }
123 else {
124 get_field_data();
125 identify_field_model();
126 }
127
128 // complete initialization of the base RecastModel
129 initialize_recast();
130
131 if (expansionForm == RF_KARHUNEN_LOEVE) {
132 // augment mvDist with normal(0,1)
133 initialize_rf_coeffs();
134 // update message lengths for send/receive of parallel jobs (normally
135 // performed once in Model::init_communicators() just after construct time)
136 estimate_message_lengths();
137
138 return true; // size of variables changed
139 }
140 // may need true for PCA/GP if the vars characterization changes
141 return false; // size of variables unchanged
142 }
143
144
145 /** Populate rfBuildData */
get_field_data()146 void RandomFieldModel::get_field_data()
147 {
148 // TODO: either load the data matrix using ReducedBasis utilities or
149 // run daceIterator
150
151 if (daceIterator.is_null()) {
152 // TODO: temporary data for testing
153 std::ifstream rf_file;
154 rf_file.open("rfbuild.test");
155 RealVectorArray va;
156 read_sized_data(rf_file, va, 5, 50);
157 rfBuildData.reshape(5,50);
158 copy_data(va,rfBuildData);
159 }
160 else {
161 // generate samples of the random field
162 Cout << "\nRandomFieldModel: Gathering random field data from RF-generating "
163 << "model" << std::endl;
164 daceIterator.run();
165 size_t num_samples = daceIterator.num_samples();
166 // BMA TODO: relax assumption of allSamples / compactMode
167 // Generalize to discrete vars
168 if (expansionForm == RF_PCA_GP) {
169 rfBuildVars.reshape(subModel.cv(), num_samples);
170 rfBuildVars.assign(daceIterator.all_samples());
171 }
172 rfBuildData.reshape(num_samples, numFns);
173 const IntResponseMap& all_resp = daceIterator.all_responses();
174 IntRespMCIter r_it = all_resp.begin();
175 for (size_t samp=0; samp<num_samples; ++samp, ++r_it)
176 for (size_t fn=0; fn<numFns; ++fn)
177 rfBuildData(samp,fn) = r_it->second.function_value(fn);
178 }
179 }
180
181
182 /// Alternative to below function when using RFSuite
rf_suite_identify_field_model()183 void RandomFieldModel::rf_suite_identify_field_model()
184 {
185 actualReducedRank = requestedReducedRank;
186 // Build an RF suite reduced model
187 // dprepro to insert covariance type / parameters / correl lengths, bases, percent variance
188 Cout << "In rf_suite_identify_field_model " << '\n';
189 //std::system("dprepro covsettings.txt KL_solve.template KL_solve.i");
190 std::system("./run_kl_solve.sh");
191 }
192
193
identify_field_model()194 void RandomFieldModel::identify_field_model()
195 {
196 // operations common to both representations
197 rfBasis.set_matrix(rfBuildData);
198 rfBasis.update_svd(true); // true: center the matrix before factoring
199 //percentVariance = 0.9; // hardcoded: need to remove
200 ReducedBasis::VarianceExplained truncation(percentVariance);
201 actualReducedRank = truncation.get_num_components(rfBasis);
202 Cout << "RandomFieldModel: retaining " << actualReducedRank
203 << " basis functions." << std::endl;
204
205 switch(expansionForm) {
206 case RF_KARHUNEN_LOEVE: {
207 Cout << "KL Expansion Form " << '\n';
208 break;
209 }
210 case RF_PCA_GP: {
211
212 Cout << "PCA Expansion Form " << '\n';
213
214 int num_samples = rfBuildData.numRows();
215
216 // Get the centered version of the original response matrix
217 const RealMatrix& centered_matrix = rfBasis.get_matrix();
218 // for now get the first factor score
219 const RealMatrix& principal_comp
220 = rfBasis.get_right_singular_vector_transpose();
221
222 // Compute the factor scores
223 RealMatrix factor_scores(num_samples, numFns);
224 int myerr = factor_scores.multiply(Teuchos::NO_TRANS, Teuchos::TRANS, 1.,
225 centered_matrix, principal_comp, 0.);
226
227 // BMA TODO: verify why this size differs; seems that factor
228 // scores should be n x p and that this could seg fault if
229 // num_samples > numFns...
230 RealMatrix
231 f_scores(Teuchos::Copy, factor_scores, num_samples, num_samples, 0, 0);
232
233 // build the GP approximations, one per principal component
234 String approx_type("global_kriging"); // Surfpack GP
235 UShortArray approx_order;
236 short data_order = 1; // assume only function values
237 short output_level = NORMAL_OUTPUT;
238 SharedApproxData sharedData;
239
240 // BMA TODO: generalize to discrete vars if possible
241 sharedData = SharedApproxData(approx_type, approx_order, subModel.cv(),
242 data_order, output_level);
243
244 // build one GP for each Principal Component
245 gpApproximations.clear();
246 for (int i = 0; i < actualReducedRank; ++i)
247 gpApproximations.push_back(Approximation(sharedData));
248 for (int i = 0; i < actualReducedRank; ++i) {
249 RealVector factor_i = Teuchos::getCol(Teuchos::View,f_scores,i);
250 gpApproximations[i].add_array(rfBuildVars, factor_i);
251 gpApproximations[i].build();
252 const String gp_string = std::to_string(i);
253 const String gp_prefix = "PCA_GP";
254 gpApproximations[i].export_model(StringArray(), gp_string, gp_prefix,
255 ALGEBRAIC_FILE);
256 }
257 break;
258 }
259 default:
260 Cerr << "Not implemented";
261 break;
262 }
263 }
264
265
266 /** Initialize the recast model to augment the uncertain variables
267 with actualReducedRank additional N(0,1) variables, with no
268 response function mapping (for now).*/
initialize_recast()269 void RandomFieldModel::initialize_recast()
270 {
271 // For now, we assume the map is over all functions, without
272 // distinguishing primary from secondary
273
274 // ---
275 // Variables mapping: RecastModel maps augmented (uncertainVars +
276 // RFcoeffs) variables to original submodel which accepts only
277 // uncertainVars (plus a field realization)
278 //
279 // BMA TODO: In the case of KL, vars are expanded by RFcoeffs; in
280 // case of PCA/GP, only original uncVars are needed and the vars map
281 // is likely the identity.
282 //
283 // Consider two derived classes or deriving PCA/GP model from
284 // DataFitSurrModel, especially since no Recast is needed for the
285 // PCA/GP case.
286 // ---
287
288 // We assume the mapping is for all active variables, but only
289 // normal uncertain get modified
290 size_t submodel_vars =
291 subModel.cv()+ subModel.div() + subModel.dsv() + subModel.drv();
292 size_t recast_vars = submodel_vars + actualReducedRank;
293
294 // BMA TODO: This is wrong! Assumes normal lead the cv array!
295 UShortMultiArrayConstView sm_cv_types = subModel.continuous_variable_types();
296 size_t num_sm_normal
297 = std::count(sm_cv_types.begin(), sm_cv_types.end(), NORMAL_UNCERTAIN);
298
299 // TODO: don't assume this for PCA case!
300
301 // In general, each submodel continuous variable depends on all of
302 // the recast (reduced) variables; others are one-to-one.
303 Sizet2DArray vars_map_indices(submodel_vars);
304 for (size_t i=0; i<submodel_vars; ++i) {
305 vars_map_indices[i].resize(submodel_vars);
306 size_t j = 0;
307 for ( ; j<num_sm_normal; ++j)
308 vars_map_indices[i][j] = j;
309 // skip the N(0,1) coeffs, if they exist
310 for ( ; j<num_sm_normal; ++j)
311 vars_map_indices[i][j] = actualReducedRank + j;
312 }
313 // Variables map is linear
314 bool nonlinear_vars_mapping = false;
315
316 SizetArray vars_comps_total = variables_resize();
317 BitArray all_relax_di, all_relax_dr; // default: empty; no discrete relaxation
318
319 // Primary and secondary mapping are one-to-one (NULL callbacks)
320 // TODO: can we get RecastModel to tolerate empty indices when no
321 // map is present?
322 size_t num_primary = subModel.num_primary_fns(),
323 num_secondary = subModel.num_secondary_fns(),
324 num_recast_fns = num_primary + num_secondary,
325 recast_secondary_offset = subModel.num_nonlinear_ineq_constraints();
326
327 Sizet2DArray primary_resp_map_indices(num_primary);
328 for (size_t i=0; i<num_primary; i++) {
329 primary_resp_map_indices[i].resize(1);
330 primary_resp_map_indices[i][0] = i;
331 }
332
333 Sizet2DArray secondary_resp_map_indices(num_secondary);
334 for (size_t i=0; i<num_secondary; i++) {
335 secondary_resp_map_indices[i].resize(1);
336 secondary_resp_map_indices[i][0] = num_primary + i;
337 }
338
339 BoolDequeArray nonlinear_resp_mapping(numFns, BoolDeque(numFns, false));
340
341 // Initial response order for the newly built subspace model same as
342 // the subModel (does not augment with gradient request)
343 const Response& curr_resp = subModel.current_response();
344 short recast_resp_order = 1; // recast resp order to be same as original resp
345 if (!curr_resp.function_gradients().empty()) recast_resp_order |= 2;
346 if (!curr_resp.function_hessians().empty()) recast_resp_order |= 4;
347
348 RecastModel::
349 init_sizes(vars_comps_total, all_relax_di, all_relax_dr, num_primary,
350 num_secondary, recast_secondary_offset, recast_resp_order);
351
352 RecastModel::
353 init_maps(vars_map_indices, nonlinear_vars_mapping, vars_mapping,
354 set_mapping, primary_resp_map_indices, secondary_resp_map_indices,
355 nonlinear_resp_mapping, NULL, NULL);
356 }
357
358
359 /// Create a variables components totals array with the reduced space
360 /// size for continuous variables
361 /// TODO: augment normal uncVars for KL case
variables_resize()362 SizetArray RandomFieldModel::variables_resize()
363 {
364 const SharedVariablesData& svd = subModel.current_variables().shared_data();
365 SizetArray vc_totals = svd.components_totals();
366
367 // the map size only changes for KL to augment the coeffs by
368 // actualReducedRank N(0,1) variables
369 if (expansionForm == RF_KARHUNEN_LOEVE) {
370 // TODO: validate active view on subModel in case there are now CAUV
371 vc_totals[TOTAL_CAUV] += actualReducedRank;
372 }
373 return vc_totals;
374 }
375
376
377 /** Initialzie the aleatory dist params for the KL coeffs */
initialize_rf_coeffs()378 void RandomFieldModel::initialize_rf_coeffs()
379 {
380 // BMA TODO: more gracefully insert the variables into their place
381
382 // the map size only changes for KL to augment the coeffs by
383 // actualReducedRank N(0,1) variables
384 if (expansionForm == RF_KARHUNEN_LOEVE) {
385
386 // get submodel normal parameters (could get from current object as well)
387 const Pecos::MultivariateDistribution& sm_dist
388 = subModel.multivariate_distribution();
389 std::shared_ptr<Pecos::MarginalsCorrDistribution> sm_mvd_rep =
390 std::static_pointer_cast<Pecos::MarginalsCorrDistribution>
391 (sm_dist.multivar_dist_rep());
392 RealVector normal_means, normal_stdev, normal_lb, normal_ub;
393 sm_mvd_rep->pull_parameters(Pecos::NORMAL, Pecos::N_MEAN, normal_means);
394 sm_mvd_rep->pull_parameters(Pecos::NORMAL, Pecos::N_STD_DEV, normal_stdev);
395 sm_mvd_rep->pull_parameters(Pecos::NORMAL, Pecos::N_LWR_BND, normal_lb);
396 sm_mvd_rep->pull_parameters(Pecos::NORMAL, Pecos::N_UPR_BND, normal_ub);
397
398 // append normal variables
399 int num_sm_normal = normal_means.length();
400 normal_means.resize(num_sm_normal + actualReducedRank);
401 normal_stdev.resize(num_sm_normal + actualReducedRank);
402 normal_lb.resize(num_sm_normal + actualReducedRank);
403 normal_ub.resize(num_sm_normal + actualReducedRank);
404 // BMA TODO: update label management to not assume normal are leading vars
405 StringMultiArrayConstView sm_cv_labels =
406 subModel.continuous_variable_labels();
407 for (int i=0 ; i<num_sm_normal; ++i)
408 currentVariables.continuous_variable_label(sm_cv_labels[i], i);
409 for (int i=0; i<actualReducedRank; ++i) {
410 normal_means[num_sm_normal + i] = 0.0;
411 normal_stdev[num_sm_normal + i] = 1.0;
412 normal_lb[num_sm_normal + i] = -std::numeric_limits<Real>::infinity();
413 normal_ub[num_sm_normal + i] = std::numeric_limits<Real>::infinity();
414 String xi_label = "xi_" + std::to_string(i+1);
415 currentVariables.
416 continuous_variable_label(xi_label, num_sm_normal + i);
417 }
418 for (int i=num_sm_normal; i<sm_cv_labels.size(); ++i)
419 currentVariables.
420 continuous_variable_label(sm_cv_labels[i], actualReducedRank + i);
421
422 // update mvDist for the RandomFieldModel
423 std::shared_ptr<Pecos::MarginalsCorrDistribution> mvd_rep =
424 std::static_pointer_cast<Pecos::MarginalsCorrDistribution>
425 (mvDist.multivar_dist_rep());
426 mvd_rep->push_parameters(Pecos::NORMAL, Pecos::N_MEAN, normal_means);
427 mvd_rep->push_parameters(Pecos::NORMAL, Pecos::N_STD_DEV, normal_stdev);
428 mvd_rep->push_parameters(Pecos::NORMAL, Pecos::N_LWR_BND, normal_lb);
429 mvd_rep->push_parameters(Pecos::NORMAL, Pecos::N_UPR_BND, normal_ub);
430 }
431 }
432
433 /// map the active continuous recast variables to the active
434 /// submodel variables
vars_mapping(const Variables & recast_augmented_vars,Variables & sub_model_vars)435 void RandomFieldModel::vars_mapping(const Variables& recast_augmented_vars,
436 Variables& sub_model_vars)
437 {
438 if (rfmInstance->expansionForm == RF_KARHUNEN_LOEVE) {
439 // send the submodel all but the N(0,1) vars
440
441 // BMA TODO: generalize this for other views; for now, assume cv()
442 // starts with normal uncertain
443 size_t num_sm_cv = rfmInstance->subModel.cv();
444 UShortMultiArrayConstView sm_cv_types
445 = rfmInstance->subModel.continuous_variable_types();
446 size_t num_sm_normal
447 = std::count(sm_cv_types.begin(), sm_cv_types.end(), NORMAL_UNCERTAIN);
448
449 const RealVector& augmented_cvars =
450 recast_augmented_vars.continuous_variables();
451
452 size_t i = 0;
453 RealVector sm_cvars(num_sm_cv);
454 for ( ; i<num_sm_normal; ++i)
455 sm_cvars[i] = augmented_cvars[i];
456 // skip the N(0,1) coeffs, if they exist
457 for ( ; i<num_sm_cv; ++i)
458 sm_cvars[i] = augmented_cvars[rfmInstance->actualReducedRank + i];
459
460 // propagate variables to subModel
461 sub_model_vars.continuous_variables(sm_cvars);
462 sub_model_vars.discrete_int_variables(recast_augmented_vars.
463 discrete_int_variables());
464 sub_model_vars.discrete_string_variables(recast_augmented_vars.
465 discrete_string_variables());
466 sub_model_vars.discrete_real_variables(recast_augmented_vars.
467 discrete_real_variables());
468 }
469 else
470 sub_model_vars.active_variables(recast_augmented_vars);
471 }
472
473
derived_evaluate(const ActiveSet & set)474 void RandomFieldModel::derived_evaluate(const ActiveSet& set)
475 {
476 fieldRealizationId++;
477
478 if (expansionForm == RF_KARHUNEN_LOEVE)
479 generate_kl_realization();
480 else if (expansionForm == RF_PCA_GP)
481 generate_pca_gp_realization();
482
483 // May need hook to communicate the appropraiate mesh file to the simulation
484
485 RecastModel::derived_evaluate(set);
486
487 }
488
489
derived_evaluate_nowait(const ActiveSet & set)490 void RandomFieldModel::derived_evaluate_nowait(const ActiveSet& set)
491 {
492 fieldRealizationId++;
493
494 if (expansionForm == RF_KARHUNEN_LOEVE)
495 generate_kl_realization();
496 else if (expansionForm == RF_PCA_GP)
497 generate_pca_gp_realization();
498
499 RecastModel::derived_evaluate_nowait(set);
500 }
501
502
generate_kl_realization()503 void RandomFieldModel::generate_kl_realization()
504 {
505 // ReducedBasis gives the singular values of the centered data
506 // matrix; the covariance is scaled by n-1:
507 int cov_dof = std::sqrt( (double)rfBasis.get_matrix().numRows() - 1 );
508 const RealVector& data_singular_values = rfBasis.get_singular_values();
509 RealMatrix rf_ev_trans = rfBasis.get_right_singular_vector_transpose();
510
511 // extract N(0,1) KL coefficients to generate a field realization
512 //
513 // BMA TODO: properly extract the N(0,1) vars from their place in
514 // the overall vector when not in aleatory view (what's in the total
515 // vector depends on the view...)
516 UShortMultiArrayConstView sm_cv_types = subModel.continuous_variable_types();
517 size_t num_sm_normal
518 = std::count(sm_cv_types.begin(), sm_cv_types.end(), NORMAL_UNCERTAIN);
519 const RealVector& augmented_cvars = currentVariables.continuous_variables();
520 RealVector kl_coeffs(Teuchos::View, augmented_cvars.values() + num_sm_normal,
521 actualReducedRank);
522
523 if (outputLevel >= DEBUG_OUTPUT) {
524 Cout << "Augmented continuous variables:\n" << augmented_cvars << std::endl;
525 Cout << "KL random coeffs:\n" << kl_coeffs << std::endl;
526 }
527
528 // Run KL realize with RF Suite
529 // dprepro to configure kl_realize.i with kl_coeffs, mesh number
530 //std::system("dprepro randomcoeffs.txt KL_realize.template KL_realize.i");
531 //std::system("launch -n 1 encore -i KL_realize.i");
532
533 if (covarianceForm != NOCOVAR)
534 std::system("./run_kl_realize.sh");
535
536 // post-condition: mesh file gets written containing the field realization
537 // probably want to tag it with evalID...
538 // bfs::copy(mesh.exo mesh.realize1.exo)
539 // need to obtain the realization ID for this Model/Interface
540
541 // For now use fieldRealizationId
542
543 // May want to create a new derived Interface from
544 // ForkApplicInterface called ExternalFieldManagerInterface
545 // in order to better manage hierarchical tagging
546
547 // augment the mean prediction with the covariance contributions
548 RealVector kl_prediction = rfBasis.get_column_means();
549 for (int i=0; i<actualReducedRank; ++i) {
550 // BMA TODO: replace with matrix-vector ops (perhaps in ReducedBasis)
551 Real mult = data_singular_values[i]/cov_dof * kl_coeffs[i];
552 for (int k=0; k<numFns; ++k)
553 kl_prediction[k] += mult*rf_ev_trans(i,k);
554 }
555
556 write_field(kl_prediction);
557 }
558
559
generate_pca_gp_realization()560 void RandomFieldModel::generate_pca_gp_realization()
561 {
562 // augment the mean prediction with the GP contributions
563 RealVector pca_prediction = rfBasis.get_column_means();
564 // reduced basis comprised of the rows of V'
565 const RealMatrix& principal_comp
566 = rfBasis.get_right_singular_vector_transpose();
567
568 for (int i=0; i<actualReducedRank; ++i) {
569 const RealVector& new_sample = currentVariables.continuous_variables();
570 Real pca_coeff = gpApproximations[i].value(new_sample);
571 if (outputLevel == DEBUG_OUTPUT)
572 Cout << "DEBUG: pca_coeff = " << pca_coeff << '\n';
573 for (int k=0; k<numFns; ++k)
574 pca_prediction[k] += pca_coeff*principal_comp(i,k);
575 }
576
577 write_field(pca_prediction);
578 }
579
580
write_field(const RealVector & field_prediction)581 void RandomFieldModel::write_field(const RealVector& field_prediction)
582 {
583 // TODO: write to file per eval, preferrably in work_directory
584 // BMA TODO: something smarter than modelEvalCntr / eval ID
585 if (outputLevel >= VERBOSE_OUTPUT) {
586 String pred_count(std::to_string(evaluation_id() + 1));
587 std::ofstream myfile;
588 myfile.open(("field_prediction." + pred_count + ".txt").c_str());
589 Cout << "Field prediction " << pred_count << "\n";
590 Cout << field_prediction << std::endl;
591 for (int i=0; i<field_prediction.length(); ++i)
592 myfile << field_prediction[i] << " ";
593 myfile << std::endl;
594 }
595 }
596
597
598 /// map the inbound ActiveSet to the sub-model (map derivative variables)
set_mapping(const Variables & recast_vars,const ActiveSet & recast_set,ActiveSet & sub_model_set)599 void RandomFieldModel::set_mapping(const Variables& recast_vars,
600 const ActiveSet& recast_set,
601 ActiveSet& sub_model_set)
602 { }
603
604 }
605