DART 6.10.1
Loading...
Searching...
No Matches
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
40namespace dart {
41namespace math {
42namespace detail {
43
44template <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
66template <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
92namespace Eigen {
93namespace internal {
94
95template <typename T>
96struct functor_has_linear_access<
97 dart::math::detail::UniformScalarFromMatrixFunctor<T>>
98{
99 enum
100 {
101 ret = false
102 };
103};
104
105template <typename T>
106struct 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
120namespace dart {
121namespace math {
122
123namespace detail {
124
125//==============================================================================
126template <template <typename...> class C, typename... Ts>
127std::true_type is_base_of_template_impl(const C<Ts...>*);
128
129template <template <typename...> class C>
130std::false_type is_base_of_template_impl(...);
131
132template <template <typename...> class C, typename T>
134 = decltype(is_base_of_template_impl<C>(std::declval<T*>()));
135
136template <typename T>
138
139//==============================================================================
143template <typename T, typename Enable = void>
145{
146 // Define nothing
147};
148
149// clang-format off
150
151template <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//==============================================================================
171template <typename S, typename Enable = void>
173{
174 // Define nothing
175};
176
177//==============================================================================
178// Floating-point case
179template <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
195template <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//==============================================================================
211template <typename Derived, typename Enable = void>
213{
214 // Define nothing
215};
216
217//==============================================================================
218// Dynamic matrix case
219template <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
247template <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
272template <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
297template <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//==============================================================================
321template <typename T, typename Enable = void>
323{
324 // Define nothing
325};
326
327//==============================================================================
328template <typename T>
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//==============================================================================
340template <typename T>
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//==============================================================================
352template <typename S, typename Enable = void>
354{
355 // Define nothing
356};
357
358//==============================================================================
359// Floating-point case
360template <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
374template <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//==============================================================================
391template <typename T, typename Enable = void>
393{
394 // Define nothing
395};
396
397//==============================================================================
398template <typename T>
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//==============================================================================
412template <typename S>
413S Random::uniform(S min, S max)
414{
415 return detail::UniformImpl<S>::run(min, max);
416}
417
418//==============================================================================
419template <typename FixedSizeT>
421 typename FixedSizeT::Scalar min, typename FixedSizeT::Scalar max)
422{
423 return uniform<FixedSizeT>(
424 FixedSizeT::Constant(min), FixedSizeT::Constant(max));
425}
426
427//==============================================================================
428template <typename DynamicSizeVectorT>
429DynamicSizeVectorT 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//==============================================================================
440template <typename DynamicSizeMatrixT>
441DynamicSizeMatrixT 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//==============================================================================
453template <typename S>
454S 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
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