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
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 }