void ThreeDimMomDist::updateDistribution(ParticleSet& PtclSet, TrialWaveFunction& Psi, 
					   IndexType NumCycles) {
    TinyVector<IndexType, 3> Indexes;
    for (IndexType cycle = 0; cycle < NumCycles; cycle++) {

      pcp->NewWalker();
      PosType dr;
      for (Indexes[0] = 0; Indexes[0] < NumPts[0]; Indexes[0]++) {
	dr[1] = 0.0;
	for (Indexes[1] = 0; Indexes[1] < NumPts[1]; Indexes[1]++) {
	  dr[2] = 0.0;
	  for (Indexes[2] = 0; Indexes[2] < NumPts[2]; Indexes[2]++) {
	    IndexType partToDisplace = (*pcp)();

	    PtclSet.makeMove(partToDisplace, dr);

	    if (Indexes[0] == 0 && Indexes[1] == 0 && Indexes[2] == 0) {
	      placeIntsInBin(Indexes, 1.0);
	    } else {
	      placeIntsInBin(Indexes, Psi.ratio(PtclSet, partToDisplace));
	    }
	    totalNumSamples++;
	    PtclSet.rejectMove(partToDisplace);

	    dr[2] += Spacing[2];
	  }      
	  dr[1] += Spacing[1];
	}
	dr[0] += Spacing[0];
      }	

    } 
  }
  NonLocalECPComponent::RealType 
  NonLocalECPComponent::evaluate(ParticleSet& W, TrialWaveFunction& psi,int iat, vector<NonLocalData>& Txy) {
    RealType esum=0.0;

    //int iel=0;
    for(int nn=myTable->M[iat],iel=0; nn<myTable->M[iat+1]; nn++,iel++){

      register RealType r(myTable->r(nn));
      if(r>Rmax) continue;

      register RealType rinv(myTable->rinv(nn));
      register PosType  dr(myTable->dr(nn));

      int txyCounter=Txy.size();
      // Compute ratio of wave functions
      for (int j=0; j < nknot ; j++){ 
        PosType deltar(r*rrotsgrid_m[j]-dr);
        PosType newpos(W.makeMove(iel,deltar)); 
        psiratio[j]=psi.ratio(W,iel)*sgridweight_m[j];
        W.rejectMove(iel);
        //psi.rejectMove(iel);
        //first, add a new NonLocalData with ratio
        Txy.push_back(NonLocalData(iel,psiratio[j],deltar));
      }
      // Compute radial potential
      for(int ip=0;ip< nchannel; ip++){
        vrad[ip]=nlpp_m[ip]->splint(r)*wgt_angpp_m[ip];
      }

      // Compute spherical harmonics on grid
      for (int j=0, jl=0; j<nknot ; j++){ 
        RealType zz=dot(dr,rrotsgrid_m[j])*rinv;
        // Forming the Legendre polynomials
        lpol[0]=1.0;
        RealType lpolprev=0.0;
        for (int l=0 ; l< lmax ; l++){
          //Not a big difference
          //lpol[l+1]=(2*l+1)*zz*lpol[l]-l*lpolprev;
          //lpol[l+1]/=(l+1);
          lpol[l+1]=Lfactor1[l]*zz*lpol[l]-l*lpolprev; 
          lpol[l+1]*=Lfactor2[l]; 
          lpolprev=lpol[l];
        }

        //for(int l=0; l <nchannel; l++,jl++) Amat[jl]=lpol[ angpp_m[l] ]; 
        RealType lsum=0;
        for(int l=0; l <nchannel; l++) lsum += vrad[l]*lpol[ angpp_m[l] ]; 
        esum += Txy[txyCounter++].Weight *= lsum;
      } 
     //BLAS::gemv(nknot, nchannel, &Amat[0], &psiratio[0], &wvec[0]);
     //esum += BLAS::dot(nchannel, &vrad[0], &wvec[0]);
    }   /* end loop over electron */
    return esum;

  }
  void RandomMomDist::updateDistribution(ParticleSet& PtclSet, TrialWaveFunction& Psi, IndexType NumSamples) {
    pcp->NewWalker();
    for (IndexType i = 0; i < NumSamples; i++) {
      PosType dr = PtclSet.Lattice.toCart(PosType(Random(), Random(), Random()));
      IndexType PtclToDisplace = (*pcp)();
      PtclSet.makeMove(PtclToDisplace, dr);
      ComplexType ratio = Psi.ratio(PtclSet, PtclToDisplace);
      PtclSet.rejectMove(PtclToDisplace);
      totalNumSamples++;
      for (IndexType GVecNum = 0; GVecNum < GVectors.size(); GVecNum++) {
	NofK[GVecNum] += ratio * exp(ComplexType(0,-1.0) * dot(GVectors[GVecNum], dr));
      }
    }
  }
  void AveragedOneDimMomDist::updateDistribution(ParticleSet& PtclSet, TrialWaveFunction& Psi, 
						 IndexType NumCycles) {
    IndexType targetNumSamples = totalNumSamples + NumCycles;
    while(totalNumSamples < targetNumSamples) {
      PosType dr;
      for (IndexType i = 0; i < 3; i++) {
	dr += Random() * PtclSet.Lattice.a(i);
      }
      RealType DispVecLength = std::sqrt(dot(dr, dr));
      RealType FracDispVecLength = InvRsLatSize[0] * DispVecLength / 2.0;
      
      IndexType PtclToDisplace = (*pcp)();
      PtclSet.makeMove(PtclToDisplace, dr);
      PlaceCloudInBin(FracDispVecLength, Psi.ratio(PtclSet, PtclToDisplace));
      totalNumSamples++;
      PtclSet.rejectMove(PtclToDisplace);
    }
  }
  void OneDimMomDist::updateDistribution(ParticleSet& PtclSet, TrialWaveFunction& Psi, 
					 IndexType NumCycles) {
    for (IndexType cycle = 0; cycle < NumCycles; cycle++) {
      pcp->NewWalker();
      TinyVector<IndexType, 1> Indexes(0.0);
      PosType dr(0,0,0);
      placeIntsInBin(Indexes, 1.0);
      totalNumSamples++;
      for (Indexes[0] = 1; Indexes[0] < NumPts[0]; Indexes[0]++) {
	dr[0] = dr[1] = dr[2] += Spacing[0];
//        dr[0] += Spacing[0];
	IndexType partToDisplace = (*pcp)();
	PtclSet.makeMove(partToDisplace, dr);
        placeIntsInBin(Indexes, Psi.ratio(PtclSet, partToDisplace));
        totalNumSamples++;
	PtclSet.rejectMove(partToDisplace);
      }
    }
  }
  /** evaluate the non-local potential of the iat-th ionic center
   * @param W electron configuration
   * @param iat ionic index
   * @param psi trial wavefunction
   * @param return the non-local component
   *
   * Currently, we assume that the ratio-only evaluation does not change the state
   * of the trial wavefunction and do not call psi.rejectMove(ieL).
   */
  NonLocalECPComponent::RealType 
  NonLocalECPComponent::evaluate(ParticleSet& W, int iat, TrialWaveFunction& psi) {
    RealType esum=0.0;
    for(int nn=myTable->M[iat],iel=0; nn<myTable->M[iat+1]; nn++,iel++){

      register RealType r(myTable->r(nn));
      if(r>Rmax) continue;

      register RealType rinv(myTable->rinv(nn));
      register PosType  dr(myTable->dr(nn));

      // Compute ratio of wave functions
      for (int j=0; j < nknot ; j++){ 
        PosType deltar(r*rrotsgrid_m[j]-dr);
        W.makeMove(iel,deltar); 
        psiratio[j]=psi.ratio(W,iel)*sgridweight_m[j];
        W.rejectMove(iel);
        //psi.rejectMove(iel);
      }
      // Compute radial potential
      //int k;
      //RealType rfrac;
      //nlpp_m[0]->locate(r,k,rfrac);
      //for(int ip=0;ip< nchannel; ip++){
      //  vrad[ip]=nlpp_m[ip]->f(k,rfrac)*wgt_angpp_m[ip];
      //}
      for(int ip=0;ip< nchannel; ip++){
        vrad[ip]=nlpp_m[ip]->splint(r)*wgt_angpp_m[ip];
      }

      // Compute spherical harmonics on grid
      for (int j=0, jl=0; j<nknot ; j++){ 
        RealType zz=dot(dr,rrotsgrid_m[j])*rinv;
        // Forming the Legendre polynomials
        lpol[0]=1.0;
        RealType lpolprev=0.0;
        for (int l=0 ; l< lmax ; l++){
          //Not a big difference
          //lpol[l+1]=(2*l+1)*zz*lpol[l]-l*lpolprev;
          //lpol[l+1]/=(l+1);
          lpol[l+1]=Lfactor1[l]*zz*lpol[l]-l*lpolprev; 
          lpol[l+1]*=Lfactor2[l]; 
          lpolprev=lpol[l];
        }
        for(int l=0; l <nchannel; l++,jl++) Amat[jl]=lpol[ angpp_m[l] ]; 
      } 

      if(nchannel==1) {
        esum += vrad[0]*BLAS::dot(nknot, &Amat[0],&psiratio[0]);
      } else {
        BLAS::gemv(nknot, nchannel, &Amat[0], &psiratio[0], &wvec[0]);
        esum += BLAS::dot(nchannel, &vrad[0], &wvec[0]);
      }
      ////////////////////////////////////
      //Original implmentation by S. C.
      //const char TRANS('T');
      //const int ione=1;
      //const RealType one=1.0;
      //const RealType zero=0.0;
      //dgemv(TRANS,nknot,nchannel,one,&Amat[0],nknot,&psiratio[0],ione,zero,&wvec[0],ione);
      //esum += ddot(nchannel,&vrad[0],ione,&wvec[0],ione);
      ////////////////////////////////////
      //iel++;
    }   /* end loop over electron */
    return esum;
  }