void Jastrow_threebody_piece_diffspin::getParmDeriv(const Array3 <doublevar> & eibasis, const Array3 <doublevar> & eebasis, Parm_deriv_return & deriv) { //cout << "Jastrow_threebody_piece_diffspin::getParmDeriv" << endl; assert(eibasis.GetDim(1) >= parm_centers.GetDim(0)); int natoms=parm_centers.GetDim(0); int nelectrons=eebasis.GetDim(0); const doublevar tiny=1e-14; //cout << "updateLap " << endl; for(int at=0; at < natoms; at++) { int p=parm_centers(at); for(int i=0; i< _nparms(p); i++) { int k=klm(i,0), el=klm(i,1), m=klm(i,2); for(int e=0; e< nelectrons; e++) { if(fabs(eibasis(e,at,k)) > tiny || fabs(eibasis(e,at,el)) > tiny) { for(int j=e+1; j< nelectrons; j++) { int s=(j < nspin_up) != (e < nspin_up); int index=linear_parms(s)(p,i); doublevar vkl=(//eibasis(e,at,k)*eibasis(j,at,el) +eibasis(j,at,k)*eibasis(e,at,el)); deriv.gradient(index)+=vkl*eebasis(e,j,m); } } } } } }
int BCS_wf::getParmDeriv(Wavefunction_data *wfdata , Sample_point * sample, Parm_deriv_return & parm_derivatives ) { // analytic expressions below are valid only if jastrow can provide // analytic derivatives (not sure if it is enough to test this) if ( !parent->jastdata.supports(parameter_derivatives) ) return 0; //cout << "BCS_wf: doing analytic derivatives with respect to parameters." // << endl ; int nparms_full=parent->nparms(); int nparms_start=parm_derivatives.nparms_start; int nparms_end=parm_derivatives.nparms_end; int nparms=nparms_end-nparms_start; parm_derivatives.gradient.Resize(nparms); parm_derivatives.hessian.Resize(nparms, nparms); // gradients of the two-body orbital Array3 <doublevar> twobody_parm_deriv; jast.updateLap(&parent->jastdata,sample); jast.get_twobody_ParmDeriv(sample,twobody_parm_deriv); // gradient parm_derivatives.gradient=0.0; for(int det=0; det < ndet; det++) { for (int alpha=0; alpha<nparms; alpha++) { for(int i=0; i< nelectrons(0); i++) { for (int j=0; j< nelectrons(1); j++) { parm_derivatives.gradient(alpha)+= twobody_parm_deriv(i,nelectrons(0)+j,alpha)*inverse(det)(i,j)* parent->magnification_factor; } } } } // hessian parm_derivatives.hessian=0.0; for(int det=0; det < ndet; det++) { for (int alpha=0; alpha<nparms; alpha++) { for (int beta=0; beta<nparms; beta++) { parm_derivatives.hessian(alpha,beta)+= parm_derivatives.gradient(alpha)*parm_derivatives.gradient(beta); for(int i=0; i< nelectrons(0); i++) { for (int j=0; j< nelectrons(1); j++) { for(int k=0; k< nelectrons(0); k++) { for (int l=0; l< nelectrons(1); l++) { parm_derivatives.hessian(alpha,beta)-= twobody_parm_deriv(i,nelectrons(0)+j,alpha)*inverse(det)(k,j)* twobody_parm_deriv(k,nelectrons(0)+l,beta)*inverse(det)(i,l)* parent->magnification_factor*parent->magnification_factor; } } } } } } } return 1; }