EigenRand  0.5.0
 
All Classes Namespaces Files Functions Typedefs Pages
Loading...
Searching...
No Matches
Basic.h
Go to the documentation of this file.
1
12#ifndef EIGENRAND_DISTS_BASIC_H
13#define EIGENRAND_DISTS_BASIC_H
14
15namespace Eigen
16{
17 namespace Rand
18 {
19 namespace constant
20 {
21 static constexpr double pi = 3.1415926535897932;
22 static constexpr double e = 2.7182818284590452;
23 }
24
31 template<typename DerivedGen, typename Scalar>
32 class GenBase
33 {
34 public:
38 DerivedGen &derived() { return static_cast<DerivedGen &>(*this); }
39
51 template<typename Derived, typename Urng>
52 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>, const Derived>
53 generate(Index rows, Index cols, Urng&& urng)
54 {
55 return {
56 rows, cols, { std::forward<Urng>(urng), derived() }
57 };
58 }
59
70 template<typename Derived, typename Urng>
71 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>, const Derived>
72 generateLike(const Derived& o, Urng&& urng)
73 {
74 return {
75 o.rows(), o.cols(), { std::forward<Urng>(urng), derived() }
76 };
77 }
78 };
79
80 template<typename DerivedGen, typename Scalar, typename ScalarA>
81 class UnaryGenBase
82 {
83 public:
87 DerivedGen &derived() { return static_cast<DerivedGen &>(*this); }
88
99 template<typename Lhs, typename Urng>
100 inline CwiseUnaryOp<
101 internal::scalar_unary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, Urng>,
102 const Lhs
103 > generate(Urng&& urng, const ArrayBase<Lhs>& a)
104 {
105 return {
106 a, { std::forward<Urng>(urng), derived() }
107 };
108 }
109 };
110
111 template<typename DerivedGen, typename Scalar, typename ScalarA, typename ScalarB>
112 class BinaryGenBase
113 {
114 public:
118 DerivedGen &derived() { return static_cast<DerivedGen &>(*this); }
119
130 template<typename Lhs, typename Rhs, typename Urng>
131 inline CwiseBinaryOp<
132 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng>,
133 const Lhs, const Rhs
134 > generate(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
135 {
136 return {
137 a, b, { std::forward<Urng>(urng), derived() }
138 };
139 }
140
141 template<typename Lhs, typename Rhs, typename Urng>
142 inline CwiseBinaryOp<
143 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, Rhs, Urng>,
144 const Lhs, CwiseNullaryOp<internal::scalar_constant_op<Rhs>, const Lhs>
145 > generate(Urng&& urng, const ArrayBase<Lhs>& a, Rhs b)
146 {
147 return {
148 a, { a.rows(), a.cols(), internal::scalar_constant_op<Rhs>{ b } },
149 { std::forward<Urng>(urng), derived() }
150 };
151 }
152
153 template<typename Lhs, typename Rhs, typename Urng>
154 inline CwiseBinaryOp<
155 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, Lhs, typename Rhs::Scalar, Urng>,
156 CwiseNullaryOp<internal::scalar_constant_op<Lhs>, const Rhs>, const Rhs
157 > generate(Urng&& urng, Lhs a, const ArrayBase<Rhs>& b)
158 {
159 return {
160 { b.rows(), b.cols(), internal::scalar_constant_op<Lhs>{ a } }, b,
161 { std::forward<Urng>(urng), derived() }
162 };
163 }
164 };
165
173 template<typename DerivedGen, typename _Scalar, Index Dim>
175 {
176 public:
180 DerivedGen &derived() { return static_cast<DerivedGen &>(*this); }
181
185 Index dims() const { return derived().dims(); }
186
196 template<typename Urng>
197 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
198 {
199 return derived().generate(std::forward<Urng>(urng), samples);
200 }
201
209 template<typename Urng>
210 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
211 {
212 return derived().generate(std::forward<Urng>(urng));
213 }
214 };
215
223 template<typename DerivedGen, typename _Scalar, Index Dim>
225 {
226 public:
230 DerivedGen &derived() { return static_cast<DerivedGen &>(*this); }
231
235 Index dims() const { return derived().dims(); }
236
246 template<typename Urng>
247 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
248 {
249 return derived().generate(std::forward<Urng>(urng), samples);
250 }
251
259 template<typename Urng>
260 inline Matrix<_Scalar, Dim, Dim> generate(Urng&& urng)
261 {
262 return derived().generate(std::forward<Urng>(urng));
263 }
264 };
265
266 template<Index _alignment=0>
267 class CacheStore
268 {
269 protected:
270 enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
271 int8_t raw_data[max_size + _alignment - 1] = { 0, };
272 void* aligned_ptr;
273
274 public:
275 CacheStore()
276 {
277 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
278 }
279
280 CacheStore(const CacheStore& c)
281 {
282 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
283 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
284 }
285
286 CacheStore(CacheStore&& c)
287 {
288 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
289 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
290 }
291
292 template<typename Ty>
293 Ty& get()
294 {
295 return *(Ty*)aligned_ptr;
296 }
297
298 template<typename Ty>
299 const Ty& get() const
300 {
301 return *(const Ty*)aligned_ptr;
302 }
303 };
304
305 template<>
306 class CacheStore<0>
307 {
308 protected:
309 enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
310 int8_t raw_data[max_size] = { 0, };
311
312 public:
313 CacheStore()
314 {
315 }
316
317 CacheStore(const CacheStore& c)
318 {
319 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
320 }
321
322 CacheStore(CacheStore&& c)
323 {
324 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
325 }
326
327 template<typename Ty>
328 Ty& get()
329 {
330 return *(Ty*)raw_data;
331 }
332
333 template<typename Ty>
334 const Ty& get() const
335 {
336 return *(const Ty*)raw_data;
337 }
338 };
339
340 using OptCacheStore = CacheStore<EIGEN_MAX_ALIGN_BYTES>;
341
342 template<typename _Scalar>
343 struct ExtractFirstUint;
344
345 template<>
346 struct ExtractFirstUint<float>
347 {
348 template<typename Packet>
349 auto operator()(Packet v) -> decltype(Eigen::internal::pfirst(v))
350 {
351 return Eigen::internal::pfirst(v);
352 }
353 };
354
355 template<>
356 struct ExtractFirstUint<double>
357 {
358 template<typename Packet>
359 auto operator()(Packet v) -> uint64_t
360 {
361#ifdef EIGEN_VECTORIZE_AVX512
362 return Eigen::internal::pfirst(v);
363#else
364 uint64_t arr[sizeof(Packet) / 8];
365 Eigen::internal::pstoreu((Packet*)arr, v);
366 return arr[0];
367#endif
368 }
369 };
370
376 template<typename _Scalar>
377 class RandbitsGen : public GenBase<RandbitsGen<_Scalar>, _Scalar>
378 {
379 static_assert(std::is_integral<_Scalar>::value, "randBits needs integral types.");
380
381 public:
382 using Scalar = _Scalar;
383
384 template<typename Rng>
385 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
386 {
387 using namespace Eigen::internal;
388 return pfirst(std::forward<Rng>(rng)());
389 }
390
391 template<typename Packet, typename Rng>
392 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
393 {
394 using namespace Eigen::internal;
395 using RUtils = RawbitsMaker<Packet, Rng>;
396 return RUtils{}.rawbits(std::forward<Rng>(rng));
397 }
398 };
399
405 template<typename _Scalar>
406 class BalancedGen : public GenBase<BalancedGen<_Scalar>, _Scalar>
407 {
408 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
409
410 public:
411 using Scalar = _Scalar;
412
413 template<typename Rng>
414 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
415 {
416 using namespace Eigen::internal;
417 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * 2 - 1;
418 }
419
420 template<typename Packet, typename Rng>
421 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
422 {
423 using namespace Eigen::internal;
424 using RUtils = RandUtils<Packet, Rng>;
425 return RUtils{}.balanced(std::forward<Rng>(rng));
426 }
427 };
428
434 template<typename _Scalar>
435 class Balanced2Gen : public GenBase<Balanced2Gen<_Scalar>, _Scalar>
436 {
437 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
438 _Scalar slope = 2, bias = -1;
439 public:
440 using Scalar = _Scalar;
441
447 Balanced2Gen(_Scalar _a = -1, _Scalar _b = 1)
448 : slope{ _b - _a }, bias{ _a }
449 {
450 }
451
452 template<typename Rng>
453 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
454 {
455 using namespace Eigen::internal;
456 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * slope + bias;
457 }
458
459 template<typename Packet, typename Rng>
460 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
461 {
462 using namespace Eigen::internal;
463 using RUtils = RandUtils<Packet, Rng>;
464 return RUtils{}.balanced(std::forward<Rng>(rng), slope, bias);
465 }
466 };
467
468 template<typename _Scalar>
469 class BalancedVGen : public BinaryGenBase<BalancedVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
470 {
471 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
472
473 public:
474 using Scalar = _Scalar;
475
476 template<typename Rng>
477 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
478 {
479 using namespace Eigen::internal;
480 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * (b - a) + a;
481 }
482
483 template<typename Packet, typename Rng>
484 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
485 {
486 using namespace Eigen::internal;
487 using RUtils = RandUtils<Packet, Rng>;
488 return padd(pmul(RUtils{}.zero_to_one(std::forward<Rng>(rng)), psub(b, a)), a);
489 }
490 };
491
492 namespace detail
493 {
494 template<size_t v>
495 struct BitWidth
496 {
497 static constexpr size_t value = BitWidth<v / 2>::value + 1;
498 };
499
500 template<>
501 struct BitWidth<0>
502 {
503 static constexpr size_t value = 0;
504 };
505
506 template<class Rng>
507 struct RngBitSize
508 {
509 static constexpr size_t _min = Rng::min();
510 static constexpr size_t _max = Rng::max();
511
512 static constexpr bool _fullbit_rng = _min == 0 && (_max & (_max + 1)) == 0;
513 static constexpr size_t value = IsPacketRandomEngine<Rng>::value ? sizeof(typename Rng::result_type) * 8 : (_fullbit_rng ? BitWidth<_max>::value : 0);
514 };
515 }
516
522 template<typename _Scalar>
523 class StdUniformRealGen : public GenBase<StdUniformRealGen<_Scalar>, _Scalar>
524 {
525 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
526
527 public:
528 using Scalar = _Scalar;
529
530 template<typename Rng,
531 typename std::enable_if<sizeof(Scalar) * 8 <= detail::RngBitSize<typename std::remove_const<typename std::remove_reference<Rng>::type>::type>::value, int>::type = 0
532 >
533 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
534 {
535 using namespace Eigen::internal;
536 return BitScalar<_Scalar>{}.to_ur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
537 }
538
539 template<typename Rng,
540 typename std::enable_if<detail::RngBitSize<typename std::remove_const<typename std::remove_reference<Rng>::type>::type>::value < sizeof(Scalar) * 8, int>::type = 0
541 >
542 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
543 {
544 using RRng = typename std::remove_const<typename std::remove_reference<Rng>::type>::type;
545 static_assert(detail::RngBitSize<RRng>::value > 0,
546 "BaseRng must be a kind of mersenne_twister_engine.");
547 using ResultType = typename std::conditional<detail::RngBitSize<RRng>::value == 32, uint32_t, uint64_t>::type;
548 using namespace Eigen::internal;
549 ResultType arr[sizeof(Scalar) / sizeof(ResultType)];
550 for (size_t i = 0; i < sizeof(Scalar) / sizeof(ResultType); ++i)
551 {
552 arr[i] = rng();
553 }
554 return BitScalar<_Scalar>{}.to_ur(*(uint64_t*)arr);
555 }
556
557 template<typename Rng,
558 typename std::enable_if<sizeof(Scalar) <= sizeof(typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type), int>::type = 0
559 >
560 EIGEN_STRONG_INLINE const _Scalar nzur_scalar(Rng&& rng)
561 {
562 using namespace Eigen::internal;
563 return BitScalar<_Scalar>{}.to_nzur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
564 }
565
566 template<typename Rng,
567 typename std::enable_if<sizeof(typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type) < sizeof(Scalar), int > ::type = 0
568 >
569 EIGEN_STRONG_INLINE const _Scalar nzur_scalar(Rng&& rng)
570 {
571 using namespace Eigen::internal;
572 using RngResult = typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type;
573 RngResult arr[sizeof(Scalar) / sizeof(RngResult)];
574 for (size_t i = 0; i < sizeof(Scalar) / sizeof(RngResult); ++i)
575 {
576 arr[i] = rng();
577 }
578 return BitScalar<_Scalar>{}.to_nzur(*(Scalar*)arr);
579 }
580
581 template<typename Packet, typename Rng>
582 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
583 {
584 using namespace Eigen::internal;
585 using RUtils = RandUtils<Packet, Rng>;
586 return RUtils{}.uniform_real(std::forward<Rng>(rng));
587 }
588 };
589
595 template<typename _Scalar>
596 class UniformRealGen : public GenBase<UniformRealGen<_Scalar>, _Scalar>
597 {
598 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
599 _Scalar bias, slope;
600
601 public:
602 using Scalar = _Scalar;
603
604 UniformRealGen(_Scalar _min = 0, _Scalar _max = 1)
605 : bias{ _min }, slope{ _max - _min }
606 {
607 }
608
609 UniformRealGen(const UniformRealGen&) = default;
610 UniformRealGen(UniformRealGen&&) = default;
611
612 UniformRealGen& operator=(const UniformRealGen&) = default;
613 UniformRealGen& operator=(UniformRealGen&&) = default;
614
615 template<typename Rng>
616 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
617 {
618 using namespace Eigen::internal;
619 return bias + BitScalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)())) * slope;
620 }
621
622 template<typename Packet, typename Rng>
623 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
624 {
625 using namespace Eigen::internal;
626 using RUtils = RandUtils<Packet, Rng>;
627 return padd(pmul(
628 RUtils{}.uniform_real(std::forward<Rng>(rng)), pset1<Packet>(slope)
629 ), pset1<Packet>(bias));
630 }
631 };
632
633 template<typename _Scalar>
634 class UniformRealVGen : public BinaryGenBase<UniformRealVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
635 {
636 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
637
638 public:
639 using Scalar = _Scalar;
640
641 template<typename Rng>
642 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
643 {
644 using namespace Eigen::internal;
645 return a + BitScalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)())) * (b - a);
646 }
647
648 template<typename Packet, typename Rng>
649 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
650 {
651 using namespace Eigen::internal;
652 using RUtils = RandUtils<Packet, Rng>;
653 return padd(pmul(
654 RUtils{}.uniform_real(std::forward<Rng>(rng)), psub(b, a)
655 ), a);
656 }
657 };
658
659
665 template<typename _Scalar>
666 class BernoulliGen : public GenBase<BernoulliGen<_Scalar>, _Scalar>
667 {
668 uint32_t p;
669 public:
670 using Scalar = _Scalar;
671
672 BernoulliGen(double _p = 0.5)
673 {
674 eigen_assert(0 <= _p && _p <= 1 );
675 p = (uint32_t)(_p * 0x80000000);
676 }
677
678 BernoulliGen(const BernoulliGen&) = default;
679 BernoulliGen(BernoulliGen&&) = default;
680
681 BernoulliGen& operator=(const BernoulliGen&) = default;
682 BernoulliGen& operator=(BernoulliGen&&) = default;
683
684 template<typename Rng>
685 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
686 {
687 using namespace Eigen::internal;
688 return (((uint32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) < p) ? 1 : 0;
689 }
690
691 template<typename Packet, typename Rng>
692 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
693 {
694 using namespace Eigen::internal;
695 using IPacket = decltype(reinterpret_to_int(std::declval<Packet>()));
696 using RUtils = RawbitsMaker<IPacket, Rng>;
697 auto one = pset1<Packet>(1);
698 auto zero = pset1<Packet>(0);
699 auto r = RUtils{}.rawbits(std::forward<Rng>(rng));
700 r = pand(r, pset1<IPacket>(0x7FFFFFFF));
701 return pblendv(pcmplt(r, pset1<IPacket>(p)), one, zero);
702 }
703 };
704
705 template<typename _Scalar>
706 class BernoulliVGen : public UnaryGenBase<BernoulliVGen<_Scalar>, _Scalar, _Scalar>
707 {
708 static_assert(std::is_floating_point<_Scalar>::value, "vectorized `bernoulli` needs a float type.");
709 public:
710 using Scalar = _Scalar;
711
712 template<typename Rng>
713 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a)
714 {
715 using namespace Eigen::internal;
716 uint32_t p = (uint32_t)(a * 0x80000000);
717 return (((uint32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) < p) ? 1 : 0;
718 }
719
720 template<typename Packet, typename Rng>
721 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a)
722 {
723 using namespace Eigen::internal;
724 using IPacket = decltype(reinterpret_to_int(std::declval<Packet>()));
725 using RUtils = RawbitsMaker<IPacket, Rng>;
726 auto one = pset1<Packet>(1);
727 auto zero = pset1<Packet>(0);
728 auto p = pcast<Packet, IPacket>(pmul(a, pset1<Packet>(0x80000000)));
729 auto r = RUtils{}.rawbits(std::forward<Rng>(rng));
730 r = pand(r, pset1<IPacket>(0x7FFFFFFF));
731 return pblendv(pcmplt(r, p), one, zero);
732 }
733 };
734
735 template<typename Derived, typename Urng>
736 using RandBitsType = CwiseNullaryOp<internal::scalar_rng_adaptor<RandbitsGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
737
750 template<typename Derived, typename Urng>
751 inline const RandBitsType<Derived, Urng>
752 randBits(Index rows, Index cols, Urng&& urng)
753 {
754 return {
755 rows, cols, { std::forward<Urng>(urng) }
756 };
757 }
758
770 template<typename Derived, typename Urng>
771 inline const RandBitsType<Derived, Urng>
772 randBitsLike(Derived& o, Urng&& urng)
773 {
774 return {
775 o.rows(), o.cols(), { std::forward<Urng>(urng) }
776 };
777 }
778
779 template<typename Derived, typename Urng>
780 using BalancedType = CwiseNullaryOp<internal::scalar_rng_adaptor<BalancedGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
781
794 template<typename Derived, typename Urng>
795 inline const BalancedType<Derived, Urng>
796 balanced(Index rows, Index cols, Urng&& urng)
797 {
798 return {
799 rows, cols, { std::forward<Urng>(urng) }
800 };
801 }
802
814 template<typename Derived, typename Urng>
815 inline const BalancedType<Derived, Urng>
816 balancedLike(const Derived& o, Urng&& urng)
817 {
818 return {
819 o.rows(), o.cols(), { std::forward<Urng>(urng) }
820 };
821 }
822
823 template<typename Derived, typename Urng>
824 using Balanced2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<Balanced2Gen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
825
839 template<typename Derived, typename Urng>
840 inline const Balanced2Type<Derived, Urng>
841 balanced(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a, typename Derived::Scalar b)
842 {
843 return {
844 rows, cols, { std::forward<Urng>(urng), Balanced2Gen<typename Derived::Scalar>{a, b} }
845 };
846 }
847
860 template<typename Derived, typename Urng>
861 inline const Balanced2Type<Derived, Urng>
862 balancedLike(const Derived& o, Urng&& urng, typename Derived::Scalar a, typename Derived::Scalar b)
863 {
864 return {
865 o.rows(), o.cols(), { std::forward<Urng>(urng), Balanced2Gen<typename Derived::Scalar>{a, b} }
866 };
867 }
868
869 template<typename Derived, typename Urng>
870 using BalancedVVType = CwiseBinaryOp<
871 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
872 const Derived, const Derived
873 >;
874
888 template<typename Lhs, typename Rhs, typename Urng>
889 inline const BalancedVVType<Lhs, Urng>
890 balanced(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
891 {
892 static_assert(std::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value, "`Lhs::Scalar` must be equal to `Rhs::Scalar`");
893 return {
894 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
895 { std::forward<Urng>(urng), BalancedVGen<typename Lhs::Scalar>{} }
896 };
897 }
898
899 template<typename Derived, typename Urng>
900 using BalancedVSType = CwiseBinaryOp<
901 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
902 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
903 >;
904
905 template<typename Lhs, typename Urng>
906 inline const BalancedVSType<Lhs, Urng>
907 balanced(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
908 {
909 return {
910 static_cast<const Lhs&>(a), { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
911 { std::forward<Urng>(urng), BalancedVGen<typename Lhs::Scalar>{} }
912 };
913 }
914
915 template<typename Derived, typename Urng>
916 using BalancedSVType = CwiseBinaryOp<
917 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
918 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
919 >;
920
921 template<typename Rhs, typename Urng>
922 inline const BalancedSVType<Rhs, Urng>
923 balanced(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
924 {
925 return {
926 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } }, static_cast<const Rhs&>(b),
927 { std::forward<Urng>(urng), BalancedVGen<typename Rhs::Scalar>{} }
928 };
929 }
930
931 template<typename Derived, typename Urng>
932 using StdUniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdUniformRealGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
933
946 template<typename Derived, typename Urng>
947 inline const StdUniformRealType<Derived, Urng>
948 uniformReal(Index rows, Index cols, Urng&& urng)
949 {
950 return {
951 rows, cols, { std::forward<Urng>(urng) }
952 };
953 }
954
966 template<typename Derived, typename Urng>
967 inline const StdUniformRealType<Derived, Urng>
968 uniformRealLike(Derived& o, Urng&& urng)
969 {
970 return {
971 o.rows(), o.cols(), { std::forward<Urng>(urng) }
972 };
973 }
974
975 template<typename Derived, typename Urng>
976 using UniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformRealGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
977
991 template<typename Derived, typename Urng>
992 inline const UniformRealType<Derived, Urng>
993 uniformReal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar min, typename Derived::Scalar max)
994 {
995 return {
996 rows, cols, { std::forward<Urng>(urng), UniformRealGen<typename Derived::Scalar>{ min, max } }
997 };
998 }
999
1012 template<typename Derived, typename Urng>
1013 inline const UniformRealType<Derived, Urng>
1014 uniformRealLike(Derived& o, Urng&& urng, typename Derived::Scalar min, typename Derived::Scalar max)
1015 {
1016 return {
1017 o.rows(), o.cols(), { std::forward<Urng>(urng), UniformRealGen<typename Derived::Scalar>{ min, max } }
1018 };
1019 }
1020
1021 template<typename Derived, typename Urng>
1022 using UniformRealVVType = CwiseBinaryOp<
1023 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1024 const Derived, const Derived
1025 >;
1026
1040 template<typename Lhs, typename Rhs, typename Urng>
1041 inline const UniformRealVVType<Lhs, Urng>
1042 uniformReal(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1043 {
1044 static_assert(std::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value, "`Lhs::Scalar` must be equal to `Rhs::Scalar`");
1045 return {
1046 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1047 { std::forward<Urng>(urng), UniformRealVGen<typename Lhs::Scalar>{} }
1048 };
1049 }
1050
1051 template<typename Derived, typename Urng>
1052 using UniformRealVSType = CwiseBinaryOp<
1053 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1054 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1055 >;
1056
1057 template<typename Lhs, typename Urng>
1058 inline const UniformRealVSType<Lhs, Urng>
1059 uniformReal(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1060 {
1061 return {
1062 static_cast<const Lhs&>(a), { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1063 { std::forward<Urng>(urng), UniformRealVGen<typename Lhs::Scalar>{} }
1064 };
1065 }
1066
1067
1068 template<typename Derived, typename Urng>
1069 using UniformRealSVType = CwiseBinaryOp<
1070 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1071 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1072 >;
1073
1074 template<typename Rhs, typename Urng>
1075 inline const UniformRealSVType<Rhs, Urng>
1076 uniformReal(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1077 {
1078 return {
1079 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } }, static_cast<const Rhs&>(b),
1080 { std::forward<Urng>(urng), UniformRealVGen<typename Rhs::Scalar>{} }
1081 };
1082 }
1083
1084 template<typename Derived, typename Urng>
1085 using BernoulliType = CwiseNullaryOp<internal::scalar_rng_adaptor<BernoulliGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1086
1098 template<typename Derived, typename Urng>
1099 inline const BernoulliType<Derived, Urng>
1100 bernoulli(Index rows, Index cols, Urng&& urng, double p = 0.5)
1101 {
1102 return {
1103 rows, cols, { std::forward<Urng>(urng), BernoulliGen<typename Derived::Scalar>{ p } }
1104 };
1105 }
1106
1117 template<typename Derived, typename Urng>
1118 inline const BernoulliType<Derived, Urng>
1119 bernoulli(Derived& o, Urng&& urng, double p = 0.5)
1120 {
1121 return {
1122 o.rows(), o.cols(), { std::forward<Urng>(urng), BernoulliGen<typename Derived::Scalar>{ p } }
1123 };
1124 }
1125
1126 template<typename Derived, typename Urng>
1127 using BernoulliVType = CwiseUnaryOp<
1128 internal::scalar_unary_rng_adaptor<BernoulliVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1129 const Derived
1130 >;
1131
1141 template<typename Lhs, typename Urng>
1142 inline const BernoulliVType<Lhs, Urng>
1143 bernoulli(Urng&& urng, const ArrayBase<Lhs>& p)
1144 {
1145 return BernoulliVType<Lhs, Urng>{
1146 static_cast<const Lhs&>(p), { std::forward<Urng>(urng), BernoulliVGen<typename Lhs::Scalar>{} }
1147 };
1148 }
1149 }
1150}
1151
1152#endif
Generator of reals in a range [a, b]
Definition Basic.h:436
Balanced2Gen(_Scalar _a=-1, _Scalar _b=1)
Construct a new balanced generator.
Definition Basic.h:447
Generator of reals in a range [-1, 1]
Definition Basic.h:407
Generator of Bernoulli distribution.
Definition Basic.h:667
Base class of all univariate random generators.
Definition Basic.h:33
const CwiseNullaryOp< internal::scalar_rng_adaptor< DerivedGen &, Scalar, Urng >, const Derived > generate(Index rows, Index cols, Urng &&urng)
generate random values from its distribution
Definition Basic.h:53
const CwiseNullaryOp< internal::scalar_rng_adaptor< DerivedGen &, Scalar, Urng >, const Derived > generateLike(const Derived &o, Urng &&urng)
generate random values from its distribution
Definition Basic.h:72
DerivedGen & derived()
Return a reference to the derived type.
Definition Basic.h:38
Base class of all multivariate random matrix generators.
Definition Basic.h:225
DerivedGen & derived()
Return a reference to the derived type.
Definition Basic.h:230
Index dims() const
returns the dimensions of matrices to be generated
Definition Basic.h:235
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition Basic.h:247
Matrix< _Scalar, Dim, Dim > generate(Urng &&urng)
generates one sample
Definition Basic.h:260
Base class of all multivariate random vector generators.
Definition Basic.h:175
DerivedGen & derived()
Return a reference to the derived type.
Definition Basic.h:180
Matrix< _Scalar, Dim, 1 > generate(Urng &&urng)
generates one sample
Definition Basic.h:210
Index dims() const
returns the dimensions of vectors to be generated
Definition Basic.h:185
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition Basic.h:197
Generator of random bits for integral scalars.
Definition Basic.h:378
Generator of reals in a range [0, 1)
Definition Basic.h:524
Generator of reals in a range [a, b)
Definition Basic.h:597
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition Basic.h:796
const RandBitsType< Derived, Urng > randBitsLike(Derived &o, Urng &&urng)
generates integers with random bits
Definition Basic.h:772
const BalancedType< Derived, Urng > balancedLike(const Derived &o, Urng &&urng)
generates reals in a range [-1, 1]
Definition Basic.h:816
const RandBitsType< Derived, Urng > randBits(Index rows, Index cols, Urng &&urng)
generates integers with random bits
Definition Basic.h:752
const StdUniformRealType< Derived, Urng > uniformRealLike(Derived &o, Urng &&urng)
generates reals in a range [0, 1)
Definition Basic.h:968
const StdUniformRealType< Derived, Urng > uniformReal(Index rows, Index cols, Urng &&urng)
generates reals in a range [0, 1)
Definition Basic.h:948
const BernoulliType< Derived, Urng > bernoulli(Index rows, Index cols, Urng &&urng, double p=0.5)
generates 1 with probability p and 0 with probability 1 - p
Definition Basic.h:1100