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: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
8 //
9 // File created by: Brett Van Der Goetz, bvdg@berkeley.edu, University of California at Berkeley
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef QMCPLUSPLUS_GAUSSIAN_FUNCTOR_H
13 #define QMCPLUSPLUS_GAUSSIAN_FUNCTOR_H
14 
15 #include "OhmmsData/AttributeSet.h"
16 #include "Optimize/VariableSet.h"
17 #include <array>
18 
19 namespace qmcplusplus
20 {
21 
22 // doesn't inherit from OptimizableFunctorBase since this is a function of the entire position vector
23 class CountingGaussian
24 {
25   using RealType = QMCTraits::RealType;
26   using PosType = QMCTraits::PosType;
27   using GradType = QMCTraits::PosType; // complex not implemented
28   using TensorType = QMCTraits::TensorType;
29 
30   using real_type = optimize::VariableSet::real_type;
31   using opt_variables_type = optimize::VariableSet;
32 
33   // enumerations for axis parameters
34   enum A_vars
35   {
36     XX,
37     XY,
38     XZ,
39     YY,
40     YZ,
41     ZZ,
42     NUM_A
43   };
44   enum B_vars
45   {
46     X,
47     Y,
48     Z,
49     DIM
50   };
51 
52 
53   // opt variables: vector of bools: one for each parameter
54   std::vector<bool> opt_A;
55   std::vector<bool> opt_B;
56   bool opt_C;
57 
58   // id string
59   std::string id;
60 
61   // reference gaussian
62   CountingGaussian* gref = NULL;
63 
64   // most recent evaluations
65   RealType Fval;
66   GradType Fgrad;
67   RealType Flap;
68 
69 public:
70   TensorType A;
71   PosType B;
72   RealType C;
73 
74   // optimizable variables
75   opt_variables_type myVars;
76 
CountingGaussian(std::string fid)77   CountingGaussian(std::string fid) { id = fid; }
78 
79   // constructor for voronoi region
CountingGaussian(std::string fid,RealType alpha,PosType r,bool opt)80   CountingGaussian(std::string fid, RealType alpha, PosType r, bool opt)
81   {
82     id = fid;
83     // set opt flags
84     opt_A.resize(6);
85     opt_B.resize(3);
86     for(auto it = opt_A.begin(); it != opt_A.end(); ++it)
87       *it = opt;
88     for(auto it = opt_B.begin(); it != opt_B.end(); ++it)
89       *it = opt;
90     opt_C = opt;
91     // set A
92     A(0,0) = A(1,1) = A(2,2) = -1.0*alpha;
93     A(0,1) = A(1,0) = A(0,2) = A(2,0) = A(1,2) = A(2,1) = 0;
94     // set B
95     d_to_b(r, A, B);
96     // set C
97     k_to_c(0, A, r, C);
98   }
99 
100   // initialize with another gaussian reference
initialize(CountingGaussian * ref)101   void initialize(CountingGaussian* ref)
102   {
103     // register and update optimizable variables to current values
104     myVars.insert(id + "_A_xx", A(X, X), opt_A[XX], optimize::OTHER_P);
105     myVars[id + "_A_xx"] = A(X, X);
106     myVars.insert(id + "_A_xy", A(X, Y), opt_A[XY], optimize::OTHER_P);
107     myVars[id + "_A_xy"] = A(X, Y);
108     myVars.insert(id + "_A_xz", A(X, Z), opt_A[XZ], optimize::OTHER_P);
109     myVars[id + "_A_xz"] = A(X, Z);
110     myVars.insert(id + "_A_yy", A(Y, Y), opt_A[YY], optimize::OTHER_P);
111     myVars[id + "_A_yy"] = A(Y, Y);
112     myVars.insert(id + "_A_yz", A(Y, Z), opt_A[YZ], optimize::OTHER_P);
113     myVars[id + "_A_yz"] = A(Y, Z);
114     myVars.insert(id + "_A_zz", A(Z, Z), opt_A[ZZ], optimize::OTHER_P);
115     myVars[id + "_A_zz"] = A(Z, Z);
116     myVars.insert(id + "_B_x", B[X], opt_B[X], optimize::OTHER_P);
117     myVars[id + "_B_x"] = B[X];
118     myVars.insert(id + "_B_y", B[Y], opt_B[Y], optimize::OTHER_P);
119     myVars[id + "_B_y"] = B[Y];
120     myVars.insert(id + "_B_z", B[Z], opt_B[Z], optimize::OTHER_P);
121     myVars[id + "_B_z"] = B[Z];
122     myVars.insert(id + "_C", C, opt_C, optimize::OTHER_P);
123     myVars[id + "_C"] = C;
124     // transform according to reference
125     if(gref != NULL)
126       this->divide_eq(gref);
127   }
128 
restore(int iat)129   void restore(int iat) {}
130 
checkInVariables(opt_variables_type & active)131   void checkInVariables(opt_variables_type& active) { active.insertFrom(myVars); }
132 
133 
checkOutVariables(const opt_variables_type & active)134   void checkOutVariables(const opt_variables_type& active) { myVars.getIndex(active); }
135 
136 
resetParameters(const opt_variables_type & active)137   void resetParameters(const opt_variables_type& active)
138   {
139     int ia;
140     std::string vid;
141     if (opt_A[XX])
142     {
143       vid = id + "_A_xx";
144       ia = active.getLoc(vid);
145       myVars[vid] = active[ia];
146       A(0, 0) = std::real(myVars[vid]);
147     }
148     if (opt_A[YY])
149     {
150       vid = id + "_A_yy";
151       ia = active.getLoc(vid);
152       myVars[vid] = active[ia];
153       A(1, 1) = std::real(myVars[vid]);
154     }
155     if (opt_A[ZZ])
156     {
157       vid = id + "_A_zz";
158       ia = active.getLoc(vid);
159       myVars[vid] = active[ia];
160       A(2, 2) = std::real(myVars[vid]);
161     }
162     if (opt_A[XY])
163     {
164       vid = id + "_A_xy";
165       ia = active.getLoc(vid);
166       myVars[vid] = active[ia];
167       A(1, 0) = A(0, 1) = std::real(myVars[vid]);
168     }
169     if (opt_A[XZ])
170     {
171       vid = id + "_A_xz";
172       ia = active.getLoc(vid);
173       myVars[vid] = active[ia];
174       A(2, 0) = A(0, 2) = std::real(myVars[vid]);
175     }
176     if (opt_A[YZ])
177     {
178       vid = id + "_A_yz";
179       ia = active.getLoc(vid);
180       myVars[vid] = active[ia];
181       A(2, 1) = A(1, 2) = std::real(myVars[vid]);
182     }
183     if (opt_B[X])
184     {
185       vid = id + "_B_x";
186       ia = active.getLoc(vid);
187       myVars[vid] = active[ia];
188       B[X] = std::real(myVars[vid]);
189     }
190     if (opt_B[Y])
191     {
192       vid = id + "_B_y";
193       ia = active.getLoc(vid);
194       myVars[vid] = active[ia];
195       B[Y] = std::real(myVars[vid]);
196     }
197     if (opt_B[Z])
198     {
199       vid = id + "_B_z";
200       ia = active.getLoc(vid);
201       myVars[vid] = active[ia];
202       B[Z] = std::real(myVars[vid]);
203     }
204     if (opt_C)
205     {
206       vid = id + "_C";
207       ia = active.getLoc(vid);
208       myVars[vid] = active[ia];
209       C = std::real(myVars[vid]);
210     }
211     // transform according to reference
212     if(gref != NULL)
213       this->divide_eq(gref);
214   }
215 
reportStatus(std::ostream & os)216   void reportStatus(std::ostream& os)
217   {
218     os << "    type: CountingGaussian" << std::endl;
219     os << "    id: " << id << std::endl;
220     app_log() << std::endl;
221     myVars.print(os, 6, true);
222     app_log() << std::endl;
223   }
224 
makeClone(std::string fid)225   CountingGaussian* makeClone(std::string fid) const
226   {
227     CountingGaussian* rptr = new CountingGaussian(fid);
228     for (int i = 0; i < A.size(); ++i)
229       rptr->A[i] = A[i];
230     for (int i = 0; i < B.size(); ++i)
231       rptr->B[i] = B[i];
232     rptr->C = C;
233     rptr->opt_A.resize(opt_A.size());
234     rptr->opt_B.resize(opt_B.size());
235     for (int i = 0; i < opt_A.size(); ++i)
236       rptr->opt_A[i] = opt_A[i];
237     for (int i = 0; i < opt_B.size(); ++i)
238       rptr->opt_B[i] = opt_B[i];
239     rptr->opt_C  = opt_C;
240     rptr->myVars = myVars;
241     return rptr;
242   }
243 
244   // builds the full matrix from its upper triangle
triang_to_matrix(const std::array<RealType,6> & triang,TensorType & matrix)245   void triang_to_matrix(const std::array<RealType, 6>& triang, TensorType& matrix)
246   {
247     auto it = triang.begin();
248     for (int i = 0; i < 3; ++i)
249       for (int j = i; j < 3; ++j)
250       {
251         matrix(i, j) = matrix(j, i) = *it;
252         ++it;
253       }
254   }
255 
d_to_b(const PosType & d,const TensorType & a,PosType & b)256   void d_to_b(const PosType& d, const TensorType& a, PosType& b) { b = dot(a, d); }
257 
k_to_c(const RealType & k,const TensorType & a,const PosType & d,RealType & c)258   void k_to_c(const RealType& k, const TensorType& a, const PosType& d, RealType& c) { c = k + dot(d, dot(a, d)); }
259 
put(xmlNodePtr cur)260   bool put(xmlNodePtr cur)
261   {
262     //app_log() << "CountingGaussian::put" << std::endl;
263     bool put_A = false, put_B = false, put_C = false, put_D = false, put_K = false;
264     // alternate inputs
265     std::array<RealType, 6> A_triang;
266     PosType D  = 0;
267     RealType K = 0;
268     cur        = cur->xmlChildrenNode;
269     while (cur != NULL)
270     {
271       std::string cname((const char*)(cur->name));
272       if (cname == "var")
273       {
274         std::string opt  = "false";
275         std::string name = "none";
276         OhmmsAttributeSet rAttrib;
277         rAttrib.add(name, "name");
278         rAttrib.add(opt, "opt");
279         rAttrib.add(opt, "opt_bits");
280         rAttrib.put(cur);
281         // check if opt is a binary string
282         bool is_bitstr = std::all_of(opt.begin(), opt.end(), [&](char c) { return c == '0' || c == '1'; });
283         std::transform(opt.begin(), opt.end(), opt.begin(), (int (*)(int))std::tolower);
284         std::transform(name.begin(), name.end(), name.begin(), (int (*)(int))std::tolower);
285         if (name == "a") // input is the upper-triangle of A
286         {
287           opt_A.resize(6);
288           if (opt.size() == 6 && is_bitstr)
289             std::transform(opt.begin(), opt.end(), opt_A.begin(), [&](char c) { return (c == '1'); });
290           // default opt = true
291           else
292             std::fill(opt_A.begin(), opt_A.end(), (opt == "true"));
293           put_A = putContent(A_triang.begin(), A_triang.end(), cur);
294           // perform conversion
295           triang_to_matrix(A_triang, A);
296         }
297         if (name == "b")
298         {
299           opt_B.resize(3);
300           if (opt.size() == 3 && is_bitstr)
301             std::transform(opt.begin(), opt.end(), opt_B.begin(), [&](char c) { return (c == '1'); });
302           // default opt = true
303           else
304             std::fill(opt_B.begin(), opt_B.end(), (opt == "true"));
305           put_B = putContent(B.begin(), B.end(), cur);
306         }
307         if (name == "d")
308         {
309           opt_B.resize(3);
310           if (opt.size() == 3 && is_bitstr)
311             std::transform(opt.begin(), opt.end(), opt_B.begin(), [&](char c) { return (c == '1'); });
312           else
313             std::fill(opt_B.begin(), opt_B.end(), (opt == "true"));
314           put_D = putContent(D.begin(), D.end(), cur);
315         }
316         if (name == "c")
317         {
318           opt_C = (opt == "true");
319           put_C = putContent(C, cur);
320         }
321         if (name == "k")
322         {
323           opt_C = (opt == "true");
324           put_K = putContent(K, cur);
325         }
326       }
327       cur = cur->next;
328     }
329     // convert B <=> D
330     if (put_B && put_D)
331       APP_ABORT("CountingGaussian::put: overdetermined: both B and D are specified");
332     if (put_C && put_K)
333       APP_ABORT("CountingGaussian::put: overdetermined: both C and K are specified");
334     // convert D,B using A
335     if (put_D)
336       d_to_b(D, A, B);
337     if (put_K)
338       k_to_c(K, A, D, C);
339     // check that we got everything
340     if (!(put_A && (put_B || put_D) && (put_C || put_K)))
341     {
342       std::ostringstream err;
343       err << "CountingGaussian::put:  required variable unspecified: ";
344       err << "put_A: " << put_A << ", put_B: " << put_B << ", put_C: " << put_C << ", put_D: " << put_D
345           << ", put_K: " << put_K << std::endl;
346       //      APP_ABORT(err.str());
347       app_log() << err.str();
348     }
349     return true;
350   }
351 
divide_eq(const CountingGaussian * rhs)352   void divide_eq(const CountingGaussian* rhs)
353   {
354     A = A - rhs->A;
355     B = B - rhs->B;
356     C = C - rhs->C;
357   }
358 
359 
360   // f = std::exp(x^T A x - 2B^T x + C)
evaluate(PosType r,RealType & fval,GradType & fgrad,RealType & flap)361   void evaluate(PosType r, RealType& fval, GradType& fgrad, RealType& flap)
362   {
363     PosType Ar = dot(A, r);
364     RealType x = dot(Ar - 2 * B, r) + C;
365     fval       = std::exp(x);
366     fgrad      = 2 * (Ar - B) * fval;
367     flap       = 4 * dot(Ar - B, Ar - B) * fval + 2 * trace(A) * fval;
368   }
369 
evaluateLog(PosType r,RealType & lval,GradType & lgrad,RealType & llap)370   void evaluateLog(PosType r, RealType& lval, GradType& lgrad, RealType& llap)
371   {
372     PosType Ar = dot(A, r);
373     lval       = dot(Ar - 2 * B, r) + C;
374     lgrad      = 2 * (Ar - B);
375     llap       = 2 * trace(A);
376   }
377 
evaluateDerivative_A(A_vars q,PosType r,RealType & dfval,GradType & dfgrad,RealType & dflap)378   void evaluateDerivative_A(A_vars q, PosType r, RealType& dfval, GradType& dfgrad, RealType& dflap)
379   {
380     // Fval, Fgrad, Flap are up-to-date function values
381     // x correponds to the exponent value: x = ln f; dx are param derivs
382     RealType dxval = 0, dxlap = 0;
383     GradType dxgrad = 0;
384     if (q == XX)
385     {
386       dxval  = r[X] * r[X];
387       dxgrad = GradType(2 * r[X], 0, 0);
388       dxlap  = 2;
389     }
390     if (q == YY)
391     {
392       dxval  = r[Y] * r[Y];
393       dxgrad = GradType(0, 2 * r[Y], 0);
394       dxlap  = 2;
395     }
396     if (q == ZZ)
397     {
398       dxval  = r[Z] * r[Z];
399       dxgrad = GradType(0, 0, 2 * r[Z]);
400       dxlap  = 2;
401     }
402     // off-diagonal terms: factor of two is since A is symmetric
403     if (q == XY)
404     {
405       dxval  = 2 * r[X] * r[Y];
406       dxgrad = 2 * GradType(r[Y], r[X], 0);
407       dxlap  = 0;
408     }
409     if (q == XZ)
410     {
411       dxval  = 2 * r[X] * r[Z];
412       dxgrad = 2 * GradType(r[Z], 0, r[X]);
413       dxlap  = 0;
414     }
415     if (q == YZ)
416     {
417       dxval  = 2 * r[Y] * r[Z];
418       dxgrad = 2 * GradType(0, r[Z], r[Y]);
419       dxlap  = 0;
420     }
421     dfval  = Fval * dxval;
422     dfgrad = Fgrad * dxval + Fval * dxgrad;
423     dflap  = Flap * dxval + 2 * dot(Fgrad, dxgrad) + dxlap * Fval;
424   }
425 
evaluateDerivative_B(B_vars q,PosType r,RealType & dfval,GradType & dfgrad,RealType & dflap)426   void evaluateDerivative_B(B_vars q, PosType r, RealType& dfval, GradType& dfgrad, RealType& dflap)
427   {
428     RealType dxval = 0, dxlap = 0;
429     GradType dxgrad = 0;
430     if (q == X)
431     {
432       dxval  = -2 * r[X];
433       dxgrad = -2 * GradType(1, 0, 0);
434       dxlap  = 0;
435     }
436     if (q == Y)
437     {
438       dxval  = -2 * r[Y];
439       dxgrad = -2 * GradType(0, 1, 0);
440       dxlap  = 0;
441     }
442     if (q == Z)
443     {
444       dxval  = -2 * r[Z];
445       dxgrad = -2 * GradType(0, 0, 1);
446       dxlap  = 0;
447     }
448     dfval  = Fval * dxval;
449     dfgrad = Fgrad * dxval + Fval * dxgrad;
450     dflap  = Flap * dxval + 2 * dot(Fgrad, dxgrad) + dxlap * Fval;
451   }
452 
evaluateDerivatives(PosType r,std::vector<RealType> & dfval,std::vector<GradType> & dfgrad,std::vector<RealType> & dflap)453   void evaluateDerivatives(PosType r,
454                            std::vector<RealType>& dfval,
455                            std::vector<GradType>& dfgrad,
456                            std::vector<RealType>& dflap)
457   {
458     evaluate(r, Fval, Fgrad, Flap);
459     int p = 0;
460     if (opt_A[XX])
461     {
462       evaluateDerivative_A(XX, r, dfval[p], dfgrad[p], dflap[p]);
463       ++p;
464     }
465     if (opt_A[XY])
466     {
467       evaluateDerivative_A(XY, r, dfval[p], dfgrad[p], dflap[p]);
468       ++p;
469     }
470     if (opt_A[XZ])
471     {
472       evaluateDerivative_A(XZ, r, dfval[p], dfgrad[p], dflap[p]);
473       ++p;
474     }
475     if (opt_A[YY])
476     {
477       evaluateDerivative_A(YY, r, dfval[p], dfgrad[p], dflap[p]);
478       ++p;
479     }
480     if (opt_A[YZ])
481     {
482       evaluateDerivative_A(YZ, r, dfval[p], dfgrad[p], dflap[p]);
483       ++p;
484     }
485     if (opt_A[ZZ])
486     {
487       evaluateDerivative_A(ZZ, r, dfval[p], dfgrad[p], dflap[p]);
488       ++p;
489     }
490     if (opt_B[X])
491     {
492       evaluateDerivative_B(X, r, dfval[p], dfgrad[p], dflap[p]);
493       ++p;
494     }
495     if (opt_B[Y])
496     {
497       evaluateDerivative_B(Y, r, dfval[p], dfgrad[p], dflap[p]);
498       ++p;
499     }
500     if (opt_B[Z])
501     {
502       evaluateDerivative_B(Z, r, dfval[p], dfgrad[p], dflap[p]);
503       ++p;
504     }
505     if (opt_C)
506     {
507       dfval[p]  = Fval;
508       dfgrad[p] = Fgrad;
509       dflap[p]  = Flap;
510       ++p;
511     }
512   }
513 
514   // evaluate parameter derivatives of log of the wavefunction
evaluateLogDerivatives(PosType r,std::vector<RealType> & dlval,std::vector<GradType> & dlgrad,std::vector<RealType> & dllap)515   void evaluateLogDerivatives(PosType r,
516                               std::vector<RealType>& dlval,
517                               std::vector<GradType>& dlgrad,
518                               std::vector<RealType>& dllap)
519   {
520     int p = 0;
521     if (opt_A[XX])
522     {
523       dlval[p]  = r[X] * r[X];
524       dlgrad[p] = 2 * GradType(r[X], 0, 0);
525       dllap[p]  = 2;
526       ++p;
527     }
528     if (opt_A[XY])
529     {
530       dlval[p]  = 2 * r[X] * r[Y];
531       dlgrad[p] = 2 * GradType(r[Y], r[X], 0);
532       dllap[p]  = 0;
533       ++p;
534     }
535     if (opt_A[XZ])
536     {
537       dlval[p]  = 2 * r[X] * r[Z];
538       dlgrad[p] = 2 * GradType(r[Z], 0, r[X]);
539       dllap[p]  = 0;
540       ++p;
541     }
542     if (opt_A[YY])
543     {
544       dlval[p]  = r[Y] * r[Y];
545       dlgrad[p] = 2 * GradType(0, r[Y], 0);
546       dllap[p]  = 2;
547       ++p;
548     }
549     if (opt_A[YZ])
550     {
551       dlval[p]  = 2 * r[Y] * r[Z];
552       dlgrad[p] = 2 * GradType(0, r[Z], r[Y]);
553       dllap[p]  = 0;
554       ++p;
555     }
556     if (opt_A[ZZ])
557     {
558       dlval[p]  = r[Z] * r[Z];
559       dlgrad[p] = 2 * GradType(0, 0, r[Z]);
560       dllap[p]  = 2;
561       ++p;
562     }
563     if (opt_B[X])
564     {
565       dlval[p]  = -2 * r[X];
566       dlgrad[p] = -2 * GradType(1, 0, 0);
567       dllap[p]  = 0;
568       ++p;
569     }
570     if (opt_B[Y])
571     {
572       dlval[p]  = -2 * r[Y];
573       dlgrad[p] = -2 * GradType(0, 1, 0);
574       dllap[p]  = 0;
575       ++p;
576     }
577     if (opt_B[Z])
578     {
579       dlval[p]  = -2 * r[Z];
580       dlgrad[p] = -2 * GradType(0, 0, 1);
581       dllap[p]  = 0;
582       ++p;
583     }
584     if (opt_C)
585     {
586       dlval[p]  = 1;
587       dlgrad[p] = 0;
588       dllap[p]  = 0;
589       ++p;
590     }
591   }
592 
evaluateLogTempDerivatives(PosType r,std::vector<RealType> & dlval)593   void evaluateLogTempDerivatives(PosType r, std::vector<RealType>& dlval)
594   {
595     int p = 0;
596     if (opt_A[XX])
597     {
598       dlval[p] = r[X] * r[X];
599       ++p;
600     }
601     if (opt_A[XY])
602     {
603       dlval[p] = 2 * r[X] * r[Y];
604       ++p;
605     }
606     if (opt_A[XZ])
607     {
608       dlval[p] = 2 * r[X] * r[Z];
609       ++p;
610     }
611     if (opt_A[YY])
612     {
613       dlval[p] = r[Y] * r[Y];
614       ++p;
615     }
616     if (opt_A[YZ])
617     {
618       dlval[p] = 2 * r[Y] * r[Z];
619       ++p;
620     }
621     if (opt_A[ZZ])
622     {
623       dlval[p] = r[Z] * r[Z];
624       ++p;
625     }
626     if (opt_B[X])
627     {
628       dlval[p] = -2 * r[X];
629       ++p;
630     }
631     if (opt_B[Y])
632     {
633       dlval[p] = -2 * r[Y];
634       ++p;
635     }
636     if (opt_B[Z])
637     {
638       dlval[p] = -2 * r[Z];
639       ++p;
640     }
641     if (opt_C)
642     {
643       dlval[p] = 1;
644       ++p;
645     }
646   }
647 
evaluate_print(std::ostream & os,const ParticleSet & P)648   void evaluate_print(std::ostream& os, const ParticleSet& P)
649   {
650     // calculate all intermediates and values for electrons in a particle set
651     std::vector<PosType> r_vec;
652     std::vector<PosType> Ar_vec;
653     std::vector<RealType> x_vec;
654     std::vector<RealType> fval_vec;
655     std::vector<GradType> fgrad_vec;
656     std::vector<RealType> flap_vec;
657     RealType x, fval, flap;
658     PosType Ar, r;
659     GradType fgrad;
660     for (auto it = P.R.begin(); it != P.R.end(); ++it)
661     {
662       r     = *it;
663       Ar    = dot(A, r);
664       x     = dot(Ar - 2 * B, r) + C;
665       fval  = std::exp(x);
666       fgrad = 2 * (Ar - B) * fval;
667       flap  = 4 * dot(Ar - B, Ar - B) * fval + 2 * trace(A) * fval;
668 
669       r_vec.push_back(r);
670       Ar_vec.push_back(Ar);
671       x_vec.push_back(x);
672       fval_vec.push_back(fval);
673       fgrad_vec.push_back(fgrad);
674       flap_vec.push_back(flap);
675     }
676     os << "CountingGaussian::evaluate_print: id: " << id << std::endl;
677     os << "r: ";
678     std::copy(r_vec.begin(), r_vec.end(), std::ostream_iterator<PosType>(os, ", "));
679     os << std::endl << "Ar: ";
680     std::copy(Ar_vec.begin(), Ar_vec.end(), std::ostream_iterator<PosType>(os, ", "));
681     os << std::endl << "x: ";
682     std::copy(x_vec.begin(), x_vec.end(), std::ostream_iterator<RealType>(os, ", "));
683     os << std::endl << "fval: ";
684     std::copy(fval_vec.begin(), fval_vec.end(), std::ostream_iterator<RealType>(os, ", "));
685     os << std::endl << "fgrad: ";
686     std::copy(fgrad_vec.begin(), fgrad_vec.end(), std::ostream_iterator<GradType>(os, ", "));
687     os << std::endl << "flap: ";
688     std::copy(flap_vec.begin(), flap_vec.end(), std::ostream_iterator<RealType>(os, ", "));
689     os << std::endl;
690   }
691 };
692 
693 } // namespace qmcplusplus
694 #endif
695