00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCObjectiveFunctionResult.h"
00014
00015 QMCObjectiveFunctionResult::QMCObjectiveFunctionResult()
00016 {
00017 }
00018
00019 QMCObjectiveFunctionResult::~QMCObjectiveFunctionResult()
00020 {
00021 Input = 0;
00022 }
00023
00024 QMCObjectiveFunctionResult::QMCObjectiveFunctionResult(QMCInput *input,
00025 double energyAve, double energyVar,
00026 double logWeightAve, double logWeightVar,
00027 int numSamples,
00028 Array1D<Complex> & poles)
00029 {
00030 Input = input;
00031 this->numSamples = numSamples;
00032
00033 set_energy_ave( energyAve );
00034 set_energy_var( energyVar );
00035 set_log_weights_ave( logWeightAve );
00036 set_log_weights_var( logWeightVar );
00037
00038 set_score(poles);
00039 set_score_for_derivative(poles);
00040 }
00041
00042 QMCObjectiveFunctionResult::QMCObjectiveFunctionResult(
00043 QMCObjectiveFunctionResult & rhs)
00044 {
00045 *this = rhs;
00046 }
00047
00048 double QMCObjectiveFunctionResult::getLogWeightsAve()
00049 {
00050 return log_weights_ave;
00051 }
00052
00053 double QMCObjectiveFunctionResult::getLogWeightsVar()
00054 {
00055 return log_weights_var;
00056 }
00057
00058 double QMCObjectiveFunctionResult::getEnergyAve() const
00059 {
00060 return energy_ave;
00061 }
00062
00063 double QMCObjectiveFunctionResult::getEnergyVar() const
00064 {
00065 return energy_var;
00066 }
00067
00068 int QMCObjectiveFunctionResult::getNumberSamples() const
00069 {
00070 return numSamples;
00071 }
00072
00073 double QMCObjectiveFunctionResult::getScore() const
00074 {
00075 return score;
00076 }
00077
00078 double QMCObjectiveFunctionResult::getDerivativeScore()
00079 {
00080 return score_for_derivative;
00081 }
00082
00083 void QMCObjectiveFunctionResult::set_log_weights_ave(double wa)
00084 {
00085 if(IeeeMath::isNaN(wa) != 0)
00086 {
00087 log_weights_ave = MAX_RESULT_VALUE;
00088 }
00089 else if(fabs(wa) > MAX_RESULT_VALUE)
00090 {
00091 log_weights_ave = MAX_RESULT_VALUE;
00092 }
00093 else
00094 {
00095 log_weights_ave = wa;
00096 }
00097 }
00098
00099 void QMCObjectiveFunctionResult::set_log_weights_var(double wv)
00100 {
00101 if(IeeeMath::isNaN(wv) != 0)
00102 {
00103 log_weights_var = MAX_RESULT_VALUE;
00104 }
00105 else if(fabs(wv) > MAX_RESULT_VALUE)
00106 {
00107 log_weights_var = MAX_RESULT_VALUE;
00108 }
00109 else if(wv < 0.0)
00110 {
00111 log_weights_var=MAX_RESULT_VALUE;
00112 }
00113 else
00114 {
00115 log_weights_var = wv;
00116 }
00117 }
00118
00119 void QMCObjectiveFunctionResult::set_energy_ave(double ea)
00120 {
00121 if(IeeeMath::isNaN(ea) != 0)
00122 {
00123 energy_ave = MAX_RESULT_VALUE;
00124 }
00125 else if(fabs(ea) > MAX_RESULT_VALUE)
00126 {
00127 energy_ave = MAX_RESULT_VALUE;
00128 }
00129 else
00130 {
00131 energy_ave=ea;
00132 }
00133 }
00134
00135 void QMCObjectiveFunctionResult::set_energy_var(double ev)
00136 {
00137 if(IeeeMath::isNaN(ev) != 0)
00138 {
00139 energy_var=MAX_RESULT_VALUE;
00140 }
00141 else if(fabs(ev) > MAX_RESULT_VALUE)
00142 {
00143 energy_var=MAX_RESULT_VALUE;
00144 }
00145 else if(ev < 0.0)
00146 {
00147 energy_var=MAX_RESULT_VALUE;
00148 }
00149 else
00150 {
00151 energy_var=ev;
00152 }
00153 }
00154
00155 void QMCObjectiveFunctionResult::operator=(const QMCObjectiveFunctionResult &rhs)
00156 {
00157 this->score = rhs.score;
00158 this->score_for_derivative = rhs.score_for_derivative;
00159 this->log_weights_ave = rhs.log_weights_ave;
00160 this->log_weights_var = rhs.log_weights_var;
00161 this->energy_ave = rhs.energy_ave;
00162 this->energy_var = rhs.energy_var;
00163 this->numSamples = rhs.numSamples;
00164 this->Input = rhs.Input;
00165 }
00166
00167 void QMCObjectiveFunctionResult::set_score(Array1D<Complex> & poles)
00168 {
00169
00170
00171
00172 if(Input->flags.optimize_Psi_criteria=="energy_variance")
00173 {
00174 score = getEnergyVar();
00175 }
00176 else if(Input->flags.optimize_Psi_criteria=="energy_average")
00177 {
00178 score = getEnergyAve();
00179 }
00180 else if(Input->flags.optimize_Psi_criteria=="umrigar88")
00181 {
00182 score = calculate_umrigar88();
00183 }
00184 else if(Input->flags.optimize_Psi_criteria=="monkey_spank")
00185 {
00186 score = calculate_monkey_spank();
00187 }
00188 else
00189 {
00190 cerr<<"ERROR: in Input.flags.optimize_Psi_criteria"<<endl;
00191 cerr<<Input->flags.optimize_Psi_criteria<<endl;
00192 exit(1);
00193 }
00194
00195
00196 score += QMCJastrowParameters::calculate_penalty_function(poles) *
00197 Input->flags.singularity_penalty_function_parameter;
00198 }
00199
00200 void QMCObjectiveFunctionResult::set_score_for_derivative(
00201 Array1D<Complex> & poles)
00202 {
00203
00204
00205
00206 if(Input->flags.numerical_derivative_surface=="energy_variance")
00207 {
00208 score_for_derivative = getEnergyVar();
00209 }
00210 else if(Input->flags.numerical_derivative_surface=="energy_average")
00211 {
00212 score_for_derivative = getEnergyAve();
00213 }
00214 else if(Input->flags.numerical_derivative_surface=="umrigar88")
00215 {
00216 score_for_derivative = calculate_umrigar88();
00217 }
00218 else if(Input->flags.numerical_derivative_surface=="monkey_spank")
00219 {
00220 score_for_derivative = calculate_monkey_spank();
00221 }
00222 else
00223 {
00224 cerr<<"ERROR: in Input.flags.numerical_derivative_surface"<<endl;
00225 cerr<<Input->flags.numerical_derivative_surface<<endl;
00226 exit(1);
00227 }
00228
00229
00230 score_for_derivative += QMCJastrowParameters::calculate_penalty_function(poles) *
00231 Input->flags.singularity_penalty_function_parameter;
00232 }
00233
00234
00235
00236 double QMCObjectiveFunctionResult::mikes_score_function()
00237 {
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 double dev_log_weights_var = 0.1*Input->flags.optimize_Psi_barrier_parameter;
00252
00253 double LV;
00254
00256
00258
00259
00260 double f1,f2,f3,f4;
00261
00262 f1=1.0;
00263
00264
00265 f2=1.0+energy_var;
00266
00267
00268
00269
00270 f3 = 1.0;
00271
00272
00273 LV = mikes_penalty_scaler(log_weights_var/dev_log_weights_var);
00274 f4 = mikes_penalty(LV);
00275
00276
00277 #ifdef DEBUG_MIKES_FUNCTION
00278 cerr << "mike's function: " << f1 << "\t" << f2 << "\t" << f3
00279 << "\t" << f4 << endl;
00280 #endif
00281
00282 return f1*f2*f3*f4;
00283 }
00284
00285
00286
00287
00288
00289
00290 double QMCObjectiveFunctionResult::mikes_penalty(double x)
00291 {
00292 double result;
00293 int steepness=4;
00294 result=exp(log(2.0)*pow(x,steepness*2.0));
00295 return result;
00296 }
00297
00298
00299
00300
00301
00302 double QMCObjectiveFunctionResult::mikes_penalty_scaler(double x)
00303 {
00304 double MAX=1.5;
00305
00306
00307
00308
00309
00310 if( IeeeMath::isNaN(x) != 0 ) return MAX;
00311 if( fabs(x) >= MAX) return MAX;
00312
00313 if( IeeeMath::isNaN(x) != 0 )
00314 {
00315 cerr << x << endl;
00316 cerr <<"ERROR QMCObjectiveFunctionResult::mikes_penalty_scaler(double x)"
00317 << endl;
00318 exit(1);
00319 }
00320 double result = MAX*(1.0-exp(log(1.0-1.0/MAX)*fabs(x)));
00321 return result;
00322 }
00323
00324
00325 double QMCObjectiveFunctionResult::calculate_monkey_spank()
00326 {
00327 return mikes_score_function();
00328 }
00329
00330
00331 double QMCObjectiveFunctionResult::calculate_umrigar88()
00332 {
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 double temp = Input->flags.energy_estimated - getEnergyAve();
00346 double val = getEnergyVar() + temp*temp;
00347 return val;
00348 }
00349
00350 ostream& operator<<(ostream & strm, QMCObjectiveFunctionResult & rhs)
00351 {
00352 strm << "log(weights): " << rhs.getLogWeightsAve() << "+/-"
00353 << sqrt(rhs.getLogWeightsVar()) << endl;
00354
00355 strm << "energy: " << rhs.getEnergyAve() << "+/-"
00356 << sqrt(rhs.getEnergyVar()) << endl;
00357
00358 strm << "score: " << rhs.getScore() << endl;
00359 strm << "derivative score: " << rhs.getDerivativeScore() << endl;
00360
00361 return strm;
00362 }