• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/StatCalc.cpp

00001 #include "ECF_base.h"
00002 #include "ECF_macro.h"
00003 #include <cmath>
00004 
00005 
00006 StatCalc::StatCalc() 
00007 {
00008     statNo = 0;
00009     statsFileName_ = "";
00010 }
00011 
00012 
00013 void StatCalc::registerParameters(StateP state)
00014 {
00015     state->getRegistry()->registerEntry("stats.file", (voidP) (new std::string("")), ECF::STRING);
00016 }
00017 
00018 
00019 bool StatCalc::initialize(StateP state)
00020 {
00021     state_ = state;
00022     average_.clear();
00023     stdDev_.clear();
00024     max_.clear();
00025     min_.clear();
00026     time_.clear();
00027     sampleSize_.clear();
00028 
00029     if(state->getRegistry()->isModified("stats.file")) {
00030         voidP sptr = state->getRegistry()->getEntry("stats.file");
00031         statsFileName_ = *((std::string*) sptr.get());
00032 
00033         statsFile_.open(statsFileName_.c_str());
00034         if(!statsFile_) {
00035             throw std::string("Error: can't open stats file (") + statsFileName_ + ")";
00036         }
00037     }
00038     return true;
00039 }
00040 
00041 
00042 double StatCalc::getFitnessMin(int generation)
00043 {
00044     if(generation == -1)
00045         generation = statNo;
00046     return min_[generation];
00047 }
00048 
00049 
00050 double StatCalc::getFitnessMax(int generation)
00051 {
00052     if(generation == -1)
00053         generation = statNo;
00054     return max_[generation];
00055 }
00056 
00057 
00058 bool StatCalc::operate(const std::vector<IndividualP>& pool)
00059 {
00060     std::vector<double> fitnessTemp;
00061 
00062     sampleSize_.push_back((uint)pool.size());
00063     fitnessTemp.resize(pool.size());
00064 
00065     for(uint i = 0; i < pool.size(); i++) 
00066         fitnessTemp[i] = pool[i]->fitness->getValue();
00067 
00068     max_.push_back(fitnessTemp[0]);
00069     min_.push_back(fitnessTemp[0]);
00070     statNo = (uint) max_.size() - 1;
00071     double sum = 0;
00072 
00073     for(uint i = 0; i < fitnessTemp.size(); i++) {
00074         if(fitnessTemp[i] > max_[statNo]) {
00075             max_[statNo] = fitnessTemp[i];
00076         }
00077         if(fitnessTemp[i] < min_[statNo]) {
00078             min_[statNo] = fitnessTemp[i];
00079         }
00080         sum += fitnessTemp[i];
00081     }
00082 
00083     average_.push_back(sum / fitnessTemp.size());
00084 
00085     if(fitnessTemp.size() > 1) {
00086         double numerator = 0, denominator;
00087         for(uint i = 0; i < fitnessTemp.size(); i++) {
00088             numerator += ((fitnessTemp[i] - average_[statNo]) * (fitnessTemp[i] - average_[statNo]));
00089         }
00090         denominator = (fitnessTemp.size() - 1);
00091         stdDev_.push_back(sqrt(numerator / denominator));
00092     }
00093     else
00094         stdDev_.push_back(fitnessTemp[0]);
00095 
00096     time_.push_back(state_->getElapsedTime());
00097 
00098     return true;
00099 }
00100 
00101 
00102 bool StatCalc::update(std::vector<double> stats)
00103 {
00104     double outMin = stats[0];
00105     double outMax = stats[1];
00106     double outAvg = stats[2];
00107     double outDev = stats[3];
00108     uint outSize = (uint) stats[4];
00109 
00110     if(outMin < min_.back())
00111         min_.back() = outMin;
00112     
00113     if(outMax > max_.back())
00114         max_.back() = outMax;
00115 
00116     uint mySize = sampleSize_.back();
00117     if(mySize > 1) {
00118         sampleSize_.back() = mySize + outSize;
00119         double myAvg = average_.back();
00120         double newAvg = (myAvg * mySize + outAvg * outSize) / sampleSize_.back();
00121         average_.back() = newAvg;
00122 
00123         uint totSize = sampleSize_.back();
00124         double mySum = myAvg * mySize;
00125         double outSum = outAvg * outSize;
00126         double totSum = mySum + outSum;
00127         double mySumSqr = pow(stdDev_.back(), 2) * mySize + mySum / mySize * mySum;
00128         double outSumSqr = outDev * outDev * outSize + outSum / outSize * outSum;
00129         double newDev = sqrt((mySumSqr + outSumSqr - (totSum / totSize * totSum)) / totSize);
00130         stdDev_.back() = newDev;
00131     }
00132     else {
00133         average_.back() = outAvg;
00134         stdDev_.back() = outDev;
00135         sampleSize_.back() = outSize;
00136     }
00137 
00138     return true;
00139 }
00140 
00141 
00142 std::vector<double> StatCalc::getStats(int gen)
00143 {
00144     if(gen == -1)
00145         gen = statNo;
00146 
00147     std::vector<double> stats;
00148     stats.push_back(min_[gen]);
00149     stats.push_back(max_[gen]);
00150     stats.push_back(average_[gen]);
00151     stats.push_back(stdDev_[gen]);
00152     stats.push_back(sampleSize_[gen]);
00153     stats.push_back(time_[gen]);
00154 
00155     return stats;
00156 }
00157 
00158 
00159 void StatCalc::log(int generation)
00160 {
00161     if(generation == -1)
00162         generation = statNo;
00163 
00164     ECF_LOG(state_, 3, "Stats: fitness\n\tmax: " + dbl2str(max_[generation]) + "\n\tmin: " +
00165         dbl2str(min_[generation]) + "\n\tavg: " + dbl2str(average_[generation]) + "\n\tstdev: " + 
00166         dbl2str(stdDev_[generation]));
00167 }
00168 
00169 
00170 // ispis tijeka min fitnesa - za potrebe mjerenja
00171 void StatCalc::output(uint step)
00172 {
00173     std::stringstream log;
00174     for(uint i = 0; i < min_.size(); i += step)
00175         log << i << "\t" << min_[i] << std::endl;
00176     ECF_LOG(state_, 2, log.str());
00177 }

Generated on Thu Oct 6 2011 13:41:01 for ECF by  doxygen 1.7.1