aimstil  5.0.5
numeric_array_tools.h
Go to the documentation of this file.
1 #ifndef TIL_NUMERIC_ARRAY_TOOLS_H
2 #define TIL_NUMERIC_ARRAY_TOOLS_H
3 
6 
7 namespace til
8 {
9 
10  //---------------------------------------------------------------------------
11 
12  // Technically, it's OK if newSize if simply <= D. But the problem is that
13  // if we allow newSize < D, we have the surprising effect that doing a resize
14  // won't affect a.size()...
15  //TODO: I think this crap is completely obsolete, right? I hope so.
16  template < typename T, std::size_t D >
17  inline void resize(numeric_array<T,D> &, std::size_t newSize)
18  __attribute__((__deprecated__));
19 
20  template < typename T, std::size_t D >
21  inline void resize(numeric_array<T,D> &, std::size_t
22 #ifndef NDEBUG
23  newSize
24 #endif
25  )
26  {
27  assert(newSize == D);
28  }
29 
30  //---------------------------------------------------------------------------
31 
32  // TODO: keep this in a perf namespace and compare with current min version.
33  /*
34  template < typename T, std::size_t D >
35  inline T min(const numeric_array<T,D> & x)
36  { return min(x.whole_range()); }
37  */
38 
39  template < typename TCollection >
40  inline
41  std::ostream & stream_collection(std::ostream & os, const TCollection & v)
42  {
43  os << "[ ";
44  typename TCollection::const_iterator iV = v.begin();
45  for (; iV != v.end(); ++iV)
46  {
47  os << *iV << ", ";
48  }
49  os << " ]";
50  return os;
51  }
52 
53  //---------------------------------------------------------------------------
54 
55  template < typename T, std::size_t D >
56  inline std::ostream & operator<<(std::ostream & os, const numeric_array<T,D> & x)
57  { return stream_collection(os,x); }
58 
60  // TODO: How to adapt this when storage is sparse?
61  template < typename TPrec, typename T, std::size_t D >
62  inline TPrec norm2(const numeric_array<T,D> & a, prec<TPrec>)
63  {
64  typedef TPrec prec_type;
65  prec_type res(0);
66  for (std::size_t i = 0; i < D; ++i)
67  {
68  res += square(static_cast<prec_type>(a[i]));
69  }
70  return res;
71  }
72 
73  //---------------------------------------------------------------------------
74 
76  template < typename T, std::size_t D >
77  inline T norm2(const numeric_array<T,D> & a)
78  { return norm2(a, prec<T>()); }
79 
80  //---------------------------------------------------------------------------
81 
83  template < typename TPrec, typename T, std::size_t D >
84  inline TPrec norm(const numeric_array<T,D> & a, prec<TPrec>)
85  { return std::sqrt(norm2(a, prec<TPrec>())); }
86 
87  //---------------------------------------------------------------------------
88 
90  template < typename T, std::size_t D >
91  inline T norm(const numeric_array<T,D> & a)
92  { return norm(a, prec<T>()); }
93 
94  //---------------------------------------------------------------------------
95 
98  template < typename TPrec, typename T1, typename T2, std::size_t D >
99  inline
100  TPrec
102  {
103  typedef TPrec prec_type;
104  prec_type res(0);
105  // TODO: replace this by a template expression when have time
106  for (std::size_t i = 0; i < D; ++i)
107  {
108  // NB: I prefer to directly convert into TPrec in case
109  // the content of vectors is unsigned.
110  res += square(static_cast<prec_type>(v1[i]) - static_cast<prec_type>(v2[i]));
111  }
112  return res;
113  }
114 
115  //---------------------------------------------------------------------------
116 
118  template < typename T, std::size_t D >
119  inline
120  T
122  { return dist2(v1, v2, prec<T>()); }
123 
124  //---------------------------------------------------------------------------
125 
127  template < typename TPrec, typename T1, typename T2, std::size_t D >
128  inline
129  TPrec
131  { return std::sqrt(dist2(v1, v2, prec<TPrec>())); }
132 
133  //---------------------------------------------------------------------------
134 
136  template < typename T, std::size_t D >
137  inline T
139  { return dist(v1, v2, prec<T>()); }
140 
141  //---------------------------------------------------------------------------
142 
144  template < typename TPrec, typename T1, typename T2, std::size_t D >
145  inline TPrec
147  {
148  typedef TPrec prec_type;
149  prec_type res = 0;
150  for (std::size_t i = 0; i < D; ++i) res += static_cast<prec_type>(a1[i]) * static_cast<prec_type>(a2[i]);
151  return res;
152  }
153 
154  //---------------------------------------------------------------------------
155 
157  template < typename T, std::size_t D >
158  inline T dot(const numeric_array<T,D> & a1, const numeric_array<T,D> & a2)
159  { return dot(a1, a2, prec<T>()); }
160 
161  //---------------------------------------------------------------------------
162 
163  namespace
164  {
165  template < typename T >
166  inline T
167  cross_line(T a1, T a2, T b1, T b2) { return a1 * b2 - a2 * b1; }
168  }
169 
170  //---------------------------------------------------------------------------
171 
173  template < typename TPrec, typename T1, typename T2 >
174  inline numeric_array<TPrec,3>
176  {
177  // TODO: each element is cast twice to TPrec -- this could be improved.
179  (
180  cross_line<TPrec>(vec1[1], vec1[2], vec2[1], vec2[2]),
181  cross_line<TPrec>(vec1[2], vec1[0], vec2[2], vec2[0]),
182  cross_line<TPrec>(vec1[0], vec1[1], vec2[0], vec2[1])
183  );
184  }
185 
186  //---------------------------------------------------------------------------
187 
189  template < typename T1, typename T2 >
190  inline
191  double
193  {
194  return std::sqrt(
195  til::square(cross_line<double>(vec1[1], vec1[2], vec2[1], vec2[2])) +
196  til::square(cross_line<double>(vec1[2], vec1[0], vec2[2], vec2[0])) +
197  til::square(cross_line<double>(vec1[0], vec1[1], vec2[0], vec2[1]))
198  );
199  }
200 
201  //---------------------------------------------------------------------------
202 
204  template < typename T, std::size_t D >
205  inline numeric_array<T,D>
207  {
208  numeric_array<T,D> res;
209  for (std::size_t i = 0; i < D; ++i) res[i] = std::abs(a[i]);
210  return res;
211  }
212 
213  //---------------------------------------------------------------------------
214 
216  template < typename T, std::size_t D >
217  inline T max(const numeric_array<T,D> & a)
218  {
219  T res = a[0];
220  for (std::size_t i = 1; i < D; ++i) max_helper(res, a[i]);
221  return res;
222  }
223 
224  //---------------------------------------------------------------------------
225 
227  template < typename T, std::size_t D >
228  inline T min(const numeric_array<T,D> & a)
229  {
230  T res = a[0];
231  for (std::size_t i = 1; i < D; ++i) min_helper(res, a[i]);
232  return res;
233  }
234 
235  //---------------------------------------------------------------------------
236 
238  template < typename T >
240  { return cross(vec1, vec2, prec<T>()); }
241 
242  //---------------------------------------------------------------------------
243 
245  template < typename T, std::size_t D >
246  inline T norm_inf(const numeric_array<T,D> & a)
247  {
248  T res = std::abs(a[0]);
249  for (std::size_t i = 1; i < D; ++i) max_helper(res, std::abs(a[i]));
250  return res;
251  }
252 
253  //---------------------------------------------------------------------------
254 
256  template < typename T, std::size_t D >
257  inline void neg(numeric_array<T,D> & vec)
258  { for (std::size_t i = 0; i < D; ++i) vec[i] = -vec[i]; }
259 
260  //---------------------------------------------------------------------------
261 
263  template < typename T, std::size_t D, typename TNewPrecision>
264  struct change_precision< numeric_array<T,D> , TNewPrecision>
265  {
267  private: // requirements
269  };
270 
271  //---------------------------------------------------------------------------
272 
275  template < typename T, std::size_t D >
276  inline bool is_nan(const numeric_array<T,D> & a)
277  {
278  for (std::size_t i = 0; i < D; ++i) if (is_nan(a[i])) return true;
279  return false;
280  }
281 
282  //---------------------------------------------------------------------------
283 
284  template < typename T >
285  inline T cross(const numeric_array<T,2> & x, const numeric_array<T,2> & y)
286  { return x[0] * y[1] - x[1] * y[0]; }
287 
288 
289  //---------------------------------------------------------------------------
290 
291  // This is just to speed up things. Not sure whether this is really necessary...
292  // Actually, this does not have to know numeric_array explicitely, does it?
293  template < int x, int y, int z, typename TIN, typename TOUT >
294  inline void addTo
295  (
296  const numeric_array<TIN,3> & vIn,
297  numeric_array<TOUT,3> & vOut
298  )
299  {
300  if (x) vOut[0] = vIn[0] + x;
301  if (y) vOut[1] = vIn[1] + y;
302  if (z) vOut[2] = vIn[2] + z;
303 
304  }
305 
306  //---------------------------------------------------------------------------
307 
309  template < typename T >
310  inline void
311  tdot
312  (
313  numeric_array<T,3> const & v
314  , SymMatrix3<T> & mat
315  )
316  {
317  for (int j = 0; j < 3; ++j)
318  {
319  T vj = v[j];
320  for (int i = j; i < 3; ++i)
321  {
322  mat(i,j) = v[i] * vj;
323  }
324  }
325  }
326 
327  //---------------------------------------------------------------------------
328 
330  template < typename T >
331  inline void
332  tdot
333  (
334  numeric_array<T,3> const & v1
335  , numeric_array<T,3> const & v2
336  , Matrix3<T> & mat
337  )
338  {
339  for (int j = 0; j < 3; ++j)
340  {
341  T v1j = v1[j];
342  for (int i = 0; i < 3; ++i)
343  {
344  mat(i,j) = v2[i] * v1j;
345  }
346  }
347  }
348  //---------------------------------------------------------------------------
349 
350 } // namespace til
351 
352 
353 #endif
354 
355 
void min_helper(T &minx, T x)
Little helper for something often used when looking for a minimum.
Definition: miscTools.h:220
numeric_array< TPrec, 3 > cross(const numeric_array< T1, 3 > &vec1, const numeric_array< T2, 3 > &vec2, prec< TPrec >)
Return the cross product of two 3D vectors.
TPrec norm2(const numeric_array< T, D > &a, prec< TPrec >)
Return the squared euclidean norm of a.
boost::enable_if< is_Image< TImage >, typename TImage::value_type >::type min(const TImage &im)
numeric_array< typename change_precision< T, TNewPrecision >::type, D > type
void sqrt(const TImage &in, TImage &out)
Definition: imageArith.h:326
std::ostream & stream_collection(std::ostream &os, const TCollection &v)
TPrec dot(const numeric_array< T1, D > &a1, const numeric_array< T2, D > &a2, prec< TPrec >)
Return the dot product of two vectors.
A class to store a 3*3 symetric matrix.
Definition: SymMatrix3.h:23
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
void resize(numeric_array< T, D > &, std::size_t newSize) __attribute__((__deprecated__))
T norm_inf(const numeric_array< T, D > &a)
Return the infinity norm (i.e. max absolute value) of array.
void tdot(numeric_array< T, 3 > const &v, SymMatrix3< T > &mat)
Stores v.v^T in mat.
numeric_array< T, D > abs(const numeric_array< T, D > &a)
Absolute value, element-wise.
TImage::value_type max(const TImage &im)
Returns the maximum intensity of the input image.
TPrec dist(const numeric_array< T1, D > &v1, const numeric_array< T2, D > &v2, prec< TPrec >)
Return the Euclidean distance between two arrays.
A mathematical matrix.
Definition: Matrix3.h:90
void addTo(const numeric_array< TIN, 3 > &vIn, numeric_array< TOUT, 3 > &vOut)
void neg(TImage &im)
Definition: imageArith.h:32
double cross_norm(const numeric_array< T1, 3 > &vec1, const numeric_array< T2, 3 > &vec2)
Return the norm of the cross product of two 3D vectors.
void max_helper(T &maxx, T x)
Little helper for something often used when looking for a maximum.
Definition: miscTools.h:213
void square(const TImage &in, TImage &out)
Definition: imageArith.h:310
Changing the numerical precision of an object.
Definition: traits.h:106
A dummy class used to pass a precision type for computations to some functions.
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...
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...