EigenRand  0.3.0
Basic.h
Go to the documentation of this file.
1 
12 #ifndef EIGENRAND_DISTS_BASIC_H
13 #define EIGENRAND_DISTS_BASIC_H
14 
15 namespace 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 
82  template<typename DerivedGen, typename _Scalar, Index Dim>
84  {
85  public:
89  Index dims() const { return static_cast<DerivedGen&>(*this).dims(); }
90 
100  template<typename Urng>
101  inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
102  {
103  return static_cast<DerivedGen&>(*this).generatr(std::forward<Urng>(urng), samples);
104  }
105 
113  template<typename Urng>
114  inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
115  {
116  return static_cast<DerivedGen&>(*this).generatr(std::forward<Urng>(urng));
117  }
118  };
119 
127  template<typename DerivedGen, typename _Scalar, Index Dim>
129  {
130  public:
134  Index dims() const { return static_cast<DerivedGen&>(*this).dims(); }
135 
145  template<typename Urng>
146  inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
147  {
148  return static_cast<DerivedGen&>(*this).generate(std::forward<Urng>(urng), samples);
149  }
150 
158  template<typename Urng>
159  inline Matrix<_Scalar, Dim, Dim> generate(Urng&& urng)
160  {
161  return static_cast<DerivedGen&>(*this).generate(std::forward<Urng>(urng));
162  }
163  };
164 
165  template<Index _alignment=0>
166  class CacheStore
167  {
168  protected:
169  enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
170  int8_t raw_data[max_size + _alignment - 1] = { 0, };
171  void* aligned_ptr;
172 
173  public:
174  CacheStore()
175  {
176  aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
177  }
178 
179  CacheStore(const CacheStore& c)
180  {
181  std::copy(c.raw_data, c.raw_data + max_size, raw_data);
182  aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
183  }
184 
185  CacheStore(CacheStore&& c)
186  {
187  std::copy(c.raw_data, c.raw_data + max_size, raw_data);
188  aligned_ptr = (void*)((((size_t)raw_data + _alignment - 1) / _alignment) * _alignment);
189  }
190 
191  template<typename Ty>
192  Ty& get()
193  {
194  return *(Ty*)aligned_ptr;
195  }
196 
197  template<typename Ty>
198  const Ty& get() const
199  {
200  return *(const Ty*)aligned_ptr;
201  }
202  };
203 
204  template<>
205  class CacheStore<0>
206  {
207  protected:
208  enum { max_size = sizeof(internal::find_best_packet<float, -1>::type) };
209  int8_t raw_data[max_size] = { 0, };
210 
211  public:
212  CacheStore()
213  {
214  }
215 
216  CacheStore(const CacheStore& c)
217  {
218  std::copy(c.raw_data, c.raw_data + max_size, raw_data);
219  }
220 
221  CacheStore(CacheStore&& c)
222  {
223  std::copy(c.raw_data, c.raw_data + max_size, raw_data);
224  }
225 
226  template<typename Ty>
227  Ty& get()
228  {
229  return *(Ty*)raw_data;
230  }
231 
232  template<typename Ty>
233  const Ty& get() const
234  {
235  return *(const Ty*)raw_data;
236  }
237  };
238 
239  using OptCacheStore = CacheStore<EIGEN_MAX_ALIGN_BYTES>;
240 
246  template<typename _Scalar>
247  class RandbitsGen : public GenBase<RandbitsGen<_Scalar>, _Scalar>
248  {
249  static_assert(std::is_integral<_Scalar>::value, "randBits needs integral types.");
250 
251  public:
252  using Scalar = _Scalar;
253 
254  template<typename Rng>
255  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
256  {
257  using namespace Eigen::internal;
258  return pfirst(std::forward<Rng>(rng)());
259  }
260 
261  template<typename Packet, typename Rng>
262  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
263  {
264  using namespace Eigen::internal;
265  using RUtils = RawbitsMaker<Packet, Rng>;
266  return RUtils{}.rawbits(std::forward<Rng>(rng));
267  }
268  };
269 
275  template<typename _Scalar>
276  class BalancedGen : public GenBase<BalancedGen<_Scalar>, _Scalar>
277  {
278  static_assert(std::is_floating_point<_Scalar>::value, "balanced needs floating point types.");
279 
280  public:
281  using Scalar = _Scalar;
282 
283  template<typename Rng>
284  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
285  {
286  using namespace Eigen::internal;
287  return ((_Scalar)((int32_t)pfirst(std::forward<Rng>(rng)()) & 0x7FFFFFFF) / 0x7FFFFFFF) * 2 - 1;
288  }
289 
290  template<typename Packet, typename Rng>
291  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
292  {
293  using namespace Eigen::internal;
294  using RUtils = RandUtils<Packet, Rng>;
295  return RUtils{}.balanced(std::forward<Rng>(rng));
296  }
297  };
298 
304  template<typename _Scalar>
305  class UniformRealGen : public GenBase<UniformRealGen<_Scalar>, _Scalar>
306  {
307  static_assert(std::is_floating_point<_Scalar>::value, "uniformReal needs floating point types.");
308 
309  public:
310  using Scalar = _Scalar;
311 
312  template<typename Rng>
313  EIGEN_STRONG_INLINE const _Scalar operator() (Rng&& rng)
314  {
315  using namespace Eigen::internal;
316  return bit_scalar<_Scalar>{}.to_ur(pfirst(std::forward<Rng>(rng)()));
317  }
318 
319  template<typename Rng>
320  EIGEN_STRONG_INLINE const _Scalar nzur_scalar(Rng&& rng)
321  {
322  using namespace Eigen::internal;
323  return bit_scalar<_Scalar>{}.to_nzur(pfirst(std::forward<Rng>(rng)()));
324  }
325 
326  template<typename Packet, typename Rng>
327  EIGEN_STRONG_INLINE const Packet packetOp(Rng&& rng)
328  {
329  using namespace Eigen::internal;
330  using RUtils = RandUtils<Packet, Rng>;
331  return RUtils{}.uniform_real(std::forward<Rng>(rng));
332  }
333  };
334 
335 
336  template<typename Derived, typename Urng>
337  using RandBitsType = CwiseNullaryOp<internal::scalar_rng_adaptor<RandbitsGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
338 
351  template<typename Derived, typename Urng>
352  inline const RandBitsType<Derived, Urng>
353  randBits(Index rows, Index cols, Urng&& urng)
354  {
355  return {
356  rows, cols, { std::forward<Urng>(urng) }
357  };
358  }
359 
371  template<typename Derived, typename Urng>
372  inline const RandBitsType<Derived, Urng>
373  randBitsLike(Derived& o, Urng&& urng)
374  {
375  return {
376  o.rows(), o.cols(), { std::forward<Urng>(urng) }
377  };
378  }
379 
380  template<typename Derived, typename Urng>
381  using BalancedType = CwiseNullaryOp<internal::scalar_rng_adaptor<BalancedGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
382 
395  template<typename Derived, typename Urng>
396  inline const BalancedType<Derived, Urng>
397  balanced(Index rows, Index cols, Urng&& urng)
398  {
399  return {
400  rows, cols, { std::forward<Urng>(urng) }
401  };
402  }
403 
415  template<typename Derived, typename Urng>
416  inline const BalancedType<Derived, Urng>
417  balancedLike(const Derived& o, Urng&& urng)
418  {
419  return {
420  o.rows(), o.cols(), { std::forward<Urng>(urng) }
421  };
422  }
423 
424  template<typename Derived, typename Urng>
425  using UniformRealType = CwiseNullaryOp<internal::scalar_rng_adaptor<UniformRealGen<typename Derived::Scalar>, typename Derived::Scalar, Urng, true>, const Derived>;
426 
439  template<typename Derived, typename Urng>
440  inline const UniformRealType<Derived, Urng>
441  uniformReal(Index rows, Index cols, Urng&& urng)
442  {
443  return {
444  rows, cols, { std::forward<Urng>(urng) }
445  };
446  }
447 
459  template<typename Derived, typename Urng>
460  inline const UniformRealType<Derived, Urng>
461  uniformRealLike(Derived& o, Urng&& urng)
462  {
463  return {
464  o.rows(), o.cols(), { std::forward<Urng>(urng) }
465  };
466  }
467  }
468 }
469 
470 #endif
Eigen::Rand::balanced
const BalancedType< Derived, Urng > balanced(Index rows, Index cols, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:397
Eigen::Rand::GenBase
Base class of all univariate random generators.
Definition: Basic.h:33
Eigen::Rand::uniformReal
const UniformRealType< Derived, Urng > uniformReal(Index rows, Index cols, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:441
Eigen::Rand::GenBase::generateLike
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
Eigen::Rand::MvVecGenBase
Base class of all multivariate random vector generators.
Definition: Basic.h:84
Eigen::Rand::MvMatGenBase
Base class of all multivariate random matrix generators.
Definition: Basic.h:129
Eigen::Rand::MvVecGenBase::dims
Index dims() const
returns the dimensions of vectors to be generated
Definition: Basic.h:89
Eigen::Rand::randBitsLike
const RandBitsType< Derived, Urng > randBitsLike(Derived &o, Urng &&urng)
generates integers with random bits
Definition: Basic.h:373
Eigen::Rand::MvVecGenBase::generate
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:101
Eigen::Rand::GenBase::generate
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
Eigen::Rand::UniformRealGen
Generator of reals in a range [0, 1)
Definition: Basic.h:306
Eigen::Rand::MvVecGenBase::generate
Matrix< _Scalar, Dim, 1 > generate(Urng &&urng)
generates one sample
Definition: Basic.h:114
Eigen::Rand::BalancedGen
Generator of reals in a range [-1, 1]
Definition: Basic.h:277
Eigen::Rand::MvMatGenBase::generate
Matrix< _Scalar, Dim, -1 > generate(Urng &&urng, Index samples)
generates multiple samples at once
Definition: Basic.h:146
Eigen::Rand::uniformRealLike
const UniformRealType< Derived, Urng > uniformRealLike(Derived &o, Urng &&urng)
generates reals in a range [0, 1)
Definition: Basic.h:461
Eigen::Rand::balancedLike
const BalancedType< Derived, Urng > balancedLike(const Derived &o, Urng &&urng)
generates reals in a range [-1, 1]
Definition: Basic.h:417
Eigen::Rand::MvMatGenBase::generate
Matrix< _Scalar, Dim, Dim > generate(Urng &&urng)
generates one sample
Definition: Basic.h:159
Eigen::Rand::randBits
const RandBitsType< Derived, Urng > randBits(Index rows, Index cols, Urng &&urng)
generates integers with random bits
Definition: Basic.h:353
Eigen::Rand::RandbitsGen
Generator of random bits for integral scalars.
Definition: Basic.h:248
Eigen::Rand::MvMatGenBase::dims
Index dims() const
returns the dimensions of matrices to be generated
Definition: Basic.h:134