DART  6.10.1
Random-impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2021, The DART development contributors
3  * All rights reserved.
4  *
5  * The list of contributors can be found at:
6  * https://github.com/dartsim/dart/blob/master/LICENSE
7  *
8  * This file is provided under the following "BSD-style" License:
9  * Redistribution and use in source and binary forms, with or
10  * without modification, are permitted provided that the following
11  * conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 #include "dart/math/Random.hpp"
34 
35 //==============================================================================
36 // This workaround is necessary for old Eigen (< 3.3). See the details here:
37 // http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1286
38 #if !EIGEN_VERSION_AT_LEAST(3, 3, 0)
39 
40 namespace dart {
41 namespace math {
42 namespace detail {
43 
44 template <typename Derived>
46 {
47  using S = typename Derived::Scalar;
48 
50  const Eigen::MatrixBase<Derived>& min,
51  const Eigen::MatrixBase<Derived>& max)
52  : mMin(min), mMax(max)
53  {
54  // Do nothing
55  }
56 
57  S operator()(int i, int j) const
58  {
59  return Random::uniform<S>(mMin(i, j), mMax(i, j));
60  }
61 
62  const Eigen::MatrixBase<Derived>& mMin;
63  const Eigen::MatrixBase<Derived>& mMax;
64 };
65 
66 template <typename Derived>
68 {
69  using S = typename Derived::Scalar;
70 
72  const Eigen::MatrixBase<Derived>& min,
73  const Eigen::MatrixBase<Derived>& max)
74  : mMin(min), mMax(max)
75  {
76  // Do nothing
77  }
78 
79  S operator()(int i) const
80  {
81  return Random::uniform<S>(mMin[i], mMax[i]);
82  }
83 
84  const Eigen::MatrixBase<Derived>& mMin;
85  const Eigen::MatrixBase<Derived>& mMax;
86 };
87 
88 } // namespace detail
89 } // namespace math
90 } // namespace dart
91 
92 namespace Eigen {
93 namespace internal {
94 
95 template <typename T>
96 struct functor_has_linear_access<
97  dart::math::detail::UniformScalarFromMatrixFunctor<T>>
98 {
99  enum
100  {
101  ret = false
102  };
103 };
104 
105 template <typename T>
106 struct functor_has_linear_access<
107  dart::math::detail::UniformScalarFromVectorFunctor<T>>
108 {
109  enum
110  {
111  ret = true
112  };
113 };
114 
115 } // namespace internal
116 } // namespace Eigen
117 
118 #endif // !EIGEN_VERSION_AT_LEAST(3,3,0)
119 
120 namespace dart {
121 namespace math {
122 
123 namespace detail {
124 
125 //==============================================================================
126 template <template <typename...> class C, typename... Ts>
127 std::true_type is_base_of_template_impl(const C<Ts...>*);
128 
129 template <template <typename...> class C>
130 std::false_type is_base_of_template_impl(...);
131 
132 template <template <typename...> class C, typename T>
134  = decltype(is_base_of_template_impl<C>(std::declval<T*>()));
135 
136 template <typename T>
138 
139 //==============================================================================
143 template <typename T, typename Enable = void>
145 {
146  // Define nothing
147 };
148 
149 // clang-format off
150 
151 template <typename T>
153  T, typename std::enable_if<
154  std::is_same<typename std::remove_cv<T>::type, short>::value
155  || std::is_same<typename std::remove_cv<T>::type, int>::value
156  || std::is_same<typename std::remove_cv<T>::type, long>::value
157  || std::is_same<typename std::remove_cv<T>::type, long long>::value
158  || std::is_same<typename std::remove_cv<T>::type, unsigned short>::value
159  || std::is_same<typename std::remove_cv<T>::type, unsigned int>::value
160  || std::is_same<typename std::remove_cv<T>::type, unsigned long>::value
161  || std::is_same<typename std::remove_cv<T>::type, unsigned long long>::value
162  >::type
163  > : std::true_type
164 {
165  // Define nothing
166 };
167 
168 // clang-format on
169 
170 //==============================================================================
171 template <typename S, typename Enable = void>
173 {
174  // Define nothing
175 };
176 
177 //==============================================================================
178 // Floating-point case
179 template <typename S>
181  S,
182  typename std::enable_if<std::is_floating_point<S>::value>::type>
183 {
184  static S run(S min, S max)
185  {
186  // Distribution objects are lightweight so we simply construct a new
187  // distribution for each random number generation.
188  Random::UniformRealDist<S> d(min, max);
189  return d(Random::getGenerator());
190  }
191 };
192 
193 //==============================================================================
194 // Floating-point case
195 template <typename S>
197  S,
198  typename std::enable_if<
199  is_compatible_to_uniform_int_distribution<S>::value>::type>
200 {
201  static S run(S min, S max)
202  {
203  // Distribution objects are lightweight so we simply construct a new
204  // distribution for each random number generation.
205  Random::UniformIntDist<S> d(min, max);
206  return d(Random::getGenerator());
207  }
208 };
209 
210 //==============================================================================
211 template <typename Derived, typename Enable = void>
213 {
214  // Define nothing
215 };
216 
217 //==============================================================================
218 // Dynamic matrix case
219 template <typename Derived>
221  Derived,
222  typename std::enable_if<
223  !Derived::IsVectorAtCompileTime
224  && Derived::SizeAtCompileTime == Eigen::Dynamic>::type>
225 {
226  static typename Derived::PlainObject run(
227  const Eigen::MatrixBase<Derived>& min,
228  const Eigen::MatrixBase<Derived>& max)
229  {
230 #if EIGEN_VERSION_AT_LEAST(3, 3, 0)
231  const auto uniformFunc = [&](int i, int j) {
232  return Random::uniform<typename Derived::Scalar>(min(i, j), max(i, j));
233  };
234  return Derived::PlainObject::NullaryExpr(
235  min.rows(), min.cols(), uniformFunc);
236 #else
237  return Derived::PlainObject::NullaryExpr(
238  min.rows(),
239  min.cols(),
241 #endif
242  }
243 };
244 
245 //==============================================================================
246 // Dynamic vector case
247 template <typename Derived>
249  Derived,
250  typename std::enable_if<
251  Derived::IsVectorAtCompileTime
252  && Derived::SizeAtCompileTime == Eigen::Dynamic>::type>
253 {
254  static typename Derived::PlainObject run(
255  const Eigen::MatrixBase<Derived>& min,
256  const Eigen::MatrixBase<Derived>& max)
257  {
258 #if EIGEN_VERSION_AT_LEAST(3, 3, 0)
259  const auto uniformFunc = [&](int i) {
260  return Random::uniform<typename Derived::Scalar>(min[i], max[i]);
261  };
262  return Derived::PlainObject::NullaryExpr(min.size(), uniformFunc);
263 #else
264  return Derived::PlainObject::NullaryExpr(
266 #endif
267  }
268 };
269 
270 //==============================================================================
271 // Fixed matrix case
272 template <typename Derived>
274  Derived,
275  typename std::enable_if<
276  !Derived::IsVectorAtCompileTime
277  && Derived::SizeAtCompileTime != Eigen::Dynamic>::type>
278 {
279  static typename Derived::PlainObject run(
280  const Eigen::MatrixBase<Derived>& min,
281  const Eigen::MatrixBase<Derived>& max)
282  {
283 #if EIGEN_VERSION_AT_LEAST(3, 3, 0)
284  const auto uniformFunc = [&](int i, int j) {
285  return Random::uniform<typename Derived::Scalar>(min(i, j), max(i, j));
286  };
287  return Derived::PlainObject::NullaryExpr(uniformFunc);
288 #else
289  return Derived::PlainObject::NullaryExpr(
291 #endif
292  }
293 };
294 
295 //==============================================================================
296 // Fixed vector case
297 template <typename Derived>
299  Derived,
300  typename std::enable_if<
301  Derived::IsVectorAtCompileTime
302  && Derived::SizeAtCompileTime != Eigen::Dynamic>::type>
303 {
304  static typename Derived::PlainObject run(
305  const Eigen::MatrixBase<Derived>& min,
306  const Eigen::MatrixBase<Derived>& max)
307  {
308 #if EIGEN_VERSION_AT_LEAST(3, 3, 0)
309  const auto uniformFunc = [&](int i) {
310  return Random::uniform<typename Derived::Scalar>(min[i], max[i]);
311  };
312  return Derived::PlainObject::NullaryExpr(uniformFunc);
313 #else
314  return Derived::PlainObject::NullaryExpr(
316 #endif
317  }
318 };
319 
320 //==============================================================================
321 template <typename T, typename Enable = void>
323 {
324  // Define nothing
325 };
326 
327 //==============================================================================
328 template <typename T>
329 struct UniformImpl<
330  T,
331  typename std::enable_if<std::is_arithmetic<T>::value>::type>
332 {
333  static T run(T min, T max)
334  {
335  return UniformScalarImpl<T>::run(min, max);
336  }
337 };
338 
339 //==============================================================================
340 template <typename T>
341 struct UniformImpl<
342  T,
343  typename std::enable_if<is_base_of_matrix<T>::value>::type>
344 {
345  static T run(const Eigen::MatrixBase<T>& min, const Eigen::MatrixBase<T>& max)
346  {
347  return UniformMatrixImpl<T>::run(min, max);
348  }
349 };
350 
351 //==============================================================================
352 template <typename S, typename Enable = void>
354 {
355  // Define nothing
356 };
357 
358 //==============================================================================
359 // Floating-point case
360 template <typename S>
362  S,
363  typename std::enable_if<std::is_floating_point<S>::value>::type>
364 {
365  static S run(S mean, S sigma)
366  {
367  Random::NormalRealDist<S> d(mean, sigma);
368  return d(Random::getGenerator());
369  }
370 };
371 
372 //==============================================================================
373 // Floating-point case
374 template <typename S>
376  S,
377  typename std::enable_if<
378  is_compatible_to_uniform_int_distribution<S>::value>::type>
379 {
380  static S run(S mean, S sigma)
381  {
382  using DefaultFloatType = float;
383  const DefaultFloatType realNormal = Random::normal(
384  static_cast<DefaultFloatType>(mean),
385  static_cast<DefaultFloatType>(sigma));
386  return static_cast<S>(std::round(realNormal));
387  }
388 };
389 
390 //==============================================================================
391 template <typename T, typename Enable = void>
393 {
394  // Define nothing
395 };
396 
397 //==============================================================================
398 template <typename T>
399 struct NormalImpl<
400  T,
401  typename std::enable_if<std::is_arithmetic<T>::value>::type>
402 {
403  static T run(T min, T max)
404  {
405  return NormalScalarImpl<T>::run(min, max);
406  }
407 };
408 
409 } // namespace detail
410 
411 //==============================================================================
412 template <typename S>
413 S Random::uniform(S min, S max)
414 {
415  return detail::UniformImpl<S>::run(min, max);
416 }
417 
418 //==============================================================================
419 template <typename FixedSizeT>
420 FixedSizeT Random::uniform(
421  typename FixedSizeT::Scalar min, typename FixedSizeT::Scalar max)
422 {
423  return uniform<FixedSizeT>(
424  FixedSizeT::Constant(min), FixedSizeT::Constant(max));
425 }
426 
427 //==============================================================================
428 template <typename DynamicSizeVectorT>
429 DynamicSizeVectorT Random::uniform(
430  int size,
431  typename DynamicSizeVectorT::Scalar min,
432  typename DynamicSizeVectorT::Scalar max)
433 {
434  return uniform<DynamicSizeVectorT>(
435  DynamicSizeVectorT::Constant(size, min),
436  DynamicSizeVectorT::Constant(size, max));
437 }
438 
439 //==============================================================================
440 template <typename DynamicSizeMatrixT>
441 DynamicSizeMatrixT Random::uniform(
442  int rows,
443  int cols,
444  typename DynamicSizeMatrixT::Scalar min,
445  typename DynamicSizeMatrixT::Scalar max)
446 {
447  return uniform<DynamicSizeMatrixT>(
448  DynamicSizeMatrixT::Constant(rows, cols, min),
449  DynamicSizeMatrixT::Constant(rows, cols, max));
450 }
451 
452 //==============================================================================
453 template <typename S>
454 S Random::normal(S min, S max)
455 {
456  return detail::NormalImpl<S>::run(min, max);
457 }
458 
459 } // namespace math
460 } // namespace dart
std::string type
Definition: SdfParser.cpp:82
std::uniform_int_distribution< IntType > UniformIntDist
Definition: Random.hpp:52
std::normal_distribution< FloatType > NormalRealDist
Definition: Random.hpp:55
std::uniform_real_distribution< FloatType > UniformRealDist
Definition: Random.hpp:49
static S normal(S mean, S sigma)
Returns a random number from a normal distribution.
Definition: Random-impl.hpp:454
static GeneratorType & getGenerator()
Returns a mutable reference to the random generator.
Definition: Random.cpp:39
static S uniform(S min, S max)
Returns a random number from an uniform distribution.
Definition: Random-impl.hpp:413
Definition: Random-impl.hpp:92
decltype(is_base_of_template_impl< C >(std::declval< T * >())) is_base_of_template
Definition: Random-impl.hpp:134
std::true_type is_base_of_template_impl(const C< Ts... > *)
is_base_of_template< Eigen::MatrixBase, T > is_base_of_matrix
Definition: Random-impl.hpp:137
double round(double _x)
Definition: Helpers.hpp:144
Definition: BulletCollisionDetector.cpp:65
Definition: SharedLibraryManager.hpp:46
Definition: Random-impl.hpp:393
Definition: Random-impl.hpp:354
static T run(const Eigen::MatrixBase< T > &min, const Eigen::MatrixBase< T > &max)
Definition: Random-impl.hpp:345
Definition: Random-impl.hpp:323
static Derived::PlainObject run(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:254
static Derived::PlainObject run(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:304
static Derived::PlainObject run(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:279
static Derived::PlainObject run(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:226
Definition: Random-impl.hpp:213
typename Derived::Scalar S
Definition: Random-impl.hpp:47
const Eigen::MatrixBase< Derived > & mMin
Definition: Random-impl.hpp:62
UniformScalarFromMatrixFunctor(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:49
const Eigen::MatrixBase< Derived > & mMax
Definition: Random-impl.hpp:63
S operator()(int i, int j) const
Definition: Random-impl.hpp:57
UniformScalarFromVectorFunctor(const Eigen::MatrixBase< Derived > &min, const Eigen::MatrixBase< Derived > &max)
Definition: Random-impl.hpp:71
S operator()(int i) const
Definition: Random-impl.hpp:79
const Eigen::MatrixBase< Derived > & mMin
Definition: Random-impl.hpp:84
typename Derived::Scalar S
Definition: Random-impl.hpp:69
const Eigen::MatrixBase< Derived > & mMax
Definition: Random-impl.hpp:85
Definition: Random-impl.hpp:173
Check whether T can be used for std::uniform_int_distribution<T> Reference: https://en....
Definition: Random-impl.hpp:145