DART 6.7.3
Loading...
Searching...
No Matches
Random-impl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2019, 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<dart::math::detail::
97 UniformScalarFromMatrixFunctor<T>>
98{
99 enum
100 {
101 ret = false
102 };
103};
104
105template <typename T>
106struct functor_has_linear_access<dart::math::detail::
107 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 {
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>
133using is_base_of_template
134 = decltype(is_base_of_template_impl<C>(std::declval<T*>()));
135
136template <typename T>
137using is_base_of_matrix = is_base_of_template<Eigen::MatrixBase, T>;
138
139//==============================================================================
143template <typename T, typename Enable = void>
144struct is_compatible_to_uniform_int_distribution : std::false_type
145{
146 // Define nothing
147};
148
149// clang-format off
150
151template <typename T>
152struct is_compatible_to_uniform_int_distribution<
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>
172struct UniformScalarImpl
173{
174 // Define nothing
175};
176
177//==============================================================================
178// Floating-point case
179template <typename S>
180struct UniformScalarImpl<S,
181 typename std::
182 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>
196struct
197 UniformScalarImpl<S,
198 typename std::
199 enable_if<is_compatible_to_uniform_int_distribution<S>::
200 value>::type>
201{
202 static S run(S min, S max)
203 {
204 // Distribution objects are lightweight so we simply construct a new
205 // distribution for each random number generation.
206 Random::UniformIntDist<S> d(min, max);
207 return d(Random::getGenerator());
208 }
209};
210
211//==============================================================================
212template <typename Derived, typename Enable = void>
213struct UniformMatrixImpl
214{
215 // Define nothing
216};
217
218//==============================================================================
219// Dynamic matrix case
220template <typename Derived>
221struct UniformMatrixImpl<Derived,
222 typename std::enable_if<!Derived::IsVectorAtCompileTime
223 && Derived::SizeAtCompileTime
224 == Eigen::Dynamic>::
225 type>
226{
227 static typename Derived::PlainObject run(
228 const Eigen::MatrixBase<Derived>& min,
229 const Eigen::MatrixBase<Derived>& max)
230 {
231#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
232 const auto uniformFunc = [&](int i, int j) {
233 return Random::uniform<typename Derived::Scalar>(min(i, j), max(i, j));
234 };
235 return Derived::PlainObject::NullaryExpr(
236 min.rows(), min.cols(), uniformFunc);
237#else
238 return Derived::PlainObject::NullaryExpr(
239 min.rows(),
240 min.cols(),
241 detail::UniformScalarFromMatrixFunctor<Derived>(min, max));
242#endif
243 }
244};
245
246//==============================================================================
247// Dynamic vector case
248template <typename Derived>
249struct UniformMatrixImpl<Derived,
250 typename std::enable_if<Derived::IsVectorAtCompileTime
251 && Derived::SizeAtCompileTime
252 == Eigen::Dynamic>::
253 type>
254{
255 static typename Derived::PlainObject run(
256 const Eigen::MatrixBase<Derived>& min,
257 const Eigen::MatrixBase<Derived>& max)
258 {
259#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
260 const auto uniformFunc = [&](int i) {
261 return Random::uniform<typename Derived::Scalar>(min[i], max[i]);
262 };
263 return Derived::PlainObject::NullaryExpr(min.size(), uniformFunc);
264#else
265 return Derived::PlainObject::NullaryExpr(
266 min.size(), detail::UniformScalarFromVectorFunctor<Derived>(min, max));
267#endif
268 }
269};
270
271//==============================================================================
272// Fixed matrix case
273template <typename Derived>
274struct UniformMatrixImpl<Derived,
275 typename std::enable_if<!Derived::IsVectorAtCompileTime
276 && Derived::SizeAtCompileTime
277 != Eigen::Dynamic>::
278 type>
279{
280 static typename Derived::PlainObject run(
281 const Eigen::MatrixBase<Derived>& min,
282 const Eigen::MatrixBase<Derived>& max)
283 {
284#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
285 const auto uniformFunc = [&](int i, int j) {
286 return Random::uniform<typename Derived::Scalar>(min(i, j), max(i, j));
287 };
288 return Derived::PlainObject::NullaryExpr(uniformFunc);
289#else
290 return Derived::PlainObject::NullaryExpr(
291 detail::UniformScalarFromMatrixFunctor<Derived>(min, max));
292#endif
293 }
294};
295
296//==============================================================================
297// Fixed vector case
298template <typename Derived>
299struct UniformMatrixImpl<Derived,
300 typename std::enable_if<Derived::IsVectorAtCompileTime
301 && Derived::SizeAtCompileTime
302 != Eigen::Dynamic>::
303 type>
304{
305 static typename Derived::PlainObject run(
306 const Eigen::MatrixBase<Derived>& min,
307 const Eigen::MatrixBase<Derived>& max)
308 {
309#if EIGEN_VERSION_AT_LEAST(3, 3, 0)
310 const auto uniformFunc = [&](int i) {
311 return Random::uniform<typename Derived::Scalar>(min[i], max[i]);
312 };
313 return Derived::PlainObject::NullaryExpr(uniformFunc);
314#else
315 return Derived::PlainObject::NullaryExpr(
316 detail::UniformScalarFromVectorFunctor<Derived>(min, max));
317#endif
318 }
319};
320
321//==============================================================================
322template <typename T, typename Enable = void>
323struct UniformImpl
324{
325 // Define nothing
326};
327
328//==============================================================================
329template <typename T>
330struct UniformImpl<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>
341struct UniformImpl<T,
342 typename std::enable_if<is_base_of_matrix<T>::value>::type>
343{
344 static T run(const Eigen::MatrixBase<T>& min, const Eigen::MatrixBase<T>& max)
345 {
346 return UniformMatrixImpl<T>::run(min, max);
347 }
348};
349
350//==============================================================================
351template <typename S, typename Enable = void>
352struct NormalScalarImpl
353{
354 // Define nothing
355};
356
357//==============================================================================
358// Floating-point case
359template <typename S>
360struct NormalScalarImpl<S,
361 typename std::
362 enable_if<std::is_floating_point<S>::value>::type>
363{
364 static S run(S mean, S sigma)
365 {
366 Random::NormalRealDist<S> d(mean, sigma);
367 return d(Random::getGenerator());
368 }
369};
370
371//==============================================================================
372// Floating-point case
373template <typename S>
374struct
375 NormalScalarImpl<S,
376 typename std::
377 enable_if<is_compatible_to_uniform_int_distribution<S>::
378 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>
392struct NormalImpl
393{
394 // Define nothing
395};
396
397//==============================================================================
398template <typename T>
399struct NormalImpl<T,
400 typename std::enable_if<std::is_arithmetic<T>::value>::type>
401{
402 static T run(T min, T max)
403 {
404 return NormalScalarImpl<T>::run(min, max);
405 }
406};
407
408} // (anonymous) namespace
409
410//==============================================================================
411template <typename S>
412S Random::uniform(S min, S max)
413{
414 return UniformImpl<S>::run(min, max);
415}
416
417//==============================================================================
418template <typename FixedSizeT>
420 typename FixedSizeT::Scalar min, typename FixedSizeT::Scalar max)
421{
422 return uniform<FixedSizeT>(
423 FixedSizeT::Constant(min), FixedSizeT::Constant(max));
424}
425
426//==============================================================================
427template <typename DynamicSizeVectorT>
428DynamicSizeVectorT Random::uniform(
429 int size,
430 typename DynamicSizeVectorT::Scalar min,
431 typename DynamicSizeVectorT::Scalar max)
432{
433 return uniform<DynamicSizeVectorT>(
434 DynamicSizeVectorT::Constant(size, min),
435 DynamicSizeVectorT::Constant(size, max));
436}
437
438//==============================================================================
439template <typename DynamicSizeMatrixT>
440DynamicSizeMatrixT Random::uniform(
441 int rows,
442 int cols,
443 typename DynamicSizeMatrixT::Scalar min,
444 typename DynamicSizeMatrixT::Scalar max)
445{
446 return uniform<DynamicSizeMatrixT>(
447 DynamicSizeMatrixT::Constant(rows, cols, min),
448 DynamicSizeMatrixT::Constant(rows, cols, max));
449}
450
451//==============================================================================
452template <typename S>
453S Random::normal(S min, S max)
454{
455 return NormalImpl<S>::run(min, max);
456}
457
458} // namespace math
459} // namespace dart
std::string type
Definition SdfParser.cpp:82
static S normal(S mean, S sigma)
Returns a random number from a normal distribution.
Definition Random-impl.hpp:453
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:412
Definition Random-impl.hpp:92
Definition BulletCollisionDetector.cpp:63
Definition SharedLibraryManager.hpp:43
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