EigenRand  0.5.0
 
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:
46 template<typename Derived, typename Urng>
47 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>, const Derived>
48 generate(Index rows, Index cols, Urng&& urng)
49 {
50 return {
51 rows, cols, { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
52 };
53 }
54
65 template<typename Derived, typename Urng>
66 inline const CwiseNullaryOp<internal::scalar_rng_adaptor<DerivedGen&, Scalar, Urng>, const Derived>
67 generateLike(const Derived& o, Urng&& urng)
68 {
69 return {
70 o.rows(), o.cols(), { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
71 };
72 }
73 };
74
75 template<typename DerivedGen, typename Scalar, typename ScalarA>
76 class UnaryGenBase
77 {
78 public:
89 template<typename Lhs, typename Urng>
90 inline CwiseUnaryOp<
91 internal::scalar_unary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, Urng>,
92 const Lhs
93 > generate(Urng&& urng, const ArrayBase<Lhs>& a)
94 {
95 return {
96 a, { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
97 };
98 }
99 };
100
101 template<typename DerivedGen, typename Scalar, typename ScalarA, typename ScalarB>
102 class BinaryGenBase
103 {
104 public:
115 template<typename Lhs, typename Rhs, typename Urng>
116 inline CwiseBinaryOp<
117 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, typename Rhs::Scalar, Urng>,
118 const Lhs, const Rhs
119 > generate(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
120 {
121 return {
122 a, b, { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
123 };
124 }
125
126 template<typename Lhs, typename Rhs, typename Urng>
127 inline CwiseBinaryOp<
128 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, typename Lhs::Scalar, Rhs, Urng>,
129 const Lhs, CwiseNullaryOp<internal::scalar_constant_op<Rhs>, const Lhs>
130 > generate(Urng&& urng, const ArrayBase<Lhs>& a, Rhs b)
131 {
132 return {
133 a, { a.rows(), a.cols(), internal::scalar_constant_op<Rhs>{ b } },
134 { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
135 };
136 }
137
138 template<typename Lhs, typename Rhs, typename Urng>
139 inline CwiseBinaryOp<
140 internal::scalar_binary_rng_adaptor<DerivedGen&, Scalar, Lhs, typename Rhs::Scalar, Urng>,
141 CwiseNullaryOp<internal::scalar_constant_op<Lhs>, const Rhs>, const Rhs
142 > generate(Urng&& urng, Lhs a, const ArrayBase<Rhs>& b)
143 {
144 return {
145 { b.rows(), b.cols(), internal::scalar_constant_op<Lhs>{ a } }, b,
146 { std::forward<Urng>(urng), static_cast<DerivedGen&>(*this) }
147 };
148 }
149 };
150
158 template<typename DerivedGen, typename _Scalar, Index Dim>
160 {
161 public:
165 Index dims() const { return static_cast<DerivedGen&>(*this).dims(); }
166
176 template<typename Urng>
177 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
178 {
179 return static_cast<DerivedGen&>(*this).generatr(std::forward<Urng>(urng), samples);
180 }
181
189 template<typename Urng>
190 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
191 {
192 return static_cast<DerivedGen&>(*this).generatr(std::forward<Urng>(urng));
193 }
194 };
195
203 template<typename DerivedGen, typename _Scalar, Index Dim>
205 {
206 public:
210 Index dims() const { return static_cast<DerivedGen&>(*this).dims(); }
211
221 template<typename Urng>
222 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
223 {
224 return static_cast<DerivedGen&>(*this).generate(std::forward<Urng>(urng), samples);
225 }
226
234 template<typename Urng>
235 inline Matrix<_Scalar, Dim, Dim> generate(Urng&& urng)
236 {
237 return static_cast<DerivedGen&>(*this).generate(std::forward<Urng>(urng));
238 }
239 };
240
241 template<Index _alignment=0>
242 class CacheStore
243 {
244 protected:
245 enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
246 int8_t raw_data[max_size + _alignment - 1] = { 0, };
247 void* aligned_ptr;
248
249 public:
250 CacheStore()
251 {
252 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
253 }
254
255 CacheStore(const CacheStore& c)
256 {
257 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
258 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
259 }
260
261 CacheStore(CacheStore&& c)
262 {
263 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
264 aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
265 }
266
267 template<typename Ty>
268 Ty& get()
269 {
270 return *(Ty*)aligned_ptr;
271 }
272
273 template<typename Ty>
274 const Ty& get() const
275 {
276 return *(const Ty*)aligned_ptr;
277 }
278 };
279
280 template<>
281 class CacheStore<0>
282 {
283 protected:
284 enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
285 int8_t raw_data[max_size] = { 0, };
286
287 public:
288 CacheStore()
289 {
290 }
291
292 CacheStore(const CacheStore& c)
293 {
294 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
295 }
296
297 CacheStore(CacheStore&& c)
298 {
299 std::copy(c.raw_data, c.raw_data + max_size, raw_data);
300 }
301
302 template<typename Ty>
303 Ty& get()
304 {
305 return *(Ty*)raw_data;
306 }
307
308 template<typename Ty>
309 const Ty& get() const
310 {
311 return *(const Ty*)raw_data;
312 }
313 };
314
315 using OptCacheStore = CacheStore<EIGEN_MAX_ALIGN_BYTES>;
316
317 template<typename _Scalar>
318 struct ExtractFirstUint;
319
320 template<>
321 struct ExtractFirstUint<float>
322 {
323 template<typename Packet>
324 auto operator()(Packet v) -> decltype(Eigen::internal::pfirst(v))
325 {
326 return Eigen::internal::pfirst(v);
327 }
328 };
329
330 template<>
331 struct ExtractFirstUint<double>
332 {
333 template<typename Packet>
334 auto operator()(Packet v) -> uint64_t
335 {
336 uint64_t arr[sizeof(Packet) / 8];
337 Eigen::internal::pstoreu((Packet*)arr, v);
338 return arr[0];
339 }
340 };
341
347 template<typename _Scalar>
348 class RandbitsGen : public GenBase<RandbitsGen<_Scalar>, _Scalar>
349 {
350 static_assert(std::is_integral<_Scalar>::value, "randBits needs integral types.");
351
352 public:
353 using Scalar = _Scalar;
354
355 template<typename Rng>
356 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
357 {
358 using namespace Eigen::internal;
359 return pfirst(std::forward<Rng>(rng)());
360 }
361
362 template<typename Packet, typename Rng>
363 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
364 {
365 using namespace Eigen::internal;
366 using RUtils = RawbitsMaker<Packet, Rng>;
367 return RUtils{}.rawbits(std::forward<Rng>(rng));
368 }
369 };
370
376 template<typename _Scalar>
377 class BalancedGen : public GenBase<BalancedGen<_Scalar>, _Scalar>
378 {
379 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point 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 ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * 2 - 1;
389 }
390
391 template<typename Packet, typename Rng>
392 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
393 {
394 using namespace Eigen::internal;
395 using RUtils = RandUtils<Packet, Rng>;
396 return RUtils{}.balanced(std::forward<Rng>(rng));
397 }
398 };
399
405 template<typename _Scalar>
406 class Balanced2Gen : public GenBase<Balanced2Gen<_Scalar>, _Scalar>
407 {
408 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
409 _Scalar slope = 2, bias = -1;
410 public:
411 using Scalar = _Scalar;
412
418 Balanced2Gen(_Scalar _a = -1, _Scalar _b = 1)
419 : slope{ _b - _a }, bias{ _a }
420 {
421 }
422
423 template<typename Rng>
424 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
425 {
426 using namespace Eigen::internal;
427 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * slope + bias;
428 }
429
430 template<typename Packet, typename Rng>
431 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
432 {
433 using namespace Eigen::internal;
434 using RUtils = RandUtils<Packet, Rng>;
435 return RUtils{}.balanced(std::forward<Rng>(rng), slope, bias);
436 }
437 };
438
439 template<typename _Scalar>
440 class BalancedVGen : public BinaryGenBase<BalancedVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
441 {
442 static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
443
444 public:
445 using Scalar = _Scalar;
446
447 template<typename Rng>
448 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
449 {
450 using namespace Eigen::internal;
451 return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * (b - a) + a;
452 }
453
454 template<typename Packet, typename Rng>
455 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
456 {
457 using namespace Eigen::internal;
458 using RUtils = RandUtils<Packet, Rng>;
459 return padd(pmul(RUtils{}.zero_to_one(std::forward<Rng>(rng)), psub(b, a)), a);
460 }
461 };
462
463 namespace detail
464 {
465 template<size_t v>
466 struct BitWidth
467 {
468 static constexpr size_t value = BitWidth<v / 2>::value + 1;
469 };
470
471 template<>
472 struct BitWidth<0>
473 {
474 static constexpr size_t value = 0;
475 };
476
477 template<class Rng>
478 struct RngBitSize
479 {
480 static constexpr size_t _min = Rng::min();
481 static constexpr size_t _max = Rng::max();
482
483 static constexpr bool _fullbit_rng = _min == 0 && (_max & (_max + 1)) == 0;
484 static constexpr size_t value = IsPacketRandomEngine<Rng>::value ? sizeof(typename Rng::result_type) * 8 : (_fullbit_rng ? BitWidth<_max>::value : 0);
485 };
486 }
487
493 template<typename _Scalar>
494 class StdUniformRealGen : public GenBase<StdUniformRealGen<_Scalar>, _Scalar>
495 {
496 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
497
498 public:
499 using Scalar = _Scalar;
500
501 template<typename Rng,
502 typename std::enable_if<sizeof(Scalar) * 8 <= detail::RngBitSize<typename std::remove_const<typename std::remove_reference<Rng>::type>::type>::value, int>::type = 0
503 >
504 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
505 {
506 using namespace Eigen::internal;
507 return BitScalar<_Scalar>{}.to_ur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
508 }
509
510 template<typename Rng,
511 typename std::enable_if<detail::RngBitSize<typename std::remove_const<typename std::remove_reference<Rng>::type>::type>::value < sizeof(Scalar) * 8, int>::type = 0
512 >
513 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
514 {
515 using RRng = typename std::remove_const<typename std::remove_reference<Rng>::type>::type;
516 static_assert(detail::RngBitSize<RRng>::value > 0,
517 "BaseRng must be a kind of mersenne_twister_engine.");
518 using ResultType = typename std::conditional<detail::RngBitSize<RRng>::value == 32, uint32_t, uint64_t>::type;
519 using namespace Eigen::internal;
520 ResultType arr[sizeof(Scalar) / sizeof(ResultType)];
521 for (size_t i = 0; i < sizeof(Scalar) / sizeof(ResultType); ++i)
522 {
523 arr[i] = rng();
524 }
525 return BitScalar<_Scalar>{}.to_ur(*(uint64_t*)arr);
526 }
527
528 template<typename Rng,
529 typename std::enable_if<sizeof(Scalar) <= sizeof(typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type), int>::type = 0
530 >
531 EIGEN_STRONG_INLINE const _Scalar nzur_scalar(Rng&& rng)
532 {
533 using namespace Eigen::internal;
534 return BitScalar<_Scalar>{}.to_nzur(ExtractFirstUint<_Scalar>{}(std::forward<Rng>(rng)()));
535 }
536
537 template<typename Rng,
538 typename std::enable_if<sizeof(typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type) < sizeof(Scalar), int > ::type = 0
539 >
540 EIGEN_STRONG_INLINE const _Scalar nzur_scalar(Rng&& rng)
541 {
542 using namespace Eigen::internal;
543 using RngResult = typename std::remove_const<typename std::remove_reference<Rng>::type>::type::result_type;
544 RngResult arr[sizeof(Scalar) / sizeof(RngResult)];
545 for (size_t i = 0; i < sizeof(Scalar) / sizeof(RngResult); ++i)
546 {
547 arr[i] = rng();
548 }
549 return BitScalar<_Scalar>{}.to_nzur(*(Scalar*)arr);
550 }
551
552 template<typename Packet, typename Rng>
553 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
554 {
555 using namespace Eigen::internal;
556 using RUtils = RandUtils<Packet, Rng>;
557 return RUtils{}.uniform_real(std::forward<Rng>(rng));
558 }
559 };
560
566 template<typename _Scalar>
567 class UniformRealGen : public GenBase<UniformRealGen<_Scalar>, _Scalar>
568 {
569 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
570 _Scalar bias, slope;
571
572 public:
573 using Scalar = _Scalar;
574
575 UniformRealGen(_Scalar _min = 0, _Scalar _max = 1)
576 : bias{ _min }, slope{ _max - _min }
577 {
578 }
579
580 UniformRealGen(const UniformRealGen&) = default;
581 UniformRealGen(UniformRealGen&&) = default;
582
583 UniformRealGen& operator=(const UniformRealGen&) = default;
584 UniformRealGen& operator=(UniformRealGen&&) = default;
585
586 template<typename Rng>
587 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
588 {
589 using namespace Eigen::internal;
590 return bias + BitScalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)())) * slope;
591 }
592
593 template<typename Packet, typename Rng>
594 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
595 {
596 using namespace Eigen::internal;
597 using RUtils = RandUtils<Packet, Rng>;
598 return padd(pmul(
599 RUtils{}.uniform_real(std::forward<Rng>(rng)), pset1<Packet>(slope)
600 ), pset1<Packet>(bias));
601 }
602 };
603
604 template<typename _Scalar>
605 class UniformRealVGen : public BinaryGenBase<UniformRealVGen<_Scalar>, _Scalar, _Scalar, _Scalar>
606 {
607 static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
608
609 public:
610 using Scalar = _Scalar;
611
612 template<typename Rng>
613 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a, _Scalar b)
614 {
615 using namespace Eigen::internal;
616 return a + BitScalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)())) * (b - a);
617 }
618
619 template<typename Packet, typename Rng>
620 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng, const Packet& a, const Packet& b)
621 {
622 using namespace Eigen::internal;
623 using RUtils = RandUtils<Packet, Rng>;
624 return padd(pmul(
625 RUtils{}.uniform_real(std::forward<Rng>(rng)), psub(b, a)
626 ), a);
627 }
628 };
629
630
636 template<typename _Scalar>
637 class BernoulliGen : public GenBase<BernoulliGen<_Scalar>, _Scalar>
638 {
639 uint32_t p;
640 public:
641 using Scalar = _Scalar;
642
643 BernoulliGen(double _p = 0.5)
644 {
645 eigen_assert(0 <= _p && _p <= 1 );
646 p = (uint32_t)(_p * 0x80000000);
647 }
648
649 BernoulliGen(const BernoulliGen&) = default;
650 BernoulliGen(BernoulliGen&&) = default;
651
652 BernoulliGen& operator=(const BernoulliGen&) = default;
653 BernoulliGen& operator=(BernoulliGen&&) = default;
654
655 template<typename Rng>
656 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
657 {
658 using namespace Eigen::internal;
659 return (((uint32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) < p) ? 1 : 0;
660 }
661
662 template<typename Packet, typename Rng>
663 EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
664 {
665 using namespace Eigen::internal;
666 using IPacket = decltype(reinterpret_to_int(std::declval<Packet>()));
667 using RUtils = RawbitsMaker<IPacket, Rng>;
668 auto one = pset1<Packet>(1);
669 auto zero = pset1<Packet>(0);
670 auto r = RUtils{}.rawbits(std::forward<Rng>(rng));
671 r = pand(r, pset1<IPacket>(0x7FFFFFFF));
672 return pblendv(pcmplt(r, pset1<IPacket>(p)), one, zero);
673 }
674 };
675
676 template<typename _Scalar>
677 class BernoulliVGen : public UnaryGenBase<BernoulliVGen<_Scalar>, _Scalar, _Scalar>
678 {
679 static_assert(std::is_floating_point<_Scalar>::value, "vectorized `bernoulli` needs a float type.");
680 public:
681 using Scalar = _Scalar;
682
683 template<typename Rng>
684 EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng, _Scalar a)
685 {
686 using namespace Eigen::internal;
687 uint32_t p = (uint32_t)(a * 0x80000000);
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, const Packet& a)
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 p = pcast<Packet, IPacket>(pmul(a, pset1<Packet>(0x80000000)));
700 auto r = RUtils{}.rawbits(std::forward<Rng>(rng));
701 r = pand(r, pset1<IPacket>(0x7FFFFFFF));
702 return pblendv(pcmplt(r, p), one, zero);
703 }
704 };
705
706 template<typename Derived, typename Urng>
707 using RandBitsType = CwiseNullaryOp<internal::scalar_rng_adaptor<RandbitsGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
708
721 template<typename Derived, typename Urng>
722 inline const RandBitsType<Derived, Urng>
723 randBits(Index rows, Index cols, Urng&& urng)
724 {
725 return {
726 rows, cols, { std::forward<Urng>(urng) }
727 };
728 }
729
741 template<typename Derived, typename Urng>
742 inline const RandBitsType<Derived, Urng>
743 randBitsLike(Derived& o, Urng&& urng)
744 {
745 return {
746 o.rows(), o.cols(), { std::forward<Urng>(urng) }
747 };
748 }
749
750 template<typename Derived, typename Urng>
751 using BalancedType = CwiseNullaryOp<internal::scalar_rng_adaptor<BalancedGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
752
765 template<typename Derived, typename Urng>
766 inline const BalancedType<Derived, Urng>
767 balanced(Index rows, Index cols, Urng&& urng)
768 {
769 return {
770 rows, cols, { std::forward<Urng>(urng) }
771 };
772 }
773
785 template<typename Derived, typename Urng>
786 inline const BalancedType<Derived, Urng>
787 balancedLike(const Derived& o, Urng&& urng)
788 {
789 return {
790 o.rows(), o.cols(), { std::forward<Urng>(urng) }
791 };
792 }
793
794 template<typename Derived, typename Urng>
795 using Balanced2Type = CwiseNullaryOp<internal::scalar_rng_adaptor<Balanced2Gen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
796
810 template<typename Derived, typename Urng>
811 inline const Balanced2Type<Derived, Urng>
812 balanced(Index rows, Index cols, Urng&& urng, typename Derived::Scalar a, typename Derived::Scalar b)
813 {
814 return {
815 rows, cols, { std::forward<Urng>(urng), Balanced2Gen<typename Derived::Scalar>{a, b} }
816 };
817 }
818
831 template<typename Derived, typename Urng>
832 inline const Balanced2Type<Derived, Urng>
833 balancedLike(const Derived& o, Urng&& urng, typename Derived::Scalar a, typename Derived::Scalar b)
834 {
835 return {
836 o.rows(), o.cols(), { std::forward<Urng>(urng), Balanced2Gen<typename Derived::Scalar>{a, b} }
837 };
838 }
839
840 template<typename Derived, typename Urng>
841 using BalancedVVType = CwiseBinaryOp<
842 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
843 const Derived, const Derived
844 >;
845
859 template<typename Lhs, typename Rhs, typename Urng>
860 inline const BalancedVVType<Lhs, Urng>
861 balanced(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
862 {
863 static_assert(std::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value, "`Lhs::Scalar` must be equal to `Rhs::Scalar`");
864 return {
865 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
866 { std::forward<Urng>(urng), BalancedVGen<typename Lhs::Scalar>{} }
867 };
868 }
869
870 template<typename Derived, typename Urng>
871 using BalancedVSType = CwiseBinaryOp<
872 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
873 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
874 >;
875
876 template<typename Lhs, typename Urng>
877 inline const BalancedVSType<Lhs, Urng>
878 balanced(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
879 {
880 return {
881 static_cast<const Lhs&>(a), { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
882 { std::forward<Urng>(urng), BalancedVGen<typename Lhs::Scalar>{} }
883 };
884 }
885
886 template<typename Derived, typename Urng>
887 using BalancedSVType = CwiseBinaryOp<
888 internal::scalar_binary_rng_adaptor<BalancedVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
889 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
890 >;
891
892 template<typename Rhs, typename Urng>
893 inline const BalancedSVType<Rhs, Urng>
894 balanced(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
895 {
896 return {
897 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } }, static_cast<const Rhs&>(b),
898 { std::forward<Urng>(urng), BalancedVGen<typename Rhs::Scalar>{} }
899 };
900 }
901
902 template<typename Derived, typename Urng>
903 using StdUniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<StdUniformRealGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
904
917 template<typename Derived, typename Urng>
918 inline const StdUniformRealType<Derived, Urng>
919 uniformReal(Index rows, Index cols, Urng&& urng)
920 {
921 return {
922 rows, cols, { std::forward<Urng>(urng) }
923 };
924 }
925
937 template<typename Derived, typename Urng>
938 inline const StdUniformRealType<Derived, Urng>
939 uniformRealLike(Derived& o, Urng&& urng)
940 {
941 return {
942 o.rows(), o.cols(), { std::forward<Urng>(urng) }
943 };
944 }
945
946 template<typename Derived, typename Urng>
947 using UniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformRealGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
948
962 template<typename Derived, typename Urng>
963 inline const UniformRealType<Derived, Urng>
964 uniformReal(Index rows, Index cols, Urng&& urng, typename Derived::Scalar min, typename Derived::Scalar max)
965 {
966 return {
967 rows, cols, { std::forward<Urng>(urng), UniformRealGen<typename Derived::Scalar>{ min, max } }
968 };
969 }
970
983 template<typename Derived, typename Urng>
984 inline const UniformRealType<Derived, Urng>
985 uniformRealLike(Derived& o, Urng&& urng, typename Derived::Scalar min, typename Derived::Scalar max)
986 {
987 return {
988 o.rows(), o.cols(), { std::forward<Urng>(urng), UniformRealGen<typename Derived::Scalar>{ min, max } }
989 };
990 }
991
992 template<typename Derived, typename Urng>
993 using UniformRealVVType = CwiseBinaryOp<
994 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
995 const Derived, const Derived
996 >;
997
1011 template<typename Lhs, typename Rhs, typename Urng>
1012 inline const UniformRealVVType<Lhs, Urng>
1013 uniformReal(Urng&& urng, const ArrayBase<Lhs>& a, const ArrayBase<Rhs>& b)
1014 {
1015 static_assert(std::is_same<typename Lhs::Scalar, typename Rhs::Scalar>::value, "`Lhs::Scalar` must be equal to `Rhs::Scalar`");
1016 return {
1017 static_cast<const Lhs&>(a), static_cast<const Rhs&>(b),
1018 { std::forward<Urng>(urng), UniformRealVGen<typename Lhs::Scalar>{} }
1019 };
1020 }
1021
1022 template<typename Derived, typename Urng>
1023 using UniformRealVSType = CwiseBinaryOp<
1024 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1025 const Derived, CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>
1026 >;
1027
1028 template<typename Lhs, typename Urng>
1029 inline const UniformRealVSType<Lhs, Urng>
1030 uniformReal(Urng&& urng, const ArrayBase<Lhs>& a, typename Lhs::Scalar b)
1031 {
1032 return {
1033 static_cast<const Lhs&>(a), { a.rows(), a.cols(), internal::scalar_constant_op<typename Lhs::Scalar>{ b } },
1034 { std::forward<Urng>(urng), UniformRealVGen<typename Lhs::Scalar>{} }
1035 };
1036 }
1037
1038
1039 template<typename Derived, typename Urng>
1040 using UniformRealSVType = CwiseBinaryOp<
1041 internal::scalar_binary_rng_adaptor<UniformRealVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1042 CwiseNullaryOp<internal::scalar_constant_op<typename Derived::Scalar>, const Derived>, const Derived
1043 >;
1044
1045 template<typename Rhs, typename Urng>
1046 inline const UniformRealSVType<Rhs, Urng>
1047 uniformReal(Urng&& urng, typename Rhs::Scalar a, const ArrayBase<Rhs>& b)
1048 {
1049 return {
1050 { b.rows(), b.cols(), internal::scalar_constant_op<typename Rhs::Scalar>{ a } }, static_cast<const Rhs&>(b),
1051 { std::forward<Urng>(urng), UniformRealVGen<typename Rhs::Scalar>{} }
1052 };
1053 }
1054
1055 template<typename Derived, typename Urng>
1056 using BernoulliType = CwiseNullaryOp<internal::scalar_rng_adaptor<BernoulliGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
1057
1069 template<typename Derived, typename Urng>
1070 inline const BernoulliType<Derived, Urng>
1071 bernoulli(Index rows, Index cols, Urng&& urng, double p = 0.5)
1072 {
1073 return {
1074 rows, cols, { std::forward<Urng>(urng), BernoulliGen<typename Derived::Scalar>{ p } }
1075 };
1076 }
1077
1088 template<typename Derived, typename Urng>
1089 inline const BernoulliType<Derived, Urng>
1090 bernoulli(Derived& o, Urng&& urng, double p = 0.5)
1091 {
1092 return {
1093 o.rows(), o.cols(), { std::forward<Urng>(urng), BernoulliGen<typename Derived::Scalar>{ p } }
1094 };
1095 }
1096
1097 template<typename Derived, typename Urng>
1098 using BernoulliVType = CwiseUnaryOp<
1099 internal::scalar_unary_rng_adaptor<BernoulliVGen<typename Derived::Scalar>, typename Derived::Scalar, typename Derived::Scalar, Urng, true>,
1100 const Derived
1101 >;
1102
1112 template<typename Lhs, typename Urng>
1113 inline const BernoulliVType<Lhs, Urng>
1114 bernoulli(Urng&& urng, const ArrayBase<Lhs>& p)
1115 {
1116 return BernoulliVType<Lhs, Urng>{
1117 static_cast<const Lhs&>(p), { std::forward<Urng>(urng), BernoulliVGen<typename Lhs::Scalar>{} }
1118 };
1119 }
1120 }
1121}
1122
1123#endif
Generator of reals in a range [a, b]
Definition: Basic.h:407
Balanced2Gen(_Scalar _a=-1, _Scalar _b=1)
Construct a new balanced generator.
Definition: Basic.h:418
Generator of reals in a range [-1, 1]
Definition: Basic.h:378
Generator of Bernoulli distribution.
Definition: Basic.h:638
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:48
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:67
Base class of all multivariate random matrix generators.
Definition: Basic.h:205
Index dims() const
returns the dimensions of matrices to be generated
Definition: Basic.h:210
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:222
Matrix< _Scalar, Dim, Dim > generate(Urng &&urng)
generates one sample
Definition: Basic.h:235
Base class of all multivariate random vector generators.
Definition: Basic.h:160
Matrix< _Scalar, Dim, 1 > generate(Urng &&urng)
generates one sample
Definition: Basic.h:190
Index dims() const
returns the dimensions of vectors to be generated
Definition: Basic.h:165
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:177
Generator of random bits for integral scalars.
Definition: Basic.h:349
Generator of reals in a range [0, 1)
Definition: Basic.h:495
Generator of reals in a range [a, b)
Definition: Basic.h:568
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:767
const RandBitsType< Derived, Urng > randBitsLike(Derived &o, Urng &&urng)
generates integers with random bits
Definition: Basic.h:743
const BalancedType< Derived, Urng > balancedLike(const Derived &o, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:787
const RandBitsType< Derived, Urng > randBits(Index rows, Index cols, Urng &&urng)
generates integers with random bits
Definition: Basic.h:723
const StdUniformRealType< Derived, Urng > uniformRealLike(Derived &o, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:939
const StdUniformRealType< Derived, Urng > uniformReal(Index rows, Index cols, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:919
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:1071