1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 //                    Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
9 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
10 //                    Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //                    Ye Luo, yeluo@anl.gov, Argonne National Laboratory
12 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 //
14 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
15 //////////////////////////////////////////////////////////////////////////////////////
16 
17 
18 #include "QMCCostFunctionBase.h"
19 #include "Particle/MCWalkerConfiguration.h"
20 #include "OhmmsData/AttributeSet.h"
21 #include "OhmmsData/ParameterSet.h"
22 #include "Message/CommOperators.h"
23 #include "Optimize/LeastSquaredFit.h"
24 #include <set>
25 //#define QMCCOSTFUNCTION_DEBUG
26 
27 
28 namespace qmcplusplus
29 {
QMCCostFunctionBase(MCWalkerConfiguration & w,TrialWaveFunction & psi,QMCHamiltonian & h,Communicate * comm)30 QMCCostFunctionBase::QMCCostFunctionBase(MCWalkerConfiguration& w,
31                                          TrialWaveFunction& psi,
32                                          QMCHamiltonian& h,
33                                          Communicate* comm)
34     : MPIObjectBase(comm),
35       reportH5(false),
36       CI_Opt(false),
37       W(w),
38       Psi(psi),
39       H(h),
40       Write2OneXml(true),
41       PowerE(2),
42       NumCostCalls(0),
43       NumSamples(0),
44       w_en(0.9),
45       w_var(0.1),
46       w_abs(0.0),
47       w_w(0.0),
48       MaxWeight(1e6),
49       w_beta(0.0),
50       GEVType("mixed"),
51       vmc_or_dmc(2.0),
52       needGrads(true),
53       targetExcitedStr("no"),
54       targetExcited(false),
55       omega_shift(0.0),
56       msg_stream(0),
57       m_wfPtr(NULL),
58       m_doc_out(NULL),
59       includeNonlocalH("no"),
60       debug_stream(0)
61 {
62   GEVType = "mixed";
63   //paramList.resize(10);
64   //costList.resize(10,0.0);
65   //default: don't check fo MinNumWalkers
66   MinNumWalkers = 0.3;
67   SumValue.resize(SUM_INDEX_SIZE, 0.0);
68   IsValid      = true;
69   useNLPPDeriv = false;
70 #if defined(QMCCOSTFUNCTION_DEBUG)
71   char fname[16];
72   sprintf(fname, "optdebug.p%d", OHMMS::Controller->mycontext());
73   debug_stream = new std::ofstream(fname);
74   debug_stream->setf(std::ios::scientific, std::ios::floatfield);
75   debug_stream->precision(8);
76 #endif
77 }
78 
79 /** Clean up the vector */
~QMCCostFunctionBase()80 QMCCostFunctionBase::~QMCCostFunctionBase()
81 {
82   delete_iter(dLogPsi.begin(), dLogPsi.end());
83   delete_iter(d2LogPsi.begin(), d2LogPsi.end());
84   //     if (m_doc_out != NULL) xmlFreeDoc(m_doc_out);
85   if (debug_stream)
86     delete debug_stream;
87 }
88 
setRng(std::vector<RandomGenerator_t * > & r)89 void QMCCostFunctionBase::setRng(std::vector<RandomGenerator_t*>& r)
90 {
91   if (MoverRng.size() < r.size())
92   {
93     delete_iter(MoverRng.begin(), MoverRng.end());
94     delete_iter(RngSaved.begin(), RngSaved.end());
95     MoverRng.resize(r.size());
96     RngSaved.resize(r.size());
97   }
98   for (int ip = 0; ip < r.size(); ++ip)
99     MoverRng[ip] = r[ip];
100   for (int ip = 0; ip < r.size(); ++ip)
101     RngSaved[ip] = new RandomGenerator_t(*MoverRng[ip]);
102 }
103 
setTargetEnergy(Return_rt et)104 void QMCCostFunctionBase::setTargetEnergy(Return_rt et)
105 {
106   //evaluate effective target energy
107   EtargetEff = Etarget = et;
108   //     app_log() << "Effective Target Energy = " << EtargetEff << std::endl;
109   //     app_log() << "Cost Function = " << w_en << "*<E> + "
110   //     << w_var << "*<Var> + " << w_w << "*<Var(unreweighted)> " << std::endl;
111   //if(UseWeight)
112   //app_log() << "Correlated sampling is used." << std::endl;
113   //else
114   //app_log() << "Weight is set to one." << std::endl;
115   //     if (msg_stream)
116   //       {
117   //         *msg_stream << "  Total number of walkers          = " << NumSamples << std::endl;
118   //         *msg_stream << "  Effective Target Energy = " << EtargetEff << std::endl;
119   //         *msg_stream << "  Cost Function = " << w_en << "*<E> + " << w_var << "*<Var> + " << w_w << "*<Var(unreweighted)> " << std::endl;
120   //         *msg_stream << "  Optimization report = ";
121   //         *msg_stream << "cost, walkers, eavg/wgt, eavg/walkers, evar/wgt, evar/walkers, evar_abs\n";
122   //         *msg_stream << "  Optimized variables = " << OptVariables.name(0);
123   //         for (int i=1; i<OptVariables.size(); ++i) *msg_stream << "," << OptVariables.name(i) ;
124   //         *msg_stream << std::endl;
125   //       }
126 }
127 
Cost(bool needGrad)128 QMCCostFunctionBase::Return_rt QMCCostFunctionBase::Cost(bool needGrad)
129 {
130   NumCostCalls++;
131   //reset the wave function
132   resetPsi();
133   //evaluate new local energies
134   NumWalkersEff = correlatedSampling(needGrad);
135   return computedCost();
136 }
137 
printEstimates()138 void QMCCostFunctionBase::printEstimates()
139 {
140   app_log() << "      Current ene:     " << curAvg_w << std::endl;
141   app_log() << "      Current var:     " << curVar_w << std::endl;
142   app_log() << "      Current ene_urw:     " << curAvg << std::endl;
143   app_log() << "      Current var_urw: " << curVar << std::endl;
144 }
145 
computedCost()146 QMCCostFunctionBase::Return_rt QMCCostFunctionBase::computedCost()
147 {
148   //   Assumes the Sums have been computed all ready
149   //Estimators::accumulate has been called by correlatedSampling
150   curAvg_w         = SumValue[SUM_E_WGT] / SumValue[SUM_WGT];
151   curVar_w         = SumValue[SUM_ESQ_WGT] / SumValue[SUM_WGT] - curAvg_w * curAvg_w;
152   Return_rt wgtinv = 1.0 / static_cast<Return_rt>(NumSamples);
153   // app_log() << "wgtinv = " << wgtinv << std::endl;
154   curAvg     = SumValue[SUM_E_BARE] * wgtinv;
155   curVar     = SumValue[SUM_ESQ_BARE] * wgtinv - curAvg * curAvg;
156   curVar_abs = SumValue[SUM_ABSE_WGT] / SumValue[SUM_WGT];
157   // app_log() << "curVar     = " << curVar
158   //     << "   curAvg     = " << curAvg
159   //     << "   NumWalkersEff     = " << NumWalkersEff << std::endl;
160   // app_log() << "SumValue[SUM_WGT] = " << SumValue[SUM_WGT] << std::endl;
161   // app_log() << "SumValue[SUM_WGTSQ] = " << SumValue[SUM_WGTSQ] << std::endl;
162   // app_log() << "SumValue[SUM_ABSE_WGT] = " << SumValue[SUM_ABSE_WGT] << std::endl;
163   // app_log() << "SumValue[SUM_E_WGT] = " << SumValue[SUM_E_WGT] << std::endl;
164   // app_log() << "SumValue[SUM_ESQ_WGT] = " << SumValue[SUM_ESQ_WGT] << std::endl;
165   Return_rt wgt_var = SumValue[SUM_WGTSQ] - SumValue[SUM_WGT] * SumValue[SUM_WGT];
166   wgt_var *= wgtinv;
167   CostValue             = 0.0;
168   const Return_rt small = 1.0e-10;
169   if (std::abs(w_abs) > small)
170     CostValue += w_abs * curVar_abs;
171   if (std::abs(w_var) > small)
172     CostValue += w_var * curVar_w;
173   if (std::abs(w_en) > small)
174     CostValue += w_en * curAvg_w;
175   if (std::abs(w_w) > small)
176     CostValue += w_w * curVar;
177   //CostValue = w_abs*curVar_abs + w_var*curVar_w + w_en*curAvg_w + w_w*curVar;
178   // app_log() << "CostValue, NumEffW = " << CostValue <<"  " <<NumWalkersEff << std::endl;
179   IsValid = true;
180   if (NumWalkersEff < NumSamples * MinNumWalkers)
181   //    if (NumWalkersEff < MinNumWalkers)
182   {
183     ERRORMSG("CostFunction-> Number of Effective Walkers is too small! "
184              << std::endl
185              << "  Number of effective walkers (samples) / total number of samples = "
186              << (1.0 * NumWalkersEff) / NumSamples << std::endl
187              << "  User specified threshold minwalkers = " << MinNumWalkers << std::endl
188              << "  If this message appears frequently. You might have to be cautious. " << std::endl
189              << "  Find info about parameter \"minwalkers\" in the user manual!");
190     // ERRORMSG("Going to stop now.")
191     IsValid = false;
192   }
193   return CostValue;
194 }
195 
196 
Report()197 void QMCCostFunctionBase::Report()
198 {
199   //reset the wavefunction for with the new variables
200   resetPsi();
201   if (!myComm->rank())
202   {
203     updateXmlNodes();
204     char newxml[128];
205     if (Write2OneXml)
206       sprintf(newxml, "%s.opt.xml", RootName.c_str());
207     else
208       sprintf(newxml, "%s.opt.%d.xml", RootName.c_str(), ReportCounter);
209     xmlSaveFormatFile(newxml, m_doc_out, 1);
210     if (msg_stream)
211     {
212       msg_stream->precision(8);
213       *msg_stream << " curCost " << std::setw(5) << ReportCounter << std::setw(16) << CostValue << std::setw(16)
214                   << NumWalkersEff << std::setw(16) << curAvg_w << std::setw(16) << curAvg << std::setw(16) << curVar_w
215                   << std::setw(16) << curVar << std::setw(16) << curVar_abs << std::endl;
216       *msg_stream << " curVars " << std::setw(5) << ReportCounter;
217       for (int i = 0; i < OptVariables.size(); i++)
218         *msg_stream << std::setw(16) << OptVariables[i];
219       *msg_stream << std::endl;
220     }
221     //report the data
222     //Psi.reportStatus(*mgs_stream);
223   }
224 #if defined(QMCCOSTFUNCTION_DEBUG)
225   *debug_stream << ReportCounter;
226   OptVariables.print(*debug_stream);
227   *debug_stream << std::endl;
228 #endif
229   ReportCounter++;
230   //myComm->barrier();
231 }
232 
reportParameters()233 void QMCCostFunctionBase::reportParameters()
234 {
235   //final reset, restoring the WaveFunctionComponent::IsOptimizing to false
236   resetPsi(true);
237   if (!myComm->rank())
238   {
239     char newxml[128];
240     sprintf(newxml, "%s.opt.xml", RootName.c_str());
241     *msg_stream << "  <optVariables href=\"" << newxml << "\">" << std::endl;
242     OptVariables.print(*msg_stream);
243     *msg_stream << "  </optVariables>" << std::endl;
244     updateXmlNodes();
245     xmlSaveFormatFile(newxml, m_doc_out, 1);
246   }
247 }
248 /** This function stores optimized CI coefficients in HDF5
249   * Other parameters (Jastors, orbitals), can also be stored to H5 from this function
250   * This function should be called before reportParameters()
251   * Since it is needed to call updateXmlNodes() and xmlSaveFormatFile()
252   * While it is possible to call updateXmlNodes() from QMCLinearOptimize.cpp
253   * It is not clean to call xmlSaveFormatFile() from QMCLinearOptimize.cpp
254   *
255   * @param OptVariables.size() OptVariables.name(i) OptVariables[i]
256   *
257   * OptVariables.size(): contains the total number of Optimized variables (not Only CI coeff)
258   * OptVariables.name(i): the tag of the optimized variable. To store we use the name of the variable
259   * OptVariables[i]: The new value of the optimized variable
260 */
reportParametersH5()261 void QMCCostFunctionBase::reportParametersH5()
262 {
263   if (!myComm->rank())
264   {
265     int ci_size = 0;
266     std::vector<opt_variables_type::value_type> CIcoeff;
267     for (int i = 0; i < OptVariables.size(); i++)
268     {
269       char Coeff[128];
270       sprintf(Coeff, "CIcoeff_%d", ci_size + 1);
271       if (Coeff != OptVariables.name(i))
272       {
273         if (ci_size > 0)
274           break;
275         else
276           continue;
277       }
278 
279       CIcoeff.push_back(OptVariables[i]);
280       ci_size++;
281     }
282     if (ci_size > 0)
283     {
284       CI_Opt = true;
285       //         sprintf(newh5, "%s.opt.h5", RootName.c_str());
286       newh5 = RootName + ".opt.h5";
287       *msg_stream << "  <Ci Coeffs saved in opt_coeffs=\"" << newh5 << "\">" << std::endl;
288       hdf_archive hout;
289       hout.create(newh5, H5F_ACC_TRUNC);
290       hout.push("MultiDet", true);
291       hout.write(ci_size, "NbDet");
292       hout.write(CIcoeff, "Coeff");
293       hout.close();
294     }
295   }
296 }
297 /** Apply constraints on the optimizables.
298  *
299  * Here is where constraints should go
300  */
checkParameters()301 bool QMCCostFunctionBase::checkParameters()
302 {
303   bool samesign = true;
304   //if(samesign) {
305   //  paramList.pop_back();
306   //  paramList.push_front(OptParams);
307   //}
308   return samesign;
309 }
310 
311 
312 /** Parses the xml input file for parameter definitions for the wavefunction optimization.
313  * @param q current xmlNode
314  * @return true if successful
315  *
316  * Must provide a list of the id's of the variables to be optimized. Other available elements
317  <ul>
318  <li> mcwalkerset->file: name of configuration file
319  <li> optimize->method: method of optimization, right now only
320  congjugate gradient
321  <li> cost->weight: either weight for the energy term, default 1.0,
322  or weight for the variance, default 1.0
323  <li> tolerance: for conjugate gradient, default 1e-8
324  <li> stepsize: for conjugate gradient, default 0.01
325  <li> epsilon: for conjugate gradient, default 1e-6
326  </ul>
327  */
put(xmlNodePtr q)328 bool QMCCostFunctionBase::put(xmlNodePtr q)
329 {
330   std::string writeXmlPerStep("no");
331   std::string computeNLPPderiv("no");
332   ParameterSet m_param;
333   m_param.add(writeXmlPerStep, "dumpXML");
334   m_param.add(MinNumWalkers, "minwalkers");
335   m_param.add(MaxWeight, "maxWeight");
336   m_param.add(includeNonlocalH, "nonlocalpp");
337   m_param.add(computeNLPPderiv, "use_nonlocalpp_deriv");
338   m_param.add(w_beta, "beta");
339   m_param.add(GEVType, "GEVMethod");
340   m_param.add(targetExcitedStr, "targetExcited");
341   m_param.add(omega_shift, "omega");
342   m_param.put(q);
343 
344   tolower(targetExcitedStr);
345   targetExcited = (targetExcitedStr == "yes");
346 
347   if (includeNonlocalH == "yes")
348     includeNonlocalH = "NonLocalECP";
349 
350   if (computeNLPPderiv != "no" && includeNonlocalH != "no")
351   {
352     app_log() << "   Going to include the derivatives of " << includeNonlocalH << std::endl;
353     useNLPPDeriv = true;
354   }
355   // app_log() << "  QMCCostFunctionBase::put " << std::endl;
356   // m_param.get(app_log());
357   Write2OneXml     = (writeXmlPerStep == "no");
358   xmlNodePtr qsave = q;
359   //Estimators.put(q);
360   std::vector<xmlNodePtr> cset;
361   std::vector<std::string> excluded;
362   std::map<std::string, std::vector<std::string>*> equalConstraints;
363   std::map<std::string, std::vector<std::string>*> negateConstraints;
364   std::vector<std::string> idtag;
365   xmlNodePtr cur = qsave->children;
366   int pid        = myComm->rank();
367   while (cur != NULL)
368   {
369     std::string cname((const char*)(cur->name));
370     if (cname == "optimize")
371     {
372       std::vector<std::string> tmpid;
373       putContent(tmpid, cur);
374       idtag.insert(idtag.end(), tmpid.begin(), tmpid.end());
375     }
376     else if (cname == "exclude")
377     {
378       std::vector<std::string> tmpid;
379       putContent(tmpid, cur);
380       excluded.insert(excluded.end(), tmpid.begin(), tmpid.end());
381     }
382     else if (cname == "cost")
383     {
384       cset.push_back(cur);
385     }
386     else if (cname == "set")
387     {
388       std::string ctype("equal");
389       std::string s("0");
390       OhmmsAttributeSet pAttrib;
391       pAttrib.add(ctype, "type");
392       pAttrib.add(s, "name");
393       pAttrib.put(cur);
394       if (ctype == "equal" || ctype == "=")
395       {
396         std::map<std::string, std::vector<std::string>*>::iterator eit(equalConstraints.find(s));
397         std::vector<std::string>* eqSet = 0;
398         if (eit == equalConstraints.end())
399         {
400           eqSet               = new std::vector<std::string>;
401           equalConstraints[s] = eqSet;
402         }
403         else
404           eqSet = (*eit).second;
405         std::vector<std::string> econt;
406         putContent(econt, cur);
407         eqSet->insert(eqSet->end(), econt.begin(), econt.end());
408       }
409     }
410     cur = cur->next;
411   }
412   //build optimizables from the wavefunction
413   OptVariablesForPsi.clear();
414   Psi.checkInVariables(OptVariablesForPsi);
415   OptVariablesForPsi.resetIndex();
416   //synchronize OptVariables and OptVariablesForPsi
417   OptVariables  = OptVariablesForPsi;
418   InitVariables = OptVariablesForPsi;
419   //first disable <exclude>.... </exclude> from the big list used by a TrialWaveFunction
420   OptVariablesForPsi.disable(excluded.begin(), excluded.end(), false);
421   //now, set up the real variable list for optimization
422   //check <equal>
423   int nc = 0;
424   if (equalConstraints.size())
425   {
426     std::map<std::string, std::vector<std::string>*>::iterator eit(equalConstraints.begin());
427     while (eit != equalConstraints.end())
428     {
429       nc += (*eit).second->size();
430       //actiave the active variable even though it is probably unnecessary
431       OptVariablesForPsi.activate((*eit).second->begin(), (*eit).second->end(), false);
432       excluded.insert(excluded.end(), (*eit).second->begin(), (*eit).second->end());
433       ++eit;
434     }
435   }
436   //build OptVariables which is equal to or identical to OptVariablesForPsi
437   //disable the variables that are equal to a variable
438   OptVariables.disable(excluded.begin(), excluded.end(), false);
439   //set up OptVariables and OptVariablesForPsi
440   OptVariables.activate(idtag.begin(), idtag.end(), true);
441   OptVariablesForPsi.activate(idtag.begin(), idtag.end(), true);
442   //found constraints build equalVarMap
443   if (nc > 0)
444   {
445     equalVarMap.reserve(nc + OptVariables.size());
446     //map the basic lists from the active list
447     for (int i = 0; i < OptVariables.size(); ++i)
448     {
449       int bigloc = OptVariablesForPsi.getIndex(OptVariables.name(i));
450       if (bigloc < 0)
451         continue;
452       equalVarMap.push_back(TinyVector<int, 2>(bigloc, i));
453     }
454     //add <equal/>
455     std::map<std::string, std::vector<std::string>*>::iterator eit(equalConstraints.begin());
456     while (eit != equalConstraints.end())
457     {
458       int loc = OptVariables.getIndex((*eit).first);
459       if (loc >= 0)
460       {
461         const std::vector<std::string>& elist(*((*eit).second));
462         for (int i = 0; i < elist.size(); ++i)
463         {
464           int bigloc = OptVariablesForPsi.getIndex(elist[i]);
465           if (bigloc < 0)
466             continue;
467           equalVarMap.push_back(TinyVector<int, 2>(bigloc, loc));
468         }
469       }
470       //remove std::vector<std::string>
471       delete (*eit).second;
472       ++eit;
473     }
474   }
475   //get the indices
476   Psi.checkOutVariables(OptVariablesForPsi);
477   NumOptimizables = OptVariables.size();
478   if (NumOptimizables == 0)
479   {
480     APP_ABORT("QMCCostFunctionBase::put No valid optimizable variables are found.");
481   }
482   //     app_log() << "<active-optimizables> " << std::endl;
483   //     OptVariables.print(app_log());
484   //     app_log() << "</active-optimizables>" << std::endl;
485   if (msg_stream)
486     msg_stream->setf(std::ios::scientific, std::ios::floatfield);
487   resetPsi();
488   //     Psi.reportStatus(app_log());
489   //set the cost function
490   if (cset.empty())
491   {
492     if (msg_stream)
493       *msg_stream << " Using Default Cost Function: Cost = <|E-E_ff|^2>" << std::endl;
494   }
495   else
496     resetCostFunction(cset);
497   //maybe overwritten but will try out
498   EtargetEff = Etarget;
499   return true;
500 }
501 
resetCostFunction(std::vector<xmlNodePtr> & cset)502 void QMCCostFunctionBase::resetCostFunction(std::vector<xmlNodePtr>& cset)
503 {
504   for (int i = 0; i < cset.size(); i++)
505   {
506     std::string pname;
507     OhmmsAttributeSet pAttrib;
508     pAttrib.add(pname, "name");
509     pAttrib.put(cset[i]);
510     if (pname == "energy")
511       putContent(w_en, cset[i]);
512     else if ((pname == "variance") || (pname == "unreweightedvariance"))
513       putContent(w_w, cset[i]);
514     else if (pname == "difference")
515       putContent(w_abs, cset[i]);
516     else if ((pname == "reweightedVariance") || (pname == "reweightedvariance"))
517       putContent(w_var, cset[i]);
518   }
519 }
520 
521 
updateXmlNodes()522 void QMCCostFunctionBase::updateXmlNodes()
523 {
524   if (m_doc_out == NULL) //first time, create a document tree and get parameters and attributes to be updated
525   {
526     m_doc_out          = xmlNewDoc((const xmlChar*)"1.0");
527     xmlNodePtr qm_root = xmlNewNode(NULL, BAD_CAST "qmcsystem");
528     xmlAddChild(qm_root, m_wfPtr);
529     xmlDocSetRootElement(m_doc_out, qm_root);
530     xmlXPathContextPtr acontext = xmlXPathNewContext(m_doc_out);
531 
532     //check var
533     xmlXPathObjectPtr result = xmlXPathEvalExpression((const xmlChar*)"//var", acontext);
534     for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
535     {
536       xmlNodePtr cur      = result->nodesetval->nodeTab[iparam];
537       const xmlChar* iptr = xmlGetProp(cur, (const xmlChar*)"id");
538       if (iptr == NULL)
539         continue;
540       std::string aname((const char*)iptr);
541       opt_variables_type::iterator oit(OptVariablesForPsi.find(aname));
542       if (oit != OptVariablesForPsi.end())
543       {
544         paramNodes[aname] = cur;
545       }
546     }
547     xmlXPathFreeObject(result);
548     //check radfunc
549     result = xmlXPathEvalExpression((const xmlChar*)"//radfunc", acontext);
550     for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
551     {
552       xmlNodePtr cur      = result->nodesetval->nodeTab[iparam];
553       const xmlChar* iptr = xmlGetProp(cur, (const xmlChar*)"id");
554       if (iptr == NULL)
555         continue;
556       std::string aname((const char*)iptr);
557       std::string expID = aname + "_E";
558       xmlAttrPtr aptr   = xmlHasProp(cur, (const xmlChar*)"exponent");
559       opt_variables_type::iterator oit(OptVariablesForPsi.find(expID));
560       if (aptr != NULL && oit != OptVariablesForPsi.end())
561       {
562         attribNodes[expID] = std::pair<xmlNodePtr, std::string>(cur, "exponent");
563       }
564       std::string cID = aname + "_C";
565       aptr            = xmlHasProp(cur, (const xmlChar*)"contraction");
566       oit             = OptVariablesForPsi.find(cID);
567       if (aptr != NULL && oit != OptVariablesForPsi.end())
568       {
569         attribNodes[cID] = std::pair<xmlNodePtr, std::string>(cur, "contraction");
570       }
571     }
572     xmlXPathFreeObject(result);
573     //check ci
574     result = xmlXPathEvalExpression((const xmlChar*)"//ci", acontext);
575     for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
576     {
577       xmlNodePtr cur      = result->nodesetval->nodeTab[iparam];
578       const xmlChar* iptr = xmlGetProp(cur, (const xmlChar*)"id");
579       if (iptr == NULL)
580         continue;
581       std::string aname((const char*)iptr);
582       xmlAttrPtr aptr = xmlHasProp(cur, (const xmlChar*)"coeff");
583       opt_variables_type::iterator oit(OptVariablesForPsi.find(aname));
584       if (aptr != NULL && oit != OptVariablesForPsi.end())
585       {
586         attribNodes[aname] = std::pair<xmlNodePtr, std::string>(cur, "coeff");
587       }
588     }
589     xmlXPathFreeObject(result);
590     //check csf
591     result = xmlXPathEvalExpression((const xmlChar*)"//csf", acontext);
592     for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
593     {
594       xmlNodePtr cur      = result->nodesetval->nodeTab[iparam];
595       const xmlChar* iptr = xmlGetProp(cur, (const xmlChar*)"id");
596       if (iptr == NULL)
597         continue;
598       std::string aname((const char*)iptr);
599       xmlAttrPtr aptr = xmlHasProp(cur, (const xmlChar*)"coeff");
600       opt_variables_type::iterator oit(OptVariablesForPsi.find(aname));
601       if (aptr != NULL && oit != OptVariablesForPsi.end())
602       {
603         attribNodes[aname] = std::pair<xmlNodePtr, std::string>(cur, "coeff");
604       }
605     }
606     xmlXPathFreeObject(result);
607     if (CI_Opt)
608     {
609       //check multidet
610       result = xmlXPathEvalExpression((const xmlChar*)"//detlist", acontext);
611       for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
612       {
613         xmlNodePtr cur = result->nodesetval->nodeTab[iparam];
614         xmlSetProp(cur, (const xmlChar*)"opt_coeffs", (const xmlChar*)newh5.c_str());
615       }
616       xmlXPathFreeObject(result);
617     }
618 
619     addCoefficients(acontext, "//coefficient");
620     addCoefficients(acontext, "//coefficients");
621     addCJParams(acontext, "//jastrow");
622     xmlXPathFreeContext(acontext);
623   }
624   //     Psi.reportStatus(app_log());
625   std::map<std::string, xmlNodePtr>::iterator pit(paramNodes.begin()), pit_end(paramNodes.end());
626   while (pit != pit_end)
627   {
628     //FIXME real value is forced here to makde sure that the code builds
629     Return_rt v = std::real(OptVariablesForPsi[(*pit).first]);
630     getContent(v, (*pit).second);
631     //         vout <<(*pit).second<< std::endl;
632     ++pit;
633   }
634   std::map<std::string, std::pair<xmlNodePtr, std::string>>::iterator ait(attribNodes.begin()),
635       ait_end(attribNodes.end());
636   while (ait != ait_end)
637   {
638     std::ostringstream vout;
639     vout.setf(std::ios::scientific, std::ios::floatfield);
640     vout.precision(16);
641     vout << OptVariablesForPsi[(*ait).first];
642     xmlSetProp((*ait).second.first, (const xmlChar*)(*ait).second.second.c_str(), (const xmlChar*)vout.str().c_str());
643     ++ait;
644   }
645   std::map<std::string, xmlNodePtr>::iterator cit(coeffNodes.begin()), cit_end(coeffNodes.end());
646   while (cit != cit_end)
647   {
648     std::string rname((*cit).first);
649     OhmmsAttributeSet cAttrib;
650     std::string datatype("none");
651     std::string aname("0");
652     cAttrib.add(datatype, "type");
653     cAttrib.add(aname, "id");
654     cAttrib.put((*cit).second);
655     if (datatype == "Array")
656     {
657       //
658       aname.append("_");
659       opt_variables_type::iterator vit(OptVariablesForPsi.begin());
660       std::vector<Return_rt> c;
661       while (vit != OptVariablesForPsi.end())
662       {
663         if ((*vit).first.find(aname) == 0)
664         {
665           //FIXME real value is forced here to makde sure that the code builds
666           c.push_back(std::real((*vit).second));
667         }
668         ++vit;
669       }
670       xmlNodePtr contentPtr = cit->second;
671       if (xmlNodeIsText(contentPtr->children))
672         contentPtr = contentPtr->children;
673       getContent(c, contentPtr);
674     }
675     // counting jastrow variables
676     else if (rname.find("cj_") == 0)
677     {
678       printCJParams(cit->second, rname);
679     }
680     else
681     {
682       xmlNodePtr cur = (*cit).second->children;
683       while (cur != NULL)
684       {
685         std::string cname((const char*)(cur->name));
686         if (cname == "lambda")
687         {
688           int i = 0;
689           int j = -1;
690           OhmmsAttributeSet pAttrib;
691           pAttrib.add(i, "i");
692           pAttrib.add(j, "j");
693           pAttrib.put(cur);
694           char lambda_id[32];
695           if (j < 0)
696             sprintf(lambda_id, "%s_%d", rname.c_str(), i);
697           else
698             sprintf(lambda_id, "%s_%d_%d", rname.c_str(), i, j);
699           opt_variables_type::iterator vTarget(OptVariablesForPsi.find(lambda_id));
700           if (vTarget != OptVariablesForPsi.end())
701           {
702             std::ostringstream vout;
703             vout.setf(std::ios::scientific, std::ios::floatfield);
704             vout.precision(16);
705             vout << (*vTarget).second;
706             xmlSetProp(cur, (const xmlChar*)"c", (const xmlChar*)vout.str().c_str());
707           }
708         }
709         cur = cur->next;
710       }
711     }
712     ++cit;
713   }
714 }
715 
716 /** add coefficient or coefficients
717  * @param acontext context from which xpath cname is searched
718  * @param cname xpath
719  */
addCoefficients(xmlXPathContextPtr acontext,const char * cname)720 void QMCCostFunctionBase::addCoefficients(xmlXPathContextPtr acontext, const char* cname)
721 {
722   xmlXPathObjectPtr result = xmlXPathEvalExpression((const xmlChar*)cname, acontext);
723   for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
724   {
725     xmlNodePtr cur = result->nodesetval->nodeTab[iparam];
726     OhmmsAttributeSet cAttrib;
727     std::string aname("0");
728     std::string optimize("yes");
729     std::string datatype("none");
730     cAttrib.add(aname, "id");
731     cAttrib.add(aname, "name");
732     cAttrib.add(datatype, "type");
733     cAttrib.add(optimize, "optimize");
734     cAttrib.put(cur);
735     if (aname[0] == '0')
736       continue;
737     if (datatype == "Array")
738     {
739       if (optimize == "yes")
740         coeffNodes[aname] = cur;
741     }
742     else
743     {
744       //check if any optimizables contains the id of coefficients
745       bool notlisted = true;
746       opt_variables_type::iterator oit(OptVariablesForPsi.begin()), oit_end(OptVariablesForPsi.end());
747       while (notlisted && oit != oit_end)
748       {
749         const std::string& oname((*oit).first);
750         notlisted = (oname.find(aname) >= oname.size());
751         ++oit;
752       }
753       if (!notlisted)
754       {
755         coeffNodes[aname] = cur;
756       }
757     }
758   }
759   xmlXPathFreeObject(result);
760 }
761 
addCJParams(xmlXPathContextPtr acontext,const char * cname)762 void QMCCostFunctionBase::addCJParams(xmlXPathContextPtr acontext, const char* cname)
763 {
764   xmlXPathObjectPtr result = xmlXPathEvalExpression((const xmlChar*)cname, acontext);
765   for (int iparam = 0; iparam < result->nodesetval->nodeNr; iparam++)
766   {
767     // check that we're in a counting jastrow tag space
768     xmlNodePtr cur = result->nodesetval->nodeTab[iparam];
769     OhmmsAttributeSet cAttrib;
770     std::string aname("none");
771     std::string atype("none");
772     cAttrib.add(aname, "name");
773     cAttrib.add(atype, "type");
774     cAttrib.put(cur);
775     if (atype == "Counting")
776     {
777       // iterate through children
778       xmlNodePtr cur2 = cur->xmlChildrenNode;
779       int Fnum        = 0;
780       bool Ftag_found = false;
781       // find the <var name="F" /> tag, save the location
782       while (cur2 != NULL)
783       {
784         std::string tname2((const char*)cur2->name);
785         OhmmsAttributeSet cAttrib2;
786         std::string aname2("none");
787         std::string aopt2("yes");
788         std::string ref_id("g0");
789         cAttrib2.add(aname2, "name");
790         cAttrib2.add(aopt2, "opt");
791         cAttrib2.add(ref_id, "reference_id");
792         cAttrib2.put(cur2);
793         // find the <var name="F" /> tags and register the tag location first
794         if (tname2 == "var" && aname2 == "F" && (aopt2 == "yes" || aopt2 == "true"))
795         {
796           coeffNodes["cj_F"] = cur2;
797           Ftag_found         = true;
798         }
799         cur2 = cur2->next;
800       }
801 
802       // count the total number of registered F matrix variables
803       opt_variables_type::iterator oit(OptVariables.begin()), oit_end(OptVariables.end());
804       for (; oit != oit_end; ++oit)
805       {
806         const std::string& oname((*oit).first);
807         if (oname.find("F_") == 0)
808           ++Fnum;
809       }
810       ++Fnum;
811 
812       // F variable tag isn't found; build the tag.
813       if (!Ftag_found)
814       {
815         xmlNodeAddContent(cur, (const xmlChar*)"\n      ");
816         xmlNodePtr F_tag = xmlNewChild(cur, NULL, (const xmlChar*)"var", NULL);
817         xmlSetProp(F_tag, (const xmlChar*)"name", (const xmlChar*)"F");
818         xmlSetProp(F_tag, (const xmlChar*)"opt", (const xmlChar*)"true");
819         xmlNodeSetContent(F_tag, (const xmlChar*)" ");
820         coeffNodes["cj_F"] = F_tag;
821         xmlNodeAddContent(cur, (const xmlChar*)"\n    ");
822       }
823 
824       cur2 = cur->xmlChildrenNode;
825       while (cur2 != NULL)
826       {
827         std::string tname2((const char*)cur2->name);
828         OhmmsAttributeSet cAttrib2;
829         std::string aname2("none");
830         std::string atype2("normalized_gaussian");
831         std::string aopt2("yes");
832         std::string ref_id("g0");
833         cAttrib2.add(aname2, "name");
834         cAttrib2.add(atype2, "type");
835         cAttrib2.add(aopt2, "opt");
836         cAttrib2.add(ref_id, "reference_id");
837         cAttrib2.put(cur2);
838         // find <region /> tag
839         if (tname2 == "region" && (aopt2 == "true" || aopt2 == "yes") && Fnum != 0)
840         {
841           // if type is voronoi, reconstruct the tag structure
842           if (atype2 == "voronoi")
843           {
844             // set property to normalized_gaussian, add reference, remove source
845             xmlUnsetProp(cur, (const xmlChar*)"source");
846             xmlSetProp(cur2, (const xmlChar*)"type", (const xmlChar*)"normalized_gaussian");
847             xmlSetProp(cur2, (const xmlChar*)"reference_id", (const xmlChar*)ref_id.c_str());
848             // remove existing children
849             xmlNodePtr child = cur2->xmlChildrenNode;
850             while (child != NULL)
851             {
852               xmlUnlinkNode(child);
853               child = cur2->xmlChildrenNode;
854             }
855             // get Fdim
856             int Fdim = (std::sqrt(1 + 8 * Fnum) - 1) / 2;
857             for (int i = 0; i < Fdim; ++i)
858             {
859               std::ostringstream os;
860               os << "g" << i;
861               std::string gid = os.str();
862               std::string opt = (gid != ref_id) ? "true" : "false";
863 
864               // create function tag, set id
865               xmlNodeAddContent(cur2, (const xmlChar*)"\n        ");
866               xmlNodePtr function_tag = xmlNewChild(cur2, NULL, (const xmlChar*)"function", NULL);
867               xmlNewProp(function_tag, (const xmlChar*)"id", (const xmlChar*)gid.c_str());
868               xmlNodeAddContent(function_tag, (const xmlChar*)"\n          ");
869               // create A tag
870               xmlNodePtr A_tag = xmlNewChild(function_tag, NULL, (const xmlChar*)"var", NULL);
871               xmlNodeAddContent(function_tag, (const xmlChar*)"\n          ");
872               xmlNewProp(A_tag, (const xmlChar*)"name", (const xmlChar*)"A");
873               xmlNewProp(A_tag, (const xmlChar*)"opt", (const xmlChar*)opt.c_str());
874               os.str("");
875               if (gid == ref_id)
876               {
877                 os << std::setprecision(6) << std::scientific;
878                 os << InitVariables.find(gid + "_A_xx")->second << " " << InitVariables.find(gid + "_A_xy")->second
879                    << " " << InitVariables.find(gid + "_A_xz")->second << " "
880                    << InitVariables.find(gid + "_A_yy")->second << " " << InitVariables.find(gid + "_A_yz")->second
881                    << " " << InitVariables.find(gid + "_A_zz")->second;
882               }
883               else
884                 os << " ";
885               xmlNodeSetContent(A_tag, (const xmlChar*)(os.str().c_str()));
886 
887               // create B tag
888               xmlNodePtr B_tag = xmlNewChild(function_tag, NULL, (const xmlChar*)"var", NULL);
889               xmlNodeAddContent(function_tag, (const xmlChar*)"\n          ");
890               xmlNewProp(B_tag, (const xmlChar*)"name", (const xmlChar*)"B");
891               xmlNewProp(B_tag, (const xmlChar*)"opt", (const xmlChar*)opt.c_str());
892               os.str("");
893               if (gid == ref_id)
894               {
895                 os << std::setprecision(6) << std::scientific;
896                 os << InitVariables.find(gid + "_B_x")->second << " " << InitVariables.find(gid + "_B_y")->second << " "
897                    << InitVariables.find(gid + "_B_z")->second;
898               }
899               else
900                 os << " ";
901               xmlNodeSetContent(B_tag, (const xmlChar*)(os.str().c_str()));
902 
903               // create C tag
904               xmlNodePtr C_tag = xmlNewChild(function_tag, NULL, (const xmlChar*)"var", NULL);
905               xmlNodeAddContent(function_tag, (const xmlChar*)"\n        ");
906               xmlNewProp(C_tag, (const xmlChar*)"name", (const xmlChar*)"C");
907               xmlNewProp(C_tag, (const xmlChar*)"opt", (const xmlChar*)opt.c_str());
908               os.str("");
909               if (gid == ref_id)
910               {
911                 os << std::setprecision(6) << std::scientific;
912                 os << InitVariables.find(gid + "_C")->second;
913               }
914               else
915                 os << " ";
916               xmlNodeSetContent(C_tag, (const xmlChar*)(os.str().c_str()));
917             }
918             xmlNodeAddContent(cur2, (const xmlChar*)"\n      ");
919           }
920 
921           // register the optimizable variables for each function
922           // find <function /> tags
923           xmlNodePtr cur3 = cur2->xmlChildrenNode;
924           while (cur3 != NULL)
925           {
926             std::string tname3((const char*)cur3->name);
927             OhmmsAttributeSet cAttrib3;
928             std::string fid("none");
929             cAttrib3.add(fid, "id");
930             cAttrib3.put(cur3);
931             // for each function tag, register coeffNodes[gid_A/B/C] as each variable location
932             if (tname3 == "function")
933             {
934               // find <var name="A/B/C" /> tags
935               xmlNodePtr cur4 = cur3->xmlChildrenNode;
936               while (cur4 != NULL)
937               {
938                 std::string tname4((const char*)cur4->name);
939                 OhmmsAttributeSet cAttrib4;
940                 std::string aname4("none");
941                 std::string aopt4("false");
942                 cAttrib4.add(aname4, "name");
943                 cAttrib4.add(aopt4, "opt");
944                 cAttrib4.put(cur4);
945                 if (tname4 == "var" && (aopt4 == "true" || aopt4 == "yes"))
946                 {
947                   std::string varname = "cj_" + fid + "_" + aname4;
948                   bool notlisted      = true;
949                   opt_variables_type::iterator oit(OptVariables.begin()), oit_end(OptVariables.end());
950                   while (notlisted && oit != oit_end)
951                   {
952                     const std::string& oname((*oit).first);
953                     notlisted = (oname.find(varname.substr(3)) >= oname.size());
954                     ++oit;
955                   }
956                   if (!notlisted)
957                   {
958                     coeffNodes[varname] = cur4;
959                   }
960                 }
961                 cur4 = cur4->next;
962               }
963             }
964             cur3 = cur3->next;
965           }
966         }
967         cur2 = cur2->next;
968       }
969     }
970   }
971   xmlXPathFreeObject(result);
972 }
973 
974 
printCJParams(xmlNodePtr cur,std::string & rname)975 void QMCCostFunctionBase::printCJParams(xmlNodePtr cur, std::string& rname)
976 {
977   opt_variables_type::iterator vit(OptVariables.begin());
978   // F matrix variables
979   if (rname.find("cj_F") < rname.size())
980   {
981     // get a vector of pairs with f matrix names, values
982     std::vector<Return_rt> f_vals;
983     for (auto vit = OptVariables.begin(); vit != OptVariables.end(); ++vit)
984     {
985       if ((*vit).first.find("F_") == 0)
986       {
987         Return_rt fval = std::real(vit->second);
988         f_vals.push_back(fval);
989       }
990     }
991     // manually add final element = 0
992     f_vals.push_back(0);
993     // get the dimensions of the f matrix
994     int Fdim = (std::sqrt(1 + 8 * f_vals.size()) - 1) / 2;
995     std::ostringstream os;
996     std::string pad_str = std::string(14, ' ');
997     os << std::endl;
998     os << std::setprecision(6) << std::scientific;
999     // print out the values with the proper indentation
1000     auto fit = f_vals.begin();
1001     for (int i = 0; i < Fdim; ++i)
1002     {
1003       os << pad_str;
1004       for (int j = 0; j < Fdim; ++j)
1005       {
1006         if (j < i)
1007           os << pad_str; //print blank
1008         else             // print value
1009         {
1010           os << "  " << (*fit);
1011           ++fit;
1012         }
1013       }
1014       // line break
1015       if (i < Fdim - 1)
1016         os << std::endl;
1017     }
1018     // assign to tag
1019     xmlNodePtr cur2 = cur->children;
1020     xmlNodeSetContent(cur2, (const xmlChar*)(os.str().c_str()));
1021     xmlNodeAddContent(cur2, (const xmlChar*)"\n      ");
1022   }
1023   // gaussian function parameters A, B, C
1024   else
1025   {
1026     std::string var_prefix = rname.substr(3);
1027     std::vector<Return_rt> vals;
1028 
1029     for (auto vit = OptVariablesForPsi.begin(); vit != OptVariablesForPsi.end(); ++vit)
1030     {
1031       if (vit->first.find(var_prefix) == 0)
1032       {
1033         Return_rt val = std::real(vit->second);
1034         vals.push_back(val);
1035       }
1036     }
1037     std::ostringstream os;
1038     os << std::setprecision(6) << std::scientific;
1039     for (int i = 0; i < vals.size(); ++i)
1040     {
1041       os << vals[i];
1042       if (i < vals.size() - 1)
1043         os << " ";
1044     }
1045     xmlNodePtr cur2 = cur->children;
1046     xmlNodeSetContent(cur2, (const xmlChar*)(os.str().c_str()));
1047   }
1048 }
1049 
lineoptimization(const std::vector<Return_rt> & x0,const std::vector<Return_rt> & gr,Return_rt val0,Return_rt & dl,Return_rt & val_proj,Return_rt & lambda_max)1050 bool QMCCostFunctionBase::lineoptimization(const std::vector<Return_rt>& x0,
1051                                            const std::vector<Return_rt>& gr,
1052                                            Return_rt val0,
1053                                            Return_rt& dl,
1054                                            Return_rt& val_proj,
1055                                            Return_rt& lambda_max)
1056 {
1057   return false;
1058   // PK: Commented out inaccessible code after return false, but why was return added?
1059   //  const int maxclones=3;
1060   //  const int max_poly=3;
1061   //  //Matrix<Return_t> js(maxclones+1,x0.size());
1062   //  Vector<Return_t> y(maxclones+1);
1063   //  Vector<Return_t> sigma(maxclones+1);
1064   //  Matrix<Return_t> A(maxclones+1,max_poly);
1065   //  sigma=1e-6; //a small value
1066   //  Return_t gr_norm=0.0;
1067   //  for (int j=0; j<x0.size(); ++j)
1068   //  {
1069   //    //js(0,j)=x0[j];
1070   //    gr_norm+=gr[j]*gr[j];
1071   //  }
1072   //  Return_t nw=1.0/static_cast<QMCTraits::RealType>(NumSamples);
1073   //  //Return_t MaxDispl=0.04;
1074   //  gr_norm=std::sqrt(gr_norm);
1075   //  Return_t dx=lambda_max/gr_norm;
1076   //  dx=std::min((QMCTraits::RealType)0.25,dx);
1077   //  if (val0<1e12)
1078   //  {
1079   //    y[0]=val0;
1080   //    sigma[0]=std::sqrt(val0)*nw;
1081   //  }
1082   //  else
1083   //  {
1084   //    for (int j=0; j<x0.size(); ++j)
1085   //      Params(j)=x0[j];
1086   //    Return_t costval=Cost();
1087   //    y[0]=costval;
1088   //    sigma[0]=std::sqrt(costval)*nw;
1089   //  }
1090   //  app_log() << "  lineoptimization (" << 0.0 << "," << y[0] << ")";
1091   //  for (int k=0; k<max_poly; ++k)
1092   //    A(0,k)=0.0;
1093   //  Return_t dxmax=0.0;
1094   //  for (int i=1; i<=maxclones; ++i)
1095   //  {
1096   //    dxmax+=dx;
1097   //    //set OptParams to vary
1098   //    for (int j=0; j<x0.size(); ++j)
1099   //    {
1100   //      //js(i,j)=OptParams[j]=x0[j]+dx*gr[j];
1101   //      Params(j)=x0[j]+dxmax*gr[j];
1102   //    }
1103   //    Return_t costval=Cost();
1104   //    y[i]=costval;
1105   //    sigma[i]=std::sqrt(costval)*nw;
1106   //    for (int k=0; k<max_poly; ++k)
1107   //      A(i,k)=std::pow(dxmax,k);
1108   //    app_log() << " (" << dxmax << "," << y[i] << ")";
1109   //  }
1110   //  app_log() << std::endl;
1111   //  Vector<QMCTraits::RealType> polys(max_poly);
1112   //  Vector<QMCTraits::RealType> errors(max_poly);
1113   //  LeastSquaredFitLU(y,sigma,A,polys,errors);
1114   //  dl=-polys[1]/polys[2]*0.5;
1115   //  val_proj=polys[0]+dl*(polys[1]+dl*polys[2]);
1116   //  if (dl<dx*0.25)
1117   //    lambda_max *=0.5; // narrow the bracket
1118   //  if (dl>dxmax*5.0)
1119   //    lambda_max *=2.0; //widen the bracket
1120   //  app_log() << "    minimum at " << dl << " estimated=" << val_proj << " LambdaMax " << lambda_max;
1121   //  for (int j=0; j<x0.size(); ++j)
1122   //    Params(j)=x0[j]+dl*gr[j];
1123   //  val_proj=Cost();
1124   //  app_log() << "  cost = " << val_proj << std::endl;
1125   //  //Psi.reportStatus(app_log());
1126   //  //return false;
1127   //  return true;
1128 }
1129 
1130 ///////////////////////////////////////////////////////////////////////////////////////////////////
1131 /// \brief  If the LMYEngine is available, returns the cost function calculated by the engine.
1132 ///         Otherwise, returns the usual cost function.
1133 ///
1134 /// \param[in]      needDeriv             whether derivative vectors should be computed
1135 ///
1136 ///////////////////////////////////////////////////////////////////////////////////////////////////
1137 #ifdef HAVE_LMY_ENGINE
LMYEngineCost(const bool needDeriv,cqmc::engine::LMYEngine<Return_t> * EngineObj)1138 QMCCostFunctionBase::Return_rt QMCCostFunctionBase::LMYEngineCost(const bool needDeriv,
1139                                                                   cqmc::engine::LMYEngine<Return_t>* EngineObj)
1140 {
1141   // prepare local energies, weights, and possibly derivative vectors, and compute standard cost
1142   const Return_rt standardCost = this->Cost(needDeriv);
1143 
1144   // since we are using the LMYEngine, compute and return it's cost function value
1145   return this->LMYEngineCost_detail(EngineObj);
1146 }
1147 #endif
1148 
1149 } // namespace qmcplusplus
1150