00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCCorrelatedSamplingVMCOptimization.h"
00014
00015 int QMCCorrelatedSamplingVMCOptimization::optStep = 1;
00016
00017 void QMCCorrelatedSamplingVMCOptimization::optimize(QMCInput * input,
00018 QMCProperties & lastRun,
00019 QMCPropertyArrays & fwLastRun,
00020 int configsToSkip)
00021 {
00022 double rel = 0;
00023 double abs = 0;
00024
00025
00026 Array1D<double> orig_parameters = globalInput.getAIParameters();
00027 Array1D<double> Guess_parameters(orig_parameters.dim1());
00028
00029 QMCDerivativeProperties dp(&lastRun,&fwLastRun,0);
00030
00031 if( globalInput.flags.my_rank == 0 )
00032 {
00033
00034 QMCObjectiveFunction ObjFunk;
00035 ObjFunk.initialize(input, configsToSkip);
00036
00037
00038 QMCOptimizationAlgorithm * optAlg =
00039 QMCOptimizationFactory::optimizationAlgorithmFactory(ObjFunk, input);
00040
00041 bool acceptable = false;
00042 int iter = 0;
00043 double a_diag_factor = 1.0;
00044 double penalty, norm;
00045 do {
00046 Guess_parameters =
00047 optAlg->optimize(orig_parameters,dp,
00048 a_diag_factor,
00049 optStep);
00050
00051 rel = 0;
00052 abs = 0;
00053 double num = 0;
00054 for(int i=0; i<Guess_parameters.dim1(); i++)
00055 {
00056 num += 1.0;
00057 double g = Guess_parameters(i);
00058 double o = orig_parameters(i);
00059 double v = g - o;
00060 abs += v*v;
00061 if( fabs(o) > 1.0e-100 )
00062 {
00063 v /= o;
00064 rel += v*v;
00065 }
00066 }
00067 abs = sqrt(abs)/num;
00068 rel = sqrt(rel)/num;
00069
00070 clog.unsetf(ios::scientific);
00071 clog << "(Step = " << setw(3) << optStep << "):"
00072 << " abs delta = " << setw(20) << abs
00073 << " rel delta = " << setw(20) << rel << endl;
00074
00075 globalInput.setAIParameters(Guess_parameters);
00076 penalty = globalInput.JP.calculate_penalty_function();
00077 norm = globalInput.WF.getCINorm();
00078 acceptable = true;
00079
00080 if(penalty >= 1e10)
00081 {
00082 clog << endl << endl << endl;
00083 clog << "Error: the Jastow's new guess parameters have bad poles (penalty = ";
00084 clog.width(20);
00085 clog.precision(10);
00086 clog << penalty << ")!" << endl;
00087 clog << " Parameters are: " << globalInput.JP.getJWParameters();
00088 clog << " its poles are: " << globalInput.JP.getPoles();
00089
00090
00091
00092
00093
00094 a_diag_factor *= 4.0;
00095 acceptable = false;
00096 }
00097
00098 iter++;
00099 } while( !acceptable && iter < globalInput.flags.optimization_max_iterations);
00100
00101 if(acceptable && fabs(globalInput.WF.getCINorm() - 1.0) > 1.0e-7)
00102 clog << "(Step = " << setw(3) << optStep << "): CI norm = " << globalInput.WF.getCINorm() << endl;
00103
00104 if(acceptable && fabs(penalty) > 1.0e-10)
00105 clog << "Notice: the new parameters have an acceptable singularity penalty = " << penalty << endl;
00106
00107 delete optAlg;
00108 optAlg = 0;
00109
00110 #ifdef PARALLEL
00111
00112
00113
00114
00115
00116 int WorkSignal = 0;
00117 MPI_Bcast(&WorkSignal,1,MPI_INT,0,MPI_COMM_WORLD);
00118 #endif
00119 }
00120 else
00121 {
00122 #ifdef PARALLEL
00123
00124 QMCReadAndEvaluateConfigs RAEC(input, configsToSkip);
00125
00126 while(true)
00127 {
00128
00129
00130
00131
00132
00133 int WorkSignal;
00134 MPI_Bcast(&WorkSignal,1,MPI_INT,0,MPI_COMM_WORLD);
00135
00136 if( WorkSignal == 1 ) RAEC.workerCalculateProperties();
00137 else break;
00138 }
00139 #endif
00140 }
00141
00142 #ifdef PARALLEL
00143
00144
00145 MPI_Bcast(Guess_parameters.array(),Guess_parameters.dim1(),
00146 MPI_DOUBLE,0,MPI_COMM_WORLD);
00147
00148
00149
00150
00151
00152 MPI_Bcast(&globalInput.flags.calculate_Derivatives,1,MPI_INT,0,MPI_COMM_WORLD);
00153
00154 int numCS = globalInput.cs_Parameters.dim1();
00155 MPI_Bcast(&numCS,1,MPI_INT,0,MPI_COMM_WORLD);
00156
00157 if(numCS > 0)
00158 {
00159 globalInput.cs_Parameters.allocate(numCS);
00160 for(int cs=0; cs<numCS; cs++)
00161 {
00162 globalInput.cs_Parameters(cs).allocate(Guess_parameters.dim1());
00163 MPI_Bcast(globalInput.cs_Parameters(cs).array(), globalInput.cs_Parameters(cs).dim1(),
00164 MPI_DOUBLE,0,MPI_COMM_WORLD);
00165 }
00166 }
00167 else
00168 {
00169 globalInput.cs_Parameters.deallocate();
00170 }
00171
00172 #endif
00173
00174 globalInput.setAIParameters(Guess_parameters);
00175 globalInput.WF.normalizeCI();
00176
00177 if(globalInput.flags.a_diag > 0 ||
00178 optStep%2 == 1)
00179 {
00180 clog << "(Step = " << setw(3) << optStep << "): Best Objective Value ";
00181 clog.precision(12);
00182 clog.width(20);
00183 clog.unsetf(ios::scientific);
00184 clog.unsetf(ios::fixed);
00185 clog << left << lastRun.energy.getAverage();
00186
00187 clog << " s^2 = ";
00188 clog.precision(12);
00189 clog.width(20);
00190 clog << left << lastRun.energy.getSeriallyCorrelatedVariance();
00191 clog << right;
00192
00193 clog << " ns = ";
00194 clog.width(10);
00195 clog << lastRun.energy.getNumberSamples();
00196 clog << endl << endl;
00197
00198
00199
00200
00201
00202
00203
00204 }
00205
00206 clog.setf(ios::scientific);
00207 if(globalInput.flags.a_diag > 0 ||
00208 optStep%2 == 0)
00209 {
00210 globalInput.printAIParameters(clog,"Best Step params:",20,Guess_parameters,false);
00211 clog << endl << endl;
00212
00213 globalInput.JP.print(clog);
00214 }
00215
00216 for(int i=0; i<Guess_parameters.dim1(); i++)
00217 if(IeeeMath::isNaN(Guess_parameters[i]))
00218 {
00219 clog << "Error: wavefunction has nans.\n";
00220 exit(0);
00221 }
00222
00223 double penalty = globalInput.JP.calculate_penalty_function();
00224 if(penalty >= 1e10)
00225 {
00226 clog << "Error: unable to produce acceptable parameters, quitting..." << endl;
00227 clog << " Either your guess for initial Jastrow parameters is bad or you need to change your "
00228 << "optimization choices." << endl;
00229 exit(0);
00230 }
00231
00232 optStep++;
00233 }
00234
00235
00236
00237