openModeller
Version 1.4.0
|
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 }