PageRenderTime 28ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/src/algorithms/garp/ruleset.cpp

https://gitlab.com/renato.rotenberg/openmoddler-provenience
C++ | 384 lines | 203 code | 84 blank | 97 comment | 40 complexity | 7e793d4a4166943ee0258f5131d7a00a MD5 | raw file
  1. /**
  2. * Declaration of Rule-sets used by GARP
  3. *
  4. * @file ruleset.cpp
  5. * @author Ricardo Scachetti Pereira (rpereira@ku.edu)
  6. * @date 2004-04-02
  7. * $Id: ruleset.cpp 5573 2012-07-13 14:25:27Z dbolgheroni $
  8. *
  9. * LICENSE INFORMATION
  10. *
  11. * Copyright(c), The Center for Research, University of Kansas,
  12. * 2385 Irving Hill Road, Lawrence, KS 66044-4755, USA.
  13. * Copyright(c), David R.B. Stockwell of Symbiotik Pty. Ltd.
  14. * Copyright(c), CRIA - Centro de Referencia em Informacao Ambiental
  15. *
  16. * http://www.nhm.ku.edu
  17. *
  18. * This program is free software; you can redistribute it and/or
  19. * modify it under the terms of the GNU General Public License
  20. * as published by the Free Software Foundation; either version 2
  21. * of the License, or (at your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU General Public License for more details:
  27. *
  28. * http://www.gnu.org/copyleft/gpl.html
  29. *
  30. * This is an implementation of the GARP algorithm first developed
  31. * by David Stockwell
  32. *
  33. */
  34. #include <openmodeller/Random.hh>
  35. #include <math.h>
  36. #include <string.h>
  37. #include <openmodeller/Log.hh>
  38. #include "ruleset.hh"
  39. #include "rules_base.hh"
  40. /****************************************************************/
  41. /****************** GarpRuleSet class ***************************/
  42. /****************************************************************/
  43. /****************************************************************/
  44. /****************** Constructor *********************************/
  45. GarpRuleSet::GarpRuleSet(int size)
  46. {
  47. _size = size;
  48. _rules = new GarpRule*[size];
  49. _numRules = 0;
  50. memset(_rules, 0, size * sizeof(GarpRule*));
  51. }
  52. /****************************************************************/
  53. /****************** Destructor **********************************/
  54. GarpRuleSet::~GarpRuleSet()
  55. {
  56. clear();
  57. delete [] _rules;
  58. }
  59. /****************************************************************/
  60. /****************** size ****************************************/
  61. int GarpRuleSet::size()
  62. {
  63. return _size;
  64. }
  65. /****************************************************************/
  66. /****************** numRules ************************************/
  67. int GarpRuleSet::numRules()
  68. {
  69. return _numRules;
  70. }
  71. /****************************************************************/
  72. /****************** clear ***************************************/
  73. void GarpRuleSet::clear()
  74. {
  75. trim(0);
  76. }
  77. /****************************************************************/
  78. /****************** trim ****************************************/
  79. void GarpRuleSet::trim(int rules)
  80. {
  81. int i;
  82. if (rules >= _numRules)
  83. // there are less rules than specified: nothing to do
  84. return;
  85. for (i = rules; i < _size; i++)
  86. {
  87. if (_rules[i])
  88. {
  89. delete _rules[i];
  90. _rules[i] = NULL;
  91. }
  92. }
  93. _numRules = rules;
  94. }
  95. /****************************************************************/
  96. /****************** filter **************************************/
  97. void GarpRuleSet::filter(PerfIndex index, double threshold)
  98. {
  99. int i, j;
  100. i = 0;
  101. while (i < _numRules)
  102. {
  103. //printf("%3d] Performance: %+8.4f (threshold=%+8.4f) - ",
  104. // i, _rules[i]->getPerformance(index), threshold);
  105. if (_rules[i]->getPerformance(index) < threshold)
  106. {
  107. //printf("deleting\n");
  108. // this rule has not enough performance
  109. // delete rule
  110. delete _rules[i];
  111. // and shift rules up
  112. for (j = i; j < _numRules - 1; j++)
  113. _rules[j] = _rules[j + 1];
  114. // remove the duplicated reference to the last rule
  115. _rules[_numRules - 1] = NULL;
  116. // update the number of rules in this set
  117. // no need to increment <i> because the rules were shifted up one position
  118. _numRules--;
  119. }
  120. else
  121. {
  122. //printf("keeping\n");
  123. // this rule passed the test
  124. // go to the next one
  125. i++;
  126. }
  127. }
  128. }
  129. /****************************************************************/
  130. /****************** insert **************************************/
  131. int GarpRuleSet::insert(PerfIndex perfIndex, GarpRule * rule)
  132. {
  133. double newRulePerformance;
  134. int i, j;
  135. // insert rule and keep set sorted by performance index specified (_performance[perfIndex])
  136. // find place where rule should be inserted
  137. newRulePerformance = rule->getPerformance(perfIndex);
  138. for (i = 0; i < _numRules; i++)
  139. {
  140. /*
  141. printf("Perfs[%3d/%3d]: (%+8.4f > %+8.4f)? %2d\n", i, _numRules,
  142. newRulePerformance, _rules[i]->getPerformance(perfIndex),
  143. (newRulePerformance > _rules[i]->getPerformance(perfIndex)));
  144. */
  145. if (newRulePerformance > _rules[i]->getPerformance(perfIndex))
  146. break;
  147. }
  148. // <i> has the index where new rule should be inserted
  149. // move remaining rules one position down
  150. // and insert new rule at index <i>
  151. for (j = _numRules - 1; j >= i; j--)
  152. { _rules[j + 1] = _rules[j]; }
  153. _rules[i] = rule;
  154. _numRules++;
  155. return i;
  156. }
  157. /****************************************************************/
  158. /****************** get *****************************************/
  159. GarpRule * GarpRuleSet::get(int index)
  160. {
  161. if (index >= 0 || index < _numRules)
  162. return _rules[index];
  163. else
  164. return NULL;
  165. }
  166. /****************************************************************/
  167. /****************** replace *************************************/
  168. int GarpRuleSet::replace(int index, GarpRule * rule)
  169. {
  170. if (!rule || index < 0 || index >= _numRules)
  171. return 0;
  172. delete _rules[index];
  173. _rules[index] = rule;
  174. return 1;
  175. }
  176. /****************************************************************/
  177. /****************** remove **************************************/
  178. int GarpRuleSet::remove(int index)
  179. {
  180. if (index < 0 || index >= _numRules)
  181. return 0;
  182. delete _rules[index];
  183. int i;
  184. for (i = index; i < _numRules - 1; i++)
  185. _rules[i] = _rules[i + 1];
  186. _rules[--_numRules] = NULL;
  187. return 1;
  188. }
  189. /****************************************************************/
  190. /****************** add *****************************************/
  191. int GarpRuleSet::add(GarpRule * rule)
  192. {
  193. if ( rule ) {
  194. if ( _numRules < _size ) {
  195. _rules[_numRules++] = rule;
  196. return _numRules;
  197. }
  198. else {
  199. // "Cannot add rule. Ruleset is full"
  200. return 0;
  201. }
  202. }
  203. else {
  204. // Cannot add null rule
  205. return 0;
  206. }
  207. }
  208. /****************************************************************/
  209. /****************** findSimilar *********************************/
  210. int GarpRuleSet::findSimilar(GarpRule * rule)
  211. {
  212. int i;
  213. for ( i = 0; i < _numRules; i++ ) {
  214. if ( _rules[i]->similar(rule) ) {
  215. return i;
  216. }
  217. }
  218. return -1;
  219. }
  220. /****************************************************************/
  221. /****************** getValue ************************************/
  222. Scalar GarpRuleSet::getValue(const Sample& x) const
  223. {
  224. int i;
  225. for ( i = 0; i < _numRules; i++ ) {
  226. if (_rules[i]->applies(x)) {
  227. //return i / (double) _numRules;
  228. return _rules[i]->getPrediction();
  229. }
  230. }
  231. return 0.0;
  232. }
  233. /****************************************************************/
  234. /*************** performanceSummary *****************************/
  235. void GarpRuleSet::performanceSummary(PerfIndex perfIndex,
  236. double * best,
  237. double * worst,
  238. double * average)
  239. {
  240. int i;
  241. double performance;
  242. *worst = *best = *average = 0.0;
  243. if (!_numRules)
  244. return;
  245. for (i = 0; i < _numRules; i++)
  246. {
  247. performance = _rules[i]->getPerformance(perfIndex);
  248. if (performance < *worst || !i) *worst = performance;
  249. if (performance > *best || !i) *best = performance;
  250. *average += performance;
  251. }
  252. *average /= _numRules;
  253. }
  254. /****************************************************************/
  255. /****************** log *****************************************/
  256. void GarpRuleSet::log() const
  257. {
  258. for ( int i = 0; i < _numRules; i++ )
  259. {
  260. Log::instance()->info( "%2d] ", i );
  261. _rules[i]->log();
  262. }
  263. }
  264. // ==============================================================
  265. // gather rule set statistics
  266. void GarpRuleSet::gatherRuleSetStats(int gen)
  267. {
  268. char type='0'; //initialise to some invalid value
  269. printf("%4d]", gen);
  270. for (int i = 0; i < 3; i++)
  271. {
  272. switch (i)
  273. {
  274. case 0: type ='d'; break;
  275. case 1: type ='!'; break;
  276. case 2: type ='r'; break;
  277. //case 3: type ='a'; break;
  278. }
  279. double max = -10000;
  280. double sum = 0;
  281. int ct = 0;
  282. int pres = 0;
  283. for (int j = 0; j < _numRules; j++)
  284. {
  285. GarpRule * rule = _rules[j];
  286. if (rule->type() == type)
  287. {
  288. ct++;
  289. sum += rule->getPerformance(PerfUtil);
  290. pres += (int) rule->getPrediction();
  291. if (max < rule->getPerformance(PerfUtil))
  292. max = rule->getPerformance(PerfUtil);
  293. }
  294. }
  295. if (max == -10000)
  296. max = 0;
  297. printf("%c %2d %+7.2f %+7.2f %2d|", type, ct, max, sum / ct, pres);
  298. }
  299. printf("\n");
  300. }