QMCPACK
DiracDeterminantWithBackflow.cpp
Go to the documentation of this file.
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: Jeongnim Kim, jeongnim.kim@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 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
19 #include "CPU/BLAS.hpp"
21 #include "OhmmsPETE/Tensor.h"
24 
25 namespace qmcplusplus
26 {
27 /** constructor
28  *@param spos the single-particle orbital set
29  *@param first index of the first particle
30  */
33  int first,
34  int last)
35  : DiracDeterminantBase(getClassName(), std::move(spos), first, last), BFTrans_(BF)
36 {
38  NP = 0;
40 }
41 
42 ///default destructor
44 
45 ///reset the size: with the number of particles and number of orbtials
46 void DiracDeterminantWithBackflow::resize(int nel, int morb)
47 {
48  int norb = morb;
49  if (norb <= 0)
50  norb = nel; // for morb == -1 (default)
51  psiM.resize(nel, norb);
52  dpsiM.resize(nel, norb);
53  psiMinv.resize(nel, norb);
54  WorkSpace.resize(nel);
55  Pivot.resize(nel);
56  grad_grad_psiM.resize(nel, norb);
57  grad_grad_grad_psiM.resize(nel, norb);
58  Gtemp.resize(NumParticles); // not correct for spin polarized...
59  myG.resize(NumParticles); // not correct for spin polarized...
60  myL.resize(NumParticles); // not correct for spin polarized...
61  dFa.resize(nel, norb);
62  Ajk_sum.resize(nel, norb);
63  Qmat.resize(nel, norb);
64  Fmat.resize(nel, norb);
65  Fmatdiag.resize(norb);
66  psiMinv_temp.resize(NumPtcls, norb);
67  psiV.resize(norb);
68  psiM_temp.resize(NumPtcls, norb);
69  // For forces
70  /* not used
71  grad_source_psiM.resize(nel,norb);
72  grad_lapl_source_psiM.resize(nel,norb);
73  grad_grad_source_psiM.resize(nel,norb);
74  phi_alpha_Minv.resize(nel,norb);
75  grad_phi_Minv.resize(nel,norb);
76  lapl_phi_Minv.resize(nel,norb);
77  grad_phi_alpha_Minv.resize(nel,norb);
78  */
79 }
80 
81 /** replace of SPOSet::evaluate function with the removal of t_logpsi */
83 {
84  Phi->evaluate_notranspose(BFTrans_.QP, FirstIndex, LastIndex, psiM_temp, dlogdet, grad_grad_logdet);
85  simd::transpose(psiM_temp.data(), NumOrbitals, psiM_temp.cols(), logdet.data(), NumOrbitals, logdet.cols());
86 }
87 
89  GradMatrix& dlogdet,
90  HessMatrix& grad_grad_logdet,
91  GGGMatrix& grad_grad_grad_logdet)
92 {
93  Phi->evaluate_notranspose(BFTrans_.QP, FirstIndex, LastIndex, psiM_temp, dlogdet, grad_grad_logdet,
94  grad_grad_grad_logdet);
95  simd::transpose(psiM_temp.data(), NumOrbitals, psiM_temp.cols(), logdet.data(), NumOrbitals, logdet.cols());
96 }
97 
99 {
100  if (NP == 0)
101  //first time, allocate once
102  {
103  int norb = NumOrbitals;
104  NP = P.getTotalNum();
106  dpsiM_temp.resize(NumPtcls, norb);
107  grad_grad_psiM_temp.resize(NumPtcls, norb);
108  dpsiV.resize(norb);
109  d2psiV.resize(norb);
110  grad_gradV.resize(norb);
111  Fmatdiag_temp.resize(norb);
112  myG_temp.resize(NP);
113  myL_temp.resize(NP);
115  FirstAddressOfG = &myG[0][0];
117  FirstAddressOfdV = &(dpsiM(0, 0)[0]); //(*dpsiM.begin())[0]);
119  FirstAddressOfGGG = grad_grad_psiM(0, 0).begin(); //[0];
121  FirstAddressOfFm = &(Fmatdiag[0][0]); //[0];
123  }
124  myG_temp = 0.0;
125  myL_temp = 0.0;
126  //ValueType x=evaluate(P,myG,myL);
128  P.G += myG_temp;
129  P.L += myL_temp;
130  //add the data: determinant, inverse, gradient and laplacians
131  buf.add(psiM.first_address(), psiM.last_address());
134  buf.add(myL.first_address(), myL.last_address());
137  buf.add(psiMinv.first_address(), psiMinv.last_address());
138  buf.add(log_value_);
139 }
140 
142  WFBufferType& buf,
143  bool fromscratch)
144 {
145  // for now, always recalculate from scratch
146  // enable from_scratch = true later
147  UpdateTimer.start();
148  myG_temp = 0.0;
149  myL_temp = 0.0;
151  P.G += myG_temp;
152  P.L += myL_temp;
153  //copy psiM to psiM_temp
154  psiM_temp = psiM;
155  buf.put(psiM.first_address(), psiM.last_address());
158  buf.put(myL.first_address(), myL.last_address());
161  buf.put(psiMinv.first_address(), psiMinv.last_address());
162  buf.put(log_value_);
163  UpdateTimer.stop();
164  return log_value_;
165 }
166 
168 {
169  buf.get(psiM.first_address(), psiM.last_address());
172  buf.get(myL.first_address(), myL.last_address());
175  buf.get(psiMinv.first_address(), psiMinv.last_address());
176  buf.get(log_value_);
177  //re-evaluate it for testing
178  //Phi.evaluate(P, FirstIndex, LastIndex, psiM, dpsiM, d2psiM);
179  //CurrentDet = Invert(psiM.data(),NumPtcls,NumOrbitals);
180  //need extra copy for gradient/laplacian calculations without updating it
181  //psiM_temp = psiM;
182  //dpsiM_temp = dpsiM;
183  //d2psiM_temp = d2psiM;
184 }
185 
186 /** return the ratio only for the iat-th partcle move
187  * @param P current configuration
188  * @param iat the particle thas is being moved
189  */
191 {
192  // FIX FIX FIX : code Woodbury formula
193  psiM_temp = psiM;
194  // either code Woodbury or do multiple single particle updates
196  std::vector<int>::iterator it = BFTrans_.indexQP.begin();
197  std::vector<int>::iterator it_end = BFTrans_.indexQP.end();
198  while (it != it_end)
199  {
200  if (*it < FirstIndex || *it >= LastIndex)
201  {
202  ++it;
203  continue;
204  }
205  int jat = *it - FirstIndex;
206  PosType dr = BFTrans_.newQP[*it] - BFTrans_.QP.R[*it];
207  BFTrans_.QP.makeMove(*it, dr);
208  Phi->evaluateValue(BFTrans_.QP, *it, psiV);
209  for (int orb = 0; orb < psiV.size(); orb++)
210  psiM_temp(orb, jat) = psiV[orb];
211  BFTrans_.QP.rejectMove(*it);
212  it++;
213  }
214  // FIX FIX FIX : code Woodbury formula
216  // FIX FIX FIX : code Woodbury formula
218  LogValue NewLog;
220  InverseTimer.stop();
222 }
223 
225 {
226  APP_ABORT(" Need to implement DiracDeterminantWithBackflow::evaluateRatiosAlltoOne. \n");
227 }
228 
230 {
231  GradType g;
232  g = 0.0;
233  for (int j = 0; j < NumPtcls; j++)
234  {
235  g += dot(BFTrans_.Amat(iat, FirstIndex + j), Fmatdiag[j]);
236  }
237  return g;
238 }
239 
241  ParticleSet& source,
242  int iat)
243 {
244  APP_ABORT(" Need to implement DiracDeterminantWithBackflow::evalGradSource() \n");
245  return GradType();
246 }
247 
249  ParticleSet& P,
250  ParticleSet& source,
251  int iat,
254 {
255  APP_ABORT(" Need to implement DiracDeterminantWithBackflow::evalGradSource() \n");
256  return GradType();
257 }
258 
260  int iat,
261  GradType& grad_iat)
262 {
263  // FIX FIX FIX : code Woodbury formula
264  psiM_temp = psiM;
265  dpsiM_temp = dpsiM;
267  std::vector<int>::iterator it = BFTrans_.indexQP.begin();
268  std::vector<int>::iterator it_end = BFTrans_.indexQP.end();
270  while (it != it_end)
271  {
272  if (*it < FirstIndex || *it >= LastIndex)
273  {
274  ++it;
275  continue;
276  }
277  int jat = *it - FirstIndex;
278  PosType dr = BFTrans_.newQP[*it] - BFTrans_.QP.R[*it];
279  BFTrans_.QP.makeMove(*it, dr);
280  Phi->evaluateVGL(BFTrans_.QP, *it, psiV, dpsiV, d2psiV);
281  for (int orb = 0; orb < psiV.size(); orb++)
282  psiM_temp(orb, jat) = psiV[orb];
283  std::copy(dpsiV.begin(), dpsiV.end(), dpsiM_temp.begin(jat));
284  std::copy(grad_gradV.begin(), grad_gradV.end(), grad_grad_psiM_temp.begin(jat));
285  BFTrans_.QP.rejectMove(*it);
286  it++;
287  }
288  // FIX FIX FIX : code Woodbury formula
290  // FIX FIX FIX : code Woodbury formula
292  LogValue NewLog;
294  InverseTimer.stop();
295  // update Fmatdiag_temp
296  for (int j = 0; j < NumPtcls; j++)
297  {
299  grad_iat += dot(BFTrans_.Amat_temp(iat, FirstIndex + j), Fmatdiag_temp[j]);
300  }
302 }
303 
305 {
306  GradMatrix Fmat_p, Fmat_m;
307  GradVector Fdiag_p, Fdiag_m;
308  HessMatrix Kij, Qij; // finite difference and analytic derivative of Fmat
309  using HessType_0 = Tensor<RealType, OHMMS_DIM>;
310  using GradType_0 = TinyVector<RealType, DIM>;
311  Matrix<GradType_0> Bij, dAij;
312  Matrix<HessType_0> Aij_p, Aij_m;
313  Fdiag_p.resize(NumOrbitals);
314  Fdiag_m.resize(NumOrbitals);
315  Fmat_p.resize(NumPtcls, NumOrbitals);
316  Fmat_m.resize(NumPtcls, NumOrbitals);
317  Kij.resize(NumParticles, NumPtcls);
318  Qij.resize(NumParticles, NumPtcls);
323  Fmat_p = 0.0;
324  Fmat_m = 0.0;
325  Kij = 0.0;
326  Qij = 0.0;
327  Bij = 0.0;
328  dAij = 0.0;
329  Aij_p = 0.0;
330  Aij_m = 0.0;
331  P.update();
332  BFTrans_.evaluate(P);
333  // calculate backflow matrix, 1st and 2nd derivatives
335  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
336  psiMinv = psiM;
337  // invert backflow matrix
340  InverseTimer.stop();
341  // calculate F matrix (gradients wrt bf coordinates)
342  // could use dgemv with increments of 3*nCols
343  for (int i = 0; i < NumPtcls; i++)
344  {
345  for (int j = 0; j < NumPtcls; j++)
346  {
347  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
348  }
349  Fmatdiag[i] = Fmat(i, i);
350  }
351  // calculate gradients and first piece of laplacians
352  GradType temp;
353  int num = P.getTotalNum();
354  for (int i = 0; i < num; i++)
355  for (int j = 0; j < NumPtcls; j++)
356  for (int a = 0; a < 3; a++)
357  (Bij(i, j))[a] = (BFTrans_.Bmat_full(i, FirstIndex + j))[a];
358  for (int i = 0; i < num; i++)
359  {
360  for (int j = 0; j < NumPtcls; j++)
361  {
362  HessType q_j;
363  q_j = 0.0;
364  for (int k = 0; k < NumPtcls; k++)
365  q_j += psiMinv(j, k) * grad_grad_psiM(j, k);
366  for (int a = 0; a < 3; a++)
367  {
368  for (int b = 0; b < 3; b++)
369  {
370  ValueType& qijab = (Qij(i, j))(a, b);
371  for (int k = 0; k < NumPtcls; k++)
372  {
373  if (j == k)
374  {
375  for (int c = 0; c < 3; c++)
376  qijab -=
377  ((BFTrans_.Amat(i, FirstIndex + k))(a, c)) * (((Fmat(j, k))[c]) * ((Fmat(k, j))[b]) - q_j(b, c));
378  }
379  else
380  {
381  for (int c = 0; c < 3; c++)
382  qijab -= ((BFTrans_.Amat(i, FirstIndex + k))(a, c)) * (((Fmat(j, k))[c]) * ((Fmat(k, j))[b]));
383  }
384  }
385  }
386  }
387  }
388  }
389  RealType dr = 0.000001;
390  for (int i = 0; i < num; i++)
391  {
392  for (int a = 0; a < 3; a++)
393  {
394  (P.R[i])[a] += dr;
395  P.update();
396  BFTrans_.evaluate(P);
398  psiMinv = psiM;
401  InverseTimer.stop();
402  for (int j = 0; j < NumPtcls; j++)
403  {
404  Fdiag_p[j] = simd::dot(psiMinv[j], dpsiM[j], NumOrbitals);
405  }
406  for (int j = 0; j < NumPtcls; j++)
407  for (int b = 0; b < 3; b++)
408  {
409  (Aij_p(i, j))(a, b) = (BFTrans_.Amat(i, FirstIndex + j))(a, b);
410  }
411  (P.R[i])[a] -= 2.0 * dr;
412  P.update();
413  BFTrans_.evaluate(P);
415  psiMinv = psiM;
418  InverseTimer.stop();
419  for (int j = 0; j < NumPtcls; j++)
420  {
421  Fdiag_m[j] = simd::dot(psiMinv[j], dpsiM[j], NumOrbitals);
422  }
423  for (int j = 0; j < NumPtcls; j++)
424  for (int b = 0; b < 3; b++)
425  {
426  (Aij_m(i, j))(a, b) = (BFTrans_.Amat(i, FirstIndex + j))(a, b);
427  }
428  (P.R[i])[a] += dr;
429  P.update();
430  BFTrans_.evaluate(P);
431  for (int j = 0; j < NumPtcls; j++)
432  for (int b = 0; b < 3; b++)
433  {
434  (Kij(i, j))(a, b) = ((Fdiag_p[j])[b] - (Fdiag_m[j])[b]) / ((RealType)2.0 * dr);
435  }
436  for (int j = 0; j < NumPtcls; j++)
437  for (int b = 0; b < 3; b++)
438  {
439  (dAij(i, j))[b] += ((Aij_p(i, j))(a, b) - (Aij_m(i, j))(a, b)) / ((RealType)2.0 * dr);
440  }
441  }
442  }
443  std::cout << "Testing derivative of Fjj in complex case: \n";
444  for (int i = 0; i < num; i++)
445  for (int j = 0; j < NumPtcls; j++)
446  {
447  std::cout << "i,j: " << i << " " << j << std::endl;
448  for (int a = 0; a < 3; a++)
449  for (int b = 0; b < 3; b++)
450  {
451  std::cout << a << " " << b << " " << ((Kij(i, j))(a, b)) - ((Qij(i, j))(a, b)) << " -- "
452  << ((Kij(i, j))(a, b)) << " -- " << ((Qij(i, j))(a, b)) << std::endl;
453  }
454  }
455  std::cout << "Testing derivative of Aij in complex case: \n";
456  for (int i = 0; i < num; i++)
457  for (int j = 0; j < NumPtcls; j++)
458  {
459  std::cout << "i,j: " << i << " " << j << std::endl;
460  for (int a = 0; a < 3; a++)
461  {
462  std::cout << a << " " << ((dAij(i, j))[a]) - ((Bij(i, j))[a]) << " -- " << ((dAij(i, j))[a]) << " -- "
463  << ((Bij(i, j))[a]) << std::endl;
464  }
465  }
466  std::cout.flush();
467  APP_ABORT("Finished testL: Aborting \n");
468 }
469 
470 /** Calculate the log value of the Dirac determinant for particles
471  *@param P input configuration containing N particles
472  *@param G a vector containing N gradients
473  *@param L a vector containing N laplacians
474  *@return the value of the determinant
475  *
476  *\f$ (first,first+nel). \f$ Add the gradient and laplacian
477  *contribution of the determinant to G(radient) and L(aplacian)
478  *for local energy calculations.
479  */
483 {
484  //testGG(P);
485  //testL(P);
486  // calculate backflow matrix, 1st and 2nd derivatives
488  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
489  psiMinv = psiM;
490  // invert backflow matrix
493  InverseTimer.stop();
494  // calculate F matrix (gradients wrt bf coordinates)
495  // could use dgemv with increments of 3*nCols
496  for (int i = 0; i < NumPtcls; i++)
497  {
498  for (int j = 0; j < NumPtcls; j++)
499  {
500  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
501  }
502  Fmatdiag[i] = Fmat(i, i);
503  }
504  // calculate gradients and first piece of laplacians
505  GradType temp;
506  ValueType temp2;
507  myG = 0.0;
508  myL = 0.0;
509  int num = P.getTotalNum();
510  for (int i = 0; i < num; i++)
511  {
512  temp = 0.0;
513  temp2 = 0.0;
514  for (int j = 0; j < NumPtcls; j++)
515  {
516  for (int k = 0; k < OHMMS_DIM; k++)
517  temp2 += BFTrans_.Bmat_full(i, FirstIndex + j)[k] * Fmat(j, j)[k];
518  temp += dot(BFTrans_.Amat(i, FirstIndex + j), Fmat(j, j));
519  //temp2 += rcdot(BFTrans_.Bmat_full(i,FirstIndex+j),Fmat(j,j));
520  }
521  myG[i] += temp;
522  myL[i] += temp2;
523  }
524  // NOTE: check derivatives of Fjj and Amat numerically here, the problem has to come from somewhere
525  for (int j = 0; j < NumPtcls; j++)
526  {
527  HessType q_j;
528  q_j = 0.0;
529  for (int k = 0; k < NumPtcls; k++)
530  q_j += psiMinv(j, k) * grad_grad_psiM(j, k);
531  for (int i = 0; i < num; i++)
532  {
535  myL[i] += traceAtB(AA, q_j);
536  //myL[i] += traceAtB(dot(transpose(BFTrans_.Amat(i,FirstIndex+j)),BFTrans_.Amat(i,FirstIndex+j)),q_j);
537  }
538  for (int k = 0; k < NumPtcls; k++)
539  {
540  for (int i = 0; i < num; i++)
541  {
544  HessType FF = outerProduct(Fmat(k, j), Fmat(j, k));
545  myL[i] -= traceAtB(AA, FF);
546  //myL[i] -= traceAtB(dot(transpose(BFTrans_.Amat(i,FirstIndex+j)),BFTrans_.Amat(i,FirstIndex+k)), outerProduct(Fmat(k,j),Fmat(j,k)));
547  }
548  }
549  }
550  for (int i = 0; i < num; i++)
551  {
552  L[i] += myL[i];
553  G[i] += myG[i];
554  }
555  return log_value_;
556 }
557 
558 
559 /** move was accepted, update the real container
560 */
561 void DiracDeterminantWithBackflow::acceptMove(ParticleSet& P, int iat, bool safe_to_delay)
562 {
564  UpdateTimer.start();
565  switch (UpdateMode)
566  {
567  case ORB_PBYP_RATIO:
569  psiM = psiM_temp;
570  break;
571  case ORB_PBYP_PARTIAL:
573  psiM = psiM_temp;
574  dpsiM = dpsiM_temp;
577  break;
578  default:
579  myG = myG_temp;
580  myL = myL_temp;
582  psiM = psiM_temp;
583  dpsiM = dpsiM_temp;
586  break;
587  }
588  UpdateTimer.stop();
589  curRatio = 1.0;
590 }
591 
592 /** move was rejected. Nothing to restore for now.
593 */
595 
597  const opt_variables_type& active,
598  Vector<ValueType>& dlogpsi,
599  Vector<ValueType>& dhpsioverpsi)
600 {
601  /* Note:
602  * Since evaluateDerivatives seems to always be called after
603  * evaluateDeltaLog, which in turn calls evaluateLog, many
604  * of the structures calculated here do not need to be calculated
605  * again. The only one that need to be called is a routine
606  * to calculate grad_grad_grad_psiM. The following structures
607  * should already be known here:
608  * -psiM
609  * -dpsiM
610  * -grad_grad_psiM
611  * -psiM_inv
612  * -Fmat
613  */
614  {
615  // must compute if didn;t call earlier function
617  // copy(psiM.begin(),psiM.end(),psiMinv.begin());
618  psiMinv = psiM;
619  // invert backflow matrix
622  InverseTimer.stop();
623  // calculate F matrix (gradients wrt bf coordinates)
624  // could use dgemv with increments of 3*nCols
625  for (int i = 0; i < NumPtcls; i++)
626  for (int j = 0; j < NumPtcls; j++)
627  {
628  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
629  }
630  }
631  int num = P.getTotalNum();
632  //mmorales: cheap trick for now
633  for (int j = 0; j < NumPtcls; j++)
634  for (int k = 0; k < NumPtcls; k++)
635  {
636  HessType& q_jk = Qmat(j, k);
637  q_jk = 0;
638  for (int n = 0; n < NumPtcls; n++)
639  q_jk += psiMinv(j, n) * grad_grad_psiM(k, n);
640  HessType& a_jk = Ajk_sum(j, k);
641  a_jk = 0;
642  for (int n = 0; n < num; n++)
643  a_jk += dot(transpose(BFTrans_.Amat(n, FirstIndex + j)), BFTrans_.Amat(n, FirstIndex + k));
644  }
645  // this is a mess, there should be a better way
646  // to rearrange this
647  for (int pa = 0; pa < BFTrans_.optIndexMap.size(); ++pa)
648  //for (int pa=0; pa<BFTrans_.numParams; ++pa)
649  {
650  ValueType dpsia = 0;
651  Gtemp = 0;
652  ValueType dLa = 0;
653  GradType temp;
654  temp = 0;
655  for (int i = 0; i < NumPtcls; i++)
656  for (int j = 0; j < NumPtcls; j++)
657  {
658  GradType f_a;
659  f_a = 0;
660  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
661  for (int k = 0; k < NumPtcls; k++)
662  {
663  f_a += (psiMinv(i, k) * dot(grad_grad_psiM(j, k), cj) -
664  Fmat(k, j) * rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(i, k)));
665  }
666  dFa(i, j) = f_a;
667  }
668  for (int i = 0; i < num; i++)
669  {
670  temp = 0;
671  for (int j = 0; j < NumPtcls; j++)
672  temp +=
673  (dot(BFTrans_.Xmat(pa, i, FirstIndex + j), Fmat(j, j)) + dot(BFTrans_.Amat(i, FirstIndex + j), dFa(j, j)));
674  Gtemp[i] += temp;
675  }
676  for (int j = 0; j < NumPtcls; j++)
677  {
678  GradType B_j;
679  B_j = 0;
680  for (int i = 0; i < num; i++)
681  B_j += BFTrans_.Bmat_full(i, FirstIndex + j);
682  dLa += (rcdot(Fmat(j, j), BFTrans_.Ymat(pa, FirstIndex + j)) + dot(B_j, dFa(j, j)));
683  dpsia += rcdot(Fmat(j, j), BFTrans_.Cmat(pa, FirstIndex + j));
684  }
685  for (int j = 0; j < NumPtcls; j++)
686  {
687  HessType a_j_prime;
688  a_j_prime = 0;
689  for (int i = 0; i < num; i++)
690  a_j_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + j)) +
691  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + j)));
692  HessType q_j_prime;
693  q_j_prime = 0;
694  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
695  for (int k = 0; k < NumPtcls; k++)
696  {
697  //tmp=0.0;
698  //for(int n=0; n<NumPtcls; n++) tmp+=psiMinv(k,n)*grad_grad_psiM(j,n);
699  //tmp *= dot(BFTrans_.Cmat(pa,FirstIndex+k),Fmat(j,k));
700  q_j_prime += (psiMinv(j, k) *
701  (cj[0] * grad_grad_grad_psiM(j, k)[0] + cj[1] * grad_grad_grad_psiM(j, k)[1]
702 #if OHMMS_DIM == 3
703  + cj[2] * grad_grad_grad_psiM(j, k)[2]
704 #endif
705  ) -
706  rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(j, k)) * Qmat(k, j));
707  }
708  dLa += (traceAtB(a_j_prime, Qmat(j, j)) + traceAtB(Ajk_sum(j, j), q_j_prime));
709  }
710  for (int j = 0; j < NumPtcls; j++)
711  {
712  for (int k = 0; k < NumPtcls; k++)
713  {
714  HessType a_jk_prime;
715  a_jk_prime = 0;
716  for (int i = 0; i < num; i++)
717  a_jk_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + k)) +
718  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + k)));
719  dLa -= (traceAtB(a_jk_prime, outerProduct(Fmat(k, j), Fmat(j, k))) +
720  traceAtB(Ajk_sum(j, k), outerProduct(dFa(k, j), Fmat(j, k)) + outerProduct(Fmat(k, j), dFa(j, k))));
721  } // k
722  } // j
723  //int kk = pa; //BFTrans_.optIndexMap[pa];
724  int kk = BFTrans_.optIndexMap[pa];
725 #if defined(QMC_COMPLEX)
726  //dlogpsi[kk] += real(dpsia);
727  dlogpsi[kk] += dpsia;
728  //dhpsioverpsi[kk] -= real(0.5 * static_cast<ParticleSet::SingleParticleValue>(dLa) + Dot(P.G, Gtemp));
729  dhpsioverpsi[kk] -= 0.5 * static_cast<ParticleSet::SingleParticleValue>(dLa) + Dot(P.G, Gtemp);
730 #else
731  dlogpsi[kk] += dpsia;
732  dhpsioverpsi[kk] -= (0.5 * static_cast<ParticleSet::SingleParticleValue>(dLa) + Dot(P.G, Gtemp));
733 #endif
734  }
735 }
736 
737 /* Used in MultiSlaterDeterminantWithBackflow::evaluateDerivatives */
739  const opt_variables_type& active,
740  int offset,
741  Matrix<RealType>& dlogpsi,
743  Matrix<RealType>& dL)
744 {
745  /* Note:
746  * Since evaluateDerivatives seems to always be called after
747  * evaluateDeltaLog, which in turn calls evaluateLog, many
748  * of the structures calculated here do not need to be calculated
749  * again. The only one that need to be called is a routine
750  * to calculate grad_grad_grad_psiM. The following structures
751  * should already be known here:
752  * -psiM
753  * -dpsiM
754  * -grad_grad_psiM
755  * -psiM_inv
756  * -Fmat
757  */
759  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
760  psiMinv = psiM;
761  // invert backflow matrix
764  InverseTimer.stop();
765  // calculate F matrix (gradients wrt bf coordinates)
766  // could use dgemv with increments of 3*nCols
767  for (int i = 0; i < NumPtcls; i++)
768  for (int j = 0; j < NumPtcls; j++)
769  {
770  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
771  }
772  //for(int i=0, iat=FirstIndex; i<NumPtcls; i++, iat++)
773  // G(iat) += Fmat(i,i);
774  const ValueType ConstZero(0.0);
775  int num = P.getTotalNum();
776  for (int j = 0; j < NumPtcls; j++)
777  for (int k = 0; k < NumPtcls; k++)
778  {
779  HessType& q_jk = Qmat(j, k);
780  q_jk = ConstZero;
781  for (int n = 0; n < NumPtcls; n++)
782  q_jk += psiMinv(j, n) * grad_grad_psiM(k, n);
783  HessType& a_jk = Ajk_sum(j, k);
784  a_jk = ConstZero;
785  for (int n = 0; n < num; n++)
786  a_jk += dot(transpose(BFTrans_.Amat(n, FirstIndex + j)), BFTrans_.Amat(n, FirstIndex + k));
787  }
788  ValueType sumL = Sum(myL);
789  ValueType dotG = Dot(myG, myG);
790  // this is a mess, there should be a better way
791  // to rearrange this
792  for (int pa = 0; pa < BFTrans_.optIndexMap.size(); ++pa)
793  //for (int pa=0; pa<BFTrans_.numParams; ++pa)
794  {
795  ValueType dpsia = ConstZero;
796  Gtemp = ConstZero;
797  ValueType dLa = ConstZero;
798  GradType temp;
799  for (int i = 0; i < NumPtcls; i++)
800  for (int j = 0; j < NumPtcls; j++)
801  {
802  GradType f_a;
803  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
804  for (int k = 0; k < NumPtcls; k++)
805  {
806  f_a += (psiMinv(i, k) * dot(grad_grad_psiM(j, k), cj) -
807  Fmat(k, j) * rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(i, k)));
808  }
809  dFa(i, j) = f_a;
810  }
811  for (int i = 0; i < num; i++)
812  {
813  temp = ConstZero;
814  for (int j = 0; j < NumPtcls; j++)
815  temp +=
816  (dot(BFTrans_.Xmat(pa, i, FirstIndex + j), Fmat(j, j)) + dot(BFTrans_.Amat(i, FirstIndex + j), dFa(j, j)));
817  Gtemp[i] += temp;
818  }
819  for (int j = 0; j < NumPtcls; j++)
820  {
821  GradType B_j;
822  for (int i = 0; i < num; i++)
823  B_j += BFTrans_.Bmat_full(i, FirstIndex + j);
824  dLa += (rcdot(Fmat(j, j), BFTrans_.Ymat(pa, FirstIndex + j)) + dot(B_j, dFa(j, j)));
825  dpsia += rcdot(Fmat(j, j), BFTrans_.Cmat(pa, FirstIndex + j));
826  }
827  for (int j = 0; j < NumPtcls; j++)
828  {
829  HessType a_j_prime;
830  for (int i = 0; i < num; i++)
831  a_j_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + j)) +
832  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + j)));
833  HessType q_j_prime;
834  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
835  for (int k = 0; k < NumPtcls; k++)
836  {
837  //tmp=0.0;
838  //for(int n=0; n<NumPtcls; n++) tmp+=psiMinv(k,n)*grad_grad_psiM(j,n);
839  //tmp *= dot(BFTrans_.Cmat(pa,FirstIndex+k),Fmat(j,k));
840  q_j_prime += (psiMinv(j, k) *
841  (cj[0] * grad_grad_grad_psiM(j, k)[0] + cj[1] * grad_grad_grad_psiM(j, k)[1] +
842  cj[2] * grad_grad_grad_psiM(j, k)[2]) -
843  rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(j, k)) * Qmat(k, j));
844  }
845  dLa += (traceAtB(a_j_prime, Qmat(j, j)) + traceAtB(Ajk_sum(j, j), q_j_prime));
846  }
847  for (int j = 0; j < NumPtcls; j++)
848  {
849  for (int k = 0; k < NumPtcls; k++)
850  {
851  HessType a_jk_prime;
852  for (int i = 0; i < num; i++)
853  a_jk_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + k)) +
854  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + k)));
855  dLa -= (traceAtB(a_jk_prime, outerProduct(Fmat(k, j), Fmat(j, k))) +
856  traceAtB(Ajk_sum(j, k), outerProduct(dFa(k, j), Fmat(j, k)) + outerProduct(Fmat(k, j), dFa(j, k))));
857  } // k
858  } // j
859 #if defined(QMC_COMPLEX)
860  convertToReal(dpsia, dlogpsi(offset, pa));
861  convertToReal(dLa + sumL * dpsia + dotG * dpsia + static_cast<ValueType>(2.0 * Dot(myG, Gtemp)), dL(offset, pa));
862 #else
863  dlogpsi(offset, pa) = dpsia; // \nabla_pa ln(D)
864  dL(offset, pa) = dLa + sumL * dpsia + dotG * dpsia + static_cast<ValueType>(2.0 * Dot(myG, Gtemp));
865 #endif
866  // \sum_i (\nabla_pa \nabla2_i D) / D
867  for (int k = 0; k < num; k++)
868  dG(offset, pa, k) =
869  Gtemp[k] + myG[k] * static_cast<ParticleSet::SingleParticleValue>(dpsia); // (\nabla_pa \nabla_i D) / D
870  }
871 }
872 
874  const opt_variables_type& active,
875  std::vector<RealType>& dlogpsi,
876  std::vector<RealType>& dhpsioverpsi,
879  int pa)
880 {
882  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
883  psiMinv = psiM;
884  // invert backflow matrix
887  InverseTimer.stop();
888  // calculate F matrix (gradients wrt bf coordinates)
889  // could use dgemv with increments of 3*nCols
890  for (int i = 0; i < NumPtcls; i++)
891  for (int j = 0; j < NumPtcls; j++)
892  {
893  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
894  }
895  //for(int i=0, iat=FirstIndex; i<NumPtcls; i++, iat++)
896  // G(iat) += Fmat(i,i);
897  // this is a mess, there should be a better way
898  // to rearrange this
899  //for (int pa=0; pa<BFTrans_.optIndexMap.size(); ++pa)
900  //for (int pa=0; pa<BFTrans_.numParams; ++pa)
901  const ValueType ConstZero(0.0);
902  {
903  ValueType dpsia = ConstZero;
904  Gtemp = ConstZero;
905  //ValueType dLa=0.0;
906  La1 = La2 = La3 = ConstZero;
907  GradType temp;
908  int num = P.getTotalNum();
909  for (int i = 0; i < NumPtcls; i++)
910  for (int j = 0; j < NumPtcls; j++)
911  {
912  GradType f_a;
913  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
914  for (int k = 0; k < NumPtcls; k++)
915  {
916  f_a += (psiMinv(i, k) * dot(grad_grad_psiM(j, k), cj) -
917  Fmat(k, j) * rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(i, k)));
918  }
919  dFa(i, j) = f_a;
920  }
921  for (int i = 0; i < num; i++)
922  {
923  temp = ConstZero;
924  for (int j = 0; j < NumPtcls; j++)
925  temp +=
926  (dot(BFTrans_.Xmat(pa, i, FirstIndex + j), Fmat(j, j)) + dot(BFTrans_.Amat(i, FirstIndex + j), dFa(j, j)));
927  Gtemp[i] += temp;
928  }
929  for (int j = 0; j < NumPtcls; j++)
930  {
931  GradType B_j;
932  for (int i = 0; i < num; i++)
933  B_j += BFTrans_.Bmat_full(i, FirstIndex + j);
934  La1 += (rcdot(Fmat(j, j), BFTrans_.Ymat(pa, FirstIndex + j)) + dot(B_j, dFa(j, j)));
935  dpsia += rcdot(Fmat(j, j), BFTrans_.Cmat(pa, FirstIndex + j));
936  }
937  for (int j = 0; j < NumPtcls; j++)
938  {
939  HessType q_j;
940  for (int k = 0; k < NumPtcls; k++)
941  q_j += psiMinv(j, k) * grad_grad_psiM(j, k);
942  // define later the dot product with a transpose tensor
943  HessType a_j;
944  for (int i = 0; i < num; i++)
945  a_j += dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + j));
946  HessType a_j_prime;
947  for (int i = 0; i < num; i++)
948  a_j_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + j)) +
949  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + j)));
950  HessType q_j_prime, tmp;
951  PosType& cj = BFTrans_.Cmat(pa, FirstIndex + j);
952  for (int k = 0; k < NumPtcls; k++)
953  {
954  tmp = ConstZero;
955  for (int n = 0; n < NumPtcls; n++)
956  tmp += psiMinv(k, n) * grad_grad_psiM(j, n);
957  tmp *= rcdot(BFTrans_.Cmat(pa, FirstIndex + k), Fmat(j, k));
958  q_j_prime += (psiMinv(j, k) *
959  (cj[0] * grad_grad_grad_psiM(j, k)[0] + cj[1] * grad_grad_grad_psiM(j, k)[1] +
960  cj[2] * grad_grad_grad_psiM(j, k)[2]) -
961  tmp);
962  }
963  La2 += (traceAtB(a_j_prime, q_j) + traceAtB(a_j, q_j_prime));
964  }
965  for (int j = 0; j < NumPtcls; j++)
966  {
967  for (int k = 0; k < NumPtcls; k++)
968  {
969  HessType a_jk;
970  for (int i = 0; i < num; i++)
971  a_jk += dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + k));
972  HessType a_jk_prime;
973  for (int i = 0; i < num; i++)
974  a_jk_prime += (dot(transpose(BFTrans_.Xmat(pa, i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + k)) +
975  dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Xmat(pa, i, FirstIndex + k)));
976  La3 -= (traceAtB(a_jk_prime, outerProduct(Fmat(k, j), Fmat(j, k))) +
977  traceAtB(a_jk, outerProduct(dFa(k, j), Fmat(j, k)) + outerProduct(Fmat(k, j), dFa(j, k))));
978  } // k
979  } // j
980  int kk = pa; //BFTrans_.optIndexMap[pa];
981 #if defined(QMC_COMPLEX)
982  dlogpsi[kk] += real(dpsia);
983  dhpsioverpsi[kk] -= real(0.5 * static_cast<ParticleSet::SingleParticleValue>(La1 + La2 + La3) + Dot(P.G, Gtemp));
984 #else
985  dlogpsi[kk] += dpsia;
986  dhpsioverpsi[kk] -= (0.5 * static_cast<ParticleSet::SingleParticleValue>(La1 + La2 + La3) + Dot(P.G, Gtemp));
987 #endif
988  *G0 += Gtemp;
989  (*L0)[0] += La1 + La2 + La3;
990  }
991 }
992 
993 std::unique_ptr<DiracDeterminantWithBackflow> DiracDeterminantWithBackflow::makeCopyWithBF(
994  std::unique_ptr<SPOSet>&& spo,
995  BackflowTransformation& BF) const
996 {
997  return std::make_unique<DiracDeterminantWithBackflow>(std::move(spo), BF, FirstIndex, LastIndex);
998 }
999 
1001 {
1003  qp_0.resize(BFTrans_.QP.getTotalNum());
1004  ValueMatrix psiM_1, psiM_2;
1005  ValueMatrix psiM_3, psiM_4;
1006  GradMatrix dpsiM_1, dpsiM_2;
1007  HessMatrix dgM, ggM, ggM0;
1008  psiM_1.resize(NumPtcls, NumOrbitals);
1009  psiM_2.resize(NumPtcls, NumOrbitals);
1010  psiM_3.resize(NumPtcls, NumOrbitals);
1011  psiM_4.resize(NumPtcls, NumOrbitals);
1012  dpsiM_1.resize(NumPtcls, NumOrbitals);
1013  dgM.resize(NumPtcls, NumOrbitals);
1014  ggM.resize(NumPtcls, NumOrbitals);
1015  ggM0.resize(NumPtcls, NumOrbitals);
1016  const RealType dh = 0.0000000001; //PREC_WARNING
1017  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1018  qp_0[i] = BFTrans_.QP.R[i];
1019  Phi->evaluate_notranspose(BFTrans_.QP, FirstIndex, LastIndex, psiM, dpsiM, ggM);
1020  app_log() << "Testing GGType calculation: " << std::endl;
1021  for (int lx = 0; lx < 3; lx++)
1022  {
1023  for (int ly = 0; ly < 3; ly++)
1024  {
1025  if (lx == ly)
1026  {
1027  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1028  BFTrans_.QP.R[i] = qp_0[i];
1029  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1030  BFTrans_.QP.R[i][lx] = qp_0[i][lx] + dh;
1031  BFTrans_.QP.update();
1032  evaluate_SPO(psiM_1, dpsiM_1, ggM0);
1033  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1034  BFTrans_.QP.R[i] = qp_0[i];
1035  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1036  BFTrans_.QP.R[i][lx] = qp_0[i][lx] - dh;
1037  BFTrans_.QP.update();
1038  evaluate_SPO(psiM_2, dpsiM_1, ggM0);
1039  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1040  BFTrans_.QP.R[i] = qp_0[i];
1041  BFTrans_.QP.update();
1042  evaluate_SPO(psiM_3, dpsiM_1, ggM0);
1043  for (int i = 0; i < NumPtcls; i++)
1044  for (int j = 0; j < NumOrbitals; j++)
1045  (dgM(i, j))(lx, ly) = (psiM_1(i, j) + psiM_2(i, j) - (RealType)2.0 * psiM_3(i, j)) / (dh * dh);
1046  }
1047  else
1048  {
1049  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1050  BFTrans_.QP.R[i] = qp_0[i];
1051  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1052  BFTrans_.QP.R[i][lx] = qp_0[i][lx] + dh;
1053  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1054  BFTrans_.QP.R[i][ly] = qp_0[i][ly] + dh;
1055  BFTrans_.QP.update();
1056  evaluate_SPO(psiM_1, dpsiM_1, ggM0);
1057  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1058  BFTrans_.QP.R[i] = qp_0[i];
1059  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1060  BFTrans_.QP.R[i][lx] = qp_0[i][lx] - dh;
1061  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1062  BFTrans_.QP.R[i][ly] = qp_0[i][ly] - dh;
1063  BFTrans_.QP.update();
1064  evaluate_SPO(psiM_2, dpsiM_1, ggM0);
1065  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1066  BFTrans_.QP.R[i] = qp_0[i];
1067  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1068  BFTrans_.QP.R[i][lx] = qp_0[i][lx] + dh;
1069  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1070  BFTrans_.QP.R[i][ly] = qp_0[i][ly] - dh;
1071  BFTrans_.QP.update();
1072  evaluate_SPO(psiM_3, dpsiM_1, ggM0);
1073  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1074  BFTrans_.QP.R[i] = qp_0[i];
1075  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1076  BFTrans_.QP.R[i][lx] = qp_0[i][lx] - dh;
1077  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1078  BFTrans_.QP.R[i][ly] = qp_0[i][ly] + dh;
1079  BFTrans_.QP.update();
1080  evaluate_SPO(psiM_4, dpsiM_1, ggM0);
1081  for (int i = 0; i < NumPtcls; i++)
1082  for (int j = 0; j < NumOrbitals; j++)
1083  (dgM(i, j))(lx, ly) =
1084  (psiM_1(i, j) + psiM_2(i, j) - psiM_3(i, j) - psiM_4(i, j)) / ((RealType)4.0 * dh * dh);
1085  }
1086  }
1087  }
1088  for (int i = 0; i < NumPtcls; i++)
1089  for (int j = 0; j < NumOrbitals; j++)
1090  {
1091  std::cout << "i,j: " << i << " " << j << std::endl;
1092  for (int lx = 0; lx < 3; lx++)
1093  for (int ly = 0; ly < 3; ly++)
1094  {
1095  std::cout << "a,b: " << lx << " " << ly << (dgM(i, j))(lx, ly) - (ggM(i, j))(lx, ly) << " -- "
1096  << (dgM(i, j))(lx, ly) << " -- " << (ggM(i, j))(lx, ly) << std::endl;
1097  }
1098  }
1099  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1100  BFTrans_.QP.R[i] = qp_0[i];
1101  BFTrans_.QP.update();
1102 }
1103 
1105 {
1107  qp_0.resize(BFTrans_.QP.getTotalNum());
1108  ValueMatrix psiM_1, psiM_2;
1109  GradMatrix dpsiM_1, dpsiM_2;
1110  HessMatrix ggM_1, ggM_2;
1111  psiM_1.resize(NumPtcls, NumOrbitals);
1112  psiM_2.resize(NumPtcls, NumOrbitals);
1113  dpsiM_1.resize(NumPtcls, NumOrbitals);
1114  dpsiM_2.resize(NumPtcls, NumOrbitals);
1115  ggM_1.resize(NumPtcls, NumOrbitals);
1116  ggM_2.resize(NumPtcls, NumOrbitals);
1117  GGGMatrix ggg_psiM1, ggg_psiM2;
1118  ggg_psiM1.resize(NumPtcls, NumOrbitals);
1119  ggg_psiM2.resize(NumPtcls, NumOrbitals);
1120  const RealType dh = 0.000001; //PREC_WARNING
1121  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1122  qp_0[i] = BFTrans_.QP.R[i];
1124  app_log() << "Testing GGGType calculation: " << std::endl;
1125  for (int lc = 0; lc < 3; lc++)
1126  {
1127  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1128  BFTrans_.QP.R[i] = qp_0[i];
1129  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1130  BFTrans_.QP.R[i][lc] = qp_0[i][lc] + dh;
1131  BFTrans_.QP.update();
1132  evaluate_SPO(psiM_1, dpsiM_1, ggM_1, ggg_psiM1);
1133  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1134  BFTrans_.QP.R[i][lc] = qp_0[i][lc] - dh;
1135  BFTrans_.QP.update();
1136  evaluate_SPO(psiM_2, dpsiM_2, ggM_2, ggg_psiM2);
1137  const RealType dh2 = RealType(0.5 / dh);
1138  RealType maxD(0);
1139  ValueType av(0);
1140  RealType cnt(0);
1141  for (int i = 0; i < NumPtcls; i++)
1142  for (int j = 0; j < NumOrbitals; j++)
1143  {
1144  //HessType dG = (ggM_1(i,j)-ggM_2(i,j))/((RealType)2.0*dh)-(grad_grad_grad_psiM(i,j))[lc];
1145  HessType dG = (ggM_1(i, j) - ggM_2(i, j)) * dh2 - grad_grad_grad_psiM(i, j)[lc];
1146  for (int la = 0; la < 9; la++)
1147  {
1148  cnt++;
1149  av += dG[la];
1150 #if defined(QMC_COMPLEX)
1151  if (std::abs(dG[la].real()) > maxD)
1152  maxD = std::abs(dG[la].real());
1153 #else
1154  if (std::abs(dG[la]) > maxD)
1155  maxD = std::abs(dG[la]);
1156 #endif
1157  }
1158  app_log() << i << " " << j << "\n"
1159  << "dG : \n"
1160  << dG << std::endl
1161  << "GGG: \n"
1162  << (grad_grad_grad_psiM(i, j))[lc] << std::endl;
1163  }
1164  app_log() << "lc, av, max: " << lc << " " << av / cnt << " " << maxD << std::endl;
1165  }
1166  for (int i = 0; i < BFTrans_.QP.getTotalNum(); i++)
1167  BFTrans_.QP.R[i] = qp_0[i];
1168  BFTrans_.QP.update();
1169 }
1170 
1172 {
1173  app_log() << " Testing derivatives of the F matrix, prm: " << pa << std::endl;
1174  opt_variables_type wfVars, wfvar_prime;
1175  BFTrans_.checkInVariables(wfVars);
1176  BFTrans_.checkOutVariables(wfVars);
1177  int Nvars = wfVars.size();
1178  wfvar_prime = wfVars;
1179  GradMatrix dpsiM_1, dpsiM_2, dpsiM_0;
1180  dpsiM_0.resize(NumPtcls, NumOrbitals);
1181  dpsiM_1.resize(NumPtcls, NumOrbitals);
1182  dpsiM_2.resize(NumPtcls, NumOrbitals);
1183  const RealType dh(0.00001); //PREC_WARN
1184  int pr = pa;
1185  for (int j = 0; j < Nvars; j++)
1186  wfvar_prime[j] = wfVars[j];
1187  wfvar_prime[pr] = wfVars[pr] + dh;
1188  BFTrans_.resetParameters(wfvar_prime);
1191  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
1192  psiMinv = psiM;
1193  // invert backflow matrix
1194  InverseTimer.start();
1196  InverseTimer.stop();
1197  // calculate F matrix (gradients wrt bf coordinates)
1198  // could use dgemv with increments of 3*nCols
1199  for (int i = 0; i < NumPtcls; i++)
1200  for (int j = 0; j < NumPtcls; j++)
1201  {
1202  dpsiM_1(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
1203  }
1204  for (int j = 0; j < Nvars; j++)
1205  wfvar_prime[j] = wfVars[j];
1206  wfvar_prime[pr] = wfVars[pr] - dh;
1207  BFTrans_.resetParameters(wfvar_prime);
1210  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
1211  psiMinv = psiM;
1212  // invert backflow matrix
1213  InverseTimer.start();
1215  InverseTimer.stop();
1216  // calculate F matrix (gradients wrt bf coordinates)
1217  // could use dgemv with increments of 3*nCols
1218  for (int i = 0; i < NumPtcls; i++)
1219  for (int j = 0; j < NumPtcls; j++)
1220  {
1221  dpsiM_2(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
1222  }
1223  for (int j = 0; j < Nvars; j++)
1224  wfvar_prime[j] = wfVars[j];
1225  BFTrans_.resetParameters(wfvar_prime);
1228  //std::copy(psiM.begin(),psiM.end(),psiMinv.begin());
1229  psiMinv = psiM;
1230  // invert backflow matrix
1231  InverseTimer.start();
1233  InverseTimer.stop();
1234  // calculate F matrix (gradients wrt bf coordinates)
1235  // could use dgemv with increments of 3*nCols
1236  for (int i = 0; i < NumPtcls; i++)
1237  for (int j = 0; j < NumPtcls; j++)
1238  {
1239  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
1240  }
1241  RealType cnt = 0, av = 0;
1242  RealType maxD(0);
1243  for (int i = 0; i < NumPtcls; i++)
1244  for (int j = 0; j < NumPtcls; j++)
1245  for (int lb = 0; lb < 3; lb++)
1246  {
1247  dpsiM_0(i, j)[lb] = 0.0;
1248  for (int k = 0; k < NumPtcls; k++)
1249  for (int lc = 0; lc < 3; lc++)
1250  {
1251  dpsiM_0(i, j)[lb] += (BFTrans_.Cmat(pr, FirstIndex + j)[lc] * psiMinv(i, k) * grad_grad_psiM(j, k)(lb, lc) -
1252  BFTrans_.Cmat(pr, FirstIndex + k)[lc] * Fmat(i, k)[lc] * Fmat(k, j)[lb]);
1253  }
1254  cnt++;
1255 #if defined(QMC_COMPLEX)
1256  RealType t = real(dpsiM_0(i, j)[lb] - (dpsiM_1(i, j)[lb] - dpsiM_2(i, j)[lb])) / (2 * dh);
1257  av += t;
1258  maxD = std::max(maxD, std::abs(t));
1259 #else
1260  av += dpsiM_0(i, j)[lb] - (dpsiM_1(i, j)[lb] - dpsiM_2(i, j)[lb]) / (2 * dh);
1261  if (std::abs(dpsiM_0(i, j)[lb] - (dpsiM_1(i, j)[lb] - dpsiM_2(i, j)[lb]) / (2 * dh)) > maxD)
1262  maxD = dpsiM_0(i, j)[lb] - (dpsiM_1(i, j)[lb] - dpsiM_2(i, j)[lb]) / (2 * dh);
1263 #endif
1264  }
1265  app_log() << " av,max : " << av / cnt << " " << maxD << std::endl;
1266  //APP_ABORT("testing Fij \n");
1267 }
1268 
1269 
1271 {
1272  //app_log() <<"Testing new L[i]: \n";
1273  opt_variables_type wfVars, wfvar_prime;
1274  BFTrans_.checkInVariables(wfVars);
1275  BFTrans_.checkOutVariables(wfVars);
1276  int Nvars = wfVars.size();
1277  wfvar_prime = wfVars;
1278  RealType dh = 0.00001;
1279  //BFTrans_.evaluate(P);
1280  ValueType L1a, L2a, L3a;
1281  ValueType L1b, L2b, L3b;
1282  //dummyEvalLi(L1,L2,L3);
1283  myG = 0.0;
1284  myL = 0.0;
1285  //ValueType ps = evaluateLog(P,myG,myL);
1286  //L0 = Sum(myL);
1287  //app_log() <<"L old, L new: " <<L0 <<" " <<L1+L2+L3 << std::endl;
1288  app_log() << std::endl << " Testing derivatives of L[i] matrix. " << std::endl;
1289  for (int j = 0; j < Nvars; j++)
1290  wfvar_prime[j] = wfVars[j];
1291  wfvar_prime[pa] = wfVars[pa] + dh;
1292  BFTrans_.resetParameters(wfvar_prime);
1293  BFTrans_.evaluate(P);
1294  dummyEvalLi(L1a, L2a, L3a);
1295  for (int j = 0; j < Nvars; j++)
1296  wfvar_prime[j] = wfVars[j];
1297  wfvar_prime[pa] = wfVars[pa] - dh;
1298  BFTrans_.resetParameters(wfvar_prime);
1299  BFTrans_.evaluate(P);
1300  dummyEvalLi(L1b, L2b, L3b);
1301  BFTrans_.resetParameters(wfVars);
1303  std::vector<RealType> dlogpsi;
1304  std::vector<RealType> dhpsi;
1305  dlogpsi.resize(Nvars);
1306  dhpsi.resize(Nvars);
1307  evaluateDerivatives(P, wfVars, dlogpsi, dhpsi, &myG, &myL, pa);
1308  app_log() << "pa: " << pa << std::endl
1309  << "dL Numrical: " << (L1a - L1b) / (2 * dh) << " " << (L2a - L2b) / (2 * dh) << " "
1310  << (L3a - L3b) / (2 * dh) << "\n"
1311  << "dL Analitival: " << La1 << " " << La2 << " " << La3 << std::endl
1312  << " dLDiff: " << (L1a - L1b) / (2 * dh) - La1 << " " << (L2a - L2b) / (2 * dh) - La2 << " "
1313  << (L3a - L3b) / (2 * dh) - La3 << std::endl;
1314 }
1315 
1316 
1317 // evaluate \sum_i L[i] splitted into three pieces
1319 {
1320  L1 = L2 = L3 = 0.0;
1322  psiMinv = psiM;
1323  InverseTimer.start();
1325  InverseTimer.stop();
1326  for (int i = 0; i < NumPtcls; i++)
1327  for (int j = 0; j < NumPtcls; j++)
1328  {
1329  Fmat(i, j) = simd::dot(psiMinv[i], dpsiM[j], NumOrbitals);
1330  }
1331  GradType temp;
1332  int num = BFTrans_.QP.getTotalNum();
1333  for (int i = 0; i < num; i++)
1334  {
1335  for (int j = 0; j < NumPtcls; j++)
1336  L1 += rcdot(Fmat(j, j), BFTrans_.Bmat_full(i, FirstIndex + j));
1337  }
1338  for (int j = 0; j < NumPtcls; j++)
1339  {
1340  HessType q_j;
1341  for (int k = 0; k < NumPtcls; k++)
1342  q_j += psiMinv(j, k) * grad_grad_psiM(j, k);
1343  HessType a_j;
1344  for (int i = 0; i < num; i++)
1345  a_j += dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + j));
1346  L2 += traceAtB(a_j, q_j);
1347  for (int k = 0; k < NumPtcls; k++)
1348  {
1349  HessType a_jk;
1350  for (int i = 0; i < num; i++)
1351  a_jk += dot(transpose(BFTrans_.Amat(i, FirstIndex + j)), BFTrans_.Amat(i, FirstIndex + k));
1352  L3 -= traceAtB(a_jk, outerProduct(Fmat(k, j), Fmat(j, k)));
1353  }
1354  }
1355 }
1356 
1357 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
T Sum(const ParticleAttrib< T > &pa)
GradType evalGradSource(ParticleSet &P, ParticleSet &source, int iat) override
return the logarithmic gradient for the iat-th particle of the source particleset ...
void evaluateDerivatives(ParticleSet &P, const opt_variables_type &active, Vector< ValueType > &dlogpsi, Vector< ValueType > &dhpsioverpsi) override
Compute the derivatives of both the log of the wavefunction and kinetic energy with respect to optimi...
GradType evalGrad(ParticleSet &P, int iat) override
return the current gradient for the iat-th particle
static T convert(const std::complex< T1 > &logpsi)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::GradType GradType
Definition: Configuration.h:62
T dot(const T *restrict a, const T *restrict b, int n, TRES res=TRES())
dot product
QTBase::RealType RealType
Definition: Configuration.h:58
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
size_t getTotalNum() const
Definition: ParticleSet.h:493
ParticleSet::ParticlePos newQP
new qp coordinates for pbyp moves.
std::ostream & app_log()
Definition: OutputManager.h:65
ValueVector psiV
value of single-particle orbital for particle-by-particle update
void dummyEvalLi(ValueType &L1, ValueType &L2, ValueType &L3)
void convertToReal(const T1 &in, T2 &out)
generic conversion from type T1 to type T2 using implicit conversion
Definition: ConvertToReal.h:32
std::unique_ptr< DiracDeterminantWithBackflow > makeCopyWithBF(std::unique_ptr< SPOSet > &&spo, BackflowTransformation &BF) const
cloning function
ParticleAttrib< QTFull::ValueType > ParticleLaplacian
Definition: Configuration.h:96
float real(const float &c)
real part of a scalar. Cannot be replaced by std::real due to AFQMC specific needs.
void transpose(const T *restrict A, size_t m, size_t lda, TO *restrict B, size_t n, size_t ldb)
transpose of A(m,n) to B(n,m)
Definition: algorithm.hpp:97
ValueMatrix psiMinv
temporary container for testing
void resize(size_type n, size_type m)
Resize the container.
Definition: OhmmsMatrix.h:99
void update(bool skipSK=false)
update the internal data
Attaches a unit to a Vector for IO.
std::complex< T > convertValueToLog(const std::complex< T > &logpsi)
evaluate log(psi) as log(|psi|) and phase
ParticleLaplacian L
laplacians of the particles
Definition: ParticleSet.h:85
OrbitalSetTraits< ValueType >::HessType HessType
T traceAtB(const Tensor< T, D > &a, const Tensor< T, D > &b)
Tr(a^t *b), .
Definition: Tensor.h:361
const int FirstIndex
index of the first particle with respect to the particle set
QTFull::ValueType SingleParticleValue
Definition: Configuration.h:97
#define OHMMS_DIM
Definition: config.h:64
T Dot(const ParticleAttrib< TinyVector< T, D >> &pa, const ParticleAttrib< TinyVector< T, D >> &pb)
void evaluateDerivatives(const ParticleSet &P)
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
std::complex< QTFull::RealType > LogValue
void evaluate_SPO(ValueMatrix &logdet, GradMatrix &dlogdet, HessMatrix &grad_grad_logdet)
replace of SPOSet::evaluate function with the removal of t_logpsi
void copy(const Array< T1, 3 > &src, Array< T2, 3 > &dest)
Definition: Blitz.h:639
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
const std::unique_ptr< SPOSet > Phi
a set of single-particle orbitals used to fill in the values of the matrix
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
void checkOutVariables(const opt_variables_type &active)
DiracDeterminantWithBackflow(std::unique_ptr< SPOSet > &&spos, BackflowTransformation &BF, int first, int last)
constructor
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > outerProduct(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
Definition: TinyVector.h:211
void rejectMove(Index_t iat)
reject a proposed move in regular mode
void InvertWithLog(T *restrict x, int n, int m, T *restrict work, int *restrict pivot, std::complex< T1 > &logdet)
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
const int LastIndex
index of the last particle with respect to the particle set
PsiValue ratio(ParticleSet &P, int iat) override
return the ratio only for the iat-th partcle move
ParticlePos R
Position.
Definition: ParticleSet.h:79
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void acceptMove(ParticleSet &P, int iat, bool safe_to_delay=false) override
move was accepted, update the real container
AntiSymTensor< T, D > transpose(const AntiSymTensor< T, D > &rhs)
const int NumOrbitals
number of single-particle orbitals which belong to this Dirac determinant
size_type size() const
return the size
Definition: VariableSet.h:88
ParticleSet::SingleParticleValue * LastAddressOfG
void checkInVariables(opt_variables_type &active)
Define determinant operators.
void makeMove(Index_t iat, const SingleParticlePos &displ, bool maybe_accept=true)
move the iat-th particle to active_pos_
void resetParameters(const opt_variables_type &active)
void evaluate(const ParticleSet &P)
calculate quasi-particle coordinates, Bmat and Amat
void registerData(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > dot(const AntiSymTensor< T1, D > &lhs, const AntiSymTensor< T2, D > &rhs)
LatticeGaussianProduct::ValueType ValueType
ParticleAttrib< QTFull::GradType > ParticleGradient
Definition: Configuration.h:95
PsiValue ratioGrad(ParticleSet &P, int iat, GradType &grad_iat) override
evaluate the ratio of the new to old WaveFunctionComponent value and the new gradient ...
LogValue updateBuffer(ParticleSet &P, WFBufferType &buf, bool fromscratch=false) override
For particle-by-particle move.
void resize(int nel, int morb)
reset the size: with the number of particles and number of orbtials
Declaration of DiracDeterminantWithBackflow with a S(ingle)P(article)O(rbital)Set.
const int NumPtcls
number of particles which belong to this Dirac determinant
A D-dimensional Array class based on PETE.
Definition: OhmmsArray.h:25
void evaluateRatiosAlltoOne(ParticleSet &P, std::vector< ValueType > &ratios) override
evaluate the ratios of one virtual move with respect to all the particles
void copyFromBuffer(ParticleSet &P, WFBufferType &buf) override
For particle-by-particle move.
void put(std::complex< T1 > &x)
Definition: PooledMemory.h:165
void restore(int iat) override
move was rejected.
LogValue evaluateLog(const ParticleSet &P, ParticleSet::ParticleGradient &G, ParticleSet::ParticleLaplacian &L) override
Calculate the log value of the Dirac determinant for particles.
ParticleSet::SingleParticleValue * FirstAddressOfG
ValueType rcdot(TinyVector< RealType, OHMMS_DIM > &lhs, TinyVector< ValueType, OHMMS_DIM > &rhs)
ParticleSet QP
quasiparticle coordinates
std::vector< int > indexQP
store index of qp coordinates that changed during pbyp move
void add(std::complex< T1 > &x)
Definition: PooledMemory.h:113
int NP
total number of particles. Ye: used to track first time allocation but I still feel it very strange...
void get(std::complex< T1 > &x)
Definition: PooledMemory.h:132