aimstil  5.0.5
miscUtils.h
Go to the documentation of this file.
1 #ifndef _MISCUTILS_H_
2 #define _MISCUTILS_H_
3 
4 // includes from STL
5 #include <algorithm>
6 #include <cassert>
7 #include <cmath>
8 #include <cstdarg> // va_start
9 #include <numeric> // accumulate
10 
11 // includes from BOOST
12 #include <boost/array.hpp>
13 #include <boost/type_traits.hpp>
14 
15 // includes from AIMS
16 #include "aims/vector/vector.h"
17 
18 // includes from TIL
19 #include "til/is_traits.h"
20 #include "til/Matrix3.h"
21 #include "til/TExpr.h"
22 #include "til/TExprOperators.h"
23 
24 // includes from TIL
25 #include "globalTraits.h"
26 
27 namespace til
28 {
29  namespace policy
30  {
31  //---------------------------------------------------------------
32 
35 
36  //---------------------------------------------------------------
37 
40 
41  //---------------------------------------------------------------
42 
43  } // namespace policy
44 
45 
46 
47 
48  //---------------------------------------------------------------------------
49  /*
51  template < typename TVertexCollection >
52  Point3dd
53  getAverage(const TVertexCollection &vertices)
54  {
55  typename TVertexCollection::const_iterator iVertex;
56  Point3dd res(0.0, 0.0, 0.0);
57 
58  // Add position of all vertices
59  for (iVertex = vertices.begin(); iVertex != vertices.end(); ++iVertex)
60  {
61  res += *iVertex;
62  }
63  // Divide by the number of points
64  res *= 1.0/size(vertices);
65  return res;
66  }
67  */
68 
69  //---------------------------------------------------------------------------
70 
72  template < typename T >
73  inline
74  T
75  norm2(T x, T y, T z)
76  { return x*x+y*y+z*z; }
77 
78  //---------------------------------------------------------------------------
79 
80  /*
81  template < typename T, typename TPoint3DFrom >
82  inline
83  typename boost::enable_if_c<is_3DPoint<TPoint3DFrom>::value>::type
84  cast(const TPoint3DFrom & x, boost::array<T,3> & y)
85  {
86  y[0] = p[0];
87  y[1] = p[1];
88  y[2] = p[2];
89  }
90  */
91 
92  /*
94  template < typename TTo, typename TFrom >
95  typename boost::disable_if_c<
96  (is_3DPoint<TFrom>::value && is_3DPoint<TTo>::value) ||
97  (is_3DPoint<TFrom>::value && is_BoostArray_N<TTo,3>::value)
98  , TTo>::type
99  cast(const TFrom & v) { return static_cast<TTo>(v); }
100 
102  template < typename TPoint3DTo, typename TPoint3DFrom >
103  typename boost::enable_if_c<is_3DPoint<TPoint3DFrom>::value && is_3DPoint<TPoint3DTo>::value, TPoint3DTo && !is_BoostArray_N<TPoint3DTo>::value>::type
104  cast(const TPoint3DFrom &p)
105  {
106  return TPoint3DTo(p[0], p[1], p[2]);
107  }
108 
109  template < typename TBoostArray, typename TPoint3DFrom >
110  typename boost::enable_if_c<is_3DPoint<TPoint3DFrom>::value && is_BoostArray_N<TBoostArray, 3>::value, TBoostArray>::type
111  cast(const TPoint3DFrom & p)
112  {
113  TBoostArray tmp;
114  tmp[0] = p[0];
115  tmp[1] = p[1];
116  tmp[2] = p[2];
117  return tmp;
118  }
119  */
120 
121  /*
122  namespace til
123  {
125  // copy process
126  template < typename TIterator1, typename TIterator2 >
127  void
128  copy_convert
129  (
130  const TIterator1 & begin1,
131  const TIterator1 & end1,
132  const TIterator2 & begin2
133  )
134  {
135  TIterator1 i1 = begin1;
136  TIterator2 i2 = begin2;
137  for (; i1 != end1; ++i1, ++i2)
138  {
139  convert(*i1, *i2);
140  }
141  }
142  }
143  */
144 
145 
146  namespace detail
147  {
148  template < typename TContainer1, typename TContainer2 >
149  typename boost::disable_if_c<
150  is_container<typename TContainer1::value_type>::value &&
151  is_container<typename TContainer2::value_type>::value
152  >::type
154  (
155  const TContainer1 & c1,
156  TContainer2 & c2
157  )
158  {
159  if (size(c2) != size(c1))
160  {
161  c2.resize(size(c1));
162  }
163  }
164 
165  template < typename TContainer1, typename TContainer2 >
166  typename boost::enable_if_c<
167  is_container<typename TContainer1::value_type>::value &&
168  is_container<typename TContainer2::value_type>::value
169  >::type
171  (
172  const TContainer1 & c1,
173  TContainer2 & c2
174  )
175  {
176  if (size(c2) != size(c1))
177  {
178  c2.resize(size(c1));
179  }
180  typename TContainer1::const_iterator iC1 = c1.begin();
181  typename TContainer2::iterator iC2 = c2.begin();
182  for (; iC1 != c1.end(); ++iC1, ++iC2)
183  {
184  _allocate_sameSize<typename TContainer1::value_type, typename TContainer2::value_type>(*iC1, *iC2);
185  }
186  }
187  }
188 
189 
198  template < typename TContainer1, typename TContainer2 >
199  void
201  (
202  const TContainer1 & c1,
203  TContainer2 & c2
204  )
205  { detail::_allocate_sameSize<TContainer1, TContainer2>(c1,c2); }
206 
207  /*
208  template < typename TContainer1, typename TContainer2 >
209  void
210  allocate_sameSize
211  (
212  const TContainer1 & c1, ///< The model
213  TContainer2 & c2 ///< The container to be allocated
214  )
215  {
216  if (size(c2) != size(c1))
217  {
218  c2.resize(size(c1));
219  }
220  if (is_container<typename TContainer1::value_type>::value &&
221  is_container<typename TContainer2::value_type>::value)
222  {
223  typename TContainer1::const_iterator iC1 = c1.begin();
224  typename TContainer2::iterator iC2 = c2.begin();
225  for (; iC1 != c1.end(); ++iC1, ++iC2)
226  {
227  allocate_sameSize(*iC1, *iC2);
228  }
229  }
230  }
231  */
232 
233 
234  namespace functor
235  {
236 
238  // TODO: I think boost::numeric::converter could be used there but maybe
239  // without range checking -- this could really drag performance down.
240  template < typename TPrecision, typename TVector3D >
241  inline
242  TPrecision
243  diff2(const TVector3D &v1, const TVector3D &v2)
244  { return static_cast<TPrecision>(norm2(v1[0]-v2[0], v1[1]-v2[1], v1[2]-v2[2])); }
245 
247  template < typename TPrecision, typename TVector3D >
248  inline
249  TPrecision
250  diff(const TVector3D &v1, const TVector3D &v2)
251  { return static_cast<TPrecision>(std::sqrt(diff2<double>(v1,v2))); }
252 
254  struct Diff2
255  {
256  template < typename TVector3D, typename TPrecision >
257  typename boost::enable_if_c<
258  is_3DVector<TVector3D>::value
259  >::type
260  operator()(const TVector3D &v1, const TVector3D &v2, TPrecision &res) const
261  { res = diff2<TPrecision>(v1,v2); }
262  };
263 
266  struct Diff
267  {
268  template < typename TVector3D, typename TPrecision >
269  void operator()(const TVector3D &v1, const TVector3D &v2, TPrecision &res) const
270  { res = diff<TPrecision>(v1,v2); }
271  };
272 
274  template < typename TVector3D >
275  struct Normalize
276  {
277  void operator()(const TVector3D &v1, const TVector3D &v2, TVector3D & res) const
278  {
279  sub(v1, v2, res);
280  div(res, norm(res));
281  }
282  };
283  }
284 
285  //---------------------------------------------------------------------------
286 
288  template < typename TRes, typename TIterator >
289  void mean(TIterator begin, TIterator end, TRes & res);
290 
291  //---------------------------------------------------------------------------
292 
296  // TODO: change this: remove res = T()
297  template < typename TRes, typename TCollection >
298  void centroid(const TCollection & c, TRes & res)
299  __attribute__((__deprecated__("use mean() instead")));
300 
301  template < typename TRes, typename TCollection >
302  void centroid(const TCollection & c, TRes & res)
303  {
304  mean(c.begin(), c.end(), res);
305  }
306 
307  //---------------------------------------------------------------------------
308 
309  template < typename TPoint, typename TPointCollection >
310  void stdev(const TPointCollection & c, TPoint & res);
311 
312  //---------------------------------------------------------------------------
313 
315  template < typename T1, typename T2 >
316  inline bool
317  same_sign(const T1 & x, const T2 & y)
318  {
319  if (x >= 0) return (y >= 0);
320  else return (y <= 0);
321  }
322 
323  //---------------------------------------------------------------------------
324 
326  template < typename T1, typename T2 >
327  inline T1 sign(T1 x, T2 y)
328  { return (y >= 0 ? x : -x); }
329 
330  //---------------------------------------------------------------------------
331 
332  template < typename T >
333  char * sprintf(T format, ... )
334  {
335  static char *s = new char[1024];
336  va_list vl;
337  va_start(vl, format);
338  vsprintf(s, format, vl);
339  return s;
340  }
341 
342  //---------------------------------------------------------------------------
343 
344  template < typename T >
346  {
347  bool operator()(const T & x, const T & y) const
348  { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
349  };
350 
351  //---------------------------------------------------------------------------
352 
360  template < typename TIndexCollection >
361  std::vector<std::list<std::size_t> >
362  invertIndices(const std::vector<TIndexCollection> & c);
363 
364  //-----------------------------------------------------------------
365 
367  template < typename TIterator >
369  {
370  bool operator()(TIterator i, TIterator j) const
371  { return &*i < &*j; }
372  };
373 
374  //-----------------------------------------------------------------
375 
377  template < typename T1, typename T2 >
379  {
380  bool operator()(const std::pair<T1,T2> & p1, const std::pair<T1,T2> & p2) const
381  { return p1.second < p2.second; }
382  };
383 
384  //-----------------------------------------------------------------
385 
387  template < typename T1, typename T2 >
389  {
390  bool operator()(const std::pair<T1,T2> & p1, const std::pair<T1,T2> & p2) const
391  { return p1.second > p2.second; }
392  };
393 
394  //-----------------------------------------------------------------
395 
397  template < typename T1, typename T2 >
399  {
400  inline T1 operator()(std::pair<T1, T2> const & p) const { return p.first; }
401  };
402 
403  //-----------------------------------------------------------------
404 
406  template < typename T >
407  inline std::size_t max_index(T x0, T x1, T x2);
408 
409  //---------------------------------------------------------------------------
410 
412  template < typename T >
413  inline std::size_t min_index(T x0, T x1, T x2);
414 
415  //---------------------------------------------------------------------------
416 
418  template < typename T >
419  inline bool is_nan(T x);
420 
421  //---------------------------------------------------------------------------
422 
423  template < typename TPrec >
425  {
426  template < typename T, std::size_t D >
427  TPrec operator() (const numeric_array<T,D> & a1, const numeric_array<T,D> & a2) const
428  {
429  return dist2(a1, a2, prec<TPrec>());
430  }
431  };
432 
433  //---------------------------------------------------------------------------
434 
436  // TODO: add a test so that it works only for signed integers... or is >> working only on signed integers anyway?
437  template < typename T >
438  bool is_dyadic(T n);
439 
440  //---------------------------------------------------------------------------
441 
443  template < typename T >
444  inline int log2(T n);
445 
446  //---------------------------------------------------------------------------
447 
449  template < typename T >
450  inline T exp2(unsigned int n);
451 
452  //---------------------------------------------------------------------------
453 
455  template < typename T >
456  inline T lower_dyadic(T n);
457 
458  //-------------------------------------------------------------------------------------------
459 
461  // TODO: shouldn't this guy be in functor or something? Or something like source or generator?
462  template < typename T >
464  {
465  public: // constructors
467  Incrementor(T i0) : m_i(i0) {}
468  public: // operator
471  T operator()() { return m_i++; }
472  private: // data
473  T m_i;
474  };
475 
476  //-------------------------------------------------------------------------------------------
477 
478 
479 } // namespace til
480 
481 // package include
482 #include "misc_utils.tpp"
483 
484 
485 #endif //_MISCUTILS_H_
Returns first value of pair.
Definition: miscUtils.h:398
TRes div(T1 x, T2 y)
Definition: functors.h:406
void stdev(const TPointCollection &c, TPoint &res)
TPrec norm2(const numeric_array< T, D > &a, prec< TPrec >)
Return the squared euclidean norm of a.
std::vector< std::list< std::size_t > > invertIndices(const std::vector< TIndexCollection > &c)
Invert an index array.
void sqrt(const TImage &in, TImage &out)
Definition: imageArith.h:326
TPrecision diff2(const TVector3D &v1, const TVector3D &v2)
Computes the squared Euclidean distance between two vectors.
Definition: miscUtils.h:243
TPrecision diff(const TVector3D &v1, const TVector3D &v2)
Computes the Euclidean distance between two vectors.
Definition: miscUtils.h:250
bool operator()(const std::pair< T1, T2 > &p1, const std::pair< T1, T2 > &p2) const
Definition: miscUtils.h:380
INLINE double norm(const T &a, const T &b)
< Euclidean norm of 2D vector (a, b)
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
TAccumulationPoint centroid(const TPointCollection &c)
Definition: point_tools.h:22
void operator()(const TVector3D &v1, const TVector3D &v2, TVector3D &res) const
Definition: miscUtils.h:277
bool operator()(TIterator i, TIterator j) const
Definition: miscUtils.h:370
std::size_t max_index(T x0, T x1, T x2)
Returns i0, where X_i0 is the greatesstructt of all Xi&#39;s.
TRes sub(T1 x, T2 y)
Definition: functors.h:398
numeric_array< T, D > size(const Box< T, D > &box)
Return the size of a box.
Definition: boxTools.h:56
A policy label to indicate that radian range is [0; PI[.
Definition: miscUtils.h:39
T lower_dyadic(T n)
Return the greater power of two inferior or equal to n.
bool operator()(const T &x, const T &y) const
Definition: miscUtils.h:347
bool same_sign(const T1 &x, const T2 &y)
Return true iff both arguments have same sign.
Definition: miscUtils.h:317
T1 operator()(std::pair< T1, T2 > const &p) const
Definition: miscUtils.h:400
boost::enable_if_c< is_container< typename TContainer1::value_type >::value &&is_container< typename TContainer2::value_type >::value >::type _allocate_sameSize(const TContainer1 &c1, TContainer2 &c2)
Definition: miscUtils.h:171
void operator()(const TVector3D &v1, const TVector3D &v2, TPrecision &res) const
Definition: miscUtils.h:269
operator< on the address in memory of the pointed object
Definition: miscUtils.h:368
Computes the Euclidean distance between two vectors.
Definition: miscUtils.h:266
t_bsprec mean(const TImage &im)
Returns the mean of the intensities of the input image.
operator< on the second member of a pair.
Definition: miscUtils.h:378
int log2(T n)
Returns the largest m so that n >= 2^m.
char * sprintf(T format,...)
Definition: miscUtils.h:333
T operator()()
Return current value.
Definition: miscUtils.h:471
void allocate_sameSize(const TContainer1 &c1, TContainer2 &c2)
A simple function to allocate a container so that its size matches the size of a second container...
Definition: miscUtils.h:201
bool is_dyadic(T n)
Returns true if argument is of the form 2^m, m>=1.
This file contains all the material a library user should need to use template expressions.
bool operator()(const std::pair< T1, T2 > &p1, const std::pair< T1, T2 > &p2) const
Definition: miscUtils.h:390
Incrementor(T i0)
Initialize with value.
Definition: miscUtils.h:467
A class which returns a value that is increased everytime it is returned.
Definition: miscUtils.h:463
Normalize a vector with its Euclidean norm.
Definition: miscUtils.h:275
Computes the squared Euclidean distance between two vectors.
Definition: miscUtils.h:254
operator> on the second member of a pair.
Definition: miscUtils.h:388
T1 sign(T1 x, T2 y)
Change the sign of x if y < 0.
Definition: miscUtils.h:327
T exp2(unsigned int n)
Returns 2^n.
A dummy class used to pass a precision type for computations to some functions.
std::size_t min_index(T x0, T x1, T x2)
Returns i0, where X_i0 is the smallest of all Xi&#39;s.
boost::enable_if_c< is_3DVector< TVector3D >::value >::type operator()(const TVector3D &v1, const TVector3D &v2, TPrecision &res) const
Definition: miscUtils.h:260
TPrec dist2(const numeric_array< T1, D > &v1, const numeric_array< T2, D > &v2, prec< TPrec >)
Return the squared Euclidean distance between two vectors, computed with a precision given as the fir...
A policy label to indicate that radian range is ]-PI; PI].
Definition: miscUtils.h:34
bool is_nan(const numeric_array< T, D > &a)
Check that numeric_array does not contain any NAN TODO: Actually, is_nan should be a functor...