00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCProperty.h"
00014 #include <sstream>
00015
00016 QMCProperty::QMCProperty()
00017 {
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 zeroOut();
00028
00029 #ifdef PARALLEL
00030 if( !mpiTypeCreated )
00031 {
00032 mpiTypeCreated = true;
00033 buildMpiType();
00034 buildMpiReduce();
00035 }
00036 #endif
00037
00038 }
00039
00040 void QMCProperty::zeroOut()
00041 {
00042 if(getNumberSamples() == 0) return;
00043
00044 for(int i=0;i<DCL;i++)
00045 {
00046 DeCorr[i].zeroOut();
00047
00048
00049
00050 }
00051 memset(&DeCorr_flags,0,sizeof(int)*DCL);
00052 memset(&DeCorr_sample,0,sizeof(double)*DCL);
00053 memset(&DeCorr_weight,0,sizeof(double)*DCL);
00054 }
00055
00056 unsigned long QMCProperty::getNumberSamples()
00057 {
00058 return DeCorr[0].getNumberSamples();
00059 }
00060
00061 string QMCProperty::getLongString()
00062 {
00063 stringstream strm;
00064 int width = 20;
00065 int prec = 12;
00066
00067 strm << fixed;
00068 if( fabs(getAverage()) > 1e-300 )
00069 if( log( fabs( getAverage() )) > 10.0)
00070 strm << scientific;
00071 strm << setw(width) << setprecision(prec) << getAverage();
00072
00073 strm << " +/- " << fixed;
00074 if( fabs(getStandardDeviation()) > 1e-300 )
00075 if( log( fabs( getStandardDeviation() )) > 10.0)
00076 strm << scientific;
00077 strm << setw(width) << setprecision(prec) << left << getStandardDeviation() << right;
00078 return strm.str();
00079 }
00080
00081 string QMCProperty::getShortString()
00082 {
00083 double avg = getAverage();
00084 double std = getStandardDeviation();
00085 stringstream strm;
00086
00087 if( fabs((std+avg)/avg-1.0) < 1e-10 || getDecorrDepth() < 0){
00088
00089 strm << fixed;
00090 if( fabs(getAverage()) > 1e-300 )
00091 if( log( fabs( getAverage() )) > 10.0)
00092 strm << scientific;
00093 strm << setw(10) << setprecision(5) << getAverage();
00094 return strm.str();
00095 }
00096
00097 int prec;
00098 if( fabs(std) > 1e-300 )
00099 prec = (int)floor(log10(std)) -1;
00100 else
00101 prec = 12;
00102
00103 double average = avg * pow(10.0,-prec);
00104 int tempA = (int)floor(average+0.5);
00105 average = tempA*pow(10.0,prec);
00106
00107 strm << fixed;
00108 if(prec < 0){
00109 strm << setprecision(-prec) << average;
00110 strm << "(" << setprecision(0) << (std*pow(10.0,-prec)) << ")";
00111 } else {
00112 strm << setprecision(0) << average;
00113 strm << "(" << setprecision(0) << std << ")";
00114 }
00115 return strm.str();
00116 }
00117
00118 double QMCProperty::getAverage()
00119 {
00120 return DeCorr[0].getAverage();
00121 }
00122
00123 double QMCProperty::getStandardDeviation()
00124 {
00125 int decorr_depth = getDecorrDepth();
00126 if (decorr_depth == -2)
00127 {
00128
00129 return 1.0e300;
00130 }
00131 else if (decorr_depth == -1)
00132 {
00133
00134 return 99;
00135 }
00136 else return getBlockStandardDeviation(decorr_depth);
00137 }
00138
00139 double QMCProperty::getSkewness()
00140 {
00141 int decorr_depth = getDecorrDepth();
00142 if (decorr_depth == -2)
00143 {
00144
00145 return 1.0e300;
00146 }
00147 else if (decorr_depth == -1)
00148 {
00149
00150 return 99;
00151 }
00152 else return getBlockSkewness(decorr_depth);
00153 }
00154
00155 double QMCProperty::getKurtosis()
00156 {
00157 int decorr_depth = getDecorrDepth();
00158 if (decorr_depth == -2)
00159 {
00160
00161 return 1.0e300;
00162 }
00163 else if (decorr_depth == -1)
00164 {
00165
00166 return 99;
00167 }
00168 else return getBlockKurtosis(decorr_depth);
00169 }
00170
00171 double QMCProperty::getCorrelationLength()
00172 {
00173 return getCorrelationLength(getDecorrDepth());
00174
00175 }
00176
00177 double QMCProperty::getCorrelationLength(int i)
00178 {
00179 if(i <= 0) return i;
00180 return getBlockVariance(i) / getBlockVariance(0);
00181 }
00182
00183 int QMCProperty::getDecorrDepth()
00184 {
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 if( getNumberSamples() < 100 )
00203 {
00204 return -2;
00205 }
00206
00207
00208
00209 double value = getBlockStandardDeviation(0) -
00210 getBlockStandardDeviationStandardDeviation(0);
00211
00212 int block = 1;
00213
00214 while(true)
00215 {
00216 if( DeCorr[block].getNumberSamples() <= 4 ) break;
00217
00218 double temp = getBlockStandardDeviation(block) -
00219 getBlockStandardDeviationStandardDeviation(block);
00220
00221 if( temp <= value )
00222 {
00223 return block-1;
00224 }
00225 else
00226 {
00227 value = temp;
00228 }
00229
00230 block++;
00231 }
00232
00233 return -1;
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 }
00399
00400 double QMCProperty::getSeriallyCorrelatedVariance()
00401 {
00402 return DeCorr[0].getVariance();
00403 }
00404
00405 double QMCProperty::getVariance()
00406 {
00407 double std = getStandardDeviation();
00408 return std*std;
00409 }
00410
00411 double QMCProperty::getSeriallyCorrelatedStandardDeviation()
00412 {
00413 return sqrt(getSeriallyCorrelatedVariance());
00414 }
00415
00416 double QMCProperty::getStandardDeviationStandardDeviation()
00417 {
00418 int decorr_depth = getDecorrDepth();
00419 if (decorr_depth < 0) return 0.0;
00420 else return getBlockStandardDeviationStandardDeviation(decorr_depth);
00421 }
00422
00423 void QMCProperty::newSample(double s, double weight)
00424 {
00425
00426
00427
00428
00429 int done=0;
00430
00431 DeCorr[0].newSample(s,weight);
00432 int inc=1;
00433 double pushed_sample=s;
00434 double pushed_weight=weight;
00435
00436 while(!done)
00437 {
00438 if(inc>=DCL)
00439 {
00440 done=1;
00441 }
00442 else
00443 {
00444 if(DeCorr_flags[inc]==0)
00445 {
00446
00447 DeCorr_sample[inc]=pushed_sample;
00448 DeCorr_weight[inc]=pushed_weight;
00449 DeCorr_flags[inc]=1;
00450 done=1;
00451 }
00452 else
00453 {
00454
00455
00456
00457 pushed_sample=(pushed_sample*pushed_weight
00458 +DeCorr_sample[inc]*DeCorr_weight[inc])
00459 /(pushed_weight+DeCorr_weight[inc]);
00460 pushed_weight=(pushed_weight+DeCorr_weight[inc])/2.0;
00461
00462
00463 DeCorr[inc].newSample(pushed_sample,pushed_weight);
00464
00465
00466 DeCorr_flags[inc]=0;
00467
00468
00469
00470 inc++;
00471 }
00472 }
00473 }
00474 }
00475
00476 void QMCProperty::operator = ( const QMCProperty & rhs )
00477 {
00478 memcpy(&DeCorr, &rhs.DeCorr, sizeof(QMCStatistic)*DCL);
00479 memcpy(&DeCorr_flags, &rhs.DeCorr_flags, sizeof(int)*DCL);
00480 memcpy(&DeCorr_sample, &rhs.DeCorr_sample, sizeof(double)*DCL);
00481 memcpy(&DeCorr_weight, &rhs.DeCorr_weight, sizeof(double)*DCL);
00482
00483
00484
00485
00486 }
00487
00488 void QMCProperty::reWeight(double w)
00489 {
00490 for(int i=0; i<DCL; i++)
00491 {
00492 DeCorr[i].reWeight(w);
00493 if(DeCorr_flags[i]==0)
00494 {
00495 DeCorr_weight[i] *= w;
00496 }
00497 }
00498 }
00499
00500 void QMCProperty::operator += ( QMCProperty &rhs)
00501 {
00502 *this = *this + rhs;
00503 }
00504
00505 QMCProperty QMCProperty::operator + ( QMCProperty &rhs)
00506 {
00507 QMCProperty result;
00508
00509 for(int i=0;i<DCL;i++)
00510 {
00511 result.DeCorr[i]=DeCorr[i]+rhs.DeCorr[i];
00512 }
00513
00514 int carry_up=0;
00515 double carry_up_sample=0.0;
00516 double carry_up_weight=0.0;
00517 int binary_sum=0;
00518 for(int i=0;i<DCL;i++)
00519 {
00520 binary_sum=carry_up+DeCorr_flags[i]+rhs.DeCorr_flags[i];
00521 if(binary_sum==0)
00522 {
00523 result.DeCorr_flags[i]=0;
00524 result.DeCorr_sample[i]=0.0;
00525 carry_up=0;
00526 carry_up_sample=0.0;
00527 carry_up_weight=0.0;
00528 }
00529 if(binary_sum==1)
00530 {
00531
00532
00533 result.DeCorr_flags[i]=1;
00534 if(DeCorr_flags[i]==1)
00535 {
00536 result.DeCorr_sample[i]=DeCorr_sample[i];
00537 result.DeCorr_weight[i]=DeCorr_weight[i];
00538 }
00539 else if(rhs.DeCorr_flags[i]==1)
00540 {
00541 result.DeCorr_sample[i]=rhs.DeCorr_sample[i];
00542 result.DeCorr_weight[i]=rhs.DeCorr_weight[i];
00543 }
00544 else
00545 {
00546 result.DeCorr_sample[i]=carry_up_sample;
00547 result.DeCorr_weight[i]=carry_up_weight;
00548 }
00549 carry_up=0;
00550 carry_up_sample=0.0;
00551 carry_up_weight=0.0;
00552 }
00553 if(binary_sum==2)
00554 {
00555
00556
00557
00558 result.DeCorr_flags[i]=0;
00559 if(DeCorr_flags[i]==0)
00560 {
00561
00562 carry_up_sample=(carry_up_sample*carry_up_weight
00563 +rhs.DeCorr_sample[i]*rhs.DeCorr_weight[i])
00564 /(carry_up_weight+rhs.DeCorr_weight[i]);
00565 carry_up_weight=(carry_up_weight+rhs.DeCorr_weight[i])/2.0;
00566 }
00567 else if(rhs.DeCorr_flags[i]==0)
00568 {
00569
00570 carry_up_sample=(carry_up_sample*carry_up_weight
00571 +DeCorr_sample[i]*DeCorr_weight[i])
00572 /(carry_up_weight+DeCorr_weight[i]);
00573 carry_up_weight=(carry_up_weight+DeCorr_weight[i])/2.0;
00574 }
00575 else
00576 {
00577
00578 carry_up_sample=(rhs.DeCorr_sample[i]*rhs.DeCorr_weight[i]
00579 +DeCorr_sample[i]*DeCorr_weight[i])
00580 /(rhs.DeCorr_weight[i]+DeCorr_weight[i]);
00581 carry_up_weight=(rhs.DeCorr_weight[i]+DeCorr_weight[i])/2.0;
00582 }
00583 carry_up=1;
00584 result.DeCorr[i].newSample(carry_up_sample,carry_up_weight);
00585 }
00586 if(binary_sum==3)
00587 {
00588
00589
00590
00591 result.DeCorr_flags[i]=1;
00592 result.DeCorr_sample[i]=carry_up_sample;
00593 result.DeCorr_weight[i]=carry_up_weight;
00594 carry_up=1;
00595 carry_up_sample=(rhs.DeCorr_sample[i]*rhs.DeCorr_weight[i]
00596 +DeCorr_sample[i]*DeCorr_weight[i])
00597 /(rhs.DeCorr_weight[i]+DeCorr_weight[i]);
00598 carry_up_weight=(rhs.DeCorr_weight[i]+DeCorr_weight[i])/2.0;
00599 result.DeCorr[i].newSample(carry_up_sample,carry_up_weight);
00600 }
00601 }
00602
00603 return result;
00604 }
00605
00606 void QMCProperty::toXML(ostream& strm)
00607 {
00608
00609 strm << "<QMCProperty>" << endl;
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 int active_elements = 0;
00621
00622 for (int i=0; i<DCL; i++)
00623 {
00624 if (DeCorr[i].getNumberSamples() == 0)
00625 break;
00626 else
00627 active_elements++;
00628 }
00629
00630 strm << "<NumberOfElements>" << endl;
00631 strm << active_elements << endl;
00632 strm << "</NumberOfElements>" << endl;
00633
00634
00635 strm << "<DeCorrStatistics>" << endl;
00636 for(int i=0; i<active_elements; i++)
00637 DeCorr[i].toXML(strm);
00638 strm << "</DeCorrStatistics>" << endl;
00639
00640
00641 strm << "<DeCorrFlags>" << endl;
00642 for(int i=0; i<active_elements; i++)
00643 strm << DeCorr_flags[i] << endl;
00644 strm << "</DeCorrFlags>" << endl;
00645
00646
00647 strm << "<DeCorrSamples>" << endl;
00648 for(int i=0; i<active_elements; i++)
00649 strm << DeCorr_sample[i] << endl;
00650 strm << "</DeCorrSamples>" << endl;
00651
00652
00653 strm << "<DeCorrWeights>" << endl;
00654 for(int i=0; i<active_elements; i++)
00655 strm << DeCorr_weight[i] << endl;
00656 strm << "</DeCorrWeights>" << endl;
00657
00658
00659 strm << "</QMCProperty>" << endl;
00660 }
00661
00662 bool QMCProperty::readXML(istream& strm)
00663 {
00664 string temp;
00665
00666
00667 strm >> temp;
00668 if (temp != "<QMCProperty>")
00669 return false;
00670
00671
00672
00673 strm >> temp;
00674 if (temp != "<NumberOfElements>")
00675 return false;
00676 strm >> temp;
00677 int active_elements = atoi(temp.c_str());
00678 strm >> temp;
00679 if (temp != "</NumberOfElements>")
00680 return false;
00681
00682
00683 strm >> temp;
00684 if (temp != "<DeCorrStatistics>")
00685 return false;
00686 for(int i=0; i<active_elements; i++)
00687 {
00688 if (!DeCorr[i].readXML(strm))
00689 return false;
00690 }
00691 strm >> temp;
00692 if (temp != "</DeCorrStatistics>")
00693 return false;
00694
00695
00696 strm >> temp;
00697 if (temp != "<DeCorrFlags>")
00698 return false;
00699 for(int i=0; i<active_elements; i++)
00700 {
00701 strm >> temp;
00702 DeCorr_flags[i] = atoi(temp.c_str());
00703 }
00704 strm >> temp;
00705 if (temp != "</DeCorrFlags>")
00706 return false;
00707
00708
00709 strm >> temp;
00710 if (temp != "<DeCorrSamples>")
00711 return false;
00712 for(int i=0; i<active_elements; i++)
00713 {
00714 strm >> temp;
00715 DeCorr_sample[i] = atof(temp.c_str());
00716 }
00717 strm >> temp;
00718 if (temp != "</DeCorrSamples>")
00719 return false;
00720
00721
00722 strm >> temp;
00723 if (temp != "<DeCorrWeights>")
00724 return false;
00725 for(int i=0; i<active_elements; i++)
00726 {
00727 strm >> temp;
00728 DeCorr_weight[i] = atof(temp.c_str());
00729 }
00730 strm >> temp;
00731 if (temp != "</DeCorrWeights>")
00732 return false;
00733
00734 for (int i=active_elements; i<DCL; i++)
00735 DeCorr[i].zeroOut();
00736
00737
00738 strm >> temp;
00739
00740 if (temp != "</QMCProperty>")
00741 return false;
00742
00743 return true;
00744 }
00745
00746 void QMCProperty::printAll(ostream & strm)
00747 {
00748 strm << *this;
00749 int width = 14;
00750 strm.precision(6);
00751
00752 strm << setw(width) << "DeCorr_depth"
00753 << setw(width) << "samples"
00754 << setw(width) << "Ave"
00755 << setw(width) << "Std"
00756 << setw(width) << "StdStd"
00757 << setw(width) << "Var"
00758 << setw(width) << "VarStd"
00759 << setw(width) << "Corr. Len."
00760 << setw(width) << "Variance"
00761 << setw(width) << "Skew"
00762 << setw(width) << "Kurtosis"
00763 << endl;
00764
00765 for(int i=0;i<DCL;i++)
00766 {
00767 if( DeCorr[i].getNumberSamples() > 0 )
00768 {
00769 strm.setf(ios::fixed);
00770 strm.unsetf(ios::scientific);
00771
00772 if(i == getDecorrDepth())
00773 strm << setw(width) << i;
00774 else
00775 strm << left << setw(width) << i << right;
00776
00777 strm << setw(width) << DeCorr[i].getNumberSamples()
00778 << setw(width) << DeCorr[i].getAverage();
00779
00780 if( DeCorr[i].getNumberSamples() > 1 )
00781 {
00782 strm.unsetf(ios::fixed);
00783 strm.setf(ios::scientific);
00784 strm << setw(width) << getBlockStandardDeviation(i)
00785 << setw(width) << getBlockStandardDeviationStandardDeviation(i)
00786 << setw(width) << getBlockVariance(i)
00787 << setw(width) << getBlockVarianceStandardDeviation(i);
00788
00789 strm.setf(ios::fixed);
00790 strm.unsetf(ios::scientific);
00791 strm << setw(width) << getCorrelationLength(i)
00792 << setw(width) << DeCorr[i].getVariance()
00793 << setw(width) << getBlockSkewness(i)
00794 << setw(width) << getBlockKurtosis(i);
00795 }
00796
00797 strm << endl;
00798 }
00799 }
00800 }
00801
00802 ostream& operator <<(ostream& strm, QMCProperty &rhs)
00803 {
00804 strm << rhs.getLongString();
00805 strm << " (" << rhs.getNumberSamples() << " samples, Tcorr ";
00806 strm.precision(5);
00807 strm.width(10);
00808 strm << fixed << rhs.getCorrelationLength() << ")" << endl;
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 return strm;
00824 }
00825
00826 double QMCProperty::getBlockVariance(int i)
00827 {
00828 double v = DeCorr[i].getVariance();
00829 double n = DeCorr[i].getNumberSamples();
00830
00831 return v/(n-1);
00832 }
00833
00834 double QMCProperty::getBlockSkewness(int i)
00835 {
00836 double v = DeCorr[i].getSkewness();
00837
00838
00839 return v;
00840 }
00841
00842 double QMCProperty::getBlockKurtosis(int i)
00843 {
00844 double v = DeCorr[i].getKurtosis();
00845
00846
00847 return v;
00848 }
00849
00850 double QMCProperty::getBlockVarianceStandardDeviation(int i)
00851 {
00852 double var = getBlockVariance(i);
00853
00854 double n = DeCorr[i].getNumberSamples();
00855 return var*sqrt(2.0/(n-1.0));
00856 }
00857
00858 double QMCProperty::getBlockStandardDeviation(int i)
00859 {
00860 return sqrt( fabs(getBlockVariance(i)) );
00861 }
00862
00863 double QMCProperty::getBlockStandardDeviationStandardDeviation(int i)
00864 {
00865 double stdev = getBlockStandardDeviation(i);
00866 double n = DeCorr[i].getNumberSamples();
00867 return stdev/sqrt(2.0*(n-1));
00868 }
00869
00870
00871 void QMCProperty::calculateObjectiveFunction(Array1D<double> & params,
00872 Array1D<double> & standardDeviations,
00873 Array1D<double> & standardDeviationsErrors,
00874 double & functionValue,
00875 Array1D<double> & gradientValue)
00876 {
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 }
00947
00948
00949 void QMCProperty::calculateObjectiveFunction(Array1D<double> & params,
00950 Array1D<double> & standardDeviations,
00951 Array1D<double> & standardDeviationsErrors,
00952 double & functionValue)
00953 {
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990 }
00991
00992
00993 double QMCProperty::calculateLineSearchObjectiveFunction(
00994 Array1D<double> & params,
00995 Array1D<double> & searchDirection,
00996 double stepLength,
00997 Array1D<double> & standardDeviations,
00998 Array1D<double> & standardDeviationsErrors)
00999 {
01000 Array1D<double> p;
01001
01002 p = params + (searchDirection*stepLength);
01003
01004 double functionValue = 1e50;
01005
01006 calculateObjectiveFunction(p, standardDeviations, standardDeviationsErrors,
01007 functionValue);
01008
01009 return functionValue;
01010 }
01011
01012 double QMCProperty::calculateLineSearchObjectiveFunctionDerivative(
01013 Array1D<double> & params,
01014 Array1D<double> & searchDirection,
01015 double stepLength,
01016 Array1D<double> & standardDeviations,
01017 Array1D<double> & standardDeviationsErrors)
01018 {
01019 Array1D<double> p;
01020
01021 p = params + (searchDirection*stepLength);
01022
01023 double functionValue;
01024 Array1D<double> grad;
01025
01026 calculateObjectiveFunction(p, standardDeviations, standardDeviationsErrors,
01027 functionValue, grad);
01028
01029 return grad*searchDirection;
01030 }
01031
01032
01033 double QMCProperty::cubicInterpolateStep(double a_lo, double a_hi,
01034 double phi_0,
01035 double phi_a_lo, double phi_a_hi,
01036 double phi_prime_0)
01037 {
01038
01039
01040
01041
01042 if( fabs(a_lo) < 1e-8 ) a_lo = 1e-8;
01043 if( fabs(a_hi) < 1e-8 ) a_hi = 1e-8;
01044 if( fabs(a_lo - a_hi) < 1e-8) return (a_lo+a_hi)/2.0;
01045
01046 Array2D<double> M(2,2);
01047
01048 M(0,0) = a_lo * a_lo;
01049 M(0,1) = -a_hi * a_hi;
01050 M(1,0) = -a_lo * a_lo * a_lo;
01051 M(1,1) = a_hi * a_hi * a_hi;
01052
01053 Array1D<double> v(2);
01054
01055 v(0) = phi_a_hi - phi_0 - a_hi * phi_prime_0;
01056 v(1) = phi_a_lo - phi_0 - a_lo * phi_prime_0;
01057
01058 double factor = a_lo * a_lo * a_hi * a_hi * ( a_hi - a_lo );
01059
01060 Array1D<double> ab(2);
01061
01062 for(int i=0; i<2; i++)
01063 {
01064 ab(i) = 0.0;
01065
01066 for(int j=0; j<2; j++)
01067 {
01068 ab(i) = M(i,j) * v(j);
01069 }
01070 }
01071
01072 ab /= factor;
01073
01074 double desc = ab(1)*ab(1)-3.0*ab(0)*phi_prime_0;
01075
01076 if( desc < 0 ) return (a_hi+a_lo)/2.0;
01077
01078 double a_new = (-ab(1)+sqrt(desc))/3.0/ab(0);
01079
01080
01081 if( a_new < a_lo ) a_new = (a_lo + a_hi)/2.0;
01082 if( a_new > a_hi ) a_new = (a_lo + a_hi)/2.0;
01083
01084
01085 double interptol = 1e-6;
01086
01087 if( fabs(a_new-a_lo) < interptol * fabs(a_hi-a_lo) )
01088 {
01089 a_new = a_lo + interptol;
01090 }
01091
01092 if( fabs(a_new-a_hi) < interptol * fabs(a_hi-a_lo) )
01093 {
01094 a_new = a_hi - interptol;
01095 }
01096
01097 return a_new;
01098 }
01099
01100
01101 double QMCProperty::zoom(double a_lo, double a_hi, double phi_0,
01102 double phi_a_lo, double phi_a_hi, double phi_prime_0,
01103 Array1D<double> & params,
01104 Array1D<double> & searchDirection,
01105 Array1D<double> & standardDeviations,
01106 Array1D<double> & standardDeviationsErrors)
01107 {
01108 const double zoomTol = 1e-7;
01109 const int maxZoomSteps = 1000;
01110 const double c1 = 1.0e-4;
01111 const double c2 = 0.1;
01112
01113 double a;
01114
01115 for(int i=0; i<maxZoomSteps; i++)
01116 {
01117
01118 if( fabs(a_lo-a_hi) < zoomTol ) return (a_lo+a_hi)/2.0;
01119
01120
01121 a = cubicInterpolateStep( a_lo, a_hi, phi_0, phi_a_lo,
01122 phi_a_hi, phi_prime_0);
01123
01124
01125 double phi_a =
01126 calculateLineSearchObjectiveFunction(params,searchDirection,a,
01127 standardDeviations,standardDeviationsErrors);
01128
01129 if( phi_a > phi_0 + c1 * a * phi_prime_0 || phi_a >= phi_a_lo )
01130 {
01131 a_hi = a;
01132 phi_a_hi = phi_a;
01133 }
01134 else
01135 {
01136 double phi_prime_a =
01137 calculateLineSearchObjectiveFunctionDerivative(params,
01138 searchDirection,a,standardDeviations,standardDeviationsErrors);
01139
01140 if( fabs(phi_prime_a) <= -c2 * phi_prime_0 )
01141 {
01142 return a;
01143 }
01144 else if( phi_prime_a * (a_hi - a_lo) >= 0 )
01145 {
01146 a_hi = a_lo;
01147 phi_a_hi = phi_a_lo;
01148 }
01149
01150 a_lo = a;
01151 phi_a_lo = phi_a;
01152 }
01153 }
01154
01155 cerr << "WARNING: zoom(...) in QMCProperty did not converge!" << endl;
01156
01157 return a;
01158 }
01159
01160
01161 double QMCProperty::wolfeStepLength(double alpha_guess,
01162 Array1D<double> & params,
01163 Array1D<double> & searchDirection,
01164 Array1D<double> & gradient,
01165 double functionValue,
01166 Array1D<double> & standardDeviations,
01167 Array1D<double> & standardDeviationsErrors)
01168 {
01169 const double alpha_max = 2.0;
01170 const int MaxWolfeSteps = 1000;
01171 const double c1 = 1.0e-4;
01172 const double c2 = 0.1;
01173
01174
01175
01176
01177
01178 double a_max = alpha_max;
01179 double phi_max =
01180 calculateLineSearchObjectiveFunction(params,searchDirection,alpha_max,
01181 standardDeviations,standardDeviationsErrors);
01182
01183 double a_0 = 0.0;
01184 double a_1 = alpha_guess;
01185
01186 double phi_0 = functionValue;
01187 double phi_prime_0 = gradient*searchDirection;
01188
01189 double phi_a_0 = phi_0;
01190 double phi_a_1;
01191 double phi_prime_a_1;
01192
01193 for( int i=0; i<MaxWolfeSteps; i++ )
01194 {
01195 phi_a_1 =
01196 calculateLineSearchObjectiveFunction(params,searchDirection,a_1,
01197 standardDeviations,standardDeviationsErrors);
01198
01199
01200 if( phi_a_1 > phi_0 + c1 * a_1 * phi_prime_0 ||
01201 ( phi_a_1 >= phi_a_0 && i>0 ) )
01202 {
01203 return zoom(a_0,a_1,phi_0,phi_a_0,phi_a_1,phi_prime_0,params,
01204 searchDirection,standardDeviations,
01205 standardDeviationsErrors);
01206 }
01207
01208
01209 phi_prime_a_1 =
01210 calculateLineSearchObjectiveFunctionDerivative(params,
01211 searchDirection,a_1,standardDeviations,
01212 standardDeviationsErrors);
01213
01214
01215 if( fabs(phi_prime_a_1) <= -c2 * phi_prime_0 )
01216 {
01217 return a_1;
01218 }
01219
01220 if( phi_prime_a_1 >= 0 )
01221 {
01222 return zoom(a_1,a_0,phi_0,phi_a_1,phi_a_0,phi_prime_0,params,
01223 searchDirection,standardDeviations,
01224 standardDeviationsErrors);
01225 }
01226
01227
01228 a_0 = a_1;
01229 phi_a_0 = phi_a_1;
01230
01231
01232 a_1 = cubicInterpolateStep(a_0,a_max,phi_0,phi_a_0,phi_max,
01233 phi_prime_0);
01234 }
01235
01236 cerr << "WARNING: wolfeStepLength(...) in QMCProperty did not converge!"
01237 << endl;
01238
01239 return a_1;
01240 }
01241
01242
01243 void QMCProperty::generateInitialGuessFittingParameters()
01244 {
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275 }
01276
01277
01278 #ifdef PARALLEL
01279
01280 bool QMCProperty::mpiTypeCreated = false;
01281
01282 void QMCProperty::buildMpiReduce()
01283 {
01284 MPI_Op_create((MPI_User_function*)Reduce_Function,
01285 true,&MPI_REDUCE);
01286 }
01287
01288 void QMCProperty::buildMpiType()
01289 {
01290 QMCProperty indata;
01291
01292 int block_lengths[4];
01293 MPI_Aint displacements[4];
01294 MPI_Aint addresses[5];
01295 MPI_Datatype typelist[4];
01296
01297 typelist[0] = QMCStatistic::MPI_TYPE;
01298 typelist[1] = MPI_INT;
01299 typelist[2] = MPI_DOUBLE;
01300 typelist[3] = MPI_DOUBLE;
01301
01302 block_lengths[0] = DCL;
01303 block_lengths[1] = DCL;
01304 block_lengths[2] = DCL;
01305 block_lengths[3] = DCL;
01306
01307 MPI_Address(&indata, &addresses[0]);
01308 MPI_Address(&(indata.DeCorr[0]), &addresses[1]);
01309 MPI_Address(&(indata.DeCorr_flags[0]), &addresses[2]);
01310 MPI_Address(&(indata.DeCorr_sample[0]), &addresses[3]);
01311 MPI_Address(&(indata.DeCorr_weight[0]), &addresses[4]);
01312
01313 displacements[0] = addresses[1] - addresses[0];
01314 displacements[1] = addresses[2] - addresses[0];
01315 displacements[2] = addresses[3] - addresses[0];
01316 displacements[3] = addresses[4] - addresses[0];
01317
01318
01319 #ifdef QMC_OLDMPICH
01320 MPI_Type_struct(4, block_lengths, displacements, typelist, &MPI_TYPE);
01321 #else
01322 MPI_Datatype temp;
01323 MPI_Type_struct(4, block_lengths, displacements, typelist, &temp);
01324 MPI_Type_create_resized(temp,0,sizeof(QMCProperty),&MPI_TYPE);
01325 #endif
01326
01327 MPI_Type_commit(&MPI_TYPE);
01328 }
01329
01330
01331 MPI_Datatype QMCProperty::MPI_TYPE;
01332
01333 MPI_Op QMCProperty::MPI_REDUCE;
01334
01335 void QMCProperty::Reduce_Function(QMCProperty *in, QMCProperty *inout,
01336 int *len, MPI_Datatype *dptr)
01337 {
01338 for(int i=0; i < *len; i++)
01339 inout[i] = inout[i] + in[i];
01340 }
01341
01342
01343 #endif
01344