openModeller  Version 1.5.0
minimum_distance.cpp
Go to the documentation of this file.
1 
28 #include "minimum_distance.hh"
29 
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <math.h>
34 
36 
37 //debug
38 #include <iostream>
39 
40 
41 /****************************************************************/
42 /********************** Algorithm's Metadata ********************/
43 
44 #define NUM_PARAM 1
45 
46 #define MAXDIST_ID "MaximumDistance"
47 
48 
49 /******************************/
50 /*** Algorithm's parameters ***/
51 
53 
54  // Metadata of the first parameter.
55  {
56  MAXDIST_ID, // Id.
57  "Maximum distance", // Name.
58  Real, // Type.
59  "Maximum cartesian distance to closest point", // Overview
60  "Maximum cartesian distance to closest point", // Description.
61 
62  1, // Not zero if the parameter has lower limit.
63  0.0, // Parameter's lower limit.
64  1, // Not zero if the parameter has upper limit.
65  1.0, // Parameter's upper limit.
66  "0.1" // Parameter's typical (default) value.
67  },
68 };
69 
70 
71 /************************************/
72 /*** Algorithm's general metadata ***/
73 
75 
76  "MinimumDistance", // Id.
77  "Minimum distance", // Name.
78  "0.2", // Version.
79 
80  // Overview
81  "Probability is inversely proportional to the cartesian\
82  distance in environmental space to the nearest presence point.",
83 
84  // Description.
85  "Normalizes the environmental variables values and the\
86  parameter (according to the number of environmental variables).\
87  Calculates the distance between the given environmental conditions\
88  to each occurrence point and selects the closest distance.\n\
89  If distance 'dist' is within [0, MaxDist] then probability will\
90  be in [0,1]. If 'dist' > MaxDist then probability will be zero.",
91 
92 
93  "Mauro E. S. Munoz", // Algorithm author.
94  "", // Bibliography.
95 
96  "Mauro E. S. Munoz", // Code author.
97  "mauro [at] cria.org.br", // Code author's contact.
98 
99  0, // Does not accept categorical data.
100  0, // Does not need (pseudo)absence points.
101 
102  NUM_PARAM, // Algorithm's parameters.
103  parameters
104 };
105 
106 
107 
108 /****************************************************************/
109 /****************** Algorithm's factory function ****************/
110 
111 OM_ALG_DLL_EXPORT
114 {
115  return new MinimumDistance();
116 }
117 
118 OM_ALG_DLL_EXPORT
119 AlgMetadata const *
121 {
122  return &metadata;
123 }
124 
125 /****************************************************************/
126 /************************ Minimum Distance **********************/
127 
128 /*******************/
129 /*** constructor ***/
130 
132  AlgorithmImpl( &metadata ),
133  _done( false ),
134  _dist(0.0),
135  _hasCategorical( false ),
136  _numLayers( 0 )
137 {
138  _normalizerPtr = new ScaleNormalizer( 0.0, 1.0, true );
139 }
140 
141 
142 /******************/
143 /*** destructor ***/
144 
146 {
147 }
148 
149 
150 /******************/
151 /*** initialize ***/
152 int
154 {
155  if ( ! getParameter( MAXDIST_ID, &_dist ) ) {
156  Log::instance()->error("Parameter '" MAXDIST_ID "' not set properly.\n");
157  return 0;
158  }
159 
160  // Distance should range from 0 to 1
161  if (_dist > 1.0) _dist = 1.0;
162  else if (_dist < 0.0) _dist = 0.0;
163 
164  int dim = _samp->numIndependent();
165 
166  _dist *= sqrt( (double) dim );
167 
168  if ( _samp->numPresence() == 0 ) {
169  Log::instance()->warn( "MinDistance: No occurrences inside the mask!\n" );
170  return 0;
171  }
172 
173  OccurrencesPtr presences = _samp->getPresences();
174 
175  // Load vector with samples containing the environmental
176  // values at each presence point
177  OccurrencesImpl::const_iterator p_iterator = presences->begin();
178  OccurrencesImpl::const_iterator p_end = presences->end();
179 
180  while ( p_iterator != p_end ) {
181 
182  Sample point = (*p_iterator)->environment();
183 
184  _envPoints.push_back(point);
185 
186  ++p_iterator;
187  }
188 
189  // Identify categorical layers
190  _numLayers = _samp->numIndependent();
192 
193  for( int i = 0; i < _numLayers; ++i ) {
194  if ( _samp->isCategorical( i ) ) {
195  _hasCategorical = true;
196  _isCategorical[i] = 1.0;
197  }
198  }
199 
200  _done = true;
201 
202  return 1;
203 
204 }
205 
206 
207 /***************/
208 /*** iterate ***/
209 int
211 {
212  return 1;
213 }
214 
215 
216 /************/
217 /*** done ***/
218 int
220 {
221  return _done;
222 }
223 
224 
225 /*****************/
226 /*** get Value ***/
227 Scalar
229 {
230  // Calculate the smallest distance between *x and the occurrence
231  // points.
232  Scalar min = -1;
233 
234  for( unsigned int i=0; i<_envPoints.size(); i++) {
235 
236  Scalar dist = findDist( x, _envPoints[i] );
237 
238  if ( (dist >= 0) && (dist < min || min < 0) )
239  min = dist;
240  }
241 
242  // Too far away or categories didn't match any occurrence
243  if ( min < 0 || min > _dist )
244  return 0.0;
245 
246  return 1.0 - (min / _dist);
247 
248 }
249 
250 
251 /***********************/
252 /*** get Convergence ***/
253 int
255 {
256  *val = 1.0;
257  return 1;
258 }
259 
260 
261 /*****************/
262 /*** find Dist ***/
263 Scalar
264 MinimumDistance::findDist( const Sample& x, const Sample& pnt ) const
265 {
266 
267  if ( _hasCategorical ) {
268  for( int i=0; i< _numLayers ; ++i ) {
269  if ( _isCategorical[i] ) {
270  if ( x[i] != pnt[i] ) {
271  return -1.0;
272  }
273  }
274  }
275  }
276 
277  Sample dif = x;
278  dif -= pnt;
279 
280  return dif.norm();
281 
282 }
283 
284 
285 /****************************************************************/
286 /****************** configuration *******************************/
287 void
289 {
290  if (!_done )
291  return;
292 
293  ConfigurationPtr model_config( new ConfigurationImpl("MinimumDistance") );
294  config->addSubsection( model_config );
295 
296  model_config->addNameValue( "IsCategoricalLayer", _isCategorical );
297  model_config->addNameValue( "Distance", _dist );
298 
299  ConfigurationPtr envpoints_config( new ConfigurationImpl("EnvironmentalReferences") );
300  model_config->addSubsection( envpoints_config );
301 
302  for( unsigned int i=0; i<_envPoints.size(); i++) {
303 
304  ConfigurationPtr point_config( new ConfigurationImpl("Reference") );
305  envpoints_config->addSubsection( point_config );
306 
307  point_config->addNameValue( "Value", _envPoints[i] );
308  }
309 }
310 
311 void
313 {
314  ConstConfigurationPtr model_config = config->getSubsection( "MinimumDistance",false );
315 
316  if (!model_config)
317  return;
318 
319  // Information about categorical layers
320  _isCategorical = model_config->getAttributeAsSample( "IsCategoricalLayer" );
321  _numLayers = (int)_isCategorical.size();
322 
323  for( int i=0; i<_numLayers; i++) {
324 
325  if ( _isCategorical[i] ) {
326 
327  _hasCategorical = true;
328  break;
329  }
330  }
331 
332  // Maximum distance
333  _dist = model_config->getAttributeAsDouble( "Distance", 0.0 );
334 
335  // Environmental points
336  ConstConfigurationPtr envpoints_config = model_config->getSubsection( "EnvironmentalReferences",false );
337 
338  Configuration::subsection_list subs = envpoints_config->getAllSubsections();
339 
340  Configuration::subsection_list::iterator begin = subs.begin();
341  Configuration::subsection_list::iterator end = subs.end();
342  for ( ; begin != end; ++begin ) {
343 
344  if ( (*begin)->getName() != "Reference" )
345  continue;
346 
347  Sample point = (*begin)->getAttributeAsSample( "Value" );
348 
349  _envPoints.push_back( point );
350  }
351 
352  _done = true;
353 }
Scalar getValue(const Sample &x) const
static AlgMetadata metadata
void warn(const char *format,...)
'Warn' level.
Definition: Log.cpp:273
std::vector< ConfigurationPtr > subsection_list
double Scalar
Type of map values.
Definition: om_defs.hh:39
#define MAXDIST_ID
std::vector< Sample > _envPoints
Scalar _dist
Parameter for MaxDistance.
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
virtual void _setConfiguration(const ConstConfigurationPtr &)
OM_ALG_DLL_EXPORT AlgorithmImpl * algorithmFactory()
OM_ALG_DLL_EXPORT AlgMetadata const * algorithmMetadata()
void error(const char *format,...)
'Error' level.
Definition: Log.cpp:290
int getParameter(std::string const &name, std::string *value)
void resize(std::size_t size)
Definition: Sample.cpp:153
static AlgParamMetadata parameters[NUM_PARAM]
Scalar norm() const
Definition: Sample.cpp:457
std::size_t size() const
Definition: Sample.hh:70
int getConvergence(Scalar *val)
#define NUM_PARAM
SamplerPtr _samp
Definition: Algorithm.hh:245
virtual void _getConfiguration(ConfigurationPtr &) const
Scalar findDist(const Sample &x, const Sample &pnt) const
std::vector< OccurrencePtr >::const_iterator const_iterator
Definition: Occurrences.hh:85
int min(int v1, int v2)
Definition: rules_base.cpp:56
Normalizer * _normalizerPtr
Definition: Algorithm.hh:247
virtual ~MinimumDistance()
Definition: Sample.hh:25