mt
 All Classes Files Functions Enumerations Groups Pages
scalar.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2006 by Adolfo Rodriguez *
3  * adolfo.rodriguez@upc.edu *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
22 
23 // HEADER GUARD
24 #ifndef MT_SCALAR_H
25 #define MT_SCALAR_H
26 
27 // C++ STANDARD HEADERS
28 #include <algorithm>
29 #include <cmath>
30 
31 // MT LIBRARY HEADERS
32 #include <mt/exception.h>
33 
34 #ifdef MT_USE_BASIC_SCALAR
35 
36  #include <mt/basic_scalar.h>
37  #include <mt/basic_scalar_utility.h>
38 
39 #endif
40 
41 
43 
44 namespace mt
45 {
46 
47 // USING DECLARATIONS/DIRECTIVES
48 using std::min;
49 using std::max;
50 
51 using std::floor;
52 using std::ceil;
53 
54 using std::abs;
55 using std::pow;
56 using std::sqrt;
57 
58 using std::exp;
59 using std::log;
60 using std::log10;
61 
62 using std::sin;
63 using std::cos;
64 using std::tan;
65 
66 using std::sinh;
67 using std::cosh;
68 using std::tanh;
69 
70 using std::acos;
71 using std::asin;
72 using std::atan;
73 using std::atan2;
74 
94 
96 
97 // Value type definition
98 
99 #ifdef MT_USE_DOUBLES
100 
101  typedef double value_t;
102 
103 #else
104 
105  typedef float value_t;
106 
107 #endif
108 
109 
110 // Scalar type definition
111 
112 #ifdef MT_USE_BASIC_SCALAR
113 
114  typedef BasicScalarTraits<value_t> ScalarTraits;
115  typedef BasicScalar<value_t> Scalar;
116 
117 #else
118 
119  typedef value_t Scalar;
120 
121 #endif
122 
123 
125 
126 const Scalar PI(std::atan2(Scalar(0.0), Scalar(-1.0)));
127 const Scalar HALF_PI(PI / Scalar(2.0));
128 const Scalar TWO_PI (PI * Scalar(2.0));
129 
130 
132 
134 Scalar degToRad(const Scalar& s);
135 
137 Scalar radToDeg(const Scalar& s);
138 
140 Scalar sq(const Scalar& s);
141 
145 Scalar sgn(const Scalar& s);
146 
167 template<class T>
168 T normalize(const T& s,
169  const T& lower,
170  const T& upper,
171  T& cycles);
172 
174 template<class T>
175 T normalize(const T& s,
176  const T& lower,
177  const T& upper);
178 
181 template<class T>
182 T saturate(const T& s,
183  const T& lower,
184  const T& upper);
185 
191 template<class T>
192 T round(const T& s,
193  const T& tol = T(1.0));
194 
200 template<class T>
201 T asinMt(const T& sin_ang,
202  const T& ref_ang);
203 
209 template<class T>
210 T acosMt(const T& cos_ang,
211  const T& ref_ang);
212 
214 template<class T>
215 T getValue(const T& s);
216 
218 
219 inline Scalar degToRad(const Scalar& s)
220 {
221  static const Scalar rads_per_deg(PI / Scalar(180.0));
222  return Scalar(s * rads_per_deg);
223 }
224 
225 
226 inline Scalar radToDeg(const Scalar& s)
227 {
228  static const Scalar degs_per_rad(Scalar(180.0) / PI);
229  return Scalar(s * degs_per_rad);
230 }
231 
232 
233 inline Scalar sq(const Scalar& s)
234 {
235  return s * s;
236 }
237 
238 inline Scalar sgn(const Scalar& s)
239 {
240  if (s >= Scalar(0.0))
241  {
242  return Scalar(1.0);
243  }
244  else
245  {
246  return Scalar(-1.0);
247  }
248 }
249 
250 
251 template<class T> inline
252 T normalize(const T& s,
253  const T& lower,
254  const T& upper,
255  T& cycles)
256 {
257  util::Assert(lower < upper,
258  Exception("Normalizing interval is ill defined"));
259 
260  T s_norm(s);
261  if (s >= lower && s < upper)
262  {
263  cycles = T(0.0);
264  }
265  else
266  {
267  const T diff(upper - lower);
268  cycles = (s < lower) ?
269  ceil((s - upper) / diff) : floor((s - lower) / diff);
270  s_norm -= (diff * cycles);
271  }
272  return s_norm;
273 }
274 
275 
276 template<class T> inline
277 T normalize(const T& s,
278  const T& lower,
279  const T& upper)
280 {
281  T cycles;
282  return normalize(s, lower, upper, cycles);
283 }
284 
285 
286 template<class T> inline
287 T saturate(const T& s,
288  const T& lower,
289  const T& upper)
290 {
291  util::Assert(lower < upper,
292  Exception("Saturation interval is ill defined"));
293 
294  T s_sat(s);
295  if (s < lower)
296  {
297  s_sat = lower;
298  }
299  else if (s > upper)
300  {
301  s_sat = upper;
302  }
303  return s_sat;
304 }
305 
306 
307 template<class T> inline
308 T round(const T& s,
309  const T& tol)
310 {
311  const T abs_tol = abs(tol); // Tolerance must be > 0.0
312  const T x = s / abs_tol;
313  return T(floor(x + 0.5) * abs_tol);
314 }
315 
316 
317 template<class T> inline
318 T asinMt(const T& sin_ang,
319  const T& ref_ang)
320 {
321  // Two possible angle values
322  T val1(asin(sin_ang));
323  T val2(PI - val1);
324 
325  // Normalizes val1 and ref_ang value to the [0, 2pi) interval
326  val1 = normalize(val1, T(0.0), TWO_PI);
327  Scalar ref_norm(normalize(ref_ang, T(0.0), TWO_PI));
328 
329  // Selects the appropiate angle using the the reference ang_ref
330  T diff1(abs(ref_norm - val1));
331  T diff2(abs(ref_norm - val2));
332  return (diff1 < diff2) ? val1 : val2;
333 }
334 
335 
336 template<class T> inline
337 T acosMt(const T& cos_ang,
338  const T& ref_ang)
339 {
340  // Two possible angle values
341  const T val1(acos(cos_ang));
342  const T val2(TWO_PI - val1);
343 
344  // Normalizes ref_ang value to the [0, 2pi) interval
345  Scalar ref_norm(normalize(ref_ang, T(0.0), TWO_PI));
346 
347  // Selects the appropiate angle using the the reference ang_ref
348  T diff1(abs(ref_norm - val1));
349  T diff2(abs(ref_norm - val2));
350  return (diff1 < diff2) ? val1 : val2;
351 }
352 
353 
354 template<class T> inline
355 T getValue(const T& s)
356 {
357  return s;
358 }
359 
360 } // mt
361 
362 #endif // MT_SCALAR_H