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