openModeller
Version 1.4.0
|
00001 00002 /* ************************************** 00003 * GARP Modeling Package 00004 * 00005 * ************************************** 00006 * 00007 * Copyright (c), The Center for Research, University of Kansas, 2385 Irving Hill Road, Lawrence, KS 66044-4755, USA. 00008 * Copyright (C), David R.B. Stockwell of Symbiotik Pty. Ltd. 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the license that is distributed with the software. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * license.txt file included with this software for more details. 00017 */ 00018 00019 // RuleSet.cpp : Implementation of CRuleSet 00020 00021 #ifdef WIN32 00022 // avoid warnings caused by problems in VC headers 00023 #define _SCL_SECURE_NO_DEPRECATE 00024 #endif 00025 00026 #include "Rule.h" 00027 #include "RuleSet.h" 00028 #include "EnvCell.h" 00029 #include "EnvCellSet.h" 00030 #include "Utilities.h" 00031 00032 // ========================================================================== 00033 // RuleSet implementation 00034 // ========================================================================== 00035 RuleSet::RuleSet() 00036 { 00037 // rule set starts empty (without rules) 00038 intRules = 0; 00039 00040 // reset rule pointers 00041 for (int i = 0; i < MAX_RULES; i++) 00042 objRules[i] = NULL; 00043 00044 // reset area counters 00045 iTotalArea = iPresenceArea = iAbsenceArea = iNonPredictedArea = 0; 00046 } 00047 00048 // ========================================================================== 00049 RuleSet::~RuleSet() 00050 { 00051 clear(); 00052 } 00053 00054 // ========================================================================== 00055 void RuleSet::clear() 00056 { 00057 for (int i = 0; i < intRules; i++) 00058 if (objRules[i]) 00059 { 00060 delete objRules[i]; 00061 objRules[i] = NULL; 00062 } 00063 00064 // rule set become empty (without rules) 00065 intRules = 0; 00066 00067 // reset area counters 00068 iTotalArea = iPresenceArea = iAbsenceArea = iNonPredictedArea = 0; 00069 } 00070 00071 // ========================================================================== 00072 void RuleSet::setActiveGenes(bool * bGeneIsActivePtr, int * iGeneIndexPtr, int iActiveGenesAux) 00073 { 00074 for (int i = 0; i < intRules; i++) 00075 { 00076 objRules[i]->bGeneIsActive = bGeneIsActivePtr; 00077 objRules[i]->iGeneIndex = iGeneIndexPtr; 00078 objRules[i]->iActiveGenes = iActiveGenesAux; 00079 } 00080 } 00081 00082 // ========================================================================== 00083 char * RuleSet::toXML(char * id) 00084 { 00085 /* XML Sample 00086 00087 <RuleSet Id="Best"> 00088 <Rule>...</Rule> 00089 . . 00090 . . 00091 . . 00092 <Rule>...</Rule> 00093 </RuleSet> 00094 */ 00095 00096 int i; 00097 int size; 00098 char * strXML, *strXMLRule; 00099 00100 size = (1024 * intRules) + 2048; 00101 strXML = new char[size]; 00102 00103 00104 // rules 00105 if (!id) 00106 strcpy(strXML, "<RuleSet>\n"); 00107 else 00108 sprintf(strXML, "<RuleSet Id=\"%s\">\n", id); 00109 00110 for (i = 0; i < intRules; i++) 00111 { 00112 strXMLRule = objRules[i]->toXML(); 00113 sprintf(strXML, "%s%s\n", strXML, strXMLRule); 00114 delete[] strXMLRule; 00115 } 00116 strcat(strXML, "</RuleSet>"); 00117 00118 // check string sizes 00119 if (strlen(strXML) > size_t(size)) 00120 throw GarpException(82, "String size exceeded in RuleSet::toXML()"); 00121 00122 // return result 00123 return strXML; 00124 } 00125 00126 // ========================================================================== 00127 void RuleSet::saveText(char * strSaveFilename) 00128 { 00129 FILE * outf; 00130 int i; 00131 00132 if (strcmp(strSaveFilename, "") == 0) 00133 throw GarpException(3, "Cannot save rule set with an empty filename"); 00134 00135 outf = fopen(strSaveFilename, "w"); 00136 00137 if (outf) 00138 { 00139 for (i = 0; i < intRules; i++) 00140 fprintf(outf, "%s\n", objRules[i]->toString()); 00141 00142 fclose(outf); 00143 } 00144 else 00145 { 00146 char msg[256]; 00147 sprintf(msg, "Rule set file <%s> could not be opened for writing", strSaveFilename); 00148 throw GarpException(4, msg); 00149 } 00150 } 00151 00152 // ========================================================================== 00153 Rule * RuleSet::get(int index) 00154 { return objRules[index]; } 00155 00156 // ========================================================================== 00157 int RuleSet::size() 00158 { return intRules; } 00159 00160 // ========================================================================== 00161 void RuleSet::set(int index, Rule * objRule) 00162 { objRules[index] = objRule; } 00163 00164 // ========================================================================== 00165 void RuleSet::add(Rule * objRule) 00166 { 00167 if (objRule) 00168 { 00169 if (intRules < MAX_RULES - 1) 00170 objRules[intRules++] = objRule; 00171 else 00172 throw GarpException(16, "Cannot add rule. Ruleset is full"); 00173 } 00174 else 00175 throw GarpException(17, "Cannot add null rule"); 00176 } 00177 00178 // ========================================================================== 00179 void RuleSet::trim(int intMaxRules) 00180 { 00181 int intInitialRules = intRules; 00182 for (int i = intMaxRules; i < intInitialRules; i++) 00183 { 00184 delete objRules[i]; 00185 objRules[i] = NULL; 00186 intRules--; 00187 } 00188 } 00189 00190 // ========================================================================== 00191 // Discard rules which performance (determined by the iPerfIndex) is less 00192 // than the specified dValue 00193 // ========================================================================== 00194 void RuleSet::discardRules(int iPerfIndex, double dValue) 00195 { 00196 int i, j; 00197 00198 i = 0; 00199 while (i < intRules) 00200 { 00201 if (!GarpUtil::equalEps(objRules[i]->dblPerformance[8], objRules[i]->_dSig, 0.0001)) 00202 throw GarpException(1, "The actual and calculated significance values of this rule do not match."); 00203 00204 if (objRules[i]->dblPerformance[iPerfIndex] < dValue) 00205 { 00206 // this rule has not enough performance 00207 // delete rule 00208 delete objRules[i]; 00209 00210 // and shift rules up 00211 for (j = i; j < intRules - 1; j++) 00212 objRules[j] = objRules[j + 1]; 00213 00214 // remove the duplicated reference to the last rule 00215 objRules[intRules - 1] = NULL; 00216 00217 // update the number of rules in this set 00218 // no need to increment <i> because the rules were shifted up one position 00219 intRules--; 00220 } 00221 else 00222 { 00223 // this rule passed the test 00224 // go to the next one 00225 i++; 00226 } 00227 } 00228 } 00229 00230 // ========================================================================== 00231 void RuleSet::setEvaluation(bool value) 00232 { 00233 for (int i = 0; i < intRules; i++) 00234 objRules[i]->blnNeedsEvaluation = value; 00235 } 00236 00237 // ========================================================================== 00238 void RuleSet::setPad(char pad) 00239 { 00240 for (int i = 0; i < intRules; i++) 00241 objRules[i]->chrPad = pad; 00242 } 00243 00244 // ========================================================================== 00245 int RuleSet::countPad(char pad) 00246 { 00247 int sum = 0; 00248 00249 for (int i = 0; i < intRules; i++) 00250 if (objRules[i]->chrPad == pad) 00251 sum++; 00252 00253 return sum; 00254 } 00255 00256 // ========================================================================== 00257 void RuleSet::sort(int intPerfIndex) 00258 { 00259 // sort the entire ruleset using the provided performance index 00260 // implemented using bubble sort (argh!!) to be improved 00261 Rule * temp; 00262 int i, j; 00263 00264 double dSum; 00265 00266 dSum = 0.0; 00267 for (i = 0; i < this->intRules; i++) 00268 dSum += objRules[i]->dblPerformance[9]; 00269 00270 for (i = 0; i < intRules - 1; i++) 00271 for (j = intRules - 1; j > i; j--) 00272 if (objRules[j]->dblPerformance[intPerfIndex] > objRules[j - 1]->dblPerformance[intPerfIndex]) 00273 { 00274 temp = objRules[j]; 00275 objRules[j] = objRules[j - 1]; 00276 objRules[j - 1] = temp; 00277 } 00278 } 00279 00280 // ========================================================================== 00281 void RuleSet::verify(EnvCellSet * objTestDataset, double dAccLimit) 00282 { 00283 EnvCell * cell; 00284 int iRuleIndex, iPredictedValue, iActualValue; 00285 int i, n; 00286 00287 double dSum; 00288 00289 dSum = 0.0; 00290 for (i = 0; i < this->intRules; i++) 00291 dSum += objRules[i]->dblPerformance[9]; 00292 00293 // init temp structures 00294 resetConfMatrix(objTestDataset); 00295 00296 n = objTestDataset->count(); 00297 for (i = 0; i < n; i++) 00298 { 00299 // apply rules to each cell in the dataset 00300 cell = objTestDataset->get(i); 00301 iRuleIndex = applyRulesToCell(cell, dAccLimit); 00302 00303 if (iRuleIndex >= 0) 00304 { 00305 // rule applies 00306 iPredictedValue = objRules[iRuleIndex]->Gene[0]; 00307 iActualValue = cell->values[0]; 00308 00309 addConfMatrix(iPredictedValue, iActualValue); 00310 } 00311 } 00312 00313 dSum = 0.0; 00314 for (i = 0; i < this->intRules; i++) 00315 dSum += objRules[i]->dblPerformance[9]; 00316 } 00317 00318 // ========================================================================== 00319 void RuleSet::resetConfMatrix(EnvCellSet * objTestDataset) 00320 { 00321 // init temp structures 00322 iConfMatrix[0][0] = 0; 00323 iConfMatrix[0][1] = 0; 00324 iConfMatrix[1][0] = 0; 00325 iConfMatrix[1][1] = 0; 00326 00327 iTotalPoints = objTestDataset->count(); 00328 } 00329 // ========================================================================== 00330 int RuleSet::getConfMatrix(int iPredictedValue, int iActualValue) 00331 { 00332 if ((iActualValue < 0) || (iActualValue > 1) || (iPredictedValue < 0) || (iPredictedValue > 1)) 00333 throw GarpException(1, "Confusion matrix index out of range"); 00334 00335 return iConfMatrix[iActualValue][iPredictedValue]; 00336 } 00337 00338 // ========================================================================== 00339 void RuleSet::addConfMatrix(int iPredictedValue, int iActualValue) 00340 { 00341 if ((iActualValue < 0) || (iActualValue > 1) || (iPredictedValue < 0) || (iPredictedValue > 1)) 00342 throw GarpException(1, "Confusion matrix index out of range"); 00343 00344 iConfMatrix[iActualValue][iPredictedValue]++; 00345 } 00346 00347 // ========================================================================== 00348 int RuleSet::getTotalPoints() 00349 { 00350 return iTotalPoints; 00351 } 00352 // ========================================================================== 00353 int RuleSet::getPredictedPoints() 00354 { 00355 return (iConfMatrix[0][0] + iConfMatrix[0][1] + iConfMatrix[1][0] + iConfMatrix[1][1]); 00356 } 00357 00358 // ========================================================================== 00359 int RuleSet::getUnpredictedPoints() 00360 { 00361 return getTotalPoints() - getPredictedPoints(); 00362 } 00363 00364 // ========================================================================== 00365 double RuleSet::getAccuracy() 00366 { 00367 return (double) (iConfMatrix[0][0] + iConfMatrix[1][1]) / (double) getPredictedPoints(); 00368 } 00369 // ========================================================================== 00370 double RuleSet::getOverallAccuracy() 00371 { 00372 return (double) (iConfMatrix[0][0] + iConfMatrix[1][1]) / (double) getTotalPoints(); 00373 } 00374 00375 // ========================================================================== 00376 void RuleSet::updateRuleUsage() 00377 { 00378 throw GarpException(131, "Method RuleSet::updateRuleUsage not implemented yet"); 00379 } 00380 00381 // ========================================================================== 00382 double RuleSet::getOveralPerformance(int iPerfIndex, int iFirstRulesToBeIncluded) 00383 { 00384 int i; 00385 double dResult, dWeight, dWSum; 00386 00387 dWSum = 0.0; 00388 dResult = 0.0; 00389 dWeight = (double) iFirstRulesToBeIncluded; 00390 00391 for (i = 0; i < iFirstRulesToBeIncluded; i++) 00392 { 00393 if (i < intRules) 00394 { 00395 dResult += objRules[i]->dblPerformance[iPerfIndex] * dWeight; 00396 dWSum += dWeight; 00397 dWeight--; 00398 00399 //dResult += objRules[i]->dblPerformance[iPerfIndex]; 00400 } 00401 else 00402 break; 00403 } 00404 00405 dResult /= dWSum; 00406 00407 return dResult; 00408 } 00409 00410 // ========================================================================== 00411 Scalar RuleSet::getValue(const Sample& sample) const 00412 { 00413 // convert values to EnvCell 00414 BYTE bytes[256]; 00415 EnvCell cell(_dim + 2, bytes); 00416 00417 // first element of bytes is reserved for presence/absence value 00418 for (int i = 1; i < _dim; i++) 00419 { 00420 // Guard against values outside the normalization range 00421 // due to reprojection to a non-native range 00422 Scalar value = sample[i - 1]; 00423 if (value > 253.0) value = 253.0; 00424 if (value < 1.0) value = 1.0; 00425 00426 bytes[i] = (BYTE) value; 00427 } 00428 00429 int ruleIndex = applyRulesToCell(&cell, 0.0); 00430 //printf(" Idx=%+2d Pred=%+4.1f\n", ruleIndex, (ruleIndex >= 0)? (Scalar) (objRules[ruleIndex]->Gene[0]) : -1.0); 00431 00432 if (ruleIndex >= 0) 00433 return (Scalar) (objRules[ruleIndex]->Gene[0]); 00434 00435 return 0.0; 00436 } 00437 00438 // ========================================================================== 00439 void RuleSet::log() 00440 { 00441 for ( int i = 0; i < intRules; i++ ) 00442 { 00443 printf( "%2d] ", i ); 00444 objRules[i]->log(); 00445 } 00446 } 00447 00448 /* 00449 // ========================================================================== 00450 void RuleSet::predict(EnvLayer * objPredictionLayer, EnvLayerSet * objPredictionArea, double Accuracylimit) 00451 { 00452 int row, col, pos; 00453 int intRows, intColumns, intSize; 00454 int ruleIndex; 00455 bool status; 00456 BYTE bytPred; 00457 EnvCell cell; 00458 BYTE values[MAX_ENV_LAYERS]; 00459 00460 intRows = objPredictionArea->rows(); 00461 intColumns = objPredictionArea->columns(); 00462 00463 // number of values in each cell (including species and mask values (+2) 00464 intSize = objPredictionArea->size() + 2; 00465 00466 // reset position counter 00467 pos = 0; 00468 00469 // set cell parameters 00470 cell.setSize(intSize); 00471 cell.setValues(values); 00472 00473 // reset area counters 00474 iTotalArea = iPresenceArea = iAbsenceArea = iNonPredictedArea = 0; 00475 00476 // new prediction algorithm 00477 // for each cell do 00478 // visit each row 00479 for (row = 0; row < intRows; row++) 00480 { 00481 // visit each column within the current row 00482 for (col = 0; col < intColumns; col++) 00483 { 00484 // get current position 00485 //pos = (row * intColumns) + col; 00486 00487 // get current cell value 00488 status = objPredictionArea->getValue(pos, &cell); 00489 00490 // check if cell is not masked 00491 if (status) 00492 { 00493 // NOTE: the element Item[0] should never be used in prediction!!! 00494 // we don't need the datapoints to project the model back to the env. layers 00495 00496 // cell is not masked: add one cell to the total area counter 00497 iTotalArea++; 00498 00499 // check which (if any) rule apply to this cell 00500 ruleIndex = applyRulesToCell(&cell, Accuracylimit); 00501 00502 // if there is a rule that applies to this cell, write the rule value to file 00503 if (ruleIndex >= 0) 00504 { 00505 // rule <ruleIndex> applies: write its value to output layer 00506 bytPred = (BYTE) objRules[ruleIndex]->Gene[0]; 00507 objPredictionLayer->set(pos, bytPred); 00508 00509 // increment area counter (depending on the prediction) 00510 if (bytPred == PRESENCE) 00511 iPresenceArea++; 00512 else if (bytPred == ABSENCE) 00513 iAbsenceArea++; 00514 } 00515 00516 else 00517 { 00518 // no rule applies: write NODATA 00519 objPredictionLayer->set(pos, (BYTE) MISSING_VALUE); 00520 iNonPredictedArea++; 00521 } 00522 00523 } 00524 else 00525 { 00526 // if it is masked then write NODATA to cell 00527 objPredictionLayer->set(pos, (BYTE) MASK_VALUE); 00528 } 00529 00530 // visit next cell 00531 pos++; 00532 } 00533 00534 00535 //GarpProgressEvents::fireProcessEvent((int) (row * 100 / intRows), 0, 0); 00536 } 00537 00538 //GarpProgressEvents::fireProcessEvent(100, 0, 0); 00539 } 00540 00541 // ========================================================================== 00542 void RuleSet::predictRuleCoverage(EnvLayer * objPredictionLayer, EnvLayerSet * objPredictionArea, double Accuracylimit) 00543 { 00544 int row, col, pos; 00545 int intRows, intColumns, intSize; 00546 int ruleIndex; 00547 bool status; 00548 EnvCell cell; 00549 BYTE values[MAX_ENV_LAYERS]; 00550 00551 intRows = objPredictionArea->rows(); 00552 intColumns = objPredictionArea->columns(); 00553 00554 // number of values in each cell (including species and mask values (+2) 00555 intSize = objPredictionArea->size() + 2; 00556 00557 // reset position counter 00558 pos = 0; 00559 00560 // set cell parameters 00561 cell.setSize(intSize); 00562 cell.setValues(values); 00563 00564 // new prediction algorithm 00565 // for each cell do 00566 // visit each row 00567 for (row = 0; row < intRows; row++) 00568 { 00569 // visit each column within the current row 00570 for (col = 0; col < intColumns; col++) 00571 { 00572 // get current position 00573 //pos = (row * intColumns) + col; 00574 00575 // get current cell value 00576 status = objPredictionArea->getValue(pos, &cell); 00577 00578 // check if cell is not masked 00579 if (status) 00580 { 00581 // NOTE: the element Item[0] should never be used in prediction!!! 00582 // we don't need the datapoints to project the model back to the env. layers 00583 00584 // check which (if any) rule apply to this cell 00585 ruleIndex = applyRulesToCell(&cell, Accuracylimit); 00586 00587 // if there is a rule that applies to this cell, write the rule value to file 00588 if (ruleIndex >= 0) 00589 { 00590 // rule <ruleIndex> applies: write its value to output layer 00591 //objPredictionLayer->set(pos, (BYTE) objRules[ruleIndex]->Gene[0]); 00592 objPredictionLayer->set(pos, (BYTE) ruleIndex + 1); 00593 } 00594 00595 else 00596 { 00597 // no rule applies: write NODATA 00598 objPredictionLayer->set(pos, (BYTE) MISSING_VALUE); 00599 } 00600 00601 } 00602 else 00603 { 00604 // if it is masked then write NODATA to cell 00605 objPredictionLayer->set(pos, (BYTE) MASK_VALUE); 00606 } 00607 00608 // visit next cell 00609 pos++; 00610 } 00611 00612 00613 //GarpProgressEvents::fireProcessEvent((int) (row * 100 / intRows), 0, 0); 00614 } 00615 00616 //GarpProgressEvents::fireProcessEvent(100, 0, 0); 00617 } 00618 00619 */ 00620 00621 // ========================================================================== 00622 int RuleSet::applyRulesToCell(EnvCell * cell, double Accuracylimit) const 00623 { 00624 int i, maxi, ruleIndex; 00625 double u, max; 00626 int b_membership[256]; 00627 00628 for (i = 0; i < 256; i++) 00629 b_membership[i] = 0; 00630 00631 max = maxi = 0; 00632 00633 ruleIndex = -1; 00634 00635 // check every rule 00636 i = 0; 00637 while ((i < intRules) && (ruleIndex == -1)) 00638 { 00639 // get the 5th performance value 00640 u = (int)(255.0 * objRules[i]->dblPerformance[5]); 00641 00642 if (objRules[i]->dblPerformance[5] >= Accuracylimit) 00643 { 00644 if (objRules[i]->applyToCell(cell)) 00645 { 00646 ruleIndex = i; 00647 00648 // update value for 00649 if (objRules[i]->intScreen) 00650 { 00651 if (b_membership[objRules[i]->Gene[0]] < u) 00652 b_membership[objRules[i]->Gene[0]] = (int) u; 00653 00654 if (max < u) 00655 { 00656 max = u; 00657 maxi = i; 00658 } 00659 } 00660 } 00661 } 00662 00663 // check next rule 00664 i++; 00665 } 00666 00667 if (max) 00668 objRules[maxi]->dblPerformance[9]++; 00669 00670 return ruleIndex; 00671 } 00672 00673 /* 00674 // ========================================================================== 00675 bool RuleSet::projectRuleSet(EnvLayerSet * oToLayerSet, bool bConservative, RuleSet * oToRuleSet) 00676 { 00677 // check if rule set is not null 00678 if ((intRules <= 0) || (objModelLayerSet->size() == 0) || (oToLayerSet->size() == 0) || 00679 (objModelLayerSet->size() != oToLayerSet->size())) 00680 return false; 00681 00682 // this code does not work right, I guess. See the other implementation below it 00683 int i, j, iLayers; 00684 int iNatMin[MAX_ENV_LAYERS]; 00685 int iNatMax[MAX_ENV_LAYERS]; 00686 int iProjMin[MAX_ENV_LAYERS]; 00687 int iProjMax[MAX_ENV_LAYERS]; 00688 double dFactor[MAX_ENV_LAYERS]; 00689 00690 EnvLayer * oNat, *oProj; 00691 00692 // find out how many genes a rule have 00693 iLayers = objModelLayerSet->size(); 00694 00695 // now calculate the factor, min and max values for each gene 00696 // those values will be used to modify the gene values in the 00697 // result dataset 00698 for (i = 0; i < iLayers; i++) 00699 { 00700 // get one layer from native range 00701 // and other from projection area 00702 oNat = objModelLayerSet->getLayerByIndex(i); 00703 oProj = oToLayerSet->getLayerByIndex(i); 00704 00705 // get projection values for each gene 00706 // min values 00707 if (oNat->dblMinValue > oProj->dblMinValue) 00708 { 00709 iNatMin[i] = MIN_SCALED_VALUE; 00710 iProjMin[i] = oProj->scale(oNat->dblMinValue); 00711 } 00712 else 00713 { 00714 iNatMin[i] = oNat->scale(oProj->dblMinValue); 00715 iProjMin[i] = MIN_SCALED_VALUE; 00716 } 00717 00718 // now max values 00719 if (oNat->dblMaxValue > oProj->dblMaxValue) 00720 { 00721 iNatMax[i] = MAX_SCALED_VALUE; 00722 iProjMax[i] = oProj->scale(oNat->dblMaxValue); 00723 } 00724 else 00725 { 00726 iNatMax[i] = oNat->scale(oProj->dblMaxValue); 00727 iProjMax[i] = MAX_SCALED_VALUE; 00728 } 00729 00730 dFactor[i] = (((double) iProjMax[i] - (double) iProjMin[i]) / 00731 ((double) iNatMax[i] - (double) iNatMin[i])); 00732 } 00733 00734 // first clear the rule set 00735 oToRuleSet->trim(0); 00736 00737 // copy the rules to the result rule set and modify the rules 00738 for (j = 0; j < intRules; j++) 00739 { 00740 Rule * oAuxRule; 00741 00742 // get a clone of the ith rule in the current 00743 oAuxRule = objRules[j]->clone(); 00744 00745 // modify the gene values 00746 // projecting the values from the Native Dataset to the projection area 00747 // jump first gene (rule value for the species - 00748 // - presence or absence - cannot project these values) 00749 for (i = 0; i < iLayers; i++) 00750 { 00751 int iOldValue1, iOldValue2; 00752 int iNewValue1, iNewValue2; 00753 00754 iOldValue1 = (int) oAuxRule->Gene[(i + 1) * 2]; 00755 iOldValue2 = (int) oAuxRule->Gene[(i + 1) * 2 + 1]; 00756 00757 iNewValue1 = (int) ((iOldValue1 - iNatMin[i]) * dFactor[i]) + iProjMin[i]; 00758 iNewValue2 = (int) ((iOldValue2 - iNatMin[i]) * dFactor[i]) + iProjMin[i]; 00759 00760 // correct the values to avoid values out of range 00761 if (iNewValue1 < 0) 00762 iNewValue1 = 0; 00763 else if (iNewValue1 > 255) 00764 iNewValue1 = 255; 00765 00766 if (iNewValue2 < 0) 00767 iNewValue2 = 0; 00768 else if (iNewValue2 > 255) 00769 iNewValue2 = 255; 00770 00771 // decide if it is an conservative or liberal projection 00772 // In conservative projections, if the value of a gene 00773 // is in one of the bounds of the native range layer value, 00774 // this value is mapped to the correspondent value to the 00775 // projection area. In liberal projections, a value in one 00776 // of the bounds of the layer values means that the rule 00777 // applies for all values above (or below) that gene value 00778 00779 if (iOldValue1 == 0 && !bConservative) 00780 iNewValue1 = 0; 00781 00782 if (iOldValue2 == 0 && !bConservative) 00783 iNewValue2 = 0; 00784 00785 oAuxRule->Gene[(i + 1) * 2] = (BYTE) iNewValue1; 00786 oAuxRule->Gene[(i + 1) * 2 + 1] = (BYTE) iNewValue2; 00787 } 00788 00789 // add rule to the rule set 00790 oToRuleSet->add(oAuxRule); 00791 } 00792 00793 // 00794 00795 int i, j, iLayers; 00796 int iOldValue1, iOldValue2; 00797 int iNewValue1, iNewValue2; 00798 EnvLayer * oNat, *oProj; 00799 Rule * oAuxRule; 00800 00801 // find out how many genes a rule have 00802 iLayers = objModelLayerSet->size(); 00803 00804 // first clear the rule set 00805 oToRuleSet->trim(0); 00806 00807 // copy the rules to the result rule set and modify the rules 00808 for (j = 0; j < intRules; j++) 00809 { 00810 // get a clone of the ith rule in the current 00811 oAuxRule = objRules[j]->clone(); 00812 00813 // logit rules cannot be projected using this approach 00814 // so, for now, let's just copy them and hope for the best 00815 // that means, for logit rules, projection will disconsider the difference in the range of values 00816 if (oAuxRule->type() != 'r') 00817 { 00818 // modify the gene values 00819 // projecting the values from the Native Dataset to the projection area 00820 // jump first gene (rule value for the species - 00821 // - presence or absence - cannot project these values) 00822 for (i = 0; i < iLayers; i++) 00823 { 00824 oNat = objModelLayerSet->getLayerByIndex(i); 00825 oProj = oToLayerSet->getLayerByIndex(i); 00826 00827 // assertion 00828 //if ((oAuxRule->Gene[(i + 1) * 2] != objRules[j]->Gene[(i + 1) * 2]) || 00829 // (oAuxRule->Gene[(i + 1) * 2 + 1] != objRules[j]->Gene[(i + 1) * 2 + 1])) 00830 // return false; 00831 // 00832 00833 iOldValue1 = (int) oAuxRule->Gene[(i + 1) * 2]; 00834 iOldValue2 = (int) oAuxRule->Gene[(i + 1) * 2 + 1]; 00835 00836 iNewValue1 = (int) oProj->scale(oNat->unscale(iOldValue1) + 0.000000000001); 00837 iNewValue2 = (int) oProj->scale(oNat->unscale(iOldValue2) + 0.000000000001); 00838 00839 // correct the values to avoid values out of range 00840 if (iNewValue1 < 0) 00841 iNewValue1 = 1; 00842 else if (iNewValue1 > 255) 00843 iNewValue1 = 254; 00844 00845 if (iNewValue2 < 0) 00846 iNewValue2 = 1; 00847 else if (iNewValue2 > 255) 00848 iNewValue2 = 254; 00849 00850 // decide if it is an conservative or liberal projection 00851 // In conservative projections, if the value of a gene 00852 // is in one of the bounds of the native range layer value, 00853 // this value is mapped to the correspondent value to the 00854 // projection area. In liberal projections, a value in one 00855 // of the bounds of the layer values means that the rule 00856 // applies for all values above (or below) that gene value 00857 00858 if (iOldValue1 == 0 && !bConservative) 00859 iNewValue1 = 0; 00860 00861 if (iOldValue2 == 0 && !bConservative) 00862 iNewValue2 = 0; 00863 00864 if (iOldValue1 == 255 && !bConservative) 00865 iNewValue1 = 255; 00866 00867 if (iOldValue2 == 255 && !bConservative) 00868 iNewValue2 = 255; 00869 00870 oAuxRule->Gene[(i + 1) * 2] = (BYTE) iNewValue1; 00871 oAuxRule->Gene[(i + 1) * 2 + 1] = (BYTE) iNewValue2; 00872 } 00873 } // end if oAuxRule->type() != 'r' 00874 00875 // add rule to the rule set 00876 oToRuleSet->add(oAuxRule); 00877 } 00878 00879 oToRuleSet->objModelLayerSet = oToLayerSet; 00880 00881 return true; 00882 } 00883 */ 00884 // ========================================================================== 00885 00886 // ============================================================== 00887 00888 // gather rule set statistics 00889 void RuleSet::gatherRuleSetStats(int gen) 00890 { 00891 char type='0'; //initialise to something invalid 00892 00893 printf("%4d]", gen); 00894 00895 for (int i = 0; i < 3; i++) 00896 { 00897 switch (i) 00898 { 00899 case 0: type ='d'; break; 00900 case 1: type ='!'; break; 00901 case 2: type ='r'; break; 00902 //case 3: type ='a'; break; 00903 } 00904 00905 double max = -10000; 00906 double sum = 0; 00907 int ct = 0; 00908 int pres = 0; 00909 for (int j = 0; j < intRules; j++) 00910 { 00911 Rule * rule = objRules[j]; 00912 if (rule->type() == type) 00913 { 00914 ct++; 00915 sum += rule->dblPerformance[0]; 00916 pres += (int) rule->Gene[0]; 00917 if (max < rule->dblPerformance[0]) 00918 max = rule->dblPerformance[0]; 00919 } 00920 } 00921 00922 if (max == -10000) 00923 max = 0; 00924 00925 printf("%c %2d %+7.2f %+7.2f %2d|", type, ct, max, sum / ct, pres); 00926 } 00927 00928 printf("\n"); 00929 }