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);
          }
        }
      }
    }
  } 
}
Example #2
0
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;

}