• Main Page
  • Related Pages
  • Classes
  • Files
  • Examples
  • File List
  • File Members

UncertaintyQuantification.cpp

Go to the documentation of this file.
00001 //===========================================================================
00046 //===========================================================================
00047 
00048 
00049 
00050 #include <iomanip>
00051 #include <vector>
00052 #include <EALib/UncertaintyQuantification.h>
00053 
00054 
00055 // Excel way to compute percentiles
00056 template<class T> double percentile(std::vector<T> v, double p =.25) {
00057     if (v.empty()) throw SHARKEXCEPTION("[percentile] list must not be empty");
00058     std::sort(v.begin(),v.end());
00059     unsigned N = v.size();
00060 
00061     double n = p * (double(N) - 1.0) + 1.0;
00062     unsigned k = unsigned(floor(n));
00063     double d = n - k;
00064     if(k == 0) return v[0];
00065     if(k == N) return v[N - 1];
00066 
00067     return v[k - 1] + d * (v[k] - v[k - 1]);
00068 }
00069 
00070 
00071 // data structure for reevaluation and re-ranking 
00072 struct RankingObject {
00073     RankingObject(double x, unsigned i) : fitnessOld(x), fitnessNew(x), index(i), reev(false) {};
00074     double fitnessOld;
00075     double fitnessNew;
00076     unsigned rankNew;
00077     unsigned rankOld;
00078     unsigned Delta;
00079     unsigned index;
00080     bool reev;
00081 };
00082 
00083 bool rankingObjectLessFitnessOld(const RankingObject &x, const RankingObject &y) {
00084     if(x.fitnessOld < y.fitnessOld) return true;
00085     return false;
00086 }
00087 bool rankingObjectLessFitnessNew(const RankingObject &x, const RankingObject &y) {
00088     if(x.fitnessNew < y.fitnessNew) return true;
00089     return false;
00090 }
00091 
00092 // computes the limit rank change depending on theta (step 5)
00093 double deltaLimTheta(unsigned R, unsigned l, double theta) {
00094     std::vector<double> v;
00095     // for a given rank R, the multi-set of all possible rank changes are computed
00096     for(unsigned i=1; i<(2*l-1); i++) v.push_back(fabs(double(i)-double(R)));
00097     // the theta/2 percentile of the multi-set is returned
00098     return percentile(v, 0.5 * theta);
00099 }
00100 
00101 // compute uncertainty level s
00102 double UncertaintyQuantification(Population& p, NoisyFitnessFunction& f, double theta, double r_l) {
00103     unsigned l = p.size();
00104     unsigned i;
00105 
00106     // initialize data structure for reevaluation and re-ranking (step 1)
00107     std::vector<RankingObject> v;
00108     for (i=0; i<l; i++) 
00109         v.push_back(RankingObject(p[i].getFitness(), i));
00110     for (i=0; i<l; i++) 
00111         v.push_back(RankingObject(p[i].getFitness(), i));
00112 
00113     // compute the number of solutions to be reevaluated (step 2)
00114     if (!r_l) r_l = Shark::max(0.1, 2.0 / l);
00115     unsigned l_reev = unsigned(floor(r_l * l));
00116     if (Rng::coinToss(r_l * l - floor(r_l * l))) l_reev++;
00117 
00118     // reevaluate first l_reev individuals (step 3)
00119     // no perturbation is applied, does not work for frozen noise
00120     for (i=0; i<l_reev; i++) {
00121         v[i].fitnessNew = f.fitness(dynamic_cast< std::vector< double >& >(p[i][0]));
00122         v[i].reev = true;
00123     }
00124 
00125     // compute rank using original fitness
00126     std::sort(v.begin(), v.end(), &rankingObjectLessFitnessOld);
00127     for (i=0; i<2*l; i++) v[i].rankOld = i+1;
00128 
00129     // compute rank using reevaluated fitness
00130     std::sort(v.begin(), v.end(), &rankingObjectLessFitnessNew);
00131     for (i=0; i<2*l; i++) v[i].rankNew = i+1;
00132 
00133     // compute absoulte rank change, i.e., how many ranks lie strictly
00134     // between old and new rank (step 4)
00135     for (i=0; i<2*l; i++) {
00136         v[i].Delta = (unsigned) abs(int(v[i].rankNew) - int(v[i].rankOld));
00137         if (v[i].Delta) v[i].Delta -= 1;
00138     }
00139 
00140     // compute uncertainty level (step 5)
00141     double s = 0.;
00142     for (i=0; i<2*l; i++) {
00143         if(v[i].reev) { // loop over reevaluated individuals
00144             // avaerage the fitness of the reevaluated individuals
00145             // this is done instead of the re-ranking (step 6)
00146             p[ v[i].index] .setFitness(.5*(v[i].fitnessNew + v[i].fitnessOld));
00147             s += 2 * v[i].Delta;
00148             if(v[i].fitnessNew > v[i].fitnessOld) {
00149                 s -= deltaLimTheta(v[i].rankNew - 1, l, theta);
00150                 s -= deltaLimTheta(v[i].rankOld, l, theta);
00151             } else if(v[i].fitnessOld > v[i].fitnessNew) {
00152                 s -= deltaLimTheta(v[i].rankNew, l, theta);
00153                 s -= deltaLimTheta(v[i].rankOld - 1, l, theta);
00154             } else{
00155                 s -= deltaLimTheta(v[i].rankNew, l, theta);
00156                 s -= deltaLimTheta(v[i].rankOld, l, theta);
00157             }
00158         }
00159     }
00160     s /= l_reev;
00161 
00162     return s;
00163 }
  • Shark Main Page
  • Array
  • Rng
  • LinAlg
  • FileUtil
  • EALib
  • MOO-EALib
  • ReClaM
  • Fuzzy
  • Mixture
  • Tutorials
  • FAQ