openModeller  Version 1.4.0
AlgorithmRun.cpp
Go to the documentation of this file.
00001 
00030 #include "AlgorithmRun.hh"
00031 #include "threads.hh"
00032 
00033 /****************************************************************/
00034 /************************ GARP Run Thread ***********************/
00035 
00036 // TODO: modify strategy to reuse threads instead of creating a 
00037 //       new one for every garp run
00038 
00039 THREAD_PROC_RETURN_TYPE AlgorithmRunThreadProc(void * threadData)
00040 {
00041   AlgorithmRun * algRun = (AlgorithmRun *) threadData;
00042 
00043   algRun->createModel();
00044 
00045   algRun->stop();
00046   THREAD_PROC_RETURN_STATEMENT;
00047 }
00048 
00049 
00050 /****************************************************************/
00051 /************************* GARP Run *****************************/
00052 
00053 AlgorithmRun::AlgorithmRun(const AlgorithmPtr& algo) :
00054   _alg( algo ),
00055   _id(-1),
00056   _running( false ),
00057   _omission( -1.0 ),
00058   _commission( -1.0 ),
00059   _commission_samples( 0 ),
00060   _train_sampler(),
00061   _test_sampler()
00062 {
00063 
00064 }
00065 
00066 /****************************************************************/
00067 AlgorithmRun::~AlgorithmRun() 
00068 {
00069 
00070 }
00071 
00072 /****************************************************************/
00073 int AlgorithmRun::initialize(int id, int comm_samples,
00074            const SamplerPtr& train_sampler, 
00075            const SamplerPtr& test_sampler ) 
00076 {
00077   _id = id;
00078   _commission_samples = comm_samples;
00079 
00080   _train_sampler = train_sampler;
00081   _test_sampler = test_sampler;
00082 
00083   return 1;
00084 }
00085 
00086 /****************************************************************/
00087 void AlgorithmRun::run()
00088 {
00089   _running = true;
00090   THREAD_START(AlgorithmRunThreadProc, this); 
00091 }
00092 
00093 void AlgorithmRun::stop()
00094 {
00095   _running = false;
00096   THREAD_END();
00097 }
00098 
00099 
00100 /****************************************************************/
00101 bool AlgorithmRun::running() const
00102 {
00103   return _running;
00104 }
00105 
00106 /****************************************************************/
00107 void AlgorithmRun::createModel()
00108 {
00109   _alg->createModel( _train_sampler );
00110 
00111 #if 1
00112   calculateCommission();
00113   calculateOmission();
00114 #else  
00115 
00116   ConfusionMatrix cm;
00117   cm.calculate( _alg->getModel(), _train_sampler );
00118 
00119   _commission = cm.getCommissionError();
00120 
00121   _omission = cm.getOmissionError();
00122 #endif
00123 }
00124 
00125 /****************************************************************/
00126 float AlgorithmRun::getProgress() const
00127 { return _alg->getProgress(); }
00128 
00129 /****************************************************************/
00130 int AlgorithmRun::calculateCommission()           
00131 {
00132   int i;
00133   double sum = 0.0;
00134 
00135   // TODO: check how to use absences in computing commission
00136 
00137   // get random points from the background to estimate 
00138   // area predicted present
00139   bool hasAbsences = (_train_sampler->numAbsence() != 0);
00140   for (i = 0; i < _commission_samples; i++) {
00141 
00142     Scalar value;
00143     if (hasAbsences) {
00144 
00145       ConstOccurrencePtr occ = _train_sampler->getAbsence();
00146       value = _alg->getValue(occ->environment());
00147     }
00148     else {
00149 
00150       OccurrencePtr occ = _train_sampler->getPseudoAbsence();
00151       value = _alg->getValue(occ->environment());
00152     }
00153 
00154     // discard novalue (-1); zero is irrelevant to the sum
00155     if (value > 0)
00156       sum += value;
00157   }
00158 
00159   _commission = sum / (double) _commission_samples;
00160 
00161   return 1;
00162 }
00163 
00164 /****************************************************************/
00165 int AlgorithmRun::calculateOmission()           
00166 {
00167   // TODO: check how to use absences in computing omission
00168 
00169   // test which kind of test (intrinsic or extrinsic) should be performed
00170   SamplerPtr sampler;
00171 
00172   if (!_test_sampler)
00173     { sampler = _train_sampler; }
00174   else
00175     { sampler = _test_sampler; }
00176 
00177   int nomitted = 0;
00178   OccurrencesPtr presences = sampler->getPresences();
00179   OccurrencesImpl::const_iterator it  = presences->begin();
00180   OccurrencesImpl::const_iterator end = presences->end();
00181 
00182   while (it != end)
00183     {
00184       nomitted = !_alg->getValue((*it)->environment()); 
00185       ++it;
00186     }
00187 
00188   _omission = (double) nomitted / (double) presences->numOccurrences();
00189 
00190   return 1;
00191 }
00192 
00193 /****************************************************************/
00194 double AlgorithmRun::getOmission() const
00195 { return _omission; }
00196 
00197 /****************************************************************/
00198 double AlgorithmRun::getCommission() const
00199 { return _commission; }
00200 
00201 /****************************************************************/
00202 double AlgorithmRun::getError(int type) const
00203 {
00204   if (!type)
00205     { return _omission; }
00206   else
00207     { return _commission; }
00208 }
00209 
00210 /****************************************************************/
00211 double AlgorithmRun::getValue(const Sample& x) const   
00212 { return _alg->getValue(x); }
00213