openModeller  Version 1.4.0
ruleset.cpp
Go to the documentation of this file.
00001 
00036 #include <openmodeller/Random.hh>
00037 #include <math.h>
00038 #include <string.h>
00039 
00040 #include <openmodeller/Log.hh>
00041 
00042 #include "ruleset.hh"
00043 #include "rules_base.hh"
00044 
00045 
00046 /****************************************************************/
00047 /****************** GarpRuleSet class ***************************/
00048 /****************************************************************/
00049 
00050 
00051 /****************************************************************/
00052 /****************** Constructor *********************************/
00053 
00054 GarpRuleSet::GarpRuleSet(int size)
00055 {
00056   _size = size;
00057   _rules = new GarpRule*[size];
00058   _numRules = 0;
00059   memset(_rules, 0, size * sizeof(GarpRule*));
00060 }
00061 
00062 
00063 /****************************************************************/
00064 /****************** Destructor **********************************/
00065 
00066 GarpRuleSet::~GarpRuleSet()
00067 {
00068   clear();
00069   delete [] _rules;
00070 }
00071 
00072 /****************************************************************/
00073 /****************** size ****************************************/
00074 
00075 int GarpRuleSet::size()
00076 { 
00077   return _size; 
00078 }
00079 
00080 /****************************************************************/
00081 /****************** numRules ************************************/
00082 
00083 int GarpRuleSet::numRules()
00084 { 
00085   return _numRules; 
00086 }
00087 
00088 /****************************************************************/
00089 /****************** clear ***************************************/
00090 
00091 void GarpRuleSet::clear()
00092 { 
00093   trim(0); 
00094 }
00095 
00096 /****************************************************************/
00097 /****************** trim ****************************************/
00098 
00099 void GarpRuleSet::trim(int rules)
00100 {
00101   int i;
00102 
00103   if (rules >= _numRules)
00104     // there are less rules than specified: nothing to do
00105     return;
00106 
00107   for (i = rules; i < _size; i++)
00108   {
00109     if (_rules[i]) 
00110       {
00111         delete _rules[i];
00112         _rules[i] = NULL;
00113       }
00114   }
00115 
00116   _numRules = rules;
00117 }
00118 
00119 /****************************************************************/
00120 /****************** filter **************************************/
00121 
00122 void GarpRuleSet::filter(PerfIndex index, double threshold)
00123 {
00124   int i, j;
00125   
00126   i = 0;
00127   while (i < _numRules)
00128     {
00129       //printf("%3d] Performance: %+8.4f (threshold=%+8.4f) - ", 
00130       //      i, _rules[i]->getPerformance(index), threshold);
00131 
00132       if (_rules[i]->getPerformance(index) < threshold)
00133   {
00134     //printf("deleting\n");
00135 
00136     // this rule has not enough performance
00137     // delete rule 
00138     delete _rules[i];
00139     
00140     // and shift rules up
00141     for (j = i; j < _numRules - 1; j++)
00142       _rules[j] = _rules[j + 1];
00143     
00144     // remove the duplicated reference to the last rule
00145     _rules[_numRules - 1] = NULL;
00146     
00147     // update the number of rules in this set
00148     // no need to increment <i> because the rules were shifted up one position
00149     _numRules--;
00150   }
00151       else
00152   {
00153     //printf("keeping\n");
00154 
00155     // this rule passed the test
00156     // go to the next one
00157     i++;
00158   }
00159     }
00160 }
00161 
00162 /****************************************************************/
00163 /****************** insert **************************************/
00164 
00165 int GarpRuleSet::insert(PerfIndex perfIndex, GarpRule * rule)
00166 {
00167   double newRulePerformance;
00168   int i, j;
00169 
00170   // insert rule and keep set sorted by performance index specified (_performance[perfIndex])
00171   // find place where rule should be inserted
00172   newRulePerformance = rule->getPerformance(perfIndex);
00173   for (i = 0; i < _numRules; i++)
00174   { 
00175     /*
00176     printf("Perfs[%3d/%3d]: (%+8.4f > %+8.4f)? %2d\n", i, _numRules, 
00177      newRulePerformance, _rules[i]->getPerformance(perfIndex),
00178      (newRulePerformance > _rules[i]->getPerformance(perfIndex)));
00179     */
00180 
00181     if (newRulePerformance > _rules[i]->getPerformance(perfIndex))
00182       break;
00183   }
00184 
00185   // <i> has the index where new rule should be inserted
00186   // move remaining rules one position down
00187   // and insert new rule at index <i>
00188   for (j = _numRules - 1; j >= i; j--)
00189   { _rules[j + 1] = _rules[j]; }
00190 
00191   _rules[i] = rule;
00192 
00193   _numRules++;
00194 
00195   return i;
00196 }
00197 
00198 /****************************************************************/
00199 /****************** get *****************************************/
00200 
00201 GarpRule * GarpRuleSet::get(int index)
00202 { 
00203   if (index >= 0 || index < _numRules)
00204     return _rules[index];
00205   else
00206     return NULL;
00207 }
00208 
00209 /****************************************************************/
00210 /****************** replace *************************************/
00211 
00212 int GarpRuleSet::replace(int index, GarpRule * rule)
00213 {
00214   if (!rule || index < 0 || index >= _numRules) 
00215     return 0;
00216 
00217   delete _rules[index];
00218   _rules[index] = rule;
00219   return 1;
00220 }
00221 
00222 /****************************************************************/
00223 /****************** remove **************************************/
00224 
00225 int GarpRuleSet::remove(int index)
00226 {
00227   if (index < 0 || index >= _numRules) 
00228     return 0;
00229 
00230   delete _rules[index];
00231 
00232   int i;
00233   for (i = index; i < _numRules - 1; i++)
00234     _rules[i] = _rules[i + 1];
00235 
00236   _rules[--_numRules] = NULL;
00237 
00238   return 1;
00239 }
00240 
00241 /****************************************************************/
00242 /****************** add *****************************************/
00243 
00244 int GarpRuleSet::add(GarpRule * rule)
00245 {
00246   if ( rule ) {
00247 
00248     if ( _numRules < _size ) {
00249 
00250       _rules[_numRules++] = rule;
00251       return _numRules;
00252     }
00253     else {
00254       // "Cannot add rule. Ruleset is full"
00255       return 0;
00256     }
00257   }
00258   else {
00259     // Cannot add null rule
00260     return 0;
00261   }
00262 }
00263 
00264 /****************************************************************/
00265 /****************** findSimilar *********************************/
00266 
00267 int GarpRuleSet::findSimilar(GarpRule * rule)
00268 {
00269   int i;
00270   for ( i = 0; i < _numRules; i++ ) {
00271 
00272     if ( _rules[i]->similar(rule) ) { 
00273 
00274       return i; 
00275     }
00276   }
00277 
00278   return -1;
00279 }
00280 
00281 /****************************************************************/
00282 /****************** getValue ************************************/
00283 
00284 
00285 Scalar GarpRuleSet::getValue(const Sample& x) const
00286 {
00287   int i;
00288 
00289   for ( i = 0; i < _numRules; i++ ) {
00290 
00291     if (_rules[i]->applies(x)) {
00292 
00293       //return i / (double) _numRules;
00294       return _rules[i]->getPrediction();
00295     }
00296   }
00297 
00298   return 0.0;
00299 }
00300 
00301 /****************************************************************/
00302 /*************** performanceSummary *****************************/
00303 
00304 void GarpRuleSet::performanceSummary(PerfIndex perfIndex, 
00305              double * best, 
00306              double * worst, 
00307              double * average)
00308 {
00309   int i;
00310   double performance;
00311 
00312   *worst = *best = *average = 0.0;
00313 
00314   if (!_numRules)
00315     return;
00316 
00317   for (i = 0; i < _numRules; i++)
00318     {
00319       performance = _rules[i]->getPerformance(perfIndex);
00320       
00321       if (performance < *worst || !i) *worst = performance;
00322       if (performance > *best  || !i) *best  = performance;
00323       *average += performance;
00324     }
00325 
00326   *average /= _numRules;
00327 }
00328 
00329 /****************************************************************/
00330 /****************** log *****************************************/
00331 
00332 void GarpRuleSet::log() const
00333 {
00334   for ( int i = 0; i < _numRules; i++ )
00335     {
00336       Log::instance()->info( "%2d] ", i );
00337       _rules[i]->log();
00338     }
00339 }
00340 
00341 // ==============================================================
00342 
00343 // gather rule set statistics
00344 void GarpRuleSet::gatherRuleSetStats(int gen)
00345 {
00346   char type='0'; //initialise to some invalid value
00347 
00348   printf("%4d]", gen);
00349 
00350   for (int i = 0; i < 3; i++)
00351   {
00352     switch (i)
00353     {
00354       case 0: type ='d'; break;
00355       case 1: type ='!'; break;
00356       case 2: type ='r'; break;
00357   //case 3: type ='a'; break;
00358     }
00359 
00360     double max = -10000;
00361     double sum = 0;
00362     int ct = 0;
00363     int pres = 0;
00364     for (int j = 0; j < _numRules; j++)
00365     {
00366       GarpRule * rule = _rules[j];
00367       if (rule->type() == type)
00368       {
00369         ct++;
00370         sum += rule->getPerformance(PerfUtil);
00371   pres += (int) rule->getPrediction();
00372   if (max < rule->getPerformance(PerfUtil))
00373     max = rule->getPerformance(PerfUtil);
00374       }
00375     }
00376 
00377     if (max == -10000)
00378       max = 0;
00379 
00380     printf("%c %2d %+7.2f %+7.2f %2d|", type, ct, max, sum / ct, pres);
00381   }
00382 
00383   printf("\n");
00384 }