00001 #include "QMCThreeBodyCorrelationFunctionParameters.h"
00002 #include "QMCInput.h"
00003 #include <iomanip>
00004 
00005 Array1D<double> QMCThreeBodyCorrelationFunctionParameters::getFreeParameters()
00006 {
00007   return freeParameters;
00008 }
00009 
00010 void QMCThreeBodyCorrelationFunctionParameters::operator = (const 
00011                                QMCThreeBodyCorrelationFunctionParameters & rhs)
00012 {
00013   NumberOfParameterTypes = rhs.NumberOfParameterTypes;
00014   NumberOfParameters = rhs.NumberOfParameters;
00015   NeN = rhs.NeN;
00016   Nee = rhs.Nee;
00017 
00018   NumberOfFreeParameters = rhs.NumberOfFreeParameters;
00019   freeParameters = rhs.freeParameters;
00020 
00021   paramDepMatrix = rhs.paramDepMatrix;
00022 
00023   TotalNumberOfParameters = rhs.TotalNumberOfParameters;
00024   Parameters = rhs.Parameters;
00025   isFree  = rhs.isFree;
00026 
00027   C = rhs.C;
00028   cutoff = rhs.cutoff;
00029 
00030   ParticleTypes = rhs.ParticleTypes;
00031   threeBodyCorrelationFunctionType = rhs.threeBodyCorrelationFunctionType;
00032 
00033   setThreeBodyCorrelationFunction();
00034   initializeThreeBodyCorrelationFunctionParameters();
00035 }
00036 
00048 bool QMCThreeBodyCorrelationFunctionParameters::read(istream & strm)
00049 {
00050   bool ok = true;
00051   string temp;
00052   int start = strm.tellg();   
00053   
00054   
00055   string pt1, pt2, pt3;
00056   strm >> temp;
00057 
00058   if(temp != "ParticleTypes:")
00059     {
00060       strm.seekg(start);
00061       return false;
00062     }
00063 
00064   strm >> pt1 >> pt2 >> pt3;
00065   pt1 = StringManipulation::toFirstUpperRestLower(pt1);
00066   pt2 = StringManipulation::toFirstUpperRestLower(pt2);
00067   pt3 = StringManipulation::toFirstUpperRestLower(pt3);
00068 
00069   
00070   
00071   
00072   
00073   
00074   
00075 
00076   ParticleTypes(0) = pt1;
00077   ParticleTypes(1) = pt2;
00078   ParticleTypes(2) = pt3;
00079 
00080   if ( pt2 == "Electron_up")
00081     {
00082       if (pt3 != "Electron_up" && pt3 != "Electron_down")
00083         {
00084           clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters: ";
00085           clog << "particles " << pt1 << ", " << pt2 << ", " << pt3 << " are ";
00086           clog << "being loaded as a three body correlation function!" << endl;
00087           ok = false;
00088         }
00089     }
00090   else if ( pt2 == "Electron_down")
00091     {
00092       if (pt3 != "Electron_down")
00093         { 
00094           
00095           
00096           clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters: ";
00097           clog << "particles " << pt1 << ", " << pt2 << ", " << pt3 << " are ";
00098           clog << "being loaded as a three body correlation function!" << endl;
00099           ok = false;
00100         }
00101     }
00102   
00103   
00104   
00105   strm >> temp;
00106 
00107   if(temp != "threeBodyCorrelationFunctionType:")
00108     {
00109       
00110       strm.seekg(start);
00111       return false;
00112     }
00113 
00114   strm >> threeBodyCorrelationFunctionType;
00115   if (threeBodyCorrelationFunctionType != "Cambridge" && 
00116       threeBodyCorrelationFunctionType != "None")
00117     {
00118       clog << "ERROR: unknown type of ThreeBodyCorrelationFunction is being ";
00119       clog << "read.  threeBodyCorrelationFunctionType = ";
00120       clog << threeBodyCorrelationFunctionType << endl;
00121       ok = false;
00122     }
00123 
00124   
00125   strm >> temp;
00126   strm >> temp;
00127   NumberOfParameterTypes = atoi(temp.c_str());
00128 
00129   if (NumberOfParameterTypes != 2)
00130     {
00131       
00132       clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters: ";
00133       clog << "NumberOfParametersTypes = " << NumberOfParameterTypes;
00134       clog << ", 2 was expected." << endl;
00135       ok = false;
00136       return ok;
00137     }
00138 
00139   
00140   
00141 
00142   NumberOfParameters.allocate(NumberOfParameterTypes);
00143   strm >> temp;
00144   
00145   for (int i=0; i<NumberOfParameterTypes; i++)
00146     {
00147       strm >> temp;
00148       NumberOfParameters(i) = atoi(temp.c_str());
00149     }
00150   
00151   NeN = NumberOfParameters(0);
00152   Nee = NumberOfParameters(1);
00153   
00154   
00155   
00156   if (NeN < 3 || Nee < 3)
00157     {
00158       clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters: ";
00159       clog << "NeN = " << NeN << ", Nee = " << Nee << ", values of at least ";
00160       clog << "3 are needed" << endl;
00161       ok = false;
00162     }
00163 
00164   
00165 
00166   TotalNumberOfParameters = NeN*NeN*Nee;
00167 
00168   
00169 
00170   Array1D<double> fileParameters(TotalNumberOfParameters);
00171   Parameters.allocate(TotalNumberOfParameters);
00172   isFree.allocate(TotalNumberOfParameters);
00173   strm >> temp;
00174 
00175   fileParameters.read(strm,0.0,"3 particle Jastrow");
00176   
00202   int counter = 0;
00203   for(int p=0; p<max(NeN,Nee); p++)
00204     for (int n=0; n<Nee; n++)
00205       for (int l=0; l<NeN; l++)
00206         for (int m=0; m<=l; m++)
00207           if( (l == p || m == p || n == p) &&
00208               (l <= p && m <= p && n <= p))
00209             {
00210               int index = map(l,m,n);
00211               Parameters(index) = fileParameters(counter);
00212               counter++;
00213 
00214               
00215               if(l != m)
00216                 {
00217                   index = map(m,l,n);
00218                   Parameters(index) = fileParameters(counter);
00219                   counter++;
00220                 }
00221             }
00222   fileParameters.deallocate();
00223   if(counter != TotalNumberOfParameters)
00224     {
00225       clog << "Error: TotalNumberOfParameters = " << TotalNumberOfParameters;
00226       clog << " but counter = " << counter << endl;
00227     }
00228 
00229   
00230   strm >> temp >> temp;
00231   C = atoi(temp.c_str());
00232 
00233   
00234   strm >> temp >> temp;
00235   cutoff = atof(temp.c_str());
00236 
00237   
00238   
00239   
00240   makeParamDepMatrix();
00241 
00242   
00243   NumberOfFreeParameters = 0;
00244   for(int p=0; p<isFree.dim1(); p++)
00245     if(isFree(p)) NumberOfFreeParameters++;
00246   
00247   
00248   NumberOfFreeParameters++;
00249   
00250   
00251   
00252   
00253   
00254   if (threeBodyCorrelationFunctionType == "None")
00255     {
00256       NumberOfParameterTypes = 0;
00257       TotalNumberOfParameters = 0;
00258       NumberOfParameters.deallocate();
00259       Parameters.deallocate();
00260       isFree.deallocate();
00261       C = 0;
00262       cutoff = 0.0;
00263       NumberOfFreeParameters = 0;
00264       freeParameters.deallocate();
00265       paramDepMatrix.deallocate();
00266     }
00267   else
00268     {
00269       setTotalParameters(Parameters);
00270     }
00271 
00272   
00273   setThreeBodyCorrelationFunction();
00274   initializeThreeBodyCorrelationFunctionParameters();
00275 
00276   return ok;
00277 }
00278 
00279 QMCThreeBodyCorrelationFunctionParameters::QMCThreeBodyCorrelationFunctionParameters()
00280 {
00281   threeBodyCorrelationFunctionType = "None";
00282   ThreeBodyCorrelationFunction = 0;
00283   ParticleTypes.allocate(3);
00284   TotalNumberOfParameters = 0;
00285   NumberOfFreeParameters = 0;
00286 
00287   NeN = 0;
00288   Nee = 0;
00289   C = 0;
00290   cutoff = 0.0;
00291 
00292   setThreeBodyCorrelationFunction();
00293 }
00294 
00295 QMCThreeBodyCorrelationFunctionParameters::QMCThreeBodyCorrelationFunctionParameters(const QMCThreeBodyCorrelationFunctionParameters & rhs)
00296 {
00297   ThreeBodyCorrelationFunction = 0;
00298   *this = rhs;
00299 }
00300 
00301 string QMCThreeBodyCorrelationFunctionParameters::getParticle1Type()
00302 {
00303   return ParticleTypes(0);
00304 }
00305 
00306 string QMCThreeBodyCorrelationFunctionParameters::getParticle2Type()
00307 {
00308   return ParticleTypes(1);
00309 }
00310 
00311 string QMCThreeBodyCorrelationFunctionParameters::getParticle3Type()
00312 {
00313   return ParticleTypes(2);
00314 }
00315 
00316 int QMCThreeBodyCorrelationFunctionParameters::getNumberOfFreeParameters()
00317 {
00318   return NumberOfFreeParameters;
00319 }
00320 
00321 int QMCThreeBodyCorrelationFunctionParameters::getNumberOfTotalParameters()
00322 {
00323   return TotalNumberOfParameters;
00324 }
00325 
00326 void QMCThreeBodyCorrelationFunctionParameters::zeroOutDerivatives()
00327 {
00328   pt_a = 0.0;
00329   pt3_xxa = 0.0;
00330   for(int i=0; i<pt2_xa.dim1(); i++)
00331     pt2_xa(i) = 0.0;
00332 }
00333 
00334 void QMCThreeBodyCorrelationFunctionParameters::getFree(const Array1D<double> & total,
00335                                                         Array1D<double> & free) 
00336 {
00337   tempArray.allocate(TotalNumberOfParameters);
00338   tempArray = 0.0;
00339   
00340   
00341   for (int i=0; i<TotalNumberOfParameters; i++)
00342     for (int j=0; j<TotalNumberOfParameters; j++)
00343       tempArray(i) += paramDepMatrix(i,j)*total.get(j);
00344   
00345   totalToFree(tempArray, free);  
00346 }
00347 
00348 void QMCThreeBodyCorrelationFunctionParameters::setTotalParameters(const Array1D<double> & total)
00349 {
00350   tempArray.allocate(TotalNumberOfParameters);
00351   tempArray = 0.0;
00352   
00353   
00354   
00355   for (int i=0; i<TotalNumberOfParameters; i++)
00356     for (int j=0; j<TotalNumberOfParameters; j++)
00357       tempArray(i) += paramDepMatrix(i,j)*total.get(j);
00358   
00359   Parameters = tempArray;
00360   
00361   if(!checkCuspAndSymmetry())
00362     {
00363       clog << "Error: checkCuspAndSymmetry failed in setTotalParameters" << endl;
00364       exit(0);
00365     }
00366 
00367   getFree(Parameters, freeParameters);
00368 }
00369 
00370 void QMCThreeBodyCorrelationFunctionParameters::setFreeParameters(const Array1D<double> & free)
00371 {
00372   if(!isUsed()) return; 
00373 
00374   if( free.dim1() != NumberOfFreeParameters )
00375     {
00376       clog << "ERROR: Parameters of the incorrect size are trying to be set "
00377            << "in setFreeParameters" << endl;
00378     }
00379 
00380   freeParameters = free;
00381   freeToTotal(freeParameters, Parameters);
00382 
00383   tempArray.allocate(TotalNumberOfParameters);
00384   tempArray = 0.0;
00385   
00386   for (int i=0; i<TotalNumberOfParameters; i++)
00387     for (int j=0; j<TotalNumberOfParameters; j++)
00388       tempArray(i) += paramDepMatrix(i,j)*Parameters(j);
00389   
00390   Parameters = tempArray;
00391 
00392   
00393 
00394 
00395 
00396   if(globalInput.cs_Parameters.dim1() == 0)
00397     if(!checkCuspAndSymmetry())
00398       {
00399         clog << "Error: checkCuspAndSymmetry failed in setFreeParameters" << endl;
00400         exit(0);
00401       }
00402   initializeThreeBodyCorrelationFunctionParameters();
00403 }
00404 
00405 void QMCThreeBodyCorrelationFunctionParameters::setParticle1Type(string val)
00406 {
00407   ParticleTypes(0) = val;
00408 }
00409 
00410 void QMCThreeBodyCorrelationFunctionParameters::setParticle2Type(string val)
00411 {
00412   ParticleTypes(1) = val;
00413 }
00414 
00415 void QMCThreeBodyCorrelationFunctionParameters::setParticle3Type(string val)
00416 {
00417   ParticleTypes(2) = val;
00418 }
00419 
00420 double QMCThreeBodyCorrelationFunctionParameters::getCutoffDist()
00421 {
00422   return cutoff;
00423 }
00424 
00425 void QMCThreeBodyCorrelationFunctionParameters::setThreeBodyCorrelationFunction()
00426 {
00427   if( ThreeBodyCorrelationFunction != 0 )
00428     {
00429       delete ThreeBodyCorrelationFunction;
00430       ThreeBodyCorrelationFunction = 0;
00431     }
00432   ThreeBodyCorrelationFunction = QMCThreeBodyCorrelationFunctionFactory::
00433     threeBodyCorrelationFunctionFactory(threeBodyCorrelationFunctionType);
00434 }
00435 
00436 QMCThreeBodyCorrelationFunction * QMCThreeBodyCorrelationFunctionParameters::
00437                                              getThreeBodyCorrelationFunction()
00438 {
00439   return ThreeBodyCorrelationFunction;
00440 }
00441 
00442 bool QMCThreeBodyCorrelationFunctionParameters::isUsed() const
00443 {
00444   if(threeBodyCorrelationFunctionType == "None")
00445     return false;
00446   return true;
00447 }
00448 
00449 QMCThreeBodyCorrelationFunctionParameters::~QMCThreeBodyCorrelationFunctionParameters()
00450 {
00451   NumberOfParameters.deallocate();
00452   Parameters.deallocate();
00453   isFree.deallocate();
00454   freeParameters.deallocate();
00455   ParticleTypes.deallocate();
00456   
00457   if( ThreeBodyCorrelationFunction != 0 )
00458     {
00459       delete ThreeBodyCorrelationFunction;
00460       ThreeBodyCorrelationFunction = 0;
00461     }
00462 }
00463 
00464 void QMCThreeBodyCorrelationFunctionParameters::
00465                              initializeThreeBodyCorrelationFunctionParameters()
00466 {
00467   ThreeBodyCorrelationFunction->initializeParameters(NeN,Nee,Parameters,C,
00468                                                      cutoff);
00469 
00470   pt_a.allocate(TotalNumberOfParameters+1);
00471   pt2_xa.allocate(TotalNumberOfParameters+1);
00472   pt3_xxa.allocate(TotalNumberOfParameters+1);
00473 
00474   for(int i=0; i<pt2_xa.dim1(); i++)
00475     pt2_xa(i).allocate(globalInput.WF.getNumberElectrons(),3); 
00476 }
00477 
00478 ostream & operator << (ostream & strm, 
00479                        QMCThreeBodyCorrelationFunctionParameters & rhs)
00480 {
00481   int Nee = rhs.Nee;
00482   int NeN = rhs.NeN;
00483 
00484   strm << "ParticleTypes:\t" << rhs.ParticleTypes(0) << "\t" 
00485        << rhs.ParticleTypes(1) << "\t" << rhs.ParticleTypes(2) << endl;
00486 
00487   strm << "threeBodyCorrelationFunctionType:\t" 
00488        << rhs.threeBodyCorrelationFunctionType << endl;
00489 
00490   strm << "NumberOfParameterTypes:\t" << rhs.NumberOfParameterTypes << endl;
00491 
00492   strm << "NumberOfParametersOfEachType:";
00493 
00494   for (int i = 0; i < rhs.NumberOfParameterTypes; i++)
00495     strm << "  " << rhs.NumberOfParameters(i);
00496   strm << endl;
00497 
00498   strm << "Parameters:" << endl;
00499 
00500   int counter = 0;
00501   int endlInd = 0;
00502   for(int p=0; p<max(NeN,Nee); p++)
00503     {
00504       for (int n=0; n<Nee; n++)
00505         for (int l=0; l<NeN; l++)
00506           for (int m=0; m<=l; m++)
00507             if( (l == p || m == p || n == p) &&
00508                 (l <= p && m <= p && n <= p))
00509               {
00510                 int index = rhs.map(l,m,n);
00511                 if(endlInd % (NeN) == 0 && endlInd != 0)
00512                   {
00513                     strm << endl;
00514                     endlInd = 0;
00515                   }
00516                 double val = rhs.Parameters(index);
00517                 if(val < 0.0) strm << " -";
00518                 else          strm << "  ";
00519                 strm << setw(20) << left << fabs(val);        
00520                 
00521                 counter++;
00522                 endlInd++;
00523 
00524                 if(l != m)
00525                   {
00526                     index = rhs.map(l,m,n);
00527                     if(endlInd % (NeN) == 0 && endlInd != 0)
00528                       {
00529                         strm << endl;
00530                         endlInd = 0;
00531                       }
00532                     val = rhs.Parameters(index);
00533                     if(val < 0.0) strm << " -";
00534                     else          strm << "  ";
00535                     strm << setw(20) << left << fabs(val);            
00536                     
00537                     counter++;
00538                     endlInd++;
00539                   }
00540               }
00541       strm << endl << endl;
00542       endlInd = 0;
00543     }
00544 
00545   strm << "C:  " << rhs.C << endl;
00546   
00547   strm << "Cutoff:  " << rhs.cutoff << endl;
00548 
00549   strm << endl;
00550 
00551   return strm;
00552 }
00553 
00554 void QMCThreeBodyCorrelationFunctionParameters::totalDerivativesAccumulate(QMCThreeBodyCorrelationFunctionParameters & rhs)
00555 {
00556   if(!isUsed() || !rhs.isUsed()) return;
00557 
00558 #ifdef QMC_DEBUG
00559   if(TotalNumberOfParameters != rhs.TotalNumberOfParameters)
00560     {
00561       cout << "Error: number parameters doesn't match!" << endl;
00562       cout << " this = " << TotalNumberOfParameters << endl;
00563       cout << "  rhs = " << rhs.TotalNumberOfParameters << endl;
00564       exit(0);
00565     }
00566 #endif
00567 
00568   pt_a += rhs.pt_a;
00569   pt3_xxa += rhs.pt3_xxa;
00570   
00571   for (int i=0; i<TotalNumberOfParameters+1; i++)
00572     pt2_xa(i) += rhs.pt2_xa.get(i);
00573 }
00574 
00575 void QMCThreeBodyCorrelationFunctionParameters::totalDerivativesToFree(int & shift,
00576                                                                        Array1D<double> & p_a,
00577                                                                        Array1D< Array2D<double> > & p2_xa,
00578                                                                        Array1D<double> & p3_xxa) const
00579 {
00580   if(!isUsed()) return;
00581 
00582   p_a(shift) += pt_a.get(0);
00583   for(int e=0; e<globalInput.WF.getNumberElectrons(); e++)
00584     for(int xyz=0; xyz<3; xyz++)
00585       (p2_xa(shift))(e,xyz) += (pt2_xa.get(0))(e,xyz);  
00586   p3_xxa(shift) += pt3_xxa.get(0);
00587 
00588   shift++;
00589 
00590   
00591 
00592 
00593 
00594 
00595   for (int l=0; l<NeN; l++)
00596     for (int m=0; m<NeN; m++)
00597       for (int n=0; n<Nee; n++)
00598         if(isFree.get(map(l,m,n)))
00599           {
00600             for (int i=0; i<TotalNumberOfParameters; i++)
00601               {
00602                 double pd = paramDepMatrix.get(i,map(l,m,n));
00603                 if( fabs(pd) < 1.0e-50) continue;
00604                 
00605                 p_a(shift)    += pd * pt_a.get(i+1);
00606                 p3_xxa(shift) += pd * pt3_xxa.get(i+1);
00607                 
00608                 for(int e=0; e<globalInput.WF.getNumberElectrons(); e++)
00609                   for(int xyz=0; xyz<3; xyz++)
00610                     (p2_xa(shift))(e,xyz) += pd * (pt2_xa.get(i+1))(e,xyz);
00611               }
00612             shift++;
00613           }
00614 
00615   
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 }
00627 
00628 void QMCThreeBodyCorrelationFunctionParameters::totalToFree(const Array1D<double> & total,
00629                                                             Array1D<double> & free) const
00630 {
00631   
00632   
00633   
00634 
00635   free.allocate(NumberOfFreeParameters);
00636   free = 0.0;
00637   int counter = 0;
00638 
00639   
00640   
00641   free(0) = cutoff;
00642   counter++;
00643 
00644   
00645   
00646   for (int l=0; l<NeN; l++)
00647     for (int m=0; m<NeN; m++)
00648       for (int n=0; n<Nee; n++)
00649         if(isFree.get(map(l,m,n)))
00650           {
00651             free(counter) = total.get(map(l,m,n));
00652             counter++;
00653           }
00654 
00655   if (counter != NumberOfFreeParameters)
00656     {
00657       
00658       clog << "ERROR in "
00659            << "QMCThreeBodyCorrelationFunctionParameters::totalToFree()"
00660            << ": there should be " << NumberOfFreeParameters << " free "
00661            << "parameters, but we found " << counter << endl;
00662       exit(0);
00663     }
00664 }
00665 
00666 void QMCThreeBodyCorrelationFunctionParameters::freeToTotal(const Array1D<double> & free,
00667                                                             Array1D<double> & total)
00668 {
00669   
00670   
00671 
00672   int counter = 0;
00673   total = 0.0;
00674 
00675   
00676   
00677   cutoff = free.get(0);
00678   counter++;
00679 
00680   
00681   
00682   for (int l=0; l<NeN; l++)
00683     for (int m=0; m<NeN; m++)
00684       for (int n=0; n<Nee; n++)
00685         if(isFree(map(l,m,n)))
00686           {
00687             total(map(l,m,n)) = free.get(counter);
00688             counter++;
00689           }
00690 }
00691 
00692 bool QMCThreeBodyCorrelationFunctionParameters::checkCuspAndSymmetry()
00693 {
00694   double tolerance = 1e-10;
00695   int numFree = 0;
00696   for (int l=0; l<NeN; l++)
00697     for (int m=0; m<NeN; m++)
00698       for (int n=0; n<Nee; n++)       
00699         {
00700           int c = map(l,m,n);
00701           int label = 100*l + 10*m + n;
00702           
00703           Array2D<double> tranPDM = paramDepMatrix;
00704           tranPDM.transpose();
00705           bool isInd = c == tranPDM.isDependent(c);
00706           if(isInd) numFree++;
00707           if(isInd != isFree(c))
00708             {
00709               cout << "Error for variable " << label << ": isFree = "
00710                    << isFree(c) << " while paramDepMatrix says independent." << endl;
00711               cout << "paramDepMatrix is flawed..." << endl;
00712               return false;
00713             }
00714           
00715           double sum = 0;
00716           int dependsOnDependent = -1;
00717           double dependVal = 0;
00718           for(int r=0; r<paramDepMatrix.dim1(); r++)
00719             for (int ll=0; ll<NeN; ll++)
00720               for (int mm=0; mm<NeN; mm++)
00721                 for (int nn=0; nn<Nee; nn++)                      
00722                   {
00723                     int r = map(ll,mm,nn);
00724                     int labelr = 100*ll + 10*mm + nn;
00725                     if(!isFree(r) && fabs(paramDepMatrix(r,c)) > tolerance)
00726                       {
00727                         dependsOnDependent = labelr;
00728                         dependVal = paramDepMatrix(r,c);
00729                       }
00730                     sum += fabs(paramDepMatrix(r,c));
00731                   }
00732           
00733           if(!isFree(c) && dependsOnDependent != -1)
00734             {
00735               cout << "Error: dependent parameter " << label
00736                    << " depends on dependent parameter " << dependsOnDependent
00737                    << " with coefficient " << dependVal << endl;
00738             }
00739           
00740           if(sum < tolerance && isFree(c))
00741             {
00742               cout << "Error for variable " << label << ": isFree = "
00743                    << isFree(c) << " while paramDepMatrix says dependent." << endl;
00744               cout << "paramDepMatrix is flawed..." << endl;
00745               return false;
00746             }
00747         }
00748 
00749   if(NumberOfFreeParameters - 1 != numFree)
00750     {
00751       cout << "Error: incorrect number of free parameters. We counted " << numFree;
00752       
00753       cout << " but there should have been " << (NumberOfFreeParameters-1) << endl;
00754     }
00755 
00756   
00757   
00758 
00759   
00760   
00761 
00762   int index1 = -1;
00763   int index2 = -1;
00764 
00765   for (int l=0; l<NeN-1; l++)
00766     for (int m=l+1; m<NeN; m++)
00767       for (int n=0; n<Nee; n++)
00768         {
00769           index1 = map(l,m,n);
00770           index2 = map(m,l,n);
00771           double diff = Parameters(index1)-Parameters(index2);
00772 
00773           
00774           if(fabs(Parameters(index1)) > tolerance) diff /= Parameters(index1);
00775 
00776           if ( fabs(diff) > tolerance )
00777             {
00778               clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters::"
00779                    << "checkCuspAndSymmetry(): symmetry is not satisfied, difference = " << diff << endl;
00780               clog << "   Parameters(map(" << l << "," << m << "," << n << ")) = " << setw(20) << Parameters(index1) << endl;
00781               clog << "   Parameters(map(" << m << "," << l << "," << n << ")) = " << setw(20) << Parameters(index2) << endl;
00782               return false;
00783             }
00784         }
00785 
00786   double sum;
00787   
00788   
00789   for (int k=0; k<2*NeN-1; k++)
00790     {
00791       sum = 0.0;
00792       for (int l=0; l<NeN; l++)
00793         for (int m=0; m<NeN; m++)
00794           if (l+m == k)
00795             {
00796               index1 = map(l,m,1);
00797               sum += Parameters(index1);
00798             }
00799       if (fabs(sum) > tolerance)
00800         {
00801           clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters::"
00802                << "checkCuspAndSymmetry():" << endl
00803                << "(l+m=" << k << ") electron-electron cusp condition "
00804                << "is not satisfied, sum = " << sum << endl;
00805           return false;
00806         }
00807     }
00808 
00809   
00810   for (int k=0; k<NeN+Nee-1; k++)
00811     {
00812       sum = 0.0;
00813       for (int m=0; m<NeN; m++)
00814         for (int n=0; n<Nee; n++)
00815           if (m+n == k)
00816             {
00817               index1 = map(0,m,n);
00818               index2 = map(1,m,n);
00819               sum += C*Parameters(index1) - Parameters(index2);
00820             }
00821       if (fabs(sum) > tolerance)
00822         {
00823           clog << "ERROR in QMCThreeBodyCorrelationFunctionParameters::"
00824                << "checkCuspAndSymmetry():" << endl
00825                << "(m+n=" << k << ") electron-nucleus cusp condition "
00826                << "is not satisfied, sum = " << sum << endl;
00827           return false;
00828         }
00829     }
00830   return true;
00831 }
00832 
00833 void QMCThreeBodyCorrelationFunctionParameters::gaussianParamDepMatrix()
00834 {
00835   
00836 
00837 
00838 
00839 
00840 
00841 
00842   int nn = NeN-1;
00843   int ne = Nee-1;
00844 
00845   double tolerance = 1e-50;
00846   int numConstraints = 0;
00847   int numVariables = Nee * NeN * Nee;
00848   numConstraints += Nee*NeN*(NeN-1)/2; 
00849   numConstraints += 2*nn + 1;
00850   numConstraints += nn + ne + 1;
00851 
00852   if (globalInput.flags.reproduce_NE_with_NEE_jastrow == 0)
00853     numConstraints += nn;
00854 
00855   if (globalInput.flags.reproduce_EE_with_NEE_jastrow == 0)
00856     numConstraints += ne;
00857 
00858   Array2D<double> constraints(numConstraints,numVariables);
00859   Array1D<int> labels(numVariables);
00860   Array1D<int> numbers(numVariables);
00861 
00862   constraints = 0.0;
00863   for (int l=0; l<NeN; l++)
00864     for (int m=0; m<NeN; m++)
00865       for (int n=0; n<Nee; n++)
00866         {
00867           int index = map(l,m,n);
00868           labels(index) = 100*l + 10*m + n;
00869           numbers(index) = index;
00870 
00871           if(n == 1)
00872             {
00873               
00874               int k = l + m;
00875               constraints(k,index) = 1.0;
00876             }
00877           int k0 = 2*nn+1;
00878           if(l == 0)
00879             {
00880               
00881               int k = m + n + k0;
00882               constraints(k,index) = C;
00883             }
00884           if(l == 1)
00885             {
00886               
00887               int k = m + n + k0;
00888               constraints(k,index) = -1.0;
00889             }
00890           k0 += nn+ne+1;
00891           int num = NeN * (NeN - 1) / 2;
00892           if(l > m)
00893             {
00894               
00895               int k = l*(l-1)/2 + m + n*num + k0;
00896               constraints(k,index) = -1.0;
00897             }
00898           if(l < m)
00899             {
00900               
00901               int k = m*(m-1)/2 + l + n*num + k0;
00902               constraints(k,index) = 1.0;
00903             }
00904           k0 += Nee * num;
00905           if(globalInput.flags.reproduce_EE_with_NEE_jastrow == 0)
00906             {
00907               int k = n - 1 + k0;
00908               if(l == 0 && m == 0 && n > 0)
00909                 {
00910                   constraints(k,index) = 1.0;
00911                 }
00912               k0 += ne;
00913             }
00914           if(globalInput.flags.reproduce_NE_with_NEE_jastrow == 0)
00915             {
00916               int k = l - 1 + k0;
00917               if(l > 0 && m == 0 && n == 0)
00918                 {
00919                   constraints(k,index) = 1.0;
00920                 }
00921               k0 += nn;
00922             }
00923         }
00924 
00925   int cs = 3;
00926 
00927   
00928 
00929 
00930 
00931   if (globalInput.flags.reproduce_NE_with_NEE_jastrow == 0)
00932     for(int l=1; l<NeN; l++)
00933       constraints.rref(map(l,0,0));
00934 
00935   if (globalInput.flags.reproduce_EE_with_NEE_jastrow == 0)
00936     for(int n=1; n<Nee; n++)
00937       constraints.rref(map(0,0,n));
00938 
00939   constraints.rref(map(0,0,1));
00940   constraints.rref(map(1,0,1));
00941   constraints.rref(map(nn,nn,1));
00942   constraints.rref(map(nn,nn-1,1));
00943 
00944   
00945 
00946 
00947 
00948   for (int n=0; n<Nee; n++)
00949     for (int l=0; l<NeN; l++)
00950       for (int m=0; m<NeN; m++)
00951         {
00952           int index = map(l,m,n);
00953           if(l < m) constraints.rref(index);
00954         }
00955 
00956   
00957 
00958 
00959 
00960 
00961 
00962   if(NeN == 3 && Nee == 3)
00963     {
00964       
00965       constraints.rref(map(1,0,0));
00966       constraints.rref(map(2,0,0));
00967       constraints.rref(map(2,0,2));
00968       constraints.rref(map(2,0,1));
00969       constraints.rref(map(1,1,0));
00970       constraints.rref(map(1,0,2));
00971       constraints.rref(map(0,1,2));
00972     } else if(NeN == 4 && Nee == 4)
00973       {
00974         
00975         
00976         
00977         constraints.rref(map(1,1,0));
00978         constraints.rref(map(1,0,0));
00979         constraints.rref(map(0,1,0));
00980 
00981         constraints.rref(map(2,0,0));
00982         constraints.rref(map(3,0,0));   
00983         constraints.rref(map(1,1,0));
00984         constraints.rref(map(3,0,1));
00985         constraints.rref(map(2,0,1));
00986         constraints.rref(map(3,0,2));
00987         constraints.rref(map(3,0,3));
00988         constraints.rref(map(2,0,2));
00989       }
00990 
00991   
00992   for(int con=0; con<constraints.dim1(); con++)
00993     {
00994       if(constraints.constraintUsed(con) == -1)
00995         printf("constraint %3i is available\n",con);
00996     }
00997 
00998   
00999   for(int i=0; i<constraints.dim1(); i++)
01000     for(int j=0; j<constraints.dim2(); j++)
01001       if(fabs(constraints(i,j)) < 1e-100) constraints(i,j) = 0.0;
01002 
01003   if(false)
01004     {
01005       for(int i=0; i<constraints.dim2(); i++)
01006         if(constraints.isDependent(i) == -1)
01007           printf("var L %3i N %3i is independent, has value = %20.10g\n",labels(i),i,Parameters(i));
01008 
01009       cout << " ";
01010       numbers.printArray1D(cout,2,cs,-1,' ',false);
01011       cout << endl << " ";
01012       labels.printArray1D(cout,2,cs,-1,' ',false);
01013       cout << endl;
01014       constraints.printArray2D(cout,2,cs,-1,' ',false);
01015       cout << endl;
01016     }
01017 
01018   
01019 
01020 
01021 
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033   paramDepMatrix.allocate(TotalNumberOfParameters,TotalNumberOfParameters);
01034   paramDepMatrix.setToIdentity();
01035 
01036   for(int j=0; j<constraints.dim2(); j++)
01037     {
01038       
01039       
01040       int theOne = constraints.isDependent(j);
01041       isFree(j) = theOne == -1 ? true : false;
01042 
01043       if(!isFree(j))
01044         {
01045           
01046 
01047 
01048 
01049 
01050 
01051 
01052           for(int d=0; d<constraints.dim2(); d++)
01053             if(fabs(constraints(theOne,d)) > tolerance)
01054               paramDepMatrix(j,d) = -1.0 * constraints(theOne,d);
01055           paramDepMatrix(j,j) = 0.0;
01056         }
01057     }
01058 
01059   if(constraints.numDependent() != constraints.dim1())
01060     {
01061       cout << "Error: you didn't use up all the constraints! There are too few dependent variables." << endl;
01062       cout << " number   dependent = " << constraints.numDependent() << endl;
01063       cout << " number constraints = " << constraints.dim1() << endl;
01064     }
01065 
01066   if(false)
01067     {
01068       cs = 3;
01069       cout << " ";
01070       numbers.printArray1D(cout,2,cs,-1,' ',false);
01071       cout << endl << " ";
01072       isFree.printArray1D(cout,2,cs,-1,' ',false);
01073       cout << endl << " ";
01074       labels.printArray1D(cout,2,cs,-1,' ',false);
01075       cout << endl;
01076       paramDepMatrix.printArray2D(cout,2,cs,-1,' ',false);
01077       cout << endl;
01078     }
01079 }
01080 
01081 void QMCThreeBodyCorrelationFunctionParameters::makeParamDepMatrix()
01082 {
01083   if (globalInput.flags.reproduce_NE_with_NEE_jastrow == 1 &&
01084       globalInput.flags.reproduce_EE_with_NEE_jastrow == 1)
01085     {
01086       gaussianParamDepMatrix();
01087       return;
01088     }
01089 
01090   for (int l=0; l<NeN; l++)
01091     for (int m=0; m<NeN; m++)
01092       for (int n=0; n<Nee; n++)
01093         {
01094           bool free = true;
01095 
01096           if (m>l)
01097             {
01098               
01099               free = false;
01100             }
01101           else if (l>0 && m==0 && n==0)
01102             {
01103               if (globalInput.flags.reproduce_NE_with_NEE_jastrow != 1)
01104                 free = false;
01105             }
01106           else if (l==0 && n>1)
01107             {
01108               if (globalInput.flags.reproduce_EE_with_NEE_jastrow != 1)
01109                 free = false;
01110             }
01111           
01112           else if (m==0 && n==1)
01113             {
01114               
01115               free = false;
01116             }
01117           else if (l==NeN-1 && n==1)
01118             {
01119               
01120               free = false;
01121             }
01122           
01123           else if (l==0 && n==0)
01124             {
01125               
01126               free = false;
01127             }
01128           else if (l<NeN && m==1 && n==0)
01129             {
01130               
01131               free = false;
01132             }
01133           else if (l==NeN-2 && m==1 && n==2)
01134             {
01135               
01136               free = false;
01137             }
01138           else if (l==NeN-1 && m==1 && n>1)
01139             {
01140               
01141               free = false;
01142             }
01143 
01144           isFree(map(l,m,n)) = free;
01145         }
01146 
01147   
01148   
01149   
01150   
01151 
01152   paramDepMatrix.allocate(TotalNumberOfParameters,TotalNumberOfParameters);
01153 
01154   
01155   for (int i=0; i<TotalNumberOfParameters; i++)
01156     for (int j=0; j<TotalNumberOfParameters; j++)
01157       {
01158         if (i != j)
01159           paramDepMatrix(i,j) = 0.0;
01160         else
01161           paramDepMatrix(i,j) = 1.0;
01162       }
01163 
01164   int l_index   = -1;
01165   int m_index   = -1;
01166   int n_index   = -1;
01167   int index1    = -1;
01168   int index2    = -1;
01169   int index_dep = -1;
01170 
01171   
01172   
01173   for (int l=0; l<NeN-1; l++)
01174     for (int m=l+1; m<NeN; m++)
01175       for (int n=0; n<Nee; n++)
01176         {
01177           index1 = l*NeN*Nee + m*Nee +n;
01178           paramDepMatrix(index1,index1) = 0.0;
01179         }
01180 
01181   
01182 
01183   
01184   paramDepMatrix(1,1) = 0.0;
01185 
01186   
01187   paramDepMatrix(NeN*Nee+1,NeN*Nee+1) = 0.0;
01188 
01189   for (int k=2; k<2*NeN-1; k++)
01190     {
01191       
01192       if (k<NeN)
01193         {
01194           
01195           l_index = k;
01196           m_index = 0;
01197         }
01198       else if (k>=NeN)
01199         {
01200           
01201           l_index = NeN-1;
01202           m_index = k-l_index;
01203         }
01204 
01205       index_dep = l_index*NeN*Nee + m_index*Nee +1;
01206 
01207       paramDepMatrix(index_dep,index_dep) = 0.0;
01208 
01209       
01210       
01211       if (k%2 == 0)
01212         {
01213           index1 = k*NeN*Nee/2 + k*Nee/2 +1;
01214 
01215           if (index_dep != index1) 
01216             {      
01217               if (l_index == m_index)
01218                 paramDepMatrix(index_dep,index1) = -1.0;
01219               else if (l_index != m_index)
01220                 paramDepMatrix(index_dep,index1) = -0.5;
01221             }
01222         }
01223 
01224       for (int l=0; l<NeN; l++)
01225         for (int m=0; m<l; m++)
01226           if (l+m == k)
01227             {
01228               index1 = l*NeN*Nee + m*Nee + 1;
01229 
01230               if (index_dep != index1)
01231                 {
01232                   if (l_index == m_index)
01233                     paramDepMatrix(index_dep,index1) = -2.0;
01234                   else if (l_index != m_index)
01235                     paramDepMatrix(index_dep,index1) = -1.0;
01236                 }
01237             }
01238     }
01239 
01240   
01241   double shift = 1.0;
01242 
01243   
01244   
01245 
01246   
01247   
01248   paramDepMatrix(0,0) = 0.0;
01249   paramDepMatrix(0,NeN*Nee) = shift/C;
01250 
01251   
01252   paramDepMatrix(NeN*Nee+Nee,NeN*Nee+Nee) = 0.0;
01253   paramDepMatrix(NeN*Nee+Nee,NeN*Nee) = C/shift;
01254 
01255   for (int k=2; k<NeN+Nee-1; k++)
01256     {
01257       
01258       if (k<NeN)
01259         {
01260           
01261           l_index = k;
01262           n_index = 0;
01263         }
01264       else if (k==NeN)
01265         {
01266           
01267           l_index = k-2;
01268           n_index = 2;
01269         }
01270       else if (k>NeN)
01271         {
01272           
01273           l_index = NeN-1;
01274           n_index = k-l_index;
01275         }
01276       index_dep = l_index*NeN*Nee + Nee + n_index;
01277 
01278       paramDepMatrix(index_dep,index_dep) = 0.0;
01279 
01280       if (k<Nee)
01281         {
01282           index1 = k;
01283           index2 = NeN*Nee+k;
01284           paramDepMatrix(index_dep,index1) = C/shift;
01285           if (index_dep != index2)
01286             paramDepMatrix(index_dep,index2) = -1.0;
01287         }
01288 
01289       for (int l=1; l<NeN; l++)
01290         for (int n=0; n<Nee; n++)
01291           if (l+n == k)
01292             {
01293               index1 = l*NeN*Nee + n;
01294               index2 = l*NeN*Nee + Nee + n;
01295               paramDepMatrix(index_dep,index1) = C/shift;
01296               if (index_dep != index2)
01297                 paramDepMatrix(index_dep,index2) = -1.0;
01298             }
01299     }
01300 
01301   
01302   
01303   if (globalInput.flags.reproduce_NE_with_NEE_jastrow == 0)
01304     for (int l=1; l<NeN; l++)
01305       {
01306         index1 = l*NeN*Nee;
01307         paramDepMatrix(index1,index1) = 0.0;
01308       }
01309 
01310   if (globalInput.flags.reproduce_EE_with_NEE_jastrow == 0)
01311     for (int n=2; n<Nee; n++)
01312       paramDepMatrix(n,n) = 0.0;
01313 
01314   
01315   
01316   
01317 
01318   bool goodDefs = false;
01319   int counter = 0;
01320   
01321   while (goodDefs == false)
01322     {
01323       counter++;
01324       if (counter > 100)
01325         {
01326           cerr << "ERROR in QMCThreeBodyCorrelationFunctionParameters::make"
01327                << "ParamDepMatrix(): dependent parameters are still used in "
01328                << "definitions after 100 iterations- definitions may be "
01329                << "circular" << endl;
01330           exit(0);
01331         }
01332 
01333       goodDefs = true;
01334       for (int l=0; l<NeN; l++)
01335         for (int m=0; m<=l; m++)
01336           for (int n=0; n<Nee; n++)
01337             {
01338               index1 = l*NeN*Nee + m*Nee + n;
01339               
01340               if(isFree(map(l,m,n)))
01341                 {
01342                   
01343                   
01344                   
01345 
01346                   if ( fabs(paramDepMatrix(index1,index1)-1.0) > 1e-10 )
01347                     {
01348                       cerr << "ERROR in QMCThreeBodyCorrelationFunction"
01349                            << "Parameters::makeParamDepMatrix(): parameter "
01350                            << l << m << n << " should be free, but its "
01351                            << "diagonal matrix element is "
01352                            << paramDepMatrix(index1,index1) << endl;
01353                       exit(0);
01354                     }
01355 
01356                   for (int i=0; i<TotalNumberOfParameters; i++)
01357                     if (index1 != i && fabs(paramDepMatrix(index1,i)) > 1e-10)
01358                       {
01359                         cerr << "ERROR in QMCThreeBodyCorrelationFunction"
01360                              << "Parameters::makeParamDepMatrix(): parameter "
01361                              << l << m << n << " should be free, but element "
01362                              << "(" << index1 << "," << i << ") is "
01363                              << paramDepMatrix(index1,i) << endl;
01364                         exit(0);
01365                       }
01366                 }
01367               else if (isFree(map(l,m,n)) == false)
01368                 {
01369                   
01370                   
01371                   
01372                   if ( fabs(paramDepMatrix(index1,index1)) > 1e-10 )
01373                     {
01374                       cerr << "ERROR in QMCThreeBodyCorrelationFunction"
01375                            << "Parameters::makeParamDepMatrix(): parameter "
01376                            << l << m << n << "should be dependent, but "
01377                            << "its diagonal element is "
01378                            << paramDepMatrix(index1,index1) << endl;
01379                       exit(0);
01380                     }
01381                   
01382                   for (int i=0; i<TotalNumberOfParameters; i++)             
01383                     if (index1 != i && fabs(paramDepMatrix(i,index1)) > 1e-10)
01384                       {
01385                         goodDefs = false;
01386                         for (int j=0; j<TotalNumberOfParameters; j++)
01387                           paramDepMatrix(i,j) += paramDepMatrix(i,index1) *
01388                             paramDepMatrix(index1,j);
01389                         paramDepMatrix(i,index1) = 0.0;                     
01390                       }
01391                   
01392                   for (int a=0; a<NeN; a++)
01393                     for (int b=0; b<NeN; b++)
01394                       for (int c=0; c<Nee; c++)
01395                         {
01396                           index2 = a*NeN*Nee + b*Nee + c;
01397                           if (isFree(map(a,b,c)) == false && 
01398                               fabs(paramDepMatrix(index1,index2)) > 1e-10)
01399                             {
01400                               goodDefs = false;
01401                               for (int i=0; i<TotalNumberOfParameters; i++)
01402                                 paramDepMatrix(index1,i) += 
01403                                   paramDepMatrix(index1,index2) * 
01404                                   paramDepMatrix(index2,i);
01405                               paramDepMatrix(index1,index2) = 0.0;
01406                             }
01407                         }
01408                 }
01409             }
01410     
01411     }
01412 
01413   
01414   
01415 
01416   for (int l=0; l<NeN-1; l++)
01417     for (int m=l+1; m<NeN; m++)
01418       for (int n=0; n<Nee; n++)
01419         {
01420           index1 = l*NeN*Nee + m*Nee + n;
01421           index2 = m*NeN*Nee + l*Nee + n;
01422           for (int i=0; i<TotalNumberOfParameters; i++)
01423             paramDepMatrix(index1,i) = paramDepMatrix(index2,i);
01424         }
01425 }