QMCPACK
DescentEngine.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source
3 // License.
4 // See LICENSE file in top directory for details.
5 //
6 // Copyright (c) 2019 QMCPACK developers.
7 //
8 // File developed by: Leon Otis, leon_otis@berkeley.edu University, University
9 // of California Berkeley
10 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
11 //
12 // File created by: Leon Otis, leon_otis@berkeley.edu University, University of
13 // California Berkeley
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 // Code for a descent engine
17 
18 #include "DescentEngine.h"
19 #include <cmath>
20 #include <string>
21 #include <vector>
22 #include <numeric>
23 #include "Message/CommOperators.h"
24 #include "OhmmsData/ParameterSet.h"
25 #include "CPU/math.hpp"
26 
27 namespace qmcplusplus
28 {
30  : my_comm_(comm),
31  engine_target_excited_(false),
32  num_params_(0),
33  flavor_("RMSprop"),
34  tjf_2body_eta_(.01),
35  tjf_1body_eta_(.01),
36  f_eta_(.001),
37  gauss_eta_(.001),
38  ci_eta_(.01),
39  orb_eta_(.001),
40  ramp_eta_(false),
41  ramp_num_(30),
42  store_num_(5),
43  omega_(0.0),
44  collection_step_(-1),
45  compute_step_(-1),
46  print_deriv_("no")
47 {
48  descent_num_ = 0;
49  store_count_ = 0;
50  processXML(cur);
51 }
52 
53 bool DescentEngine::processXML(const xmlNodePtr cur)
54 {
55  std::string excited("no");
56  std::string ramp_eta_str("no");
57 
58  ParameterSet m_param;
59  m_param.add(excited, "targetExcited");
60  m_param.add(omega_, "omega");
61  // Type of descent method being used
62  m_param.add(flavor_, "flavor");
63  // Step size inputs for different parameter types
64  m_param.add(tjf_2body_eta_, "TJF_2Body_eta");
65  m_param.add(tjf_1body_eta_, "TJF_1Body_eta");
66  m_param.add(f_eta_, "F_eta");
67  m_param.add(ci_eta_, "CI_eta");
68  m_param.add(gauss_eta_, "Gauss_eta");
69  m_param.add(orb_eta_, "Orb_eta");
70  // Whether to gradually ramp up step sizes and over how many steps
71  m_param.add(ramp_eta_str, "Ramp_eta");
72  m_param.add(ramp_num_, "Ramp_num");
73  // If using descent as part of hybrid method, how many parameter difference
74  // vectors to store
75  m_param.add(store_num_, "Stored_Vectors");
76  m_param.add(print_deriv_, "print_derivs");
77 
78  // When to start storing samples for a final average and when to start
79  // computing it
80  m_param.add(collection_step_, "collection_step");
81  m_param.add(compute_step_, "compute_step");
82 
83  //app_log() << "Omega from input file: " << omega_ << std::endl;
84  //app_log() << "Current collection step: " << collection_step_ << std::endl;
85  // Use -1 as a default value when you don't collect history. Would want to
86  // collect only during the descent finalization section
87  if (collection_step_ != -1)
88  {
89  app_log() << "On descent finalization, have collect_count as true" << std::endl;
90  collect_count_ = true;
91  }
92 
93  m_param.put(cur);
94 
95  engine_target_excited_ = (excited == "yes");
96 
97  ramp_eta_ = (ramp_eta_str == "yes");
98 
99  return true;
100 }
101 
102 // Prepare for taking samples to compute averaged derivatives
103 void DescentEngine::prepareStorage(const int num_replicas, const int num_optimizables)
104 {
105  lderivs_.resize(num_optimizables);
106 
107  //Resize the history vectors for the current iteration for the number of threads present
108  replica_vg_history_.resize(num_replicas);
109  replica_w_history_.resize(num_replicas);
110  replica_lev_history_.resize(num_replicas);
111 
113  {
114  replica_tnv_history_.resize(num_replicas);
115  replica_tdv_history_.resize(num_replicas);
116 
117  }
118 
119 
120  //Also resize the history vectors for descent finalization if necessary
122  {
123  replica_final_vg_history_.resize(num_replicas);
124  replica_final_w_history_.resize(num_replicas);
125  replica_final_lev_history_.resize(num_replicas);
126 
127 
128 
130  {
131  replica_final_tnv_history_.resize(num_replicas);
132  replica_final_tdv_history_.resize(num_replicas);
133 
134  }
135  }
136 
137 
138  // Ground state case
140  {
141  avg_le_der_samp_.resize(num_optimizables);
142  avg_der_rat_samp_.resize(num_optimizables);
143 
144  num_params_ = num_optimizables;
145 
146  std::fill(avg_le_der_samp_.begin(), avg_le_der_samp_.end(), 0.0);
147  std::fill(avg_der_rat_samp_.begin(), avg_der_rat_samp_.end(), 0.0);
148 
149  replica_le_der_samp_.resize(num_replicas);
150  replica_der_rat_samp_.resize(num_replicas);
151 
152  for (int i = 0; i < num_replicas; i++)
153  {
154  replica_le_der_samp_[i].resize(num_optimizables);
155  std::fill(replica_le_der_samp_[i].begin(), replica_le_der_samp_[i].end(), 0.0);
156 
157  replica_der_rat_samp_[i].resize(num_optimizables);
158  std::fill(replica_der_rat_samp_[i].begin(), replica_der_rat_samp_[i].end(), 0.0);
159  }
160  }
161  // Excited state case
162  else
163  {
164  replica_numer_der_samp_.resize(num_replicas);
165  replica_denom_der_samp_.resize(num_replicas);
166 
167  avg_numer_der_samp_.resize(num_optimizables);
168  avg_denom_der_samp_.resize(num_optimizables);
169 
170  std::fill(avg_numer_der_samp_.begin(), avg_numer_der_samp_.end(), 0.0);
171  std::fill(avg_denom_der_samp_.begin(), avg_denom_der_samp_.end(), 0.0);
172 
173  for (int i = 0; i < num_replicas; i++)
174  {
175  replica_numer_der_samp_[i].resize(num_optimizables);
176  replica_denom_der_samp_[i].resize(num_optimizables);
177 
178  std::fill(replica_numer_der_samp_[i].begin(), replica_numer_der_samp_[i].end(), 0.0);
179  std::fill(replica_denom_der_samp_[i].begin(), replica_denom_der_samp_[i].end(), 0.0);
180  }
181  }
182 
183  w_sum_ = 0;
184  e_avg_ = 0;
185  e_var_ = 0;
186  e_sd_ = 0;
187  e_err_ = 0;
188 
189  numer_avg_ = 0;
190  numer_var_ = 0;
191  numer_err_ = 0;
192 
193  denom_avg_ = 0;
194  denom_var_ = 0;
195  denom_err_ = 0;
196 
197  target_avg_ = 0;
198  target_var_ = 0;
199  target_err_ = 0;
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////////////////////////////
203 /// \brief Function that Take Sample Data from the Host Code
204 ///
205 /// \param[in] der_rat_samp <n|Psi_i>/<n|Psi> (i = 0 (|Psi>), 1, ... N_var )
206 /// \param[in] le_der_samp <n|H|Psi_i>/<n|Psi> (i = 0 (|Psi>), 1, ... N_var
207 /// )
208 /// \param[in] ls_der_samp <|S^2|Psi_i>/<n|Psi> (i = 0 (|Psi>), 1, ... N_var
209 /// )
210 /// \param[in] vgs_samp |<n|value_fn>/<n|guiding_fn>|^2
211 /// \param[in] weight_samp weight for this sample
212 ///
213 ////////////////////////////////////////////////////////////////////////////////////////////////////////
214 void DescentEngine::takeSample(const int replica_id,
215  const std::vector<FullPrecValueType>& der_rat_samp,
216  const std::vector<FullPrecValueType>& le_der_samp,
217  const std::vector<FullPrecValueType>& ls_der_samp,
218  ValueType vgs_samp,
219  ValueType weight_samp)
220 {
221 
222  const size_t num_optimizables = der_rat_samp.size() - 1;
223 
224  ValueType etmp = static_cast<ValueType>(le_der_samp.at(0));
225 
226 
227  // Store a history of samples for the current iteration
228  replica_lev_history_[replica_id].push_back(etmp * vgs_samp);
229  replica_vg_history_[replica_id].push_back(vgs_samp);
230  replica_w_history_[replica_id].push_back(static_cast<ValueType>(1.0));
231 
232  // If on descent finalizing section and past the collection step, store each
233  // local energy for this iteration
235  {
236  replica_final_lev_history_[replica_id].push_back(etmp * vgs_samp);
237  replica_final_vg_history_[replica_id].push_back(vgs_samp);
238  replica_final_w_history_[replica_id].push_back(1.0);
239  }
240 
241  // Ground State Case
243  {
244  for (int i = 0; i < num_optimizables; i++)
245  {
246  replica_le_der_samp_[replica_id].at(i) += le_der_samp.at(i + 1) * static_cast<FullPrecValueType>(vgs_samp);
247  replica_der_rat_samp_[replica_id].at(i) += der_rat_samp.at(i + 1) * static_cast<FullPrecValueType>(vgs_samp);
248  }
249  }
250  // Excited State Case
251  else
252  {
253  ValueType n;
254  ValueType d;
255 
256  n = (omega_ - etmp) * vgs_samp;
257  d = (omega_ * omega_ - static_cast<ValueType>(2) * omega_ * etmp + etmp * etmp) * vgs_samp;
258 
259  replica_tnv_history_[replica_id].push_back(n);
260  replica_tdv_history_[replica_id].push_back(d);
261 
263  {
264  replica_final_tnv_history_[replica_id].push_back(n);
265  replica_final_tdv_history_[replica_id].push_back(d);
266  }
267 
268 
269  for (int i = 0; i < num_optimizables; i++)
270  {
271  // Combination of derivative ratios for target function numerator <psi |
272  // omega -H | psi>/<psi | psi>
273  replica_numer_der_samp_[replica_id].at(i) += static_cast<FullPrecValueType>(2) *
274  (static_cast<FullPrecValueType>(omega_) * der_rat_samp.at(i + 1) - le_der_samp.at(i + 1)) *
275  static_cast<FullPrecValueType>(vgs_samp);
276 
277  // Combination of derivative ratios for target function denominator <psi |
278  // (omega -H)^2 | psi>/<psi | psi>
279  replica_denom_der_samp_[replica_id].at(i) += static_cast<FullPrecValueType>(2) *
280  ((static_cast<FullPrecValueType>(omega_) * der_rat_samp.at(i + 1) - le_der_samp.at(i + 1)) *
281  (static_cast<FullPrecValueType>(omega_) * der_rat_samp.at(0) - le_der_samp.at(0))) *
282  static_cast<FullPrecValueType>(vgs_samp);
283  }
284  }
285 }
286 
287 ////////////////////////////////////////////////////////////////////////////////////////////////////////
288 /// \brief Function that reduces all vector information from all processors to
289 /// the root processor
290 ///
291 ////////////////////////////////////////////////////////////////////////////////////////////////////////
293 {
294 
295  //After a potentially multithreaded section, cocatenate the replica history vectors
296  int num_threads = replica_vg_history_.size();
297  for(int i =0; i< num_threads; i++)
298  {
299  vg_history_.insert(vg_history_.end(), replica_vg_history_[i].begin(),replica_vg_history_[i].end());
300  w_history_.insert(w_history_.end(), replica_w_history_[i].begin(),replica_w_history_[i].end());
301  lev_history_.insert(lev_history_.end(),replica_lev_history_[i].begin(),replica_lev_history_[i].end());
302 
303  //Clear the individual thread history vectors for the next iteration after their values have been collected
304  replica_vg_history_[i].clear();
305  replica_w_history_[i].clear();
306  replica_lev_history_[i].clear();
307 
308 
310  {
311 
312  tnv_history_.insert(tnv_history_.end(), replica_tnv_history_[i].begin(),replica_tnv_history_[i].end());
313  tdv_history_.insert(tdv_history_.end(), replica_tdv_history_[i].begin(),replica_tdv_history_[i].end());
314 
315  replica_tnv_history_[i].clear();
316  replica_tdv_history_[i].clear();
317  }
318  }
319 
320  //Do the same for finalization histories if necessary
322  {
323  for(int i =0; i< num_threads; i++)
324  {
328 
329  replica_final_vg_history_[i].clear();
330  replica_final_w_history_[i].clear();
331  replica_final_lev_history_[i].clear();
332 
333 
335  {
336 
339 
340  replica_final_tnv_history_[i].clear();
341  replica_final_tdv_history_[i].clear();
342  }
343  }
344  }
345 
346 
347  int numSamples = lev_history_.size();
348 
349  //Compute average energy and variance for this iteration
351 
352  app_log() << "Energy Average: " << std::setprecision(9) << e_avg_ << std::endl;
353  app_log() << "Energy Variance: " << std::setprecision(9) << e_var_ << std::endl;
354  app_log() << "Weight Total: " << std::setprecision(9) << w_sum_ << std::endl;
356  app_log() << "Energy Standard Deviation: " << std::setprecision(9) << e_sd_ << std::endl;
357  app_log() << "Energy Standard Error: " << std::setprecision(9) << e_err_ << std::endl;
358 
359  //Store average values during descent finalization
361  {
362  final_le_avg_history_.push_back(e_avg_);
363  final_var_avg_history_.push_back(e_var_);
364  }
365 
367  {
368  for (int i = 0; i < replica_le_der_samp_.size(); i++)
369  {
370  for (int j = 0; j < lderivs_.size(); j++)
371  {
372  avg_le_der_samp_[j] += replica_le_der_samp_[i].at(j);
374  }
375  }
376 
379  }
380  else
381  {
383  numer_err_);
384 
386  denom_err_);
387 
389  target_err_);
390 
391  app_log() << "Target Function Average: " << std::setprecision(9) << target_avg_ << std::endl;
392  app_log() << "Target Function Variance: " << std::setprecision(9) << target_var_ << std::endl;
393  app_log() << "Target Function Error: " << std::setprecision(9) << target_err_ << std::endl;
394 
396  {
399  }
400  for (int i = 0; i < replica_numer_der_samp_.size(); i++)
401  {
402  for (int j = 0; j < lderivs_.size(); j++)
403  {
406  }
407  }
408 
411  }
412 
413  int num_optimizables = lderivs_.size();
414 
415  // Vectors for parts of excited state functional derivatives
416  std::vector<ValueType> numer_term1(num_optimizables, 0.0);
417  std::vector<ValueType> numer_term2(num_optimizables, 0.0);
418  std::vector<ValueType> denom(num_optimizables, 0.0);
419 
420  ValueType gradNorm = 0.0;
421 
422  // Compute contribution to derivatives
423  for (int i = 0; i < num_optimizables; i++)
424  {
425  // Ground state case
427  {
428  avg_le_der_samp_.at(i) = avg_le_der_samp_.at(i) / static_cast<FullPrecValueType>(w_sum_);
429  avg_der_rat_samp_.at(i) = avg_der_rat_samp_.at(i) / static_cast<FullPrecValueType>(w_sum_);
430 
431  lderivs_.at(i) = static_cast<FullPrecValueType>(2.0) *
432  (avg_le_der_samp_.at(i) - static_cast<FullPrecValueType>(e_avg_) * avg_der_rat_samp_.at(i));
433  if (print_deriv_ == "yes")
434  {
435  app_log() << "Parameter # " << i << " Hamiltonian term: " << avg_le_der_samp_.at(i) << std::endl;
436  app_log() << "Parameter # " << i << " Overlap term: " << avg_der_rat_samp_.at(i) << std::endl;
437  app_log() << "Derivative for param # " << i << " : " << lderivs_.at(i) << std::endl;
438  }
439  }
440  // Excited state case
441  else
442  {
443  avg_numer_der_samp_.at(i) = avg_numer_der_samp_.at(i) / static_cast<FullPrecValueType>(w_sum_);
444  avg_denom_der_samp_.at(i) = avg_denom_der_samp_.at(i) / static_cast<FullPrecValueType>(w_sum_);
445 
446  if (print_deriv_ == "yes")
447  {
448  app_log() << "Parameter # " << i << " Numer Deriv: " << avg_numer_der_samp_.at(i) << std::endl;
449  app_log() << "Parameter # " << i << " Denom Deriv: " << avg_denom_der_samp_.at(i) << std::endl;
450  }
451 
452  numer_term1.at(i) = avg_numer_der_samp_.at(i) * static_cast<FullPrecValueType>(denom_avg_);
453 
454  numer_term2.at(i) = avg_denom_der_samp_.at(i) * static_cast<FullPrecValueType>(numer_avg_);
455 
456  denom.at(i) = denom_avg_ * denom_avg_;
457 
458  lderivs_.at(i) = (numer_term1.at(i) - numer_term2.at(i)) / denom.at(i);
459  }
460 
461  gradNorm += lderivs_.at(i) * lderivs_.at(i);
462  }
463 
464  gradNorm = std::sqrt(gradNorm);
465  app_log() << "Norm of gradient vector is: " << gradNorm << std::endl;
466 
467  // Clear the history vectors for next iteration once sample_finish is done
468  lev_history_.clear();
469  vg_history_.clear();
470  w_history_.clear();
471 
473  {
474  tnv_history_.clear();
475  tdv_history_.clear();
476  }
477 }
478 
479 // Main function for computing ratios of the form <f>/<g> as well as the
480 // variance and standard error
482  std::vector<ValueType>& weights,
483  std::vector<ValueType>& numerSamples,
484  std::vector<ValueType>& denomSamples,
485  ValueType& mean,
486  ValueType& variance,
487  ValueType& stdErr)
488 {
489  std::vector<ValueType> y(7);
490  y[0] = 0.0; // normalization constant
491  y[1] = 0.0; // mean of numerator
492  y[2] = 0.0; // mean of denominator
493  y[3] = 0.0; // mean of the square of the numerator terms
494  y[4] = 0.0; // mean of the square of the denominator terms
495  y[5] = 0.0; // mean of the product of numerator times denominator
496  y[6] = ValueType(numSamples); // number of samples
497 
498  for (int i = 0; i < numSamples; i++)
499  {
500  ValueType n = numerSamples[i];
501  ValueType d = denomSamples[i];
502  ValueType weight = weights[i];
503 
504  y[0] += weight;
505  y[1] += weight * n;
506  y[2] += d;
507  y[3] += weight * n * n;
508  y[4] += weight * d * d;
509  y[5] += weight * n * d;
510  }
511 
512  my_comm_->allreduce(y);
513 
514  ValueType mf = y[1] / y[0]; // mean of numerator
515  ValueType mg = y[2] / y[0]; // mean of denominator
516  ValueType sf = y[3] / y[0]; // mean of the square of the numerator terms
517  ValueType sg = y[4] / y[0]; // mean of the square of the denominator terms
518  ValueType mp = y[5] / y[0]; // mean of the product of numerator times denominator
519  ValueType ns = y[6]; // number of samples
520 
521  ValueType vf = (sf - mf * mf) * ns / (ns - static_cast<ValueType>(1.0));
522  ValueType vg = (sg - mg * mg) * ns / (ns - static_cast<ValueType>(1.0));
523  ValueType cv = (mp - mf * mg) * ns / (ns - static_cast<ValueType>(1.0));
524 
525  w_sum_ = y[0];
526  mean = (mf / mg) / (static_cast<ValueType>(1.0) + (vg / mg / mg - cv / mf / mg) / ns);
527  variance = (mf * mf / mg / mg) * (vf / mf / mf + vg / mg / mg - static_cast<ValueType>(2.0) * cv / mf / mg);
528  stdErr = std::sqrt(variance / ns);
529 }
530 
531 // Function for updating parameters during descent optimization
533 {
534  app_log() << "Number of Parameters: " << num_params_ << std::endl;
535  app_log() << "Descent Number: " << descent_num_ << std::endl;
536 
537  app_log() << "Finalization Descent Num (should be zero if not on last section): " << final_descent_num_ << std::endl;
539  {
540  app_log() << "Should be storing history, length of history on one process is: " << final_lev_history_.size()
541  << std::endl;
542  }
543 
544  app_log() << "Parameter Type step sizes: "
545  << " TJF_2Body_eta=" << tjf_2body_eta_ << " TJF_1Body_eta=" << tjf_1body_eta_ << " F_eta=" << f_eta_
546  << " CI_eta=" << ci_eta_ << " Orb_eta=" << orb_eta_ << std::endl;
547 
548  // Get set of derivatives for current (kth) optimization step
549  std::vector<ValueType> cur_deriv_set = deriv_records_.at(deriv_records_.size() - 1);
550  std::vector<ValueType> prev_deriv_set;
551  if (!taus_.empty())
552  {
553  // Get set of derivatives for previous (k-1th) optimization step
554  prev_deriv_set = deriv_records_.at(deriv_records_.size() - 2);
555  }
556 
557  ValueType denom;
558  ValueType numer;
559  ValueType v;
560  ValueType cor_numer;
561  ValueType cor_v;
562 
563  ValueType epsilon = 1e-8;
564  ValueType type_eta = 0;
565 
566  ValueType tau = 0;
567  // Update parameters according to specified flavor of gradient descent method
568 
569  // RMSprop corresponds to the method used by Booth and co-workers
570  if (flavor_.compare("RMSprop") == 0)
571  {
572  app_log() << "Using RMSprop" << std::endl;
573 
574  // To match up with Booth group paper notation, prevLambda is lambda_k-1,
575  // curLambda is lambda_k, nextLambda is lambda_k+1
576  ValueType cur_lambda = static_cast<ValueType>(.5) +
577  static_cast<ValueType>(.5) *
578  std::sqrt(static_cast<ValueType>(1.0) + static_cast<ValueType>(4.0) * lambda_ * lambda_);
579  ValueType next_lambda = static_cast<ValueType>(.5) +
580  static_cast<ValueType>(.5) *
581  std::sqrt(static_cast<ValueType>(1.0) + static_cast<ValueType>(4.0) * cur_lambda * cur_lambda);
582  ValueType gamma = (static_cast<ValueType>(1.0) - cur_lambda) / next_lambda;
583 
584  // Define damping factor that turns off acceleration of the algorithm
585  // small value of d corresponds to quick damping and effectively using
586  // steepest descent
587  ValueType d = 100;
588  ValueType decay_factor = std::exp(-(static_cast<ValueType>(1.0) / d) * (static_cast<ValueType>(descent_num_)));
589  gamma = gamma * decay_factor;
590 
591  ValueType rho = .9;
592 
593  for (int i = 0; i < num_params_; i++)
594  {
595  ValueType cur_square = std::pow(cur_deriv_set.at(i), static_cast<RealType>(2));
596 
597  // Need to calculate step size tau for each parameter inside loop
598  // In RMSprop, the denominator of the step size depends on a a running
599  // average of past squares of the parameter derivative
600  if (derivs_squared_.size() < num_params_)
601  {
602  cur_square = std::pow(cur_deriv_set.at(i), static_cast<RealType>(2));
603  }
604  else if (derivs_squared_.size() >= num_params_)
605  {
606  cur_square = rho * derivs_squared_.at(i) +
607  (static_cast<ValueType>(1.0) - rho) * std::pow(cur_deriv_set.at(i), static_cast<RealType>(2));
608  }
609 
610  denom = std::sqrt(cur_square + epsilon);
611 
612  // The numerator of the step size is set according to parameter type based
613  // on input choices
614  type_eta = this->setStepSize(i);
615  tau = type_eta / denom;
616 
617  // Include an additional factor to cause step size to eventually decrease
618  // to 0 as number of steps taken increases
619  ValueType step_lambda = .1;
620 
621  ValueType step_decay_denom = static_cast<ValueType>(1.0) + step_lambda * static_cast<ValueType>(descent_num_);
622  tau = tau / step_decay_denom;
623 
624  // Update parameter values
625  // If case corresponds to being after the first descent step
626  if (descent_num_ > 0)
627  {
628  ValueType old_tau = taus_.at(i);
629 
630  current_params_[i] = (static_cast<ValueType>(1.0) - gamma) * (current_params_[i] - tau * cur_deriv_set[i]) +
631  gamma * (params_copy_[i] - old_tau * prev_deriv_set[i]);
632  }
633  else
634  {
635  tau = type_eta;
636 
637  current_params_[i] = current_params_[i] - tau * cur_deriv_set[i];
638  }
639 
640  if (taus_.size() < num_params_)
641  {
642  // For the first optimization step, need to add to the vectors
643  taus_.push_back(tau);
644  derivs_squared_.push_back(cur_square);
645  }
646  else
647  {
648  // When not on the first step, can overwrite the previous stored values
649  taus_[i] = tau;
650  derivs_squared_[i] = cur_square;
651  }
652 
654  }
655 
656  // Store current (kth) lambda value for next optimization step
657  lambda_ = cur_lambda;
658  }
659  // Random uses only the sign of the parameter derivatives and takes a step of
660  // random size within a range.
661  else if (flavor_.compare("Random") == 0)
662  {
663  app_log() << "Using Random" << std::endl;
664 
665  for (int i = 0; i < num_params_; i++)
666  {
667  denom = 1;
668  ValueType alpha = (static_cast<ValueType>(rand() / RAND_MAX));
669  ValueType sign = std::abs(cur_deriv_set[i]) / cur_deriv_set[i];
671  {
672  app_log() << "Got a nan, choosing sign randomly with 50-50 probability" << std::endl;
673 
674  ValueType t = (static_cast<ValueType>(rand() / RAND_MAX));
675  if (std::real(t) > std::real(.5))
676  {
677  sign = 1;
678  }
679  else
680  {
681  sign = -1;
682  }
683  }
684  app_log() << "This is random alpha: " << alpha << " with sign: " << sign << std::endl;
685 
686  current_params_.at(i) = current_params_.at(i) - tau * alpha * sign;
687  }
688  }
689 
690  else
691  {
692  // ADAM method
693  if (flavor_.compare("ADAM") == 0)
694  {
695  app_log() << "Using ADAM" << std::endl;
696 
697  for (int i = 0; i < num_params_; i++)
698  {
699  ValueType cur_square = std::pow(cur_deriv_set.at(i), static_cast<RealType>(2));
700  ValueType beta1 = .9;
701  ValueType beta2 = .99;
702  if (descent_num_ == 0)
703  {
704  numer_records_.push_back(0);
705  denom_records_.push_back(0);
706  }
707  numer = beta1 * numer_records_[i] + (static_cast<ValueType>(1.0) - beta1) * cur_deriv_set[i];
708  v = beta2 * denom_records_[i] + (static_cast<ValueType>(1.0) - beta2) * cur_square;
709 
710  cor_numer = numer / (static_cast<ValueType>(1.0) - std::pow(beta1, static_cast<RealType>(descent_num_ + 1)));
711  cor_v = v / (static_cast<ValueType>(1.0) - std::pow(beta2, static_cast<RealType>(descent_num_ + 1)));
712 
713  denom = std::sqrt(cor_v) + epsilon;
714 
715  type_eta = this->setStepSize(i);
716  tau = type_eta / denom;
717 
718  current_params_.at(i) = current_params_.at(i) - tau * cor_numer;
719 
720  if (taus_.size() < num_params_)
721  {
722  // For the first optimization step, need to add to the vectors
723  taus_.push_back(tau);
724  derivs_squared_.push_back(cur_square);
725  denom_records_[i] = v;
726  numer_records_[i] = numer;
727  }
728  else
729  {
730  // When not on the first step, can overwrite the previous stored
731  // values
732  taus_[i] = tau;
733  derivs_squared_[i] = cur_square;
734  denom_records_[i] = v;
735  numer_records_[i] = numer;
736  }
737 
738  params_copy_[i] = current_params_.at(i);
739  }
740  }
741  // AMSGrad method, similar to ADAM except for form of the step size
742  // denominator
743  else if (flavor_.compare("AMSGrad") == 0)
744  {
745  app_log() << "Using AMSGrad" << std::endl;
746 
747  for (int i = 0; i < num_params_; i++)
748  {
749  ValueType cur_square = std::pow(cur_deriv_set.at(i), static_cast<RealType>(2));
750  ValueType beta1 = .9;
751  ValueType beta2 = .99;
752  if (descent_num_ == 0)
753  {
754  numer_records_.push_back(0);
755  denom_records_.push_back(0);
756  }
757 
758  numer = beta1 * numer_records_[i] + (static_cast<ValueType>(1.0) - beta1) * cur_deriv_set[i];
759  v = beta2 * denom_records_[i] + (static_cast<ValueType>(1.0) - beta2) * cur_square;
760  v = std::max(std::real(denom_records_[i]), std::real(v));
761 
762  denom = std::sqrt(v) + epsilon;
763  type_eta = this->setStepSize(i);
764  tau = type_eta / denom;
765 
766  current_params_.at(i) = current_params_.at(i) - tau * numer;
767 
768  if (taus_.size() < num_params_)
769  {
770  // For the first optimization step, need to add to the vectors
771  taus_.push_back(tau);
772  derivs_squared_.push_back(cur_square);
773  denom_records_[i] = v;
774  numer_records_[i] = numer;
775  }
776  else
777  {
778  // When not on the first step, can overwrite the previous stored
779  // values
780  taus_[i] = tau;
781  derivs_squared_[i] = cur_square;
782  denom_records_[i] = v;
783  numer_records_[i] = numer;
784  }
785 
786  params_copy_[i] = current_params_.at(i);
787  }
788  }
789  }
790 
791  descent_num_++;
792  if (collect_count_)
793  {
795 
796  // Start computing averages and uncertainties from stored history.
797  // This should be done only near the end of the descent finalization section
798  // as it is unnecessary earlier.
800  {
801  app_log() << "Computing average energy and its variance over stored "
802  "steps and its standard error"
803  << std::endl;
804 
805  ValueType collected_steps = final_le_avg_history_.size();
806  ValueType final_e_sum =
807  std::accumulate(final_le_avg_history_.begin(), final_le_avg_history_.end(), static_cast<ValueType>(0.0));
808  ValueType final_e_avg = final_e_sum / collected_steps;
809 
810  ValueType final_var_sum =
811  std::accumulate(final_var_avg_history_.begin(), final_var_avg_history_.end(), static_cast<ValueType>(0.0));
812  ValueType final_var_avg = final_var_sum / collected_steps;
813 
814  app_log() << "Final average energy: " << final_e_avg << std::endl;
815  app_log() << "Final varaince: " << final_var_avg << std::endl;
816 
818 
819  // Do the same for the target function during excited state optimizations.
821  {
822  app_log() << "Computing average target function over stored steps and "
823  "its standard error"
824  << std::endl;
825 
826  ValueType final_tar_sum =
827  std::accumulate(final_tar_avg_history_.begin(), final_tar_avg_history_.end(), static_cast<ValueType>(0.0));
828 
829  ValueType final_tar_avg = final_tar_sum / collected_steps;
830 
831  ValueType final_tar_var_sum =
832  std::accumulate(final_tar_var_history_.begin(), final_tar_var_history_.end(), static_cast<ValueType>(0.0));
833  ValueType final_tar_var_avg = final_tar_var_sum / collected_steps;
834 
835  app_log() << "Final average target function: " << final_tar_avg << std::endl;
836  app_log() << "Final target function varaince: " << final_tar_var_avg << std::endl;
838  }
839  }
840  }
841 }
842 
843 // Helper method for setting step size according parameter type.
845 {
846  ValueType type_eta;
847 
848  std::string name = engine_param_names_[i];
849 
850  int type = engine_param_types_[i];
851 
852  // Step sizes are assigned according to parameter type identified from the
853  // variable name.
854  // Other parameter types could be added to this section as other wave function
855  // ansatzes are developed.
856  if ((name.find("uu") != std::string::npos) || (name.find("ud") != std::string::npos))
857  {
858  type_eta = tjf_2body_eta_;
859  }
860  // If parameter name doesn't have "uu" or "ud" in it and is of type 1, assume
861  // it is a 1 body Jastrow parameter.
862  else if (type == 1)
863  {
864  type_eta = tjf_1body_eta_;
865  }
866  else if (name.find("F_") != std::string::npos)
867  {
868  type_eta = f_eta_;
869  }
870  else if (name.find("CIcoeff_") != std::string::npos || name.find("CSFcoeff_") != std::string::npos)
871  {
872  type_eta = ci_eta_;
873  }
874  else if (name.find("orb_rot_") != std::string::npos)
875  {
876  type_eta = orb_eta_;
877  }
878  else if (name.find("g") != std::string::npos)
879  {
880  // Gaussian parameters are rarely optimized in practice but the descent code
881  // allows for it.
882  type_eta = gauss_eta_;
883  }
884  else
885  {
886  // If there is some other parameter type that isn't in one of the categories
887  // with a default/input, use a conservative default step size.
888  type_eta = .001;
889  }
890 
892  {
893  type_eta = type_eta * static_cast<ValueType>((descent_num_ + 1) / (double)ramp_num_);
894  }
895 
896  return type_eta;
897 }
898 
899 // Method for retrieving parameter values, names, and types from the VariableSet
900 // before the first descent optimization step
902 {
903  // omega_ = omega_input;
904 
905  num_params_ = my_vars.size();
906  app_log() << "This is num_params_: " << num_params_ << std::endl;
907  for (int i = 0; i < num_params_; i++)
908  {
909  // app_log() << "Variable #" << i << ": " << my_vars[i] << " with index val:
910  // " << my_vars.where(i) << std::endl;
911  if (my_vars.where(i) != -1)
912  {
913  engine_param_names_.push_back(my_vars.name(i));
914  engine_param_types_.push_back(my_vars.getType(i));
915  params_copy_.push_back(my_vars[i]);
916  current_params_.push_back(my_vars[i]);
917  params_for_diff_.push_back(my_vars[i]);
918  }
919  }
920 }
921 
922 // Helper method for storing vectors of parameter differences over the course of
923 // a descent optimization for use in BLM steps of the hybrid method
924 void DescentEngine::storeVectors(std::vector<ValueType>& current_params)
925 {
926  std::vector<ValueType> row_vec(current_params.size(), 0.0);
927 
928  // Take difference between current parameter values and the values from some
929  // number of
930  // iterations before to be stored as input to BLM.
931  // The current parameter values are then copied to params_for_diff_ to be used
932  // if storeVectors is called again later in the optimization.
933  for (int i = 0; i < current_params.size(); i++)
934  {
935  row_vec[i] = current_params[i] - params_for_diff_[i];
936  params_for_diff_[i] = current_params[i];
937  }
938 
939  // If on first store of descent section, clear anything that was in vector
940  if (store_count_ == 0)
941  {
942  hybrid_blm_input_.clear();
943  hybrid_blm_input_.push_back(row_vec);
944  }
945  else
946  {
947  hybrid_blm_input_.push_back(row_vec);
948  }
949 
950 #if !defined(QMC_COMPLEX)
951  for (int i = 0; i < hybrid_blm_input_.size(); i++)
952  {
953  std::string entry = "";
954  for (int j = 0; j < hybrid_blm_input_.at(i).size(); j++)
955  {
956  entry = entry + std::to_string(hybrid_blm_input_.at(i).at(j)) + ",";
957  }
958  app_log() << "Stored Vector: " << entry << std::endl;
959  }
960 #endif
961  store_count_++;
962 }
963 
964 // Function for computing uncertainties for a final energy or target function
965 // average
966 void DescentEngine::computeFinalizationUncertainties(std::vector<ValueType>& weights,
967  std::vector<ValueType>& numerSamples,
968  std::vector<ValueType>& denomSamples)
969 {
970  // Make copies of input vectors to do recursive blocking for error estimates
971  std::vector<ValueType> wtv(weights);
972  std::vector<ValueType> nmv(numerSamples);
973  std::vector<ValueType> dnv(denomSamples);
974 
975  // Reproduce LM engine's crude way of estimating uncertainty in the variance
976  int n = nmv.size();
977  int blocks = 100;
978  int section_len = n / 100;
979 
980  std::vector<ValueType> bbvars(blocks);
981  ValueType bbv = 0.0;
982  ValueType bbv2 = 0.0;
983 
984  for (int i = 0; i < blocks; i++)
985  {
986  std::vector<ValueType> sub_wtv(section_len);
987  std::vector<ValueType> sub_nmv(section_len);
988  std::vector<ValueType> sub_dnv(section_len);
989 
990  ValueType temp_e, temp_v;
991  std::copy(wtv.begin() + i * section_len, wtv.begin() + (i + 1) * section_len, sub_wtv.begin());
992  std::copy(nmv.begin() + i * section_len, nmv.begin() + (i + 1) * section_len, sub_nmv.begin());
993  std::copy(dnv.begin() + i * section_len, dnv.begin() + (i + 1) * section_len, sub_dnv.begin());
994 
995  ValueType blockVar;
996  ValueType blockMean;
997  ValueType blockErr;
998 
999  this->mpi_unbiased_ratio_of_means(section_len, sub_wtv, sub_nmv, sub_dnv, blockMean, blockVar, blockErr);
1000 
1001  bbvars[i] = blockVar;
1002 
1003  bbv += bbvars.at(i) / static_cast<ValueType>(blocks);
1004  bbv2 += bbvars.at(i) * bbvars.at(i) / static_cast<ValueType>(blocks);
1005  sub_wtv.clear();
1006  sub_nmv.clear();
1007  sub_dnv.clear();
1008  }
1009 
1010  const ValueType bbvov = bbv2 - bbv * bbv;
1011  ValueType var_uncertainty = std::sqrt(std::abs(bbvov) / blocks);
1012  // Depending on when this function is called, this will be the uncertainty in
1013  // the variance
1014  // of either the energy or the target function.
1015  // Which one should be clear from the preceding print statements in the
1016  // output file.
1017  app_log() << "Uncertainty in variance of averaged quantity: " << var_uncertainty << std::endl;
1018 
1019  // To compute the standard error on the energy/target function itself,
1020  // blocking is performed on the whole set of samples in the history of many
1021  // iterations.
1022  while (n > 128)
1023  {
1024  ValueType currentVar;
1025  ValueType currentMean;
1026  ValueType currentErr;
1027  this->mpi_unbiased_ratio_of_means(n, wtv, nmv, dnv, currentMean, currentVar, currentErr);
1028 
1029  app_log() << "Blocking analysis error for per process length " << n << " is: " << currentErr << std::endl;
1030 
1031  std::vector<ValueType> tmp1, tmp2, tmp3;
1032 
1033  for (int i = 0; i < n; i += 2)
1034  {
1035  ValueType avgW = (wtv[i] + wtv[i + 1]) / static_cast<ValueType>(2.0);
1036  ValueType avgNumer = (nmv[i] + nmv[i + 1]) / static_cast<ValueType>(2.0);
1037  ValueType avgDenom = (dnv[i] + dnv[i + 1]) / static_cast<ValueType>(2.0);
1038 
1039  tmp1.push_back(avgW);
1040  tmp2.push_back(avgNumer);
1041  tmp3.push_back(avgDenom);
1042  }
1043  wtv = tmp1;
1044  nmv = tmp2;
1045  dnv = tmp3;
1046  n = nmv.size();
1047  }
1048 }
1049 
1050 } // namespace qmcplusplus
int num_params_
Number of optimizable parameters.
std::vector< std::vector< ValueType > > deriv_records_
Vector for storing Lagrangian derivatives from previous optimization steps.
DescentEngine(Communicate *comm, const xmlNodePtr cur)
Constructor for engine.
Communicate * my_comm_
Communicator handles MPI reduction.
std::vector< std::vector< ValueType > > replica_final_tnv_history_
std::vector< ValueType > final_tar_var_history_
a vector to store the variances of the target function during the descent finalization phase ...
std::vector< ValueType > final_tdv_history_
a history of target function denomerator times the |value/guiding|^2 ratios during the descent finali...
int store_count_
Counter of how many vectors have been stored so far.
std::vector< ValueType > final_vg_history_
history of sampled |value/guiding|^2 ratios during the descent finalization phase ...
Definition: DescentEngine.h:94
QMCTraits::RealType real
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
ValueType numer_err_
Standard error of the target function numerator.
Definition: DescentEngine.h:72
int final_descent_num_
Counter for the number of descent steps taken in the finalization phase.
std::vector< ValueType > tnv_history_
a history of target function numerator times the |value/guiding|^2 ratios for one iteration ...
int ramp_num_
Number of steps over which to ramp up step size.
std::vector< ValueType > denom_records_
Vector for storing step size denominator values from previous optimization step.
void sample_finish()
Function that reduces all vector information from all processors to the root processor.
qmcplusplus::QMCTraits::RealType RealType
Definition: DescentEngine.h:31
std::vector< ValueType > taus_
Vector for storing step sizes from previous optimization step.
ValueType tjf_2body_eta_
Step sizes for different types of parameters.
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::vector< std::vector< FullPrecValueType > > replica_denom_der_samp_
Vector for target function denominator parameter derivatives on one thread.
Definition: DescentEngine.h:53
std::vector< ValueType > vg_history_
history of sampled |value/guiding|^2 ratios for one iteration
Definition: DescentEngine.h:89
int store_num_
Number of parameter difference vectors stored when descent is used in a hybrid optimization.
ValueType target_avg_
Average target function value on a descent step.
Definition: DescentEngine.h:82
std::ostream & app_log()
Definition: OutputManager.h:65
std::vector< std::vector< ValueType > > replica_final_w_history_
ValueType denom_avg_
Average target function denominator on a descent step.
Definition: DescentEngine.h:75
void setupUpdate(const optimize::VariableSet &my_vars)
helper method for transferring information on parameter names and types to the engine ...
std::vector< ValueType > final_le_avg_history_
a vector to store the averages of the energy during the descent finalization phase ...
std::vector< std::vector< FullPrecValueType > > replica_numer_der_samp_
Vector for target function numerator parameter derivatives on one thread.
Definition: DescentEngine.h:48
int collection_step_
Iteration to start collecting samples for final average and error blocking analysis.
ValueType denom_err_
Standard error of the target function denominator.
Definition: DescentEngine.h:79
std::vector< ValueType > tdv_history_
a history of target function denominator times the |value/guiding|^2 ratios for one iteration ...
std::vector< int > engine_param_types_
void updateParameters()
helper method for updating parameter values with descent
std::vector< FullPrecValueType > avg_le_der_samp_
Vector for local energy parameter derivatives.
Definition: DescentEngine.h:36
std::vector< std::vector< ValueType > > hybrid_blm_input_
Vector for storing the input vectors to the BLM steps of hybrid method.
void prepareStorage(const int num_replicas, const int num_optimizables)
Prepare for taking samples.
ValueType e_err_
Standard error of the energy.
Definition: DescentEngine.h:65
std::vector< FullPrecValueType > avg_denom_der_samp_
Vector for target function denominator parameter derivatives.
Definition: DescentEngine.h:51
bool put(std::istream &is) override
read from std::istream
Definition: ParameterSet.h:42
std::vector< FullPrecValueType > avg_numer_der_samp_
Vector for target function numerator parameter derivatives.
Definition: DescentEngine.h:46
std::vector< FullPrecValueType > avg_der_rat_samp_
Vector for WF parameter derivatives.
Definition: DescentEngine.h:41
bool engine_target_excited_
Whether to target excited state.
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
std::vector< std::vector< ValueType > > replica_final_lev_history_
Wrapping information on parallelism.
Definition: Communicate.h:68
void allreduce(T &)
MakeReturn< BinaryNode< FnPow, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t pow(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
ValueType denom_var_
Variance of the target function denominator.
Definition: DescentEngine.h:77
std::vector< std::vector< ValueType > > replica_tnv_history_
std::vector< ValueType > lderivs_
Vector that stores the final averaged derivatives of the cost function.
int compute_step_
Iteration to start computing averages and errors from the stored values during the finalization phase...
std::vector< ValueType > w_history_
history of sampled configuration weights for one iteration
Definition: DescentEngine.h:99
std::vector< std::vector< ValueType > > replica_lev_history_
class to handle a set of parameters
Definition: ParameterSet.h:27
std::vector< std::string > engine_param_names_
Vectors of parameter names and types, used in the assignment of step sizes.
std::vector< ValueType > final_w_history_
history of sampled configuration weights during descent finalization phase
std::vector< std::vector< ValueType > > replica_tdv_history_
ValueType setStepSize(int i)
helper method for seting step sizes for different parameter types in descent optimization ...
ValueType e_sd_
Standard deviation of the energy.
Definition: DescentEngine.h:63
std::vector< ValueType > params_copy_
Vector for storing parameter values from previous optimization step.
std::vector< ValueType > current_params_
Vector for storing parameter values for current optimization step.
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
ValueType target_var_
Variance of the target function.
Definition: DescentEngine.h:84
void computeFinalizationUncertainties(std::vector< ValueType > &weights, std::vector< ValueType > &numerSamples, std::vector< ValueType > &denomSamples)
Compute uncertainties for energy/target function and variance over a history of samples from a set of...
std::vector< ValueType > final_var_avg_history_
a vector to store the variances of the energy during the descent finalization phase ...
int where(int i) const
return the locator of the i-th Index
Definition: VariableSet.h:90
int getType(int i) const
get the i-th parameter&#39;s type
Definition: VariableSet.h:204
std::vector< ValueType > final_tar_avg_history_
a vector to store the averages of the target function during the descent finalization phase ...
MakeReturn< UnaryNode< FnExp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t exp(const Vector< T1, C1 > &l)
ValueType w_sum_
Total sum of weights.
Definition: DescentEngine.h:56
size_type size() const
return the size
Definition: VariableSet.h:88
double sign(double x)
Definition: Standard.h:73
bool processXML(const xmlNodePtr cur)
process xml node
ValueType numer_avg_
Average target function numerator on a descent step.
Definition: DescentEngine.h:68
ValueType e_avg_
Average energy on a descent step.
Definition: DescentEngine.h:59
void add(PDT &aparam, const std::string &aname_in, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new parameter corresponding to an xmlNode <parameter>
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
qmcplusplus::QMCTraits::ValueType ValueType
Definition: DescentEngine.h:30
std::vector< ValueType > final_lev_history_
history of sampled local energies times the |value/guiding|^2 raitos during the descent finalization ...
ValueType omega_
Value of omega in excited state functional.
bool ramp_eta_
Whether to gradually ramp up step sizes in descent.
std::vector< std::vector< FullPrecValueType > > replica_le_der_samp_
Vector for local energy parameter derivatives on one thread.
Definition: DescentEngine.h:38
const std::string & name(int i) const
return the name of i-th variable
Definition: VariableSet.h:189
std::vector< ValueType > derivs_squared_
Vector for storing running average of squares of the derivatives.
std::vector< ValueType > params_for_diff_
Vector for storing parameter values for calculating differences to be given to hybrid method...
int descent_num_
Integer for keeping track of only number of descent steps taken.
bool collect_count_
Whether to start collecting samples for the histories in the finalization phase.
void mpi_unbiased_ratio_of_means(int numSamples, std::vector< ValueType > &weights, std::vector< ValueType > &numerSamples, std::vector< ValueType > &denomSamples, ValueType &mean, ValueType &variance, ValueType &stdErr)
Function for computing ratios of the form <f>/<g> as well as the associated variance and standard err...
ValueType lambda_
Parameter for accelerated descent recursion relation.
std::vector< std::vector< FullPrecValueType > > replica_der_rat_samp_
Vector for WF parameter derivatives on one thread.
Definition: DescentEngine.h:43
void storeVectors(std::vector< ValueType > &current_params)
Store a vector of parameter differences to be used by the BLM in a hybrid optimization.
std::vector< std::vector< ValueType > > replica_final_vg_history_
Definition: DescentEngine.h:95
std::vector< std::vector< ValueType > > replica_final_tdv_history_
qmcplusplus::QMCTraits::FullPrecValueType FullPrecValueType
Definition: DescentEngine.h:29
std::string flavor_
What variety of gradient descent will be used.
std::vector< ValueType > lev_history_
a history of sampled local energies times the |value/guiding|^2 raitos for one iteration ...
ValueType e_var_
Variance of the energy.
Definition: DescentEngine.h:61
void takeSample(const int replica_id, const std::vector< FullPrecValueType > &der_rat_samp, const std::vector< FullPrecValueType > &le_der_samp, const std::vector< FullPrecValueType > &ls_der_samp, ValueType vgs_samp, ValueType weight_samp)
Function that Take Sample Data from the Host Code.
std::string print_deriv_
Whether to print out derivative terms for each parameter.
ACC::value_type mean(const ACC &ac)
Definition: accumulators.h:147
std::vector< ValueType > numer_records_
Vector for storing step size numerator values from previous optimization step.
std::vector< std::vector< ValueType > > replica_w_history_
ValueType target_err_
Standard error of the target function.
Definition: DescentEngine.h:86
std::vector< std::vector< ValueType > > replica_vg_history_
Definition: DescentEngine.h:90
ValueType numer_var_
Variance of the target function numerator.
Definition: DescentEngine.h:70
bool isnan(float a)
return true if the value is NaN.
Definition: math.cpp:18
std::vector< ValueType > final_tnv_history_
a history of target function numerator times the |value/guiding|^2 ratios during the descent finaliza...