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 }