openModeller
Version 1.4.0
|
00001 00027 #include "niche_mosaic.hh" 00028 00029 #include <openmodeller/Configuration.hh> 00030 00031 #include <openmodeller/Random.hh> 00032 00033 #include <stdio.h> 00034 #include <math.h> 00035 #include <stdlib.h> 00036 #include <time.h> 00037 00038 /****************************************************************/ 00039 /********************** Algorithm's Metadata ********************/ 00040 00041 #define NUM_PARAM 1 00042 00043 #define NUMITERATIONS_ID "NumberOfIterations" 00044 00045 /*************************************/ 00046 /*** Algorithm parameters metadata ***/ 00047 00048 static AlgParamMetadata parameters[NUM_PARAM] = { 00049 00050 // Metadata of the first parameter. 00051 { 00052 NUMITERATIONS_ID, // Id 00053 "Number of iterations", // Name. 00054 Integer, // Type. 00055 00056 // Overview 00057 "Number of iterations.", 00058 00059 // Description. 00060 "Number of iterations.", 00061 00062 1, // Not zero if the parameter has lower limit. 00063 1000, // Parameter's lower limit. 00064 0, // Not zero if the parameter has upper limit. 00065 0, // Parameter's upper limit. 00066 "2000" // Parameter's typical (default) value. 00067 }, 00068 }; 00069 00070 /************************************/ 00071 /*** Algorithm's general metadata ***/ 00072 00073 static AlgMetadata metadata = { 00074 00075 "NICHE_MOSAIC", // Id. 00076 "Niche Mosaic", // Name. 00077 "0.1", // Version. 00078 00079 // Overview 00080 "This algorithm is still experimental. You may not use it in publications without the author's permission.", 00081 00082 // Description. 00083 "This algorithm is still experimental. You may not use it in publications without the author's permission.", 00084 00085 "Missae Yamamoto", // Author 00086 00087 // Bibliography. 00088 "", 00089 00090 "Missae Yamamoto", // Code author. 00091 "missae [at] dpi.inpe.br", // Code author's contact. 00092 00093 0, // Does not accept categorical data. 00094 0, // Does not need (pseudo)absence points. 00095 00096 NUM_PARAM, // Algorithm's parameters. 00097 parameters 00098 }; 00099 00100 /****************************************************************/ 00101 /****************** Algorithm's factory function ****************/ 00102 00103 OM_ALG_DLL_EXPORT 00104 AlgorithmImpl * 00105 algorithmFactory() 00106 { 00107 return new NicheMosaic(); 00108 } 00109 00110 OM_ALG_DLL_EXPORT 00111 AlgMetadata const * 00112 algorithmMetadata() 00113 { 00114 return &metadata; 00115 } 00116 00117 /*************************************************************/ 00118 /************************ Niche Mosaic ***********************/ 00119 00120 NicheMosaic::NicheMosaic() : 00121 AlgorithmImpl( &metadata ), 00122 _num_iterations(0), 00123 _num_points(0), 00124 _num_points_test(0), 00125 _num_points_absence_test(0), 00126 _num_layers(0), 00127 _minimum(), 00128 _maximum(), 00129 _delta(), 00130 _my_presences(0), 00131 _my_presences_test(0), 00132 _my_absence_test(0), 00133 _bestCost(0), 00134 _done( false ), 00135 _progress( 0.0 ) 00136 { 00137 } 00138 00139 NicheMosaic::~NicheMosaic() 00140 { 00141 } 00142 00143 /******************/ 00144 /*** initialize ***/ 00145 int 00146 NicheMosaic::initialize() 00147 { 00148 // Check the number of presences 00149 int num_presences = _samp->numPresence(); 00150 00151 if ( num_presences < 10 ) { 00152 00153 Log::instance()->warn( "Niche Mosaic needs at least 10 presence points.\n" ); 00154 return 0; 00155 } 00156 00157 // Check number of layers 00158 _num_layers = _samp->numIndependent(); 00159 00160 if ( _num_layers < 2 ) 00161 { 00162 std::string msg = "Niche Mosaic needs at least 2 layers.\n"; 00163 00164 Log::instance()->error( msg.c_str() ); 00165 return 0; 00166 } 00167 00168 // Get parameters 00169 if ( ! getParameter( NUMITERATIONS_ID, &_num_iterations ) ) { 00170 00171 Log::instance()->error( "Parameter '" NUMITERATIONS_ID "' not passed.\n" ); 00172 return 0; 00173 } 00174 00175 if ( _num_iterations < 1000 ) { 00176 00177 Log::instance()->error( "Parameter '" NUMITERATIONS_ID "' must be greater than 999.\n" ); 00178 return 0; 00179 } 00180 00181 // remove discrepancy presence points 00182 OccurrencesPtr cleanPresences = cleanOccurrences( _samp->getPresences() ); 00183 _sampp = createSampler( _samp->getEnvironment(), cleanPresences, _samp->getAbsences() ); 00184 00185 // generate pseudo absence points using simple algorithm. 00186 size_t num_abs = (size_t)(0.40 * num_presences); 00187 if (num_abs < 10) num_abs = 10; 00188 int dim = _sampp->numIndependent(); 00189 Sample minimum(dim), maximum(dim); 00190 OccurrencesPtr pres = _sampp->getPresences(); 00191 pres->getMinMax( &minimum, &maximum ); 00192 00193 double delta; 00194 for( unsigned int i=0; i<minimum.size(); i++) { 00195 delta = (maximum[i] - minimum[i]) * 0.10; 00196 minimum[i] = minimum[i] - delta; 00197 maximum[i] = maximum[i] + delta; 00198 } 00199 00200 _my_absence_test = _sampp->getPseudoAbsences( num_abs, &minimum, &maximum ); 00201 00202 _num_points_absence_test = _my_absence_test->numOccurrences(); 00203 00204 _my_presences = new OccurrencesImpl( _my_absence_test->label(), _my_absence_test->coordSystem() ); 00205 00206 _my_presences_test = new OccurrencesImpl( _my_absence_test->label(), _my_absence_test->coordSystem() ); 00207 00208 return 1; 00209 } 00210 00211 /***************/ 00212 /*** iterate ***/ 00213 int 00214 NicheMosaic::iterate() 00215 { 00216 std::vector<Scalar> deltaBest( _num_layers ); 00217 size_t costBest, num_points_train_test, bestCost2=0; 00218 int bestIter = 0; 00219 00220 num_points_train_test = _sampp->getPresences()->numOccurrences(); 00221 _model_min_best.resize( num_points_train_test ); 00222 _model_max_best.resize( num_points_train_test ); 00223 00224 for ( unsigned int i = 0; i < _model_min_best.size(); i++ ) { 00225 _model_min_best[i] = ScalarVector( _num_layers ); 00226 _model_max_best[i] = ScalarVector( _num_layers ); 00227 }//end for 00228 00229 00230 // Split sampler in test/train 00231 splitOccurrences( _sampp->getPresences(), _my_presences, _my_presences_test ); 00232 _num_points_test = _my_presences_test->numOccurrences(); 00233 _num_points = _my_presences->numOccurrences(); 00234 00235 if ( 0 == setMinMaxDelta() ) {return 0;} 00236 00237 int endDo = _num_layers * 10; 00238 do{ 00239 findSolution(costBest, deltaBest, bestIter, bestCost2); 00240 00241 _num_iterations = _num_iterations + 8000; 00242 if (_num_iterations > 30000) break; 00243 }while( (bestIter < endDo) || (costBest < (size_t)(_num_points_test*0.8)) ); 00244 00245 if ( (size_t)(_num_points_absence_test*0.6) > bestCost2 ){ 00246 00247 int dim = _sampp->numIndependent(); 00248 Sample minimum(dim), maximum(dim); 00249 OccurrencesPtr pres = _sampp->getPresences(); 00250 pres->getMinMax( &minimum, &maximum ); 00251 00252 double delta; 00253 for( unsigned int i=0; i<minimum.size(); i++) { 00254 delta = (maximum[i] - minimum[i]) * 0.10; 00255 minimum[i] = minimum[i] - delta; 00256 maximum[i] = maximum[i] + delta; 00257 } 00258 00259 _my_absence_test = _sampp->getPseudoAbsences( 100, &minimum, &maximum ); 00260 00261 00262 _num_points_absence_test = _my_absence_test->numOccurrences(); 00263 00264 _num_iterations = 10000; 00265 findSolution(costBest, deltaBest, bestIter, bestCost2); 00266 } 00267 00268 if (costBest < _num_points_test) 00269 improveModel(deltaBest); 00270 00271 _done = 1; 00272 00273 return 1; 00274 } 00275 00276 float 00277 NicheMosaic::getProgress() const 00278 { 00279 if (done()) { 00280 00281 return 1.0; 00282 } 00283 else { 00284 00285 return _progress; 00286 } 00287 } 00288 00289 /*****************/ 00290 /*** get Value ***/ /********matchRules classes******/ 00291 Scalar 00292 NicheMosaic::getValue( const Sample& x ) const 00293 { 00294 int i, j, k = 0; 00295 Scalar percent; 00296 00297 //_num_points represents the number of rules 00298 for (i = 0; i < _num_points; i++) { 00299 for (j = 0; j < _num_layers; j++) { 00300 00301 if ( ( _model_min_best[i][j] <= x[j] ) && ( x[j] <= _model_max_best[i][j] ) ) 00302 continue; 00303 else 00304 break; 00305 }//end for 00306 00307 if ( j == _num_layers ) { 00308 k++; 00309 }//end if 00310 }//end for 00311 00312 percent = (Scalar)k /(Scalar)_num_points; 00313 if (percent == 0.0) return 0.0; 00314 else if (percent < 0.10) return 0.5; 00315 else if (percent < 0.25) return 0.7; 00316 else if (percent < 0.90) return 0.9; 00317 else return 1.0; 00318 } 00319 00320 00321 int 00322 NicheMosaic::setMinMaxDelta() 00323 { 00324 OccurrencesImpl::const_iterator oc = _my_presences->begin(); 00325 OccurrencesImpl::const_iterator end = _my_presences->end(); 00326 00327 Sample const & sample = (*oc)->environment(); 00328 _minimum = sample; 00329 _maximum = sample; 00330 ++oc; 00331 00332 while ( oc != end ) { 00333 Sample const& sample = (*oc)->environment(); 00334 _minimum &= sample; 00335 _maximum |= sample; 00336 ++oc; 00337 } 00338 00339 _delta = _maximum; 00340 _delta -= _minimum; 00341 00342 for ( int j = 0; j < _num_layers; j++ ) { 00343 if (_delta[j] == 0.0) { 00344 Log::instance()->error( "No delta for layer %d\n", j ); 00345 return 0; 00346 } 00347 } 00348 00349 return 1; 00350 } 00351 00352 void 00353 NicheMosaic::createModel( std::vector<ScalarVector> &model_min, std::vector<ScalarVector> &model_max, const std::vector<Scalar> &delta ) 00354 { 00355 size_t i=0; 00356 OccurrencesImpl::const_iterator oc = _my_presences->begin(); 00357 OccurrencesImpl::const_iterator end = _my_presences->end(); 00358 00359 while ( oc != end ) { 00360 Sample const& sample = (*oc)->environment(); 00361 00362 for ( int j = 0; j < _num_layers; j++ ) { 00363 model_min[i][j] = sample[j] - delta[j]; 00364 model_max[i][j] = sample[j] + delta[j]; 00365 }//end for 00366 00367 ++oc; 00368 ++i; 00369 }//end while 00370 } 00371 00372 void 00373 NicheMosaic::editModel( std::vector<ScalarVector> &model_min, std::vector<ScalarVector> &model_max, const std::vector<Scalar> &delta, size_t i_layer ) 00374 { 00375 size_t i=0; 00376 OccurrencesImpl::const_iterator oc = _my_presences->begin(); 00377 OccurrencesImpl::const_iterator end = _my_presences->end(); 00378 00379 while ( oc != end ) { 00380 Sample const& sample = (*oc)->environment(); 00381 00382 model_min[i][i_layer] = sample[i_layer] - delta[i_layer]; 00383 model_max[i][i_layer] = sample[i_layer] + delta[i_layer]; 00384 00385 ++oc; 00386 ++i; 00387 }//end while 00388 } 00389 00390 size_t 00391 NicheMosaic::calculateCostPres( const std::vector<ScalarVector> &model_min, const std::vector<ScalarVector> &model_max ) 00392 { 00393 OccurrencesImpl::iterator it = _my_presences_test->begin(); 00394 OccurrencesImpl::iterator last = _my_presences_test->end(); 00395 00396 int i, j, npresence = 0; 00397 00398 //presence 00399 while ( it != last ) { 00400 00401 Sample const& sample = (*it)->environment(); 00402 00403 //_num_points eh o numero de regras do modelo 00404 for (i = 0; i < _num_points; i++) { 00405 00406 for (j = 0; j < _num_layers; j++) { 00407 00408 if ( ( model_min[i][j] <= sample[j] ) && ( sample[j] <= model_max[i][j] ) ) 00409 continue; 00410 else 00411 break; 00412 }//end for 00413 00414 if ( j == _num_layers ) { 00415 npresence++; 00416 break; 00417 }//end if 00418 }//end for 00419 ++it; 00420 }//end while 00421 00422 return npresence; 00423 } 00424 00425 size_t 00426 NicheMosaic::calculateCostAus( const std::vector<ScalarVector> &model_min, const std::vector<ScalarVector> &model_max ) 00427 { 00428 int i, j, nabsence = 0; 00429 00430 //absence 00431 OccurrencesImpl::iterator it_absence = _my_absence_test->begin(); 00432 OccurrencesImpl::iterator last_absence = _my_absence_test->end(); 00433 00434 while ( it_absence != last_absence ) 00435 { 00436 Sample const& samp = (*it_absence)->environment(); 00437 00438 for (i = 0; i < _num_points; i++){ //_num_points eh o numero de regras do modelo 00439 00440 for (j = 0; j < _num_layers; j++){ 00441 00442 if ( ( model_min[i][j] <= samp[j] ) && ( samp[j] <= model_max[i][j] ) ) 00443 continue; 00444 else 00445 break; 00446 }//end for 00447 00448 if ( j == _num_layers ) 00449 break; 00450 }//end for 00451 00452 if ( i == _num_points) 00453 nabsence++; 00454 00455 ++it_absence; 00456 }//end while 00457 00458 return nabsence; 00459 } 00460 00461 size_t 00462 NicheMosaic::getRandomLayerNumber() 00463 { 00464 Random random; 00465 00466 return random( 0, _num_layers ); 00467 } 00468 00469 Scalar 00470 NicheMosaic::getRandomPercent(const std::vector<Scalar> &delta, const size_t i_layer, size_t &costPres) 00471 { 00472 int size = 100, r; 00473 00474 double min_percent = 0.12, max_percent = 0.4; 00475 00476 double new_percent, half_percent = (max_percent - min_percent) / 2 + min_percent; 00477 00478 Random random; 00479 00480 r = random( 0, size ); 00481 new_percent = (max_percent - min_percent) * ( (double) r / (double) size ) + min_percent; 00482 00483 if ( (costPres < _num_points_test) && (new_percent < half_percent) ){ 00484 00485 new_percent = new_percent + half_percent - min_percent; 00486 } 00487 00488 return new_percent; 00489 } 00490 00491 void 00492 NicheMosaic::renewTabuDegree(std::vector<size_t> &tabuDegree) 00493 { 00494 for (int i = 0; i < _num_layers; i++) { 00495 00496 if (tabuDegree[i] > 0) 00497 tabuDegree[i] = tabuDegree[i] - 1; 00498 } 00499 } 00500 00501 void 00502 NicheMosaic::saveBestModel(const std::vector<ScalarVector> &model_min, const std::vector<ScalarVector> &model_max) 00503 { 00504 for (int i = 0; i < _num_points; i++) { 00505 for (int j = 0; j < _num_layers; j++) { 00506 _model_min_best[i][j] = model_min[i][j]; 00507 _model_max_best[i][j] = model_max[i][j]; 00508 } 00509 } 00510 } 00511 00512 void 00513 NicheMosaic::improveModel( const std::vector<Scalar> &deltaBest ) 00514 { 00515 OccurrencesImpl::iterator it = _my_presences_test->begin(); 00516 OccurrencesImpl::iterator last = _my_presences_test->end(); 00517 00518 int i, j, flag = 0, n = _num_points; 00519 00520 while ( it != last ) { 00521 00522 Sample const& sample = (*it)->environment(); 00523 00524 //_num_points eh o numero de regras do modelo 00525 for (i = 0; i < n; i++) { 00526 00527 for (j = 0; j < _num_layers; j++) { 00528 00529 if ( ( _model_min_best[i][j] <= sample[j] ) && ( sample[j] <= _model_max_best[i][j] ) ) 00530 continue; 00531 else 00532 break; 00533 }//end for 00534 00535 if ( j == _num_layers ) { 00536 flag = 1; 00537 break; 00538 }//end if 00539 }//end for 00540 if (flag){ 00541 flag = 0; 00542 }else { 00543 for (j = 0; j < _num_layers; j++) { 00544 _model_min_best[n][j] = sample[j] - deltaBest[j]; 00545 _model_max_best[n][j] = sample[j] + deltaBest[j]; 00546 00547 }//end for 00548 n++; 00549 }//end if 00550 ++it; 00551 }//end while 00552 _num_points = n; 00553 } 00554 00555 void 00556 NicheMosaic::findSolution(size_t &costBest, std::vector<Scalar> &deltaBest, int &bestIter, size_t &bestCost2) 00557 { 00558 size_t cost1, cost2, i_layer; 00559 Scalar importance = 1.0, cost, deltaIni=0.4; 00560 std::vector<Scalar> delta( _num_layers ); 00561 00562 size_t nTabu = (size_t)floor(sqrt((double)(_num_layers))); 00563 std::vector<size_t> tabuDegree( _num_layers ); 00564 00565 for( int l = 0; l < _num_layers; l++ ) 00566 tabuDegree[l] = 0; 00567 00568 //model 00569 std::vector<ScalarVector> model_min( _num_points ); 00570 std::vector<ScalarVector> model_max( _num_points ); 00571 00572 for ( unsigned int i = 0; i < model_min.size(); i++ ) { 00573 model_min[i] = ScalarVector( _num_layers ); 00574 model_max[i] = ScalarVector( _num_layers ); 00575 }//end for 00576 00577 for ( int j = 0; j < _num_layers; j++ ){ 00578 00579 delta[j] = _delta[j] * deltaIni; 00580 deltaBest[j] = delta[j]; 00581 }//end for 00582 00583 createModel( model_min, model_max, delta ); 00584 cost1 = calculateCostPres( model_min, model_max ); 00585 costBest = cost1; 00586 cost2 = calculateCostAus( model_min, model_max ); 00587 cost = (Scalar)cost1*importance + (Scalar)cost2; 00588 00589 _bestCost = cost; 00590 saveBestModel(model_min, model_max); 00591 if (_bestCost == ((Scalar)_num_points_test*importance + (Scalar)_num_points_absence_test) ) 00592 return; 00593 00594 for (int iter=0; iter < _num_iterations; iter++) { 00595 00596 _progress = (float)iter/(float)_num_iterations; 00597 i_layer = getRandomLayerNumber(); 00598 00599 Scalar deltaAux = delta[i_layer]; 00600 delta[i_layer] = _delta[i_layer] * getRandomPercent(delta, i_layer, cost1); 00601 editModel( model_min, model_max, delta, i_layer ); 00602 cost1 = calculateCostPres( model_min, model_max ); 00603 cost2 = calculateCostAus( model_min, model_max ); 00604 cost = (Scalar)cost1*importance + (Scalar)cost2; 00605 00606 if ( (cost > _bestCost) || ( (cost == _bestCost) && (cost1 >= costBest) ) ) { 00607 renewTabuDegree(tabuDegree); 00608 tabuDegree[i_layer] = nTabu; 00609 costBest = cost1; 00610 _bestCost = cost; 00611 deltaBest[i_layer] = delta[i_layer]; 00612 saveBestModel(model_min, model_max); 00613 bestIter = iter; 00614 bestCost2=cost2; 00615 00616 if (_bestCost == ((Scalar)_num_points_test*importance + (Scalar)_num_points_absence_test) ) 00617 break; 00618 }else { 00619 if (tabuDegree[i_layer] == 0) { 00620 renewTabuDegree(tabuDegree); 00621 tabuDegree[i_layer] = nTabu; 00622 }else{ 00623 delta[i_layer] = deltaAux; 00624 editModel( model_min, model_max, delta, i_layer ); 00625 }//end if 00626 }//end if 00627 }//end for 00628 } 00629 00630 /****************************************************************/ 00631 /****************** configuration *******************************/ 00632 void 00633 NicheMosaic::_getConfiguration( ConfigurationPtr& config ) const 00634 { 00635 00636 if ( !_done ) 00637 return; 00638 00639 ConfigurationPtr model_config( new ConfigurationImpl( "NicheMosaic" ) ); 00640 config->addSubsection( model_config ); 00641 00642 model_config->addNameValue( "NumLayers", _num_layers ); 00643 model_config->addNameValue( "NumPoints", _num_points ); 00644 00645 for (int i = 0; i < _num_points; i++) { 00646 00647 ConfigurationPtr rule_config( new ConfigurationImpl( "Rule" ) ); 00648 model_config->addSubsection( rule_config ); 00649 00650 Sample min_best( _model_min_best[i] ); 00651 Sample max_best( _model_max_best[i] ); 00652 00653 rule_config->addNameValue( "Min", min_best ); 00654 rule_config->addNameValue( "Max", max_best ); 00655 00656 } 00657 } 00658 00659 void 00660 NicheMosaic::_setConfiguration( const ConstConfigurationPtr& config ) 00661 { 00662 ConstConfigurationPtr model_config = config->getSubsection( "NicheMosaic" ); 00663 00664 if (!model_config) 00665 return; 00666 00667 _num_layers = model_config->getAttributeAsInt( "NumLayers", 0 ); 00668 _num_points = model_config->getAttributeAsInt( "NumPoints", 0 ); 00669 00670 _model_min_best.resize( _num_points ); 00671 _model_max_best.resize( _num_points ); 00672 00673 Configuration::subsection_list subelements = model_config->getAllSubsections(); 00674 00675 Configuration::subsection_list::iterator subelement = subelements.begin(); 00676 Configuration::subsection_list::iterator last_subelement = subelements.end(); 00677 00678 int i = 0; 00679 00680 for ( ; subelement != last_subelement; ++subelement ) { 00681 00682 if ( (*subelement)->getName() == "Rule" ) { 00683 00684 _model_min_best[i] = (*subelement)->getAttributeAsVecDouble( "Min" ); 00685 _model_max_best[i] = (*subelement)->getAttributeAsVecDouble( "Max" ); 00686 00687 ++i; 00688 } 00689 } 00690 00691 _done = true; 00692 00693 return; 00694 } 00695 00696 OccurrencesPtr 00697 NicheMosaic::cleanOccurrences( const OccurrencesPtr& occurrences ) 00698 { 00699 OccurrencesPtr presence( new OccurrencesImpl(0.0) ); 00700 OccurrencesPtr presenceAux( new OccurrencesImpl(0.0) ); 00701 00702 double dist, distLimit=8.0, x, y, xmin, xmax, ymin, ymax, deltax, deltay; 00703 unsigned int flag = 0, i = 0, itrain=0, ktrain=0, ioccur=0; 00704 std::vector<double> occurTransformx( occurrences->numOccurrences() ); 00705 std::vector<double> occurTransformy( occurrences->numOccurrences() ); 00706 std::vector<int> testId( occurrences->numOccurrences() ); 00707 00708 OccurrencesImpl::const_iterator it = occurrences->begin(); 00709 OccurrencesImpl::const_iterator fin = occurrences->end(); 00710 00711 xmin = xmax = (*it)->x(); 00712 ymin = ymax = (*it)->y(); 00713 00714 ++it; 00715 while( it != fin ) { 00716 if ( (*it)->x() < xmin ) xmin = (*it)->x(); 00717 else if ( (*it)->x() > xmax) xmax = (*it)->x(); 00718 if ( (*it)->y() < ymin) ymin = (*it)->y(); 00719 else if ( (*it)->y() > ymax) ymax = (*it)->y(); 00720 ++it; 00721 } 00722 deltax = xmax - xmin; 00723 deltay = ymax - ymin; 00724 00725 it = occurrences->begin(); 00726 while( it != fin ) { 00727 occurTransformx[i] = 100 * ( (*it)->x() - xmin ) / deltax; 00728 occurTransformy[i] = 100 * ( (*it)->y() - ymin ) / deltay; 00729 i++; 00730 ++it; 00731 } 00732 00733 flag = 0, itrain=0, ktrain=0, ioccur=0; 00734 00735 it = occurrences->begin(); 00736 00737 presenceAux->insert( new OccurrenceImpl( *(*it) ) ); 00738 00739 ++it; 00740 testId[ktrain] = ioccur; 00741 ktrain++; 00742 ioccur++; 00743 00744 while( it != fin ) { 00745 00746 for ( i = 0; i < ktrain; i++ ) { 00747 itrain = testId[i]; 00748 x = occurTransformx[ioccur] - occurTransformx[itrain]; 00749 y = occurTransformy[ioccur] - occurTransformy[itrain]; 00750 dist = sqrt( (x*x) + (y*y) ); 00751 00752 if ( dist < distLimit) { 00753 presence->insert( new OccurrenceImpl( *(*it) ) ); 00754 flag = 1; 00755 break; 00756 } 00757 } 00758 00759 if (!flag){ 00760 presenceAux->insert( new OccurrenceImpl( *(*it) ) ); 00761 testId[ktrain] = ioccur; 00762 ktrain++; 00763 }else{ 00764 flag = 0; 00765 } 00766 ioccur++; 00767 ++it; 00768 } 00769 00770 //verify presenceAux points 00771 SamplerPtr samp = createSampler( _samp->getEnvironment(), presence, _samp->getAbsences() ); 00772 Sample mean; 00773 Sample deviation; 00774 computeMeanDeviation( presence, mean, deviation ); 00775 00776 OccurrencesImpl::const_iterator itt = presenceAux->begin(); 00777 OccurrencesImpl::const_iterator finn = presenceAux->end(); 00778 00779 double prob; 00780 OccurrencePtr occ; 00781 while( itt != finn ) { 00782 occ = (*itt); 00783 00784 Sample dif = occ->environment(); 00785 dif -= mean; 00786 prob = 1.0; 00787 for( unsigned int i=0; i<dif.size(); i++) { 00788 Scalar cutoff = deviation[i]; 00789 00790 if ( dif[i] > cutoff || dif[i] < -cutoff ) { 00791 prob = 0.0; 00792 break; 00793 } 00794 } 00795 00796 if ( prob == 1.0 ){ 00797 presence->insert( new OccurrenceImpl( *(*itt) ) ); 00798 } 00799 ++itt; 00800 } 00801 00802 return presence; 00803 } 00804 00805 void 00806 NicheMosaic::computeMeanDeviation( const OccurrencesPtr& occs, Sample& mean, Sample& deviation ) 00807 { 00808 // compute mean 00809 OccurrencesImpl::const_iterator oc = occs->begin(); 00810 OccurrencesImpl::const_iterator end = occs->end(); 00811 00812 Sample min, max; 00813 00814 Sample const & sample = (*oc)->environment(); 00815 min = sample; 00816 max = sample; 00817 mean = sample; 00818 ++oc; 00819 00820 while ( oc != end ) { 00821 00822 Sample const& sample = (*oc)->environment(); 00823 00824 mean += sample; 00825 min &= sample; 00826 max |= sample; 00827 00828 ++oc; 00829 } 00830 mean /= Scalar( occs->numOccurrences() ); 00831 00832 // compute the std deviation 00833 deviation.resize( mean.size() ); 00834 oc = occs->begin(); 00835 00836 // compute the variance. 00837 while ( oc != end ) { 00838 Sample tmp( (*oc)->environment() ); 00839 tmp -= mean; 00840 tmp *= tmp; 00841 deviation += tmp; 00842 ++oc; 00843 } 00844 00845 // divide by (npnt - 1) 00846 Scalar npts = Scalar( occs->numOccurrences() - 1 ); 00847 deviation /= npts; 00848 deviation.sqrt(); 00849 deviation *= 5.0; 00850 }