00001 #include "EnergyFunctionCalculatorStatistics.h"
00002 #include "EnergyFunction.h"
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <sstream>
00006
00007
00008
00009 #include <cmath>
00010
00011 #include <BasicUtils/BasicString.h>
00012 #include <BasicUtils/BasicException.h>
00013 #include <sstream>
00014 #include <CompuCell3D/PottsParseData.h>
00015 #include <XMLUtils/CC3DXMLElement.h>
00016
00017
00018
00019 using namespace CompuCell3D;
00020 using namespace std;
00021
00022 EnergyFunctionCalculatorStatistics::EnergyFunctionCalculatorStatistics():EnergyFunctionCalculator(){
00023
00024 NTot=0;
00025 NAcc=0;
00026 NRej=0;
00027 lastFlipAttempt=-1;
00028 out=0;
00029 outAccSpinFlip=0;
00030 outRejSpinFlip=0;
00031 outTotSpinFlip=0;
00032
00033 wroteHeader=false;
00034 outputEverySpinFlip=false;
00035 gatherResultsSpinFlip=false;
00036 outputAcceptedSpinFlip=false;
00037 outputRejectedSpinFlip=false;
00038 outputTotalSpinFlip=false;
00039
00040 gatherResultsFilesPrepared=false;
00041
00042
00043
00044
00045
00046
00047 mcs=0;
00048 fieldWidth=30;
00049 analysisFrequency=1;
00050 singleSpinFrequency=1;
00051 }
00052
00053 EnergyFunctionCalculatorStatistics::~EnergyFunctionCalculatorStatistics(){
00054 if(out){
00055 out->close();
00056 delete out;
00057 out=0;
00058
00059 }
00060
00061 if(outAccSpinFlip){
00062 outAccSpinFlip->close();
00063 delete outAccSpinFlip;
00064 outAccSpinFlip=0;
00065 }
00066
00067 if(outRejSpinFlip){
00068 outRejSpinFlip->close();
00069 delete outRejSpinFlip;
00070 outRejSpinFlip=0;
00071 }
00072
00073 if(outTotSpinFlip){
00074 outTotSpinFlip->close();
00075 delete outTotSpinFlip;
00076 outTotSpinFlip=0;
00077 }
00078
00079 }
00080
00081
00082 double EnergyFunctionCalculatorStatistics::changeEnergy(Point3D &pt, const CellG *newCell,const CellG *oldCell,const unsigned int _flipAttempt){
00083
00084 if(lastFlipAttempt<0){
00085 initialize();
00086 }
00087
00088 if(_flipAttempt<lastFlipAttempt){
00089 ++mcs;
00090 if(! (mcs % analysisFrequency)){
00091 outputResults();
00092 }
00093 if(!gatherResultsSpinFlip && outputEverySpinFlip && ! (mcs % singleSpinFrequency) ){
00094 outputResultsSingleSpinFlip();
00095 }
00096
00097 if(gatherResultsSpinFlip && outputEverySpinFlip && ! (mcs % singleSpinFrequency) ){
00098 if(!gatherResultsFilesPrepared){
00099 prepareGatherResultsFiles();
00100 }
00101 outputResultsSingleSpinFlipGatherResults();
00102 }
00103
00104 prepareNextStep();
00105 }
00106
00107 lastFlipAttempt=_flipAttempt;
00108
00109 double change = 0;
00110 for (unsigned int i = 0; i < energyFunctions.size(); i++){
00111 lastEnergyVec[i]=energyFunctions[i]->changeEnergy(pt, newCell, oldCell);
00112 change+=lastEnergyVec[i];
00113
00114 }
00115 totEnergyDataList.push_back(lastEnergyVec);
00116
00117 return change;
00118
00119 }
00120
00121
00122 void EnergyFunctionCalculatorStatistics::setLastFlipAccepted(bool _accept){
00123 lastFlipAccepted=_accept;
00124
00125 if (lastFlipAccepted){
00126 accNotAccList.push_back(true);
00127
00128
00129 }else{
00130 accNotAccList.push_back(false);
00131
00132
00133 }
00134
00135
00136 }
00137 void EnergyFunctionCalculatorStatistics::writeHeader(){
00138
00139 (*out)<<setw(fieldWidth)<<"1.STEP"<<setw(fieldWidth)<<"2.NAcc"<<setw(fieldWidth)<<"3.NRej"<<setw(fieldWidth)<<"4.NTot";
00140 int n=5;
00141 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00142 ostringstream str1;
00143 ostringstream str2;
00144 str1<<n<<".Acc_"<<energyFunctionsNameVec[i]<<"_AVG";
00145 str2<<n+1<<". +/-";
00146 (*out)<<setw(fieldWidth)<<str1.str()<<setw(fieldWidth)<<str2.str();
00147 n+=2;
00148 }
00149
00150 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00151 ostringstream str1;
00152 ostringstream str2;
00153 str1<<n<<".Rej_"<<energyFunctionsNameVec[i]<<"_AVG";
00154 str2<<n+1<<". +/-";
00155 (*out)<<setw(fieldWidth)<<str1.str()<<setw(fieldWidth)<<str2.str();
00156 n+=2;
00157 }
00158
00159 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00160 ostringstream str1;
00161 ostringstream str2;
00162 str1<<n<<".Tot_"<<energyFunctionsNameVec[i]<<"_AVG";
00163 str2<<n+1<<". +/-";
00164 (*out)<<setw(fieldWidth)<<str1.str()<<setw(fieldWidth)<<str2.str();
00165 n+=2;
00166 }
00167
00168
00169
00170 (*out)<<endl;
00171 }
00172
00173
00174
00175 void EnergyFunctionCalculatorStatistics::initialize(){
00176 if(!wroteHeader && out){
00177 writeHeader();
00178 wroteHeader=true;
00179 }
00180 NAcc=0;
00181 NRej=0;
00182 NTot=0;
00183
00184 int energyFunctionsVecSize=energyFunctions.size();
00185
00186 lastEnergyVec.assign(energyFunctionsVecSize,0.0);
00187 stdDevEnergyVectorTot.assign(energyFunctionsVecSize,0.0);
00188 stdDevEnergyVectorAcc.assign(energyFunctionsVecSize,0.0);
00189 stdDevEnergyVectorRej.assign(energyFunctionsVecSize,0.0);
00190
00191
00192
00193
00194
00195 totEnergyDataList.clear();
00196 accNotAccList.clear();
00197
00198
00199 }
00200
00201 void EnergyFunctionCalculatorStatistics::prepareNextStep(){
00202
00203 initialize();
00204
00205 }
00206
00207
00208 void EnergyFunctionCalculatorStatistics::calculateStatData(){
00209 unsigned int energyFunctionCount=energyFunctions.size();
00210
00211 avgEnergyVectorTot.assign(energyFunctionCount,0.0);
00212 stdDevEnergyVectorTot.assign(energyFunctionCount,0.0);
00213
00214 avgEnergyVectorAcc.assign(energyFunctionCount,0.0);
00215 stdDevEnergyVectorAcc.assign(energyFunctionCount,0.0);
00216
00217 avgEnergyVectorRej.assign(energyFunctionCount,0.0);
00218 stdDevEnergyVectorRej.assign(energyFunctionCount,0.0);
00219
00220
00221
00222
00223
00224 std::list<std::vector<double> >::iterator lVecItr;
00225 std::list<bool>::iterator lItr;
00226
00227 NTot=0;
00228 NAcc=0;
00229 NRej=0;
00230
00231
00232 lItr=accNotAccList.begin();
00233 for(lVecItr=totEnergyDataList.begin() ; lVecItr != totEnergyDataList.end() ; ++lVecItr){
00234 ++NTot;
00235 vector<double> & energyData=*lVecItr;
00236 for(int i = 0 ; i < energyFunctionCount ; ++i){
00237 avgEnergyVectorTot[i]+=energyData[i];
00238 }
00239 if(*lItr){
00240 ++NAcc;
00241 for(int i = 0 ; i < energyFunctionCount ; ++i){
00242 avgEnergyVectorAcc[i]+=energyData[i];
00243 }
00244 }else{
00245 ++NRej;
00246 for(int i = 0 ; i < energyFunctionCount ; ++i){
00247 avgEnergyVectorRej[i]+=energyData[i];
00248 }
00249 }
00250 ++lItr;
00251 }
00252
00253 for(int i = 0 ; i < energyFunctions.size() ; ++i){
00254 if(NTot)
00255 avgEnergyVectorTot[i]/=NTot;
00256 if(NAcc)
00257 avgEnergyVectorAcc[i]/=NAcc;
00258 if(NRej)
00259 avgEnergyVectorRej[i]/=NRej;
00260 }
00261
00262
00263 stdDevEnergyVectorTot.assign(energyFunctionCount,0.);
00264 stdDevEnergyVectorAcc.assign(energyFunctionCount,0.);
00265 stdDevEnergyVectorRej.assign(energyFunctionCount,0.);
00266
00267 lItr=accNotAccList.begin();
00268 for(lVecItr=totEnergyDataList.begin() ; lVecItr != totEnergyDataList.end() ; ++lVecItr){
00269 vector<double> & energyData=*lVecItr;
00270 for(int i = 0 ; i < energyFunctionCount ; ++i){
00271 stdDevEnergyVectorTot[i]+=(energyData[i]-avgEnergyVectorTot[i])*(energyData[i]-avgEnergyVectorTot[i]);
00272 }
00273 if(*lItr){
00274 for(int i = 0 ; i < energyFunctionCount ; ++i){
00275 stdDevEnergyVectorAcc[i]+=(energyData[i]-avgEnergyVectorAcc[i])*(energyData[i]-avgEnergyVectorAcc[i]);
00276 }
00277 }else{
00278 for(int i = 0 ; i < energyFunctionCount ; ++i){
00279 stdDevEnergyVectorRej[i]+=(energyData[i]-avgEnergyVectorRej[i])*(energyData[i]-avgEnergyVectorRej[i]);
00280 }
00281 }
00282 ++lItr;
00283 }
00284
00285
00286
00287
00288 for (int j = 0 ; j < energyFunctions.size() ; ++j){
00289 if(NTot)
00290 stdDevEnergyVectorTot[j]=sqrt(stdDevEnergyVectorTot[j])/NTot;
00291 if(NAcc)
00292 stdDevEnergyVectorAcc[j]=sqrt(stdDevEnergyVectorAcc[j])/NAcc;
00293 if(NRej)
00294 stdDevEnergyVectorRej[j]=sqrt(stdDevEnergyVectorRej[j])/NRej;
00295
00296 }
00297
00298
00299 }
00300
00301 void EnergyFunctionCalculatorStatistics::writeHeaderFlex(std::ofstream & _out){
00302
00303 int n=1;
00304
00305 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00306 ostringstream str1;
00307 str1<<n<<". "<<energyFunctionsNameVec[i];
00308 _out<<setw(fieldWidth)<<str1.str();
00309 n+=1;
00310 }
00311
00312 _out<<endl;
00313
00314 }
00315
00316
00317 void EnergyFunctionCalculatorStatistics::writeDataLineFlex(std::ofstream & _out, std::vector<double> & _energies){
00318
00319 for(int i = 0 ; i<_energies.size() ; ++i){
00320 _out<<setw(fieldWidth)<<_energies[i];
00321 }
00322 _out<<endl;
00323 }
00324
00325
00326 void EnergyFunctionCalculatorStatistics::prepareGatherResultsFiles(){
00327
00328 if(outputAcceptedSpinFlip){
00329 ostringstream outSingleSpinFlipStreamNameAccepted;
00330 outSingleSpinFlipStreamNameAccepted<<outFileCoreNameSpinFlips<<"."<<"accepted"<<"."<<"txt";
00331 outAccSpinFlip =new ofstream(outSingleSpinFlipStreamNameAccepted.str().c_str());
00332
00333 writeHeaderFlex(*outAccSpinFlip);
00334 }
00335
00336 if(outputRejectedSpinFlip){
00337 ostringstream outSingleSpinFlipStreamNameRejected;
00338 outSingleSpinFlipStreamNameRejected<<outFileCoreNameSpinFlips<<"."<<"rejected"<<"."<<"txt";
00339 outRejSpinFlip =new ofstream(outSingleSpinFlipStreamNameRejected.str().c_str());
00340
00341 writeHeaderFlex(*outRejSpinFlip);
00342 }
00343
00344 if(outputTotalSpinFlip){
00345 ostringstream outSingleSpinFlipStreamNameTotal;
00346 outSingleSpinFlipStreamNameTotal<<outFileCoreNameSpinFlips<<"."<<"total"<<"."<<"txt";
00347 outTotSpinFlip =new ofstream(outSingleSpinFlipStreamNameTotal.str().c_str());
00348
00349 writeHeaderFlex(*outTotSpinFlip);
00350 }
00351
00352 gatherResultsFilesPrepared=true;
00353
00354 }
00355
00356 void EnergyFunctionCalculatorStatistics::outputResultsSingleSpinFlipGatherResults(){
00357
00358
00359 std::list<std::vector<double> >::iterator lVecItr;
00360 std::list<bool>::iterator lItr;
00361
00362 lItr=accNotAccList.begin();
00363 for(lVecItr=totEnergyDataList.begin() ; lVecItr != totEnergyDataList.end() ; ++lVecItr){
00364
00365 vector<double> & energyData=*lVecItr;
00366 if(outputTotalSpinFlip)
00367 writeDataLineFlex(*outTotSpinFlip,*lVecItr);
00368
00369 if(*lItr){
00370 if(outputAcceptedSpinFlip)
00371 writeDataLineFlex(*outAccSpinFlip,*lVecItr);
00372 }else{
00373 if(outputRejectedSpinFlip)
00374 writeDataLineFlex(*outRejSpinFlip,*lVecItr);
00375 }
00376 ++lItr;
00377 }
00378
00379
00380
00381
00382 }
00383
00384
00385
00386 void EnergyFunctionCalculatorStatistics::outputResultsSingleSpinFlip(){
00387 ostringstream outSingleSpinFlipStreamNameAccepted;
00388 outSingleSpinFlipStreamNameAccepted<<outFileCoreNameSpinFlips<<"."<<"accepted"<<"."<<mcs<<"."<<"txt";
00389
00390 ostringstream outSingleSpinFlipStreamNameRejected;
00391 outSingleSpinFlipStreamNameRejected<<outFileCoreNameSpinFlips<<"."<<"rejected"<<"."<<mcs<<"."<<"txt";
00392
00393 ostringstream outSingleSpinFlipStreamNameTotal;
00394 outSingleSpinFlipStreamNameTotal<<outFileCoreNameSpinFlips<<"."<<"total"<<"."<<mcs<<"."<<"txt";
00395
00396 ofstream outSingleSpinFlipAccepted(outSingleSpinFlipStreamNameAccepted.str().c_str());
00397 ofstream outSingleSpinFlipRejected(outSingleSpinFlipStreamNameRejected.str().c_str());
00398 ofstream outSingleSpinFlipTotal(outSingleSpinFlipStreamNameTotal.str().c_str());
00399
00400 writeHeaderFlex(outSingleSpinFlipAccepted);
00401 writeHeaderFlex(outSingleSpinFlipRejected);
00402 writeHeaderFlex(outSingleSpinFlipTotal);
00403
00404 std::list<std::vector<double> >::iterator lVecItr;
00405 std::list<bool>::iterator lItr;
00406
00407 lItr=accNotAccList.begin();
00408 for(lVecItr=totEnergyDataList.begin() ; lVecItr != totEnergyDataList.end() ; ++lVecItr){
00409
00410 vector<double> & energyData=*lVecItr;
00411 writeDataLineFlex(outSingleSpinFlipTotal,*lVecItr);
00412 if(*lItr){
00413 writeDataLineFlex(outSingleSpinFlipAccepted,*lVecItr);
00414 }else{
00415 writeDataLineFlex(outSingleSpinFlipRejected,*lVecItr);
00416 }
00417 ++lItr;
00418 }
00419
00420
00421
00422 }
00423
00424
00425 void EnergyFunctionCalculatorStatistics::outputResults(){
00426 cerr<<"-------------ENERGY CALCULATOR STATISTICS-------------"<<endl;
00427 cerr<<"Accepted Energy:"<<endl;
00428 double totAccEnergyChange=0;
00429
00430
00431 calculateStatData();
00432
00433 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00434 cerr<<"TOT "<<energyFunctionsNameVec[i]<<" "<<avgEnergyVectorTot[i]*NTot<<" avg: "<<avgEnergyVectorTot[i]<<" stdDev: "<<stdDevEnergyVectorTot[i]<<endl;
00435 cerr<<"ACC "<<energyFunctionsNameVec[i]<<" "<<avgEnergyVectorAcc[i]*NAcc<<" avg: "<<avgEnergyVectorAcc[i]<<" stdDev: "<<stdDevEnergyVectorAcc[i]<<endl;
00436 cerr<<"REJ "<<energyFunctionsNameVec[i]<<" "<<avgEnergyVectorRej[i]*NRej<<" avg: "<<avgEnergyVectorRej[i]<<" stdDev: "<<stdDevEnergyVectorRej[i]<<endl;
00437
00438 totAccEnergyChange+=avgEnergyVectorAcc[i]*NAcc;
00439 }
00440
00441 if(out){
00442 (*out)<<setw(fieldWidth)<<mcs<<setw(fieldWidth)<<NAcc<<setw(fieldWidth)<<NRej<<setw(fieldWidth)<<NTot;
00443 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00444 (*out)<<setw(fieldWidth)<<avgEnergyVectorAcc[i]<<setw(fieldWidth)<<stdDevEnergyVectorAcc[i];
00445 }
00446 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00447 (*out)<<setw(fieldWidth)<<avgEnergyVectorRej[i]<<setw(fieldWidth)<<stdDevEnergyVectorRej[i];
00448 }
00449 for (int i = 0 ; i < energyFunctions.size() ; ++i){
00450 (*out)<<setw(fieldWidth)<<avgEnergyVectorTot[i]<<setw(fieldWidth)<<stdDevEnergyVectorTot[i];
00451 }
00452 (*out)<<endl;
00453
00454 }
00455
00456 cerr<<"TOTAL ACC ENERGY CHANGE="<<totAccEnergyChange<<endl;
00457 cerr<<"-------------End of ENERGY CALCULATOR STATISTICS-------------"<<endl;
00458 cerr<<"Output File name = "<<outFileName<<endl;
00459
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 void EnergyFunctionCalculatorStatistics::init(CC3DXMLElement *_xmlData){
00519 outFileName="";
00520 outFileCoreNameSpinFlips="";
00521 outputEverySpinFlip=false;
00522 gatherResultsSpinFlip=false;
00523 outputAcceptedSpinFlip=false;
00524 outputRejectedSpinFlip=false;
00525 outputTotalSpinFlip=false;
00526 analysisFrequency=1;
00527 singleSpinFrequency=1;
00528
00529
00530 CC3DXMLElement * outputFileNameElem=_xmlData->getFirstElement("OutputFileName");
00531 if(outputFileNameElem){
00532 outFileName=outputFileNameElem->getText();
00533 if(outputFileNameElem->findAttribute("Frequency"))
00534 analysisFrequency=outputFileNameElem->getAttributeAsUInt("Frequency");
00535 }
00536
00537 CC3DXMLElement * outputCoreFileNameSpinFlipsElem=_xmlData->getFirstElement("OutputCoreFileNameSpinFlips");
00538
00539 if(outputCoreFileNameSpinFlipsElem){
00540 outFileCoreNameSpinFlips=outputCoreFileNameSpinFlipsElem->getText();
00541 outputEverySpinFlip=true;
00542 if(outputCoreFileNameSpinFlipsElem->findAttribute("Frequency"))
00543 singleSpinFrequency=outputCoreFileNameSpinFlipsElem->getAttributeAsUInt("Frequency");
00544 if(outputCoreFileNameSpinFlipsElem->findAttribute("GatherResults"))
00545 gatherResultsSpinFlip=true;
00546 if(outputCoreFileNameSpinFlipsElem->findAttribute("OutputAccepted"))
00547 outputAcceptedSpinFlip=true;
00548 if(outputCoreFileNameSpinFlipsElem->findAttribute("OutputRejected"))
00549 outputRejectedSpinFlip=true;
00550 if(outputCoreFileNameSpinFlipsElem->findAttribute("OutputTotal"))
00551 outputTotalSpinFlip=true;
00552
00553 }
00554
00555 cerr<<"outFileName="<<outFileName<<endl;
00556 cerr<<"outFileCoreNameSpinFlips="<<outFileCoreNameSpinFlips<<endl;
00557 cerr<<"outputEverySpinFlip="<<outputEverySpinFlip<<endl;
00558 cerr<<"gatherResultsSpinFlip="<<gatherResultsSpinFlip<<endl;
00559 cerr<<"outputAcceptedSpinFlip="<<outputAcceptedSpinFlip<<endl;
00560 cerr<<"outputRejectedSpinFlip="<<outputRejectedSpinFlip<<endl;
00561 cerr<<"outputTotalSpinFlip="<<outputTotalSpinFlip<<endl;
00562 cerr<<"analysisFrequency="<<analysisFrequency<<endl;
00563 cerr<<"singleSpinFrequency="<<singleSpinFrequency<<endl;
00564
00565
00566
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592