Gazebo Math

API Reference

7.5.1
gz/math/Helpers.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef GZ_MATH_FUNCTIONS_HH_
18 #define GZ_MATH_FUNCTIONS_HH_
19 
20 #include <algorithm>
21 #include <chrono>
22 #include <cmath>
23 #include <cstdint>
24 #include <ostream>
25 #include <limits>
26 #include <string>
27 #include <tuple>
28 #include <utility>
29 #include <vector>
30 
31 #include <gz/math/config.hh>
32 #include "gz/math/Export.hh"
33 
36 template <typename T>
38 
39 // TODO(CH3): Deprecated. Remove on tock.
40 template <typename T>
42 
45 #ifdef M_PI
46 #define GZ_PI M_PI
47 #define GZ_PI_2 M_PI_2
48 #define GZ_PI_4 M_PI_4
49 #define GZ_SQRT2 M_SQRT2
50 #else
51 #define GZ_PI 3.14159265358979323846
52 #define GZ_PI_2 1.57079632679489661923
53 #define GZ_PI_4 0.78539816339744830962
54 #define GZ_SQRT2 1.41421356237309504880
55 #endif
56 
60 #if defined __FLT_EVAL_METHOD__ && __FLT_EVAL_METHOD__ == 2
61 #define GZ_FP_VOLATILE volatile
62 #else
63 #define GZ_FP_VOLATILE
64 #endif
65 
68 #define GZ_SPHERE_VOLUME(_radius) (4.0*GZ_PI*std::pow(_radius, 3)/3.0)
69 
73 #define GZ_CONE_VOLUME(_r, _l) (_l * GZ_PI * std::pow(_r, 2) / 3.0)
74 
78 #define GZ_CYLINDER_VOLUME(_r, _l) (_l * GZ_PI * std::pow(_r, 2))
79 
84 #define GZ_BOX_VOLUME(_x, _y, _z) (_x *_y * _z)
85 
88 #define GZ_BOX_VOLUME_V(_v) (_v.X() *_v.Y() * _v.Z())
89 
90 namespace gz::math
91 {
92  // Inline bracket to help doxygen filtering.
93  inline namespace GZ_MATH_VERSION_NAMESPACE {
94  //
96  static const size_t GZ_ZERO_SIZE_T = 0u;
97 
99  static const size_t GZ_ONE_SIZE_T = 1u;
100 
102  static const size_t GZ_TWO_SIZE_T = 2u;
103 
105  static const size_t GZ_THREE_SIZE_T = 3u;
106 
108  static const size_t GZ_FOUR_SIZE_T = 4u;
109 
111  static const size_t GZ_FIVE_SIZE_T = 5u;
112 
114  static const size_t GZ_SIX_SIZE_T = 6u;
115 
117  static const size_t GZ_SEVEN_SIZE_T = 7u;
118 
120  static const size_t GZ_EIGHT_SIZE_T = 8u;
121 
123  static const size_t GZ_NINE_SIZE_T = 9u;
124 
125  // TODO(CH3): Deprecated. Remove on tock.
126  constexpr auto GZ_DEPRECATED(7) IGN_ZERO_SIZE_T = &GZ_ZERO_SIZE_T;
127  constexpr auto GZ_DEPRECATED(7) IGN_ONE_SIZE_T = &GZ_ONE_SIZE_T;
128  constexpr auto GZ_DEPRECATED(7) IGN_TWO_SIZE_T = &GZ_TWO_SIZE_T;
129  constexpr auto GZ_DEPRECATED(7) IGN_THREE_SIZE_T = &GZ_THREE_SIZE_T;
130  constexpr auto GZ_DEPRECATED(7) IGN_FOUR_SIZE_T = &GZ_FOUR_SIZE_T;
131  constexpr auto GZ_DEPRECATED(7) IGN_FIVE_SIZE_T = &GZ_FIVE_SIZE_T;
132  constexpr auto GZ_DEPRECATED(7) IGN_SIX_SIZE_T = &GZ_SIX_SIZE_T;
133  constexpr auto GZ_DEPRECATED(7) IGN_SEVEN_SIZE_T = &GZ_SEVEN_SIZE_T;
134  constexpr auto GZ_DEPRECATED(7) IGN_EIGHT_SIZE_T = &GZ_EIGHT_SIZE_T;
135  constexpr auto GZ_DEPRECATED(7) IGN_NINE_SIZE_T = &GZ_NINE_SIZE_T;
136 
138  static const double MAX_D = std::numeric_limits<double>::max();
139 
141  static const double MIN_D = std::numeric_limits<double>::min();
142 
144  static const double LOW_D = std::numeric_limits<double>::lowest();
145 
147  static const double INF_D = std::numeric_limits<double>::infinity();
148 
150  static const double NAN_D = std::numeric_limits<double>::quiet_NaN();
151 
153  static const float MAX_F = std::numeric_limits<float>::max();
154 
156  static const float MIN_F = std::numeric_limits<float>::min();
157 
159  static const float LOW_F = std::numeric_limits<float>::lowest();
160 
162  static const float INF_F = std::numeric_limits<float>::infinity();
163 
165  static const float NAN_F = std::numeric_limits<float>::quiet_NaN();
166 
168  static const uint16_t MAX_UI16 = std::numeric_limits<uint16_t>::max();
169 
171  static const uint16_t MIN_UI16 = std::numeric_limits<uint16_t>::min();
172 
175  static const uint16_t LOW_UI16 = std::numeric_limits<uint16_t>::lowest();
176 
178  static const uint16_t INF_UI16 = std::numeric_limits<uint16_t>::infinity();
179 
181  static const int16_t MAX_I16 = std::numeric_limits<int16_t>::max();
182 
184  static const int16_t MIN_I16 = std::numeric_limits<int16_t>::min();
185 
188  static const int16_t LOW_I16 = std::numeric_limits<int16_t>::lowest();
189 
191  static const int16_t INF_I16 = std::numeric_limits<int16_t>::infinity();
192 
194  static const uint32_t MAX_UI32 = std::numeric_limits<uint32_t>::max();
195 
197  static const uint32_t MIN_UI32 = std::numeric_limits<uint32_t>::min();
198 
201  static const uint32_t LOW_UI32 = std::numeric_limits<uint32_t>::lowest();
202 
204  static const uint32_t INF_UI32 = std::numeric_limits<uint32_t>::infinity();
205 
207  static const int32_t MAX_I32 = std::numeric_limits<int32_t>::max();
208 
210  static const int32_t MIN_I32 = std::numeric_limits<int32_t>::min();
211 
214  static const int32_t LOW_I32 = std::numeric_limits<int32_t>::lowest();
215 
217  static const int32_t INF_I32 = std::numeric_limits<int32_t>::infinity();
218 
220  static const uint64_t MAX_UI64 = std::numeric_limits<uint64_t>::max();
221 
223  static const uint64_t MIN_UI64 = std::numeric_limits<uint64_t>::min();
224 
227  static const uint64_t LOW_UI64 = std::numeric_limits<uint64_t>::lowest();
228 
230  static const uint64_t INF_UI64 = std::numeric_limits<uint64_t>::infinity();
231 
233  static const int64_t MAX_I64 = std::numeric_limits<int64_t>::max();
234 
236  static const int64_t MIN_I64 = std::numeric_limits<int64_t>::min();
237 
240  static const int64_t LOW_I64 = std::numeric_limits<int64_t>::lowest();
241 
243  static const int64_t INF_I64 = std::numeric_limits<int64_t>::infinity();
244 
246  static const int NAN_I = std::numeric_limits<int>::quiet_NaN();
247 
255  template<typename T>
256  inline T clamp(T _v, T _min, T _max)
257  {
258  return std::max(std::min(_v, _max), _min);
259  }
260 
264  inline bool isnan(float _v)
265  {
266  return (std::isnan)(_v);
267  }
268 
272  inline bool isnan(double _v)
273  {
274  return (std::isnan)(_v);
275  }
276 
280  inline float fixnan(float _v)
281  {
282  return isnan(_v) || std::isinf(_v) ? 0.0f : _v;
283  }
284 
288  inline double fixnan(double _v)
289  {
290  return isnan(_v) || std::isinf(_v) ? 0.0 : _v;
291  }
292 
296  inline bool isEven(const int _v)
297  {
298  return !(_v % 2);
299  }
300 
304  inline bool isEven(const unsigned int _v)
305  {
306  return !(_v % 2);
307  }
308 
312  inline bool isOdd(const int _v)
313  {
314  return (_v % 2) != 0;
315  }
316 
320  inline bool isOdd(const unsigned int _v)
321  {
322  return (_v % 2) != 0;
323  }
324 
331  template<typename T>
332  inline int sgn(T _value)
333  {
334  return (T(0) < _value) - (_value < T(0));
335  }
336 
343  template<typename T>
344  inline int signum(T _value)
345  {
346  return sgn(_value);
347  }
348 
352  template<typename T>
353  inline T mean(const std::vector<T> &_values)
354  {
355  T sum = 0;
356  for (unsigned int i = 0; i < _values.size(); ++i)
357  sum += _values[i];
358  return sum / static_cast<T>(_values.size());
359  }
360 
364  template<typename T>
365  inline T variance(const std::vector<T> &_values)
366  {
367  T avg = mean<T>(_values);
368 
369  T sum = 0;
370  for (unsigned int i = 0; i < _values.size(); ++i)
371  sum += (_values[i] - avg) * (_values[i] - avg);
372  return sum / static_cast<T>(_values.size());
373  }
374 
378  template<typename T>
379  inline T max(const std::vector<T> &_values)
380  {
381  return *std::max_element(std::begin(_values), std::end(_values));
382  }
383 
387  template<typename T>
388  inline T min(const std::vector<T> &_values)
389  {
390  return *std::min_element(std::begin(_values), std::end(_values));
391  }
392 
398  template<typename T>
399  inline bool equal(const T &_a, const T &_b,
400  const T &_epsilon = T(1e-6))
401  {
402  GZ_FP_VOLATILE T diff = std::abs(_a - _b);
403  return diff <= _epsilon;
404  }
405 
411  template<typename T>
412  inline bool lessOrNearEqual(const T &_a, const T &_b,
413  const T &_epsilon = 1e-6)
414  {
415  return _a < _b + _epsilon;
416  }
417 
423  template<typename T>
424  inline bool greaterOrNearEqual(const T &_a, const T &_b,
425  const T &_epsilon = 1e-6)
426  {
427  return _a > _b - _epsilon;
428  }
429 
434  template<typename T>
435  inline T precision(const T &_a, const unsigned int &_precision)
436  {
437  auto p = std::pow(10, _precision);
438  return static_cast<T>(std::round(_a * p) / p);
439  }
440 
446  template<typename T>
447  inline void sort2(T &_a, T &_b)
448  {
449  if (_b < _a)
450  std::swap(_a, _b);
451  }
452 
460  template<typename T>
461  inline void sort3(T &_a, T &_b, T &_c)
462  {
463  // _a <= _b
464  sort2(_a, _b);
465  // _a <= _c, _b <= _c
466  sort2(_b, _c);
467  // _a <= _b <= _c
468  sort2(_a, _b);
469  }
470 
474  template<typename T>
475  inline void appendToStream(std::ostream &_out, T _number)
476  {
477  if (std::fpclassify(_number) == FP_ZERO)
478  {
479  _out << 0;
480  }
481  else
482  {
483  _out << _number;
484  }
485  }
486 
490  template<>
491  inline void appendToStream(std::ostream &_out, int _number)
492  {
493  _out << _number;
494  }
495 
499  inline bool isPowerOfTwo(unsigned int _x)
500  {
501  return ((_x != 0) && ((_x & (~_x + 1)) == _x));
502  }
503 
509  inline unsigned int roundUpPowerOfTwo(unsigned int _x)
510  {
511  if (_x == 0)
512  return 1;
513 
514  if (isPowerOfTwo(_x))
515  return _x;
516 
517  while (_x & (_x - 1))
518  _x = _x & (_x - 1);
519 
520  _x = _x << 1;
521 
522  return _x;
523  }
524 
535  inline int roundUpMultiple(int _num, int _multiple)
536  {
537  if (_multiple == 0)
538  return _num;
539 
540  int remainder = std::abs(_num) % _multiple;
541  if (remainder == 0)
542  return _num;
543 
544  if (_num < 0)
545  return -(std::abs(_num) - remainder);
546  else
547  return _num + _multiple - remainder;
548  }
549 
553  int GZ_MATH_VISIBLE parseInt(const std::string &_input);
554 
559  double GZ_MATH_VISIBLE parseFloat(const std::string &_input);
560 
567  const std::chrono::steady_clock::time_point &_time);
568 
575  std::chrono::steady_clock::time_point GZ_MATH_VISIBLE
577  const uint64_t &_sec, const uint64_t &_nanosec);
578 
585  std::chrono::steady_clock::duration GZ_MATH_VISIBLE secNsecToDuration(
586  const uint64_t &_sec, const uint64_t &_nanosec);
587 
594  const std::chrono::steady_clock::duration &_dur);
595 
596  // TODO(anyone): Replace this with std::chrono::days.
599 
607  template<class...Durations, class DurationIn>
608  std::tuple<Durations...> breakDownDurations(DurationIn d) {
609  std::tuple<Durations...> retval;
610  using discard = int[];
611  (void)discard{0, (void((
612  (std::get<Durations>(retval) =
613  std::chrono::duration_cast<Durations>(d)),
614  (d -= std::chrono::duration_cast<DurationIn>(
615  std::get<Durations>(retval))))), 0)...};
616  return retval;
617  }
618 
623  const std::chrono::steady_clock::time_point &_point);
624 
628  std::string GZ_MATH_VISIBLE durationToString(
629  const std::chrono::steady_clock::duration &_duration);
630 
639  bool GZ_MATH_VISIBLE splitTimeBasedOnTimeRegex(
640  const std::string &_timeString,
641  uint64_t & numberDays, uint64_t & numberHours,
642  uint64_t & numberMinutes, uint64_t & numberSeconds,
643  uint64_t & numberMilliseconds);
644 
649  inline bool isTimeString(const std::string &_timeString)
650  {
651  // These will be thrown away, just for making the function call
652  uint64_t d, h, m, s, ms;
653  return splitTimeBasedOnTimeRegex(_timeString, d, h, m, s, ms);
654  }
655 
662  std::chrono::steady_clock::duration GZ_MATH_VISIBLE stringToDuration(
663  const std::string &_timeString);
664 
671  std::chrono::steady_clock::time_point
672  GZ_MATH_VISIBLE stringToTimePoint(const std::string &_timeString);
673 
674  // Degrade precision on Windows, which cannot handle 'long double'
675  // values properly. See the implementation of Unpair.
676  // 32 bit ARM processors also define 'long double' to be the same
677  // size as 'double', and must also be degraded
678 #if defined _MSC_VER || defined __arm__
679  using PairInput = uint16_t;
680  using PairOutput = uint32_t;
681 #else
682  using PairInput = uint32_t;
683  using PairOutput = uint64_t;
684 #endif
685 
695  PairOutput GZ_MATH_VISIBLE Pair(
696  const PairInput _a, const PairInput _b);
697 
710  const PairOutput _key);
711  } // namespace GZ_MATH_VERSION_NAMESPACE
712 } // namespace gz::math
713 #endif // GZ_MATH_FUNCTIONS_HH_