/src/algorithms/garp/ruleset.cpp
C++ | 384 lines | 203 code | 84 blank | 97 comment | 40 complexity | 7e793d4a4166943ee0258f5131d7a00a MD5 | raw file
- /**
- * Declaration of Rule-sets used by GARP
- *
- * @file ruleset.cpp
- * @author Ricardo Scachetti Pereira (rpereira@ku.edu)
- * @date 2004-04-02
- * $Id: ruleset.cpp 5573 2012-07-13 14:25:27Z dbolgheroni $
- *
- * LICENSE INFORMATION
- *
- * Copyright(c), The Center for Research, University of Kansas,
- * 2385 Irving Hill Road, Lawrence, KS 66044-4755, USA.
- * Copyright(c), David R.B. Stockwell of Symbiotik Pty. Ltd.
- * Copyright(c), CRIA - Centro de Referencia em Informacao Ambiental
- *
- * http://www.nhm.ku.edu
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * http://www.gnu.org/copyleft/gpl.html
- *
- * This is an implementation of the GARP algorithm first developed
- * by David Stockwell
- *
- */
- #include <openmodeller/Random.hh>
- #include <math.h>
- #include <string.h>
- #include <openmodeller/Log.hh>
- #include "ruleset.hh"
- #include "rules_base.hh"
- /****************************************************************/
- /****************** GarpRuleSet class ***************************/
- /****************************************************************/
- /****************************************************************/
- /****************** Constructor *********************************/
- GarpRuleSet::GarpRuleSet(int size)
- {
- _size = size;
- _rules = new GarpRule*[size];
- _numRules = 0;
- memset(_rules, 0, size * sizeof(GarpRule*));
- }
- /****************************************************************/
- /****************** Destructor **********************************/
- GarpRuleSet::~GarpRuleSet()
- {
- clear();
- delete [] _rules;
- }
- /****************************************************************/
- /****************** size ****************************************/
- int GarpRuleSet::size()
- {
- return _size;
- }
- /****************************************************************/
- /****************** numRules ************************************/
- int GarpRuleSet::numRules()
- {
- return _numRules;
- }
- /****************************************************************/
- /****************** clear ***************************************/
- void GarpRuleSet::clear()
- {
- trim(0);
- }
- /****************************************************************/
- /****************** trim ****************************************/
- void GarpRuleSet::trim(int rules)
- {
- int i;
- if (rules >= _numRules)
- // there are less rules than specified: nothing to do
- return;
- for (i = rules; i < _size; i++)
- {
- if (_rules[i])
- {
- delete _rules[i];
- _rules[i] = NULL;
- }
- }
- _numRules = rules;
- }
- /****************************************************************/
- /****************** filter **************************************/
- void GarpRuleSet::filter(PerfIndex index, double threshold)
- {
- int i, j;
-
- i = 0;
- while (i < _numRules)
- {
- //printf("%3d] Performance: %+8.4f (threshold=%+8.4f) - ",
- // i, _rules[i]->getPerformance(index), threshold);
- if (_rules[i]->getPerformance(index) < threshold)
- {
- //printf("deleting\n");
- // this rule has not enough performance
- // delete rule
- delete _rules[i];
-
- // and shift rules up
- for (j = i; j < _numRules - 1; j++)
- _rules[j] = _rules[j + 1];
-
- // remove the duplicated reference to the last rule
- _rules[_numRules - 1] = NULL;
-
- // update the number of rules in this set
- // no need to increment <i> because the rules were shifted up one position
- _numRules--;
- }
- else
- {
- //printf("keeping\n");
- // this rule passed the test
- // go to the next one
- i++;
- }
- }
- }
- /****************************************************************/
- /****************** insert **************************************/
- int GarpRuleSet::insert(PerfIndex perfIndex, GarpRule * rule)
- {
- double newRulePerformance;
- int i, j;
- // insert rule and keep set sorted by performance index specified (_performance[perfIndex])
- // find place where rule should be inserted
- newRulePerformance = rule->getPerformance(perfIndex);
- for (i = 0; i < _numRules; i++)
- {
- /*
- printf("Perfs[%3d/%3d]: (%+8.4f > %+8.4f)? %2d\n", i, _numRules,
- newRulePerformance, _rules[i]->getPerformance(perfIndex),
- (newRulePerformance > _rules[i]->getPerformance(perfIndex)));
- */
- if (newRulePerformance > _rules[i]->getPerformance(perfIndex))
- break;
- }
- // <i> has the index where new rule should be inserted
- // move remaining rules one position down
- // and insert new rule at index <i>
- for (j = _numRules - 1; j >= i; j--)
- { _rules[j + 1] = _rules[j]; }
- _rules[i] = rule;
- _numRules++;
- return i;
- }
- /****************************************************************/
- /****************** get *****************************************/
- GarpRule * GarpRuleSet::get(int index)
- {
- if (index >= 0 || index < _numRules)
- return _rules[index];
- else
- return NULL;
- }
- /****************************************************************/
- /****************** replace *************************************/
- int GarpRuleSet::replace(int index, GarpRule * rule)
- {
- if (!rule || index < 0 || index >= _numRules)
- return 0;
- delete _rules[index];
- _rules[index] = rule;
- return 1;
- }
- /****************************************************************/
- /****************** remove **************************************/
- int GarpRuleSet::remove(int index)
- {
- if (index < 0 || index >= _numRules)
- return 0;
- delete _rules[index];
- int i;
- for (i = index; i < _numRules - 1; i++)
- _rules[i] = _rules[i + 1];
- _rules[--_numRules] = NULL;
- return 1;
- }
- /****************************************************************/
- /****************** add *****************************************/
- int GarpRuleSet::add(GarpRule * rule)
- {
- if ( rule ) {
- if ( _numRules < _size ) {
- _rules[_numRules++] = rule;
- return _numRules;
- }
- else {
- // "Cannot add rule. Ruleset is full"
- return 0;
- }
- }
- else {
- // Cannot add null rule
- return 0;
- }
- }
- /****************************************************************/
- /****************** findSimilar *********************************/
- int GarpRuleSet::findSimilar(GarpRule * rule)
- {
- int i;
- for ( i = 0; i < _numRules; i++ ) {
- if ( _rules[i]->similar(rule) ) {
- return i;
- }
- }
- return -1;
- }
- /****************************************************************/
- /****************** getValue ************************************/
- Scalar GarpRuleSet::getValue(const Sample& x) const
- {
- int i;
- for ( i = 0; i < _numRules; i++ ) {
- if (_rules[i]->applies(x)) {
- //return i / (double) _numRules;
- return _rules[i]->getPrediction();
- }
- }
- return 0.0;
- }
- /****************************************************************/
- /*************** performanceSummary *****************************/
- void GarpRuleSet::performanceSummary(PerfIndex perfIndex,
- double * best,
- double * worst,
- double * average)
- {
- int i;
- double performance;
- *worst = *best = *average = 0.0;
- if (!_numRules)
- return;
- for (i = 0; i < _numRules; i++)
- {
- performance = _rules[i]->getPerformance(perfIndex);
-
- if (performance < *worst || !i) *worst = performance;
- if (performance > *best || !i) *best = performance;
- *average += performance;
- }
- *average /= _numRules;
- }
- /****************************************************************/
- /****************** log *****************************************/
- void GarpRuleSet::log() const
- {
- for ( int i = 0; i < _numRules; i++ )
- {
- Log::instance()->info( "%2d] ", i );
- _rules[i]->log();
- }
- }
- // ==============================================================
- // gather rule set statistics
- void GarpRuleSet::gatherRuleSetStats(int gen)
- {
- char type='0'; //initialise to some invalid value
- printf("%4d]", gen);
- for (int i = 0; i < 3; i++)
- {
- switch (i)
- {
- case 0: type ='d'; break;
- case 1: type ='!'; break;
- case 2: type ='r'; break;
- //case 3: type ='a'; break;
- }
- double max = -10000;
- double sum = 0;
- int ct = 0;
- int pres = 0;
- for (int j = 0; j < _numRules; j++)
- {
- GarpRule * rule = _rules[j];
- if (rule->type() == type)
- {
- ct++;
- sum += rule->getPerformance(PerfUtil);
- pres += (int) rule->getPrediction();
- if (max < rule->getPerformance(PerfUtil))
- max = rule->getPerformance(PerfUtil);
- }
- }
- if (max == -10000)
- max = 0;
- printf("%c %2d %+7.2f %+7.2f %2d|", type, ct, max, sum / ct, pres);
- }
- printf("\n");
- }