00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCDerivativeProperties.h"
00014
00015
00016 QMCDerivativeProperties::QMCDerivativeProperties(QMCProperties * properties,
00017 QMCPropertyArrays * fwProperties,
00018 double dt)
00019 {
00020 this->properties = properties;
00021 this->fwProperties = fwProperties;
00022 this->dt = dt;
00023 }
00024
00025 double QMCDerivativeProperties::getEffectiveTimeStep()
00026 {
00027 double value = dt;
00028 if (properties->distanceMovedAccepted.getNumberSamples() > 0)
00029 {
00030 value = dt * properties->distanceMovedAccepted.getAverage()/
00031 properties->distanceMovedTrial.getAverage();
00032 }
00033 return value;
00034 }
00035
00036 double QMCDerivativeProperties::getEffectiveTimeStepVariance()
00037 {
00038 double result = 0.0;
00039 if (properties->distanceMovedAccepted.getNumberSamples() > 0)
00040 {
00041 double distanceMovedAcceptAve =
00042 properties->distanceMovedAccepted.getAverage();
00043 double distanceMovedAcceptVar =
00044 properties->distanceMovedAccepted.getVariance();
00045
00046 double distanceMovedTrialAve = properties->distanceMovedTrial.getAverage();
00047 double distanceMovedTrialVar = properties->distanceMovedTrial.getVariance();
00048
00049 double temp1 = 1.0/distanceMovedTrialAve/distanceMovedTrialAve;
00050 double temp2 = distanceMovedAcceptAve * temp1;
00051 temp2 = temp2*temp2;
00052
00053 result = dt * ( temp1 * distanceMovedAcceptVar +
00054 temp2 * distanceMovedTrialVar );
00055 }
00056 return result;
00057 }
00058
00059 double QMCDerivativeProperties::getEffectiveTimeStepStandardDeviation()
00060 {
00061 return sqrt( getEffectiveTimeStepVariance() );
00062 }
00063
00064 double QMCDerivativeProperties::getVirialRatio(int whichFW)
00065 {
00066 double value = -(fwProperties->props[FW_PE])[whichFW].getAverage() /
00067 (fwProperties->props[FW_KE])[whichFW].getAverage();
00068
00069 return value;
00070 }
00071
00072 double QMCDerivativeProperties::getVirialRatioVariance(int whichFW)
00073 {
00074 double vave = (fwProperties->props[FW_PE])[whichFW].getAverage();
00075 double vvar = (fwProperties->props[FW_PE])[whichFW].getVariance();
00076
00077 double tave = (fwProperties->props[FW_KE])[whichFW].getAverage();
00078 double tvar = (fwProperties->props[FW_KE])[whichFW].getVariance();
00079
00080 double temp1 = 1.0/tave/tave;
00081 double temp2 = vave*temp1;
00082 temp2 = temp2*temp2;
00083
00084 double result = temp1 * vvar + temp2 * tvar;
00085
00086 return result;
00087 }
00088
00089 double QMCDerivativeProperties::getVirialRatioStandardDeviation(int whichFW)
00090 {
00091 return sqrt( getVirialRatioVariance(whichFW) );
00092 }
00093
00094 Array1D<double> QMCDerivativeProperties::getCorrelatedSamples(int whichKind)
00095 {
00096 Array1D<double> samples;
00097 int dim = fwProperties->cs_Energies.dim1();
00098 if(dim <= 0) return samples;
00099 samples.allocate(dim);
00100 samples = 0.0;
00101
00102 for(int cs=0; cs<dim; cs++)
00103 {
00104 switch(whichKind)
00105 {
00106 case 0:
00107 samples(cs) = fwProperties->cs_Energies(cs).getAverage();
00108 break;
00109 case 1:
00110 samples(cs) = fwProperties->cs_Energies(cs).getSeriallyCorrelatedVariance();
00111 break;
00112 default:
00113 clog << "Error: unknown correlated sample type = " << whichKind << endl;
00114 break;
00115 }
00116 }
00117 return samples;
00118 }
00119
00120 double QMCDerivativeProperties::getParameterValue()
00121 {
00122 if(globalInput.flags.optimize_Psi_criteria == "generalized_eigenvector" ||
00123 globalInput.flags.optimize_Psi_criteria == "energy_average")
00124 {
00125 return properties->energy.getAverage();
00126 }
00127 return properties->energy.getSeriallyCorrelatedVariance();
00128 }
00129
00130 double QMCDerivativeProperties::getSampleVariance()
00131 {
00132
00133 return properties->energy.getVariance();
00134 }
00135
00136 Array1D<double> QMCDerivativeProperties::getParameterGradient()
00137 {
00138 Array1D<double> gradient;
00139 if(fwProperties->der.dim1() == 0 ||
00140 fwProperties->der.dim2() == 0)
00141 {
00142
00143 return gradient;
00144 }
00145
00146 int numCI = fwProperties->der.dim1();
00147
00148 gradient.allocate(numCI);
00149 for(int ci=0; ci<numCI; ci++)
00150 {
00151 double pi = fwProperties->der(ci,0);
00152 double pi_e = fwProperties->der(ci,1);
00153 double pi_e2 = fwProperties->der(ci,2);
00154 double ei = fwProperties->der(ci,3);
00155 double ei_e = fwProperties->der(ci,4);
00156 double e = properties->energy.getAverage();
00157 double e2 = properties->energy2.getAverage();
00158
00159
00160
00161 double der;
00162
00163 if(globalInput.flags.optimize_Psi_criteria == "generalized_eigenvector")
00164 {
00165
00166
00167
00168 der = pi_e - pi*e;
00169
00170 } else {
00171
00172
00173 if(!true)
00174 {
00175
00176 pi = 0;
00177 pi_e = 0;
00178 pi_e2 = 0;
00179 }
00180
00181
00182 der = ei_e - ei*e;
00183
00184
00185 der += pi_e2;
00186
00187
00188 der -= pi*e2;
00189
00190
00191 der -= 2.0*e*(pi_e - pi*e);
00192 }
00193
00194 der *= 2.0;
00195 gradient(ci) = der;
00196 }
00197 return gradient;
00198 }
00199
00200 Array2D<double> QMCDerivativeProperties::getParameterHessian()
00201 {
00202 Array2D<double> hessian;
00203 if(fwProperties->hess.dim1() == 0 ||
00204 fwProperties->hess(0).dim1() == 0 ||
00205 fwProperties->hess(0).dim2() == 0)
00206 {
00207
00208 return hessian;
00209 }
00210
00211 if(globalInput.flags.optimize_Psi_criteria != "analytical_energy_variance")
00212 return hessian;
00213
00214 int numAI = fwProperties->der.dim1();
00215 hessian.allocate(numAI,numAI);
00216
00217 for(int ai=0; ai<numAI; ai++)
00218 {
00219 for(int aj=0; aj<=ai; aj++)
00220 {
00221
00222 double h1 = (fwProperties->hess(0))(ai,aj);
00223
00224 double h2 = fwProperties->der(ai,3)
00225 * fwProperties->der(aj,3);
00226
00227 double h3 = 2.0 * (h1 - h2);
00228 hessian(ai,aj) = h3;
00229 hessian(aj,ai) = h3;
00230 }
00231 }
00232
00233 return hessian;
00234 }
00235
00236 Array2D<double> QMCDerivativeProperties::getParameterHamiltonian()
00237 {
00238 Array2D<double> hamiltonian;
00239 if(fwProperties->hess.dim1() == 0 ||
00240 fwProperties->hess(0).dim1() == 0 ||
00241 fwProperties->hess(0).dim2() == 0)
00242 {
00243 clog << "Error: the parameter hamiltonian is not available in this QMCFwProperties object.\n";
00244 return hamiltonian;
00245 }
00246
00247 if(globalInput.flags.optimize_Psi_criteria != "generalized_eigenvector")
00248 return hamiltonian;
00249
00250 int numAI = fwProperties->der.dim1();
00251 hamiltonian.allocate(numAI+1,numAI+1);
00252 hamiltonian = 0.0;
00253
00254
00255 double e = properties->energy.getAverage();
00256
00257 hamiltonian(0,0) = e;
00258
00259
00260 for(int ai=0; ai<numAI; ai++)
00261 {
00262
00263 double pi_e = fwProperties->der(ai,1);
00264
00265 double pi = fwProperties->der(ai,0);
00266
00267 double ei = fwProperties->der(ai,3);
00268
00269 hamiltonian(ai+1,0) = pi_e - pi*e;
00270 hamiltonian(0,ai+1) = pi_e - pi*e + ei;
00271
00272 for(int aj=0; aj<numAI; aj++)
00273 {
00274
00275 double ppe = (fwProperties->hess(0))(ai,aj);
00276
00277
00278 double pi_ej = (fwProperties->hess(2))(ai,aj);
00279
00280
00281 double pj_e = fwProperties->der(aj,1);
00282
00283
00284 double pj = fwProperties->der(aj,0);
00285
00286
00287 double ej = fwProperties->der(aj,3);
00288
00289 double val = ppe - pi*pj_e - pj*pi_e + pi*pj*e;
00290 val += pi_ej - pi*ej;
00291
00292 hamiltonian(ai+1,aj+1) = val;
00293 }
00294 }
00295
00296 return hamiltonian;
00297 }
00298
00299 Array2D<double> QMCDerivativeProperties::getParameterOverlap()
00300 {
00301 Array2D<double> overlap;
00302 if(fwProperties->hess.dim1() == 0 ||
00303 fwProperties->hess(0).dim1() == 0 ||
00304 fwProperties->hess(0).dim2() == 0)
00305 {
00306
00307 return overlap;
00308 }
00309
00310 if(globalInput.flags.optimize_Psi_criteria != "generalized_eigenvector")
00311 return overlap;
00312
00313 int numAI = fwProperties->der.dim1();
00314 overlap.allocate(numAI+1,numAI+1);
00315 overlap = 0.0;
00316
00317 overlap(0,0) = 1.0;
00318
00319
00320 for(int ai=0; ai<numAI; ai++)
00321 {
00322
00323 overlap(0,ai+1) = 0.0;
00324 overlap(ai+1,0) = 0.0;
00325
00326 for(int aj=0; aj<=ai; aj++)
00327 {
00328
00329 double pi_pj = (fwProperties->hess(1))(ai,aj);
00330
00331
00332 double pi = fwProperties->der(ai,0);
00333
00334 double pj = fwProperties->der(aj,0);
00335
00336 double val = pi_pj - pi*pj;
00337 overlap(ai+1,aj+1) = val;
00338 overlap(aj+1,ai+1) = val;
00339 }
00340 }
00341
00342 return overlap;
00343 }
00344
00345 ostream& operator <<(ostream& strm, QMCDerivativeProperties &rhs)
00346 {
00347 strm << "dt_effective: " << rhs.getEffectiveTimeStep() << " +/- "
00348 << rhs.getEffectiveTimeStepStandardDeviation() << endl;
00349
00350 strm << endl << "--------------- Virial Ratio (-<V>/<T>) ---------------" << endl;
00351 for(int fw=0; fw<rhs.fwProperties->numFutureWalking; fw++)
00352 {
00353 if((rhs.fwProperties->props[FW_PE])[fw].getNumberSamples() <= 0) break;
00354 strm.width(7);
00355 strm << globalInput.flags.future_walking[fw] << ": " << rhs.getVirialRatio(fw) <<
00356 " +/- " << rhs.getVirialRatioStandardDeviation(fw) << endl;
00357
00358 double vave = (rhs.fwProperties->props[FW_PE])[fw].getAverage();
00359 double vvar = (rhs.fwProperties->props[FW_PE])[fw].getVariance();
00360
00361 double tave = (rhs.fwProperties->props[FW_KE])[fw].getAverage();
00362 double tvar = (rhs.fwProperties->props[FW_KE])[fw].getVariance();
00363
00364 strm << " Total Energy Estimator (KE/Virial): " << -tave << " +/- " << sqrt(tvar) << endl;
00365 strm << " Total Energy Estimator (PE/Virial): " << vave/2.0 << " +/- " << sqrt(vvar)/2.0 << endl;
00366 }
00367
00368 return strm;
00369 }
00370
00371