MCKL
Monte Carlo Kernel Library
mkl.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/mkl.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_MKL_HPP
33 #define MCKL_RANDOM_MKL_HPP
34 
37 #include <mkl_vsl.h>
38 
39 namespace mckl {
40 
41 namespace internal {
42 
43 #if MCKL_NO_RUNTIME_ASSERT
44 
45 inline int mkl_error_check(int status, const char *, const char *)
46 {
47  return status;
48 }
49 
50 #else // MCKL_NO_RUNTIME_ASSERT
51 
52 inline int mkl_error_check(int status, const char *cpp, const char *c)
53 {
54  if (status == VSL_ERROR_OK)
55  return status;
56 
57  std::string msg;
58  msg += "**";
59  msg += cpp;
60  msg += "**";
61  msg += " failed";
62  msg += "; MKL function: ";
63  msg += c;
64  msg += "; Error code: ";
65  msg += std::to_string(status);
66 
67  runtime_assert((status == VSL_ERROR_OK), msg.c_str());
68 
69  return status;
70 }
71 
72 #endif // MCKL_NO_RUNTIME_ASSERT
73 
74 } // namespace internal
75 
78 class MKLStream
79 {
80  public:
81  explicit MKLStream(::VSLStreamStatePtr ptr = nullptr) : ptr_(nullptr)
82  {
83  reset(ptr);
84  }
85 
87  MKLStream(MKL_INT brng, MKL_UINT seed) : ptr_(nullptr)
88  {
89  reset(brng, seed);
90  }
91 
93  MKLStream(MKL_INT brng, MKL_INT n, unsigned *params) : ptr_(nullptr)
94  {
95  reset(brng, n, params);
96  }
97 
99  MKLStream(const MKLStream &other) : ptr_(nullptr)
100  {
101  ::VSLStreamStatePtr ptr = nullptr;
102  if (internal::mkl_error_check(::vslCopyStream(&ptr, other.ptr_),
103  "MKLStream::MKLStream", "::vslCopyStream") == VSL_ERROR_OK) {
104  reset(ptr);
105  }
106  }
107 
110  {
111  if (this != &other) {
112  ::VSLStreamStatePtr ptr = nullptr;
113  if (internal::mkl_error_check(::vslCopyStream(&ptr, other.ptr_),
114  "MKLStream::operator=", "::vslCopyStream") ==
115  VSL_ERROR_OK) {
116  reset(ptr);
117  }
118  }
119 
120  return *this;
121  }
122 
123  MKLStream(MKLStream &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; }
124 
126  {
127  if (this != &other) {
128  release();
129  ptr_ = other.ptr_;
130  other.ptr_ = nullptr;
131  }
132 
133  return *this;
134  }
135 
137  ~MKLStream() { release(); }
138 
139  int reset(::VSLStreamStatePtr ptr)
140  {
141  int status = release();
142  ptr_ = ptr;
143 
144  return status;
145  }
146 
148  int reset(MKL_INT brng, MKL_UINT seed)
149  {
150  ::VSLStreamStatePtr ptr = nullptr;
151  int status =
152  internal::mkl_error_check(::vslNewStream(&ptr, brng, seed),
153  "MKLStream::reset", "::vslNewStream");
154  if (status == VSL_ERROR_OK) {
155  reset(ptr);
156  }
157 
158  return status;
159  }
160 
162  int reset(MKL_INT brng, MKL_INT n, unsigned *params)
163  {
164  ::VSLStreamStatePtr ptr = nullptr;
165  int status =
166  internal::mkl_error_check(::vslNewStreamEx(&ptr, brng, n, params),
167  "MKLStream::reset", "::vslNewStreamEx");
168  if (status == VSL_ERROR_OK) {
169  reset(ptr);
170  }
171 
172  return status;
173  }
174 
176  int release()
177  {
178  if (ptr_ == nullptr) {
179  return VSL_ERROR_OK;
180  }
181 
182  int status = internal::mkl_error_check(::vslDeleteStream(&ptr_),
183  "MKLStream::release", "::vslDeleteStream");
184  ptr_ = nullptr;
185 
186  return status;
187  }
188 
189  bool empty() const { return ptr_ == nullptr; }
190 
192  int save_f(const std::string &fname) const
193  {
194  return internal::mkl_error_check(::vslSaveStreamF(ptr_, fname.c_str()),
195  "MKLStream::save_f", "::vslSaveStreamF");
196  }
197 
199  int load_f(const std::string &fname)
200  {
201  ::VSLStreamStatePtr ptr = nullptr;
202  int status =
203  internal::mkl_error_check(::vslSaveStreamF(&ptr, fname.c_str()),
204  "MKLStream::load_f", "::vslSaveStreamF");
205  if (status == VSL_ERROR_OK) {
206  reset(ptr);
207  }
208 
209  return status;
210  }
211 
213  int save_m(char *memptr) const
214  {
215  return internal::mkl_error_check(::vslSaveStreamM(ptr_, memptr),
216  "MKLStream::save_m", "::vslSaveStreamM");
217  }
218 
220  int load_m(const char *memptr)
221  {
222  ::VSLStreamStatePtr ptr = nullptr;
223  int status = internal::mkl_error_check(::vslLoadStreamM(&ptr, memptr),
224  "MKLStream::load_m", "::vslLoadStreamM");
225  if (status == VSL_ERROR_OK) {
226  reset(ptr);
227  }
228 
229  return status;
230  }
231 
233  int get_size() const { return ::vslGetStreamSize(ptr_); }
234 
236  int leapfrog(MKL_INT k, MKL_INT nstreams)
237  {
239  ::vslLeapfrogStream(ptr_, k, nstreams), "MKLStream::leapfrog",
240  "::vslLeapfrogStream");
241  }
242 
244  int skip_ahead(long long nskip)
245  {
246  return internal::mkl_error_check(::vslSkipAheadStream(ptr_, nskip),
247  "MKLStream::skip_ahead", "::vslSkipAheadStream");
248  }
249 
251  int get_brng() const { return ::vslGetStreamStateBrng(ptr_); }
252 
254  static int get_num_reg_brngs() { return ::vslGetNumRegBrngs(); }
255 
258  MKL_INT brng, ::VSLBRngProperties *properties)
259  {
261  ::vslGetBrngProperties(brng, properties),
262  "MKLStream::get_brng_properties", "::vslGetBrngProperties");
263  }
264 
266  static bool has_leap_frog(MKL_INT brng)
267  {
268  MKLStream stream(brng, 1);
269 
270  return ::vslLeapfrogStream(stream.ptr_, 1, 2) == VSL_ERROR_OK;
271  }
272 
274  static bool has_skip_ahead(MKL_INT brng)
275  {
276  MKLStream stream(brng, 1);
277 
278  return ::vslSkipAheadStream(stream.ptr_, 1) == VSL_ERROR_OK;
279  }
280 
282  static bool has_uniform_bits32(
283  MKL_INT brng, MKL_INT method = VSL_RNG_METHOD_UNIFORMBITS32_STD)
284  {
285  MKLStream stream(brng, 1);
286  unsigned r;
287 
288  return ::viRngUniformBits32(method, stream.ptr_, 1, &r) ==
289  VSL_ERROR_OK;
290  }
291 
293  static bool has_uniform_bits64(
294  MKL_INT brng, MKL_INT method = VSL_RNG_METHOD_UNIFORMBITS64_STD)
295  {
296  MKLStream stream(brng, 1);
297  unsigned MKL_INT64 r;
298 
299  return ::viRngUniformBits64(method, stream.ptr_, 1, &r) ==
300  VSL_ERROR_OK;
301  }
302 
304  int uniform(MKL_INT n, float *r, float a, float b,
305  MKL_INT method = VSL_RNG_METHOD_UNIFORM_STD)
306  {
308  ::vsRngUniform(method, ptr_, n, r, a, b), "MKLStream::uniform",
309  "::vsRngUniform");
310  }
311 
313  int uniform(MKL_INT n, double *r, double a, double b,
314  MKL_INT method = VSL_RNG_METHOD_UNIFORM_STD)
315  {
317  ::vdRngUniform(method, ptr_, n, r, a, b), "MKLStream::uniform",
318  "::vdRngUniform");
319  }
320 
322  int gaussian(MKL_INT n, float *r, float a, float sigma,
323  MKL_INT method = VSL_RNG_METHOD_GAUSSIAN_BOXMULLER2)
324  {
326  ::vsRngGaussian(method, ptr_, n, r, a, sigma),
327  "MKLStream::gaussian", "::vsRngGaussian");
328  }
329 
331  int gaussian(MKL_INT n, double *r, double a, double sigma,
332  MKL_INT method = VSL_RNG_METHOD_GAUSSIAN_BOXMULLER2)
333  {
335  ::vdRngGaussian(method, ptr_, n, r, a, sigma),
336  "MKLStream::gaussian", "::vdRngGaussian");
337  }
338 
340  int gaussian_mv(MKL_INT n, float *r, MKL_INT dimen, MKL_INT mstorage,
341  const float *a, const float *t,
342  MKL_INT method = VSL_RNG_METHOD_GAUSSIANMV_BOXMULLER2)
343  {
345  ::vsRngGaussianMV(method, ptr_, n, r, dimen, mstorage, a, t),
346  "MKLStream::gaussian_mv", "::vsRngGaussianMV");
347  }
348 
350  int gaussian_mv(MKL_INT n, double *r, MKL_INT dimen, MKL_INT mstorage,
351  const double *a, const double *t,
352  MKL_INT method = VSL_RNG_METHOD_GAUSSIANMV_BOXMULLER2)
353  {
355  ::vdRngGaussianMV(method, ptr_, n, r, dimen, mstorage, a, t),
356  "MKLStream::gaussian_mv", "::vdRngGaussianMV");
357  }
358 
360  int exponential(MKL_INT n, float *r, float a, float beta,
361  MKL_INT method = VSL_RNG_METHOD_EXPONENTIAL_ICDF)
362  {
364  ::vsRngExponential(method, ptr_, n, r, a, beta),
365  "MKLStream::exponential", "::vsRngExponential");
366  }
367 
369  int exponential(MKL_INT n, double *r, double a, double beta,
370  MKL_INT method = VSL_RNG_METHOD_EXPONENTIAL_ICDF)
371  {
373  ::vdRngExponential(method, ptr_, n, r, a, beta),
374  "MKLStream::exponential", "::vdRngExponential");
375  }
376 
378  int laplace(MKL_INT n, float *r, float a, float beta,
379  MKL_INT method = VSL_RNG_METHOD_LAPLACE_ICDF)
380  {
382  ::vsRngLaplace(method, ptr_, n, r, a, beta), "MKLStream::laplace",
383  "::vsRngLaplace");
384  }
385 
387  int laplace(MKL_INT n, double *r, double a, double beta,
388  MKL_INT method = VSL_RNG_METHOD_LAPLACE_ICDF)
389  {
391  ::vdRngLaplace(method, ptr_, n, r, a, beta), "MKLStream::laplace",
392  "::vdRngLaplace");
393  }
394 
396  int weibull(MKL_INT n, float *r, float alpha, float a, float beta,
397  MKL_INT method = VSL_RNG_METHOD_WEIBULL_ICDF)
398  {
400  ::vsRngWeibull(method, ptr_, n, r, alpha, a, beta),
401  "MKLStream::weibull", "::vsRngWeibull");
402  }
403 
405  int weibull(MKL_INT n, double *r, double alpha, double a, double beta,
406  MKL_INT method = VSL_RNG_METHOD_WEIBULL_ICDF)
407  {
409  ::vdRngWeibull(method, ptr_, n, r, alpha, a, beta),
410  "MKLStream::weibull", "::vdRngWeibull");
411  }
412 
414  int cauchy(MKL_INT n, float *r, float a, float beta,
415  MKL_INT method = VSL_RNG_METHOD_CAUCHY_ICDF)
416  {
418  ::vsRngCauchy(method, ptr_, n, r, a, beta), "MKLStream::cauchy",
419  "::vsRngCauchy");
420  }
421 
423  int cauchy(MKL_INT n, double *r, double a, double beta,
424  MKL_INT method = VSL_RNG_METHOD_CAUCHY_ICDF)
425  {
427  ::vdRngCauchy(method, ptr_, n, r, a, beta), "MKLStream::cauchy",
428  "::vdRngCauchy");
429  }
430 
432  int rayleigh(MKL_INT n, float *r, float a, float beta,
433  MKL_INT method = VSL_RNG_METHOD_RAYLEIGH_ICDF)
434  {
436  ::vsRngRayleigh(method, ptr_, n, r, a, beta),
437  "MKLStream::rayleigh", "::vsRngRayleigh");
438  }
439 
441  int rayleigh(MKL_INT n, double *r, double a, double beta,
442  MKL_INT method = VSL_RNG_METHOD_RAYLEIGH_ICDF)
443  {
445  ::vdRngRayleigh(method, ptr_, n, r, a, beta),
446  "MKLStream::rayleigh", "::vdRngRayleigh");
447  }
448 
450  int lognormal(MKL_INT n, float *r, float a, float sigma, float b,
451  float beta, MKL_INT method = VSL_RNG_METHOD_LOGNORMAL_BOXMULLER2)
452  {
454  ::vsRngLognormal(method, ptr_, n, r, a, sigma, b, beta),
455  "MKLStream::lognormal", "::vsRngLognormal");
456  }
457 
459  int lognormal(MKL_INT n, double *r, double a, double sigma, double b,
460  double beta, MKL_INT method = VSL_RNG_METHOD_LOGNORMAL_BOXMULLER2)
461  {
463  ::vdRngLognormal(method, ptr_, n, r, a, sigma, b, beta),
464  "MKLStream::lognormal", "::vdRngLognormal");
465  }
466 
468  int gumbel(MKL_INT n, float *r, float a, float beta,
469  MKL_INT method = VSL_RNG_METHOD_GUMBEL_ICDF)
470  {
472  ::vsRngGumbel(method, ptr_, n, r, a, beta), "MKLStream::gumbel",
473  "::vsRngGumbel");
474  }
475 
477  int gumbel(MKL_INT n, double *r, double a, double beta,
478  MKL_INT method = VSL_RNG_METHOD_GUMBEL_ICDF)
479  {
481  ::vdRngGumbel(method, ptr_, n, r, a, beta), "MKLStream::gumbel",
482  "::vdRngGumbel");
483  }
484 
486  int gamma(MKL_INT n, float *r, float alpha, float a, float beta,
487  MKL_INT method = VSL_RNG_METHOD_GAMMA_GNORM)
488  {
490  ::vsRngGamma(method, ptr_, n, r, alpha, a, beta),
491  "MKLStream::gamma", "::vsRngGamma");
492  }
493 
495  int gamma(MKL_INT n, double *r, double alpha, double a, double beta,
496  MKL_INT method = VSL_RNG_METHOD_GAMMA_GNORM)
497  {
499  ::vdRngGamma(method, ptr_, n, r, alpha, a, beta),
500  "MKLStream::gamma", "::vdRngGamma");
501  }
502 
504  int beta(MKL_INT n, float *r, float p, float q, float a, float beta,
505  MKL_INT method = VSL_RNG_METHOD_BETA_CJA)
506  {
508  ::vsRngBeta(method, ptr_, n, r, p, q, a, beta), "MKLStream::beta",
509  "::vsRngBeta");
510  }
511 
513  int beta(MKL_INT n, double *r, double p, double q, double a, double beta,
514  MKL_INT method = VSL_RNG_METHOD_BETA_CJA)
515  {
517  ::vdRngBeta(method, ptr_, n, r, p, q, a, beta), "MKLStream::beta",
518  "::vdRngBeta");
519  }
520 
522  int uniform(MKL_INT n, int *r, int a, int b,
523  MKL_INT method = VSL_RNG_METHOD_UNIFORM_STD)
524  {
526  ::viRngUniform(method, ptr_, n, r, a, b), "MKLStream::uniform",
527  "::viRngUniform");
528  }
529 
531  int uniform_bits(MKL_INT n, unsigned *r,
532  MKL_INT method = VSL_RNG_METHOD_UNIFORMBITS_STD)
533  {
535  ::viRngUniformBits(method, ptr_, n, r), "MKLStream::uniform_bits",
536  "::viRngUniformBits");
537  }
538 
540  int uniform_bits32(MKL_INT n, unsigned *r,
541  MKL_INT method = VSL_RNG_METHOD_UNIFORMBITS32_STD)
542  {
544  ::viRngUniformBits32(method, ptr_, n, r),
545  "MKLStream::uniform_bits32", "::viRngUniformBits32");
546  }
547 
549  int uniform_bits64(MKL_INT n, unsigned MKL_INT64 *r,
550  MKL_INT method = VSL_RNG_METHOD_UNIFORMBITS64_STD)
551  {
553  ::viRngUniformBits64(method, ptr_, n, r),
554  "MKLStream::uniform_bits64", "::viRngUniformBits64");
555  }
556 
558  int bernoulli(MKL_INT n, int *r, double p,
559  MKL_INT method = VSL_RNG_METHOD_BERNOULLI_ICDF)
560  {
562  ::viRngBernoulli(method, ptr_, n, r, p), "MKLStream::bernoulli",
563  "::viRngBernoulli");
564  }
565 
567  int geometric(MKL_INT n, int *r, double p,
568  MKL_INT method = VSL_RNG_METHOD_GEOMETRIC_ICDF)
569  {
571  ::viRngGeometric(method, ptr_, n, r, p), "MKLStream::geometric",
572  "::viRngGeometric");
573  }
574 
576  int binomial(MKL_INT n, int *r, int ntrial, double p,
577  MKL_INT method = VSL_RNG_METHOD_BINOMIAL_BTPE)
578  {
580  ::viRngBinomial(method, ptr_, n, r, ntrial, p),
581  "MKLStream::binomial", "::viRngBinomial");
582  }
583 
585  int hypergeometric(MKL_INT n, int *r, int l, int s, int m,
586  MKL_INT method = VSL_RNG_METHOD_HYPERGEOMETRIC_H2PE)
587  {
589  ::viRngHypergeometric(method, ptr_, n, r, l, s, m),
590  "MKLStream::hypergeometric", "::viRngHypergeometric");
591  }
592 
594  int poisson(MKL_INT n, int *r, double lambda,
595  MKL_INT method = VSL_RNG_METHOD_POISSON_POISNORM)
596  {
598  ::viRngPoisson(method, ptr_, n, r, lambda), "MKLStream::poisson",
599  "::viRngPoisson");
600  }
601 
603  int poisson_v(MKL_INT n, int *r, const double *lambda,
604  MKL_INT method = VSL_RNG_METHOD_POISSONV_POISNORM)
605  {
607  ::viRngPoissonV(method, ptr_, n, r, lambda),
608  "MKLStream::poisson_v", "::viRngPoissonV");
609  }
610 
612  int neg_binomial(MKL_INT n, int *r, double a, double p,
613  MKL_INT method = VSL_RNG_METHOD_NEGBINOMIAL_NBAR)
614  {
616  ::viRngNegbinomial(method, ptr_, n, r, a, p),
617  "MKLStream::neg_binomial", "::viRngNegbinomial");
618  }
619 
620  private:
621  ::VSLStreamStatePtr ptr_;
622 }; // class MKLStream
623 
626 inline bool operator==(const MKLStream &stream1, const MKLStream &stream2)
627 {
628  int brng1 = stream1.get_brng();
629  int brng2 = stream2.get_brng();
630  if (brng1 != brng2) {
631  return false;
632  }
633  if (brng1 == VSL_BRNG_NONDETERM) {
634  return false;
635  }
636 
637  std::size_t n = static_cast<std::size_t>(stream1.get_size());
638  Vector<char> s1(n);
639  Vector<char> s2(n);
640  stream1.save_m(s1.data());
641  stream2.save_m(s2.data());
642  if (s1 != s2) {
643  return false;
644  }
645 
646  return true;
647 }
648 
651 inline bool operator!=(const MKLStream &stream1, const MKLStream &stream2)
652 {
653  return !(stream1 == stream2);
654 }
655 
658 template <typename CharT, typename Traits>
659 inline std::basic_ostream<CharT, Traits> &operator<<(
660  std::basic_ostream<CharT, Traits> &os, const MKLStream &stream)
661 {
662  if (!os) {
663  return os;
664  }
665 
666  std::size_t n = static_cast<std::size_t>(stream.get_size());
667  std::size_t m = sizeof(std::uintmax_t);
668  if (n % m != 0) {
669  n += m - n % m;
670  }
671  n /= m;
673  stream.save_m(reinterpret_cast<char *>(s.data()));
674 
675  os << stream.get_brng() << ' ';
676  os << s;
677 
678  return os;
679 }
680 
683 template <typename CharT, typename Traits>
684 inline std::basic_istream<CharT, Traits> &operator>>(
685  std::basic_istream<CharT, Traits> &is, MKLStream &stream)
686 {
687  if (!is) {
688  return is;
689  }
690 
691  MKL_INT brng;
693  is >> std::ws >> brng;
694  is >> std::ws >> s;
695 
696  if (is) {
697  MKLStream tmp;
698  tmp.load_m(reinterpret_cast<const char *>(s.data()));
699  stream = std::move(tmp);
700  }
701 
702  return is;
703 }
704 
705 namespace internal {
706 
707 template <MKL_INT BRNG>
708 class MKLMaxOffset : public std::integral_constant<MKL_INT, 0>
709 {
710 }; // class MKLMaxOffset;
711 
712 template <>
713 class MKLMaxOffset<VSL_BRNG_MT2203>
714  : public std::integral_constant<MKL_INT, 6024>
715 {
716 }; // class MKLMaxOffset
717 
718 template <>
719 class MKLMaxOffset<VSL_BRNG_WH> : public std::integral_constant<MKL_INT, 273>
720 {
721 }; // class MKLMaxOffset
722 
723 template <MKL_INT BRNG, MKL_INT MaxOffset = MKLMaxOffset<BRNG>::value>
725 {
726  public:
727  static MKL_INT eval(MKL_INT offset) { return BRNG + offset % MaxOffset; }
728 }; // class MKLOffset
729 
730 template <MKL_INT BRNG>
731 class MKLOffset<BRNG, 0>
732 {
733  public:
734  static MKL_INT eval(MKL_INT) { return BRNG; }
735 }; // class MKLOffset
736 
737 template <MKL_INT, int>
739 
740 template <MKL_INT BRNG>
741 class MKLUniformBits<BRNG, 32>
742 {
743  public:
744  using result_type = unsigned;
745 
746  static constexpr result_type min()
747  {
748  return std::numeric_limits<result_type>::min();
749  }
750 
751  static constexpr result_type max()
752  {
753  return std::numeric_limits<result_type>::max();
754  }
755 
756  static void eval(MKLStream &stream, MKL_INT n, result_type *r)
757  {
758  stream.uniform_bits32(n, r);
759  }
760 }; // class MKLUniformBits
761 
762 template <MKL_INT BRNG>
763 class MKLUniformBits<BRNG, 64>
764 {
765  public:
766  using result_type = unsigned MKL_INT64;
767 
768  static constexpr result_type min()
769  {
770  return std::numeric_limits<result_type>::min();
771  }
772 
773  static constexpr result_type max()
774  {
775  return std::numeric_limits<result_type>::max();
776  }
777 
778  static void eval(MKLStream &stream, MKL_INT n, result_type *r)
779  {
780  stream.uniform_bits64(n, r);
781  }
782 }; // class MKLUniformBits
783 
784 } // namespace internal
785 
794 template <MKL_INT BRNG, int Bits>
796 {
797  static_assert(Bits == 32 || Bits == 64,
798  "**MKLEngine** used with bits other than 32, or 64");
799 
800  public:
801  using result_type =
803 
804  private:
805  template <typename T>
807 
808  public:
809  explicit MKLEngine(result_type s = 1) : index_(M_) { seed(s); }
810 
811  template <typename SeedSeq>
812  explicit MKLEngine(SeedSeq &seq,
813  std::enable_if_t<is_seed_seq<SeedSeq>::value> * = nullptr)
814  : index_(M_)
815  {
816  seed(seq);
817  }
818 
819  MKLEngine(MKL_INT offset, result_type s) : index_(M_)
820  {
821  static_assert(internal::MKLMaxOffset<BRNG>::value > 0,
822  "**MKLEngine** does not support offseting");
823 
824  seed(offset, s);
825  }
826 
827  template <typename SeedSeq>
828  explicit MKLEngine(MKL_INT offset, SeedSeq &seq,
829  std::enable_if_t<is_seed_seq<SeedSeq>::value> * = nullptr)
830  : index_(M_)
831  {
832  static_assert(internal::MKLMaxOffset<BRNG>::value > 0,
833  "**MKLEngine** does not support offseting");
834 
835  seed(offset, seq);
836  }
837 
839  {
840  s %= static_cast<result_type>(std::numeric_limits<MKL_UINT>::max());
841  MKL_INT brng = stream_.empty() ? BRNG : stream_.get_brng();
842  stream_.reset(brng, static_cast<MKL_UINT>(s));
843  index_ = M_;
844  }
845 
846  template <typename SeedSeq>
847  void seed(SeedSeq &seq,
848  std::enable_if_t<is_seed_seq<SeedSeq>::value> * = nullptr)
849  {
850  MKL_INT brng = stream_.empty() ? BRNG : stream_.get_brng();
851  Vector<MKL_UINT> params;
852  MKL_INT n = seed_params(brng, seq, params);
853  stream_.reset(brng, n, params.data());
854  index_ = M_;
855  }
856 
857  void seed(MKL_INT offset, result_type s)
858  {
859  static_assert(internal::MKLMaxOffset<BRNG>::value > 0,
860  "**MKLEngine** does not support offseting");
861 
862  s %= static_cast<result_type>(std::numeric_limits<MKL_UINT>::max());
863  MKL_INT brng = internal::MKLOffset<BRNG>::eval(offset);
864  stream_.reset(brng, static_cast<MKL_UINT>(s));
865  index_ = M_;
866  }
867 
868  template <typename SeedSeq>
869  void seed(MKL_INT offset, SeedSeq &seq,
870  std::enable_if_t<is_seed_seq<SeedSeq>::value> * = nullptr)
871  {
872  static_assert(internal::MKLMaxOffset<BRNG>::value > 0,
873  "**MKLEngine** does not support offseting");
874 
875  MKL_INT brng = internal::MKLOffset<BRNG>::eval(offset);
876  Vector<unsigned> params;
877  MKL_INT n = seed_params(brng, seq, params);
878  stream_.reset(brng, n, params.data());
879  index_ = M_;
880  }
881 
883  {
884  if (index_ == M_) {
885  generate();
886  index_ = 0;
887  }
888 
889  return result_[index_++];
890  }
891 
892  void operator()(std::size_t n, result_type *r)
893  {
894  internal::size_check<MKL_INT>(n, "MKLEngine::operator()");
895 
896  const std::size_t remain = M_ - index_;
897 
898  if (n <= remain) {
899  std::memcpy(r, result_.data() + index_, sizeof(result_type) * n);
900  index_ += n;
901  return;
902  }
903 
904  std::memcpy(r, result_.data() + index_, sizeof(result_type) * remain);
905  r += remain;
906  n -= remain;
907  index_ = M_;
908 
909  generate(n, r);
910  }
911 
915  std::size_t discard()
916  {
917  const std::size_t remain = M_ - index_;
918  index_ = M_;
919 
920  return remain;
921  }
922 
923  void discard(long long nskip)
924  {
925 
926  if (nskip <= 0) {
927  return;
928  }
929 
930  const long long remain = static_cast<long long>(M_ - index_);
931  if (nskip <= remain) {
932  index_ += static_cast<std::size_t>(nskip);
933  return;
934  }
935  nskip -= remain;
936  index_ = M_;
937 
938  ::VSLBRngProperties properties;
939  MKLStream::get_brng_properties(stream_.get_brng(), &properties);
940  const int bits = properties.NBits;
941  const long long M = static_cast<long long>(M_);
942  long long m = nskip / M * M;
943  if (Bits >= bits) {
944  m *= Bits / bits + (Bits % bits == 0 ? 0 : 1);
945  }
946  switch (stream_.get_brng()) {
947  case VSL_BRNG_ARS5:
948  stream_.skip_ahead(m);
949  break;
950  case VSL_BRNG_PHILOX4X32X10:
951  stream_.skip_ahead(m);
952  break;
953  case VSL_BRNG_MCG31:
954  stream_.skip_ahead(m);
955  break;
956  case VSL_BRNG_MRG32K3A:
957  stream_.skip_ahead(m);
958  break;
959  case VSL_BRNG_MCG59:
960  stream_.skip_ahead(m);
961  break;
962  case VSL_BRNG_WH:
963  stream_.skip_ahead(m);
964  break;
965  case VSL_BRNG_MT19937:
966  stream_.skip_ahead(m);
967  break;
968  case VSL_BRNG_SFMT19937:
969  stream_.skip_ahead(m);
970  break;
971  case VSL_BRNG_SOBOL:
972  stream_.skip_ahead(m);
973  break;
974  case VSL_BRNG_NIEDERR:
975  stream_.skip_ahead(m);
976  break;
977  default:
978  while (nskip >= M) {
979  generate();
980  nskip -= M;
981  }
982  };
983  generate();
984  index_ = static_cast<std::size_t>(nskip % M);
985  }
986 
987  static constexpr result_type min()
988  {
990  }
991 
992  static constexpr result_type max()
993  {
995  }
996 
997  MKLStream &stream() { return stream_; }
998  const MKLStream &stream() const { return stream_; }
999 
1003  friend bool operator==(
1004  const MKLEngine<BRNG, Bits> &eng1, const MKLEngine<BRNG, Bits> &eng2)
1005  {
1006  if (eng1.stream_ != eng2.stream_) {
1007  return false;
1008  }
1009  if (eng1.result_ != eng2.result_) {
1010  return false;
1011  }
1012  if (eng1.index_ != eng2.index_) {
1013  return false;
1014  }
1015  return true;
1016  }
1017 
1021  friend bool operator!=(
1022  const MKLEngine<BRNG, Bits> &eng1, const MKLEngine<BRNG, Bits> &eng2)
1023  {
1024  return !(eng1 == eng2);
1025  }
1026 
1027  template <typename CharT, typename Traits>
1028  friend std::basic_ostream<CharT, Traits> &operator<<(
1029  std::basic_ostream<CharT, Traits> &os,
1030  const MKLEngine<BRNG, Bits> &eng)
1031  {
1032  if (!os) {
1033  return os;
1034  }
1035 
1036  os << eng.stream_ << ' ';
1037  os << eng.result_ << ' ';
1038  os << eng.index_;
1039 
1040  return os;
1041  }
1042 
1043  template <typename CharT, typename Traits>
1044  friend std::basic_istream<CharT, Traits> &operator>>(
1045  std::basic_istream<CharT, Traits> &is, MKLEngine<BRNG, Bits> &eng)
1046  {
1047  if (!is) {
1048  return is;
1049  }
1050 
1051  MKLStream stream;
1052  std::array<result_type, M_> result;
1053  unsigned index;
1054  is >> std::ws >> stream;
1055  is >> std::ws >> result;
1056  is >> std::ws >> index;
1057 
1058  if (is) {
1059  eng.stream_ = std::move(stream);
1060  eng.result_ = result;
1061  eng.index_ = index;
1062  }
1063 
1064  return is;
1065  }
1066 
1067  private:
1068  static constexpr std::size_t M_ = 256;
1069 
1070  std::array<result_type, M_> result_;
1071  MKLStream stream_;
1072  std::size_t index_;
1073 
1074  void generate()
1075  {
1077  stream_, static_cast<MKL_INT>(M_), result_.data());
1078  }
1079 
1080  void generate(std::size_t n, result_type *r)
1081  {
1083  stream_, static_cast<MKL_INT>(n), r);
1084  }
1085 
1086  template <typename SeedSeq>
1087  MKL_INT seed_params(MKL_INT brng, SeedSeq &seq, Vector<unsigned> &params)
1088  {
1089  ::VSLBRngProperties properties;
1090  MKLStream::get_brng_properties(brng, &properties);
1091  MKL_INT n = properties.NSeeds;
1092  params.resize(static_cast<std::size_t>(n));
1093  seq.generate(params.begin(), params.end());
1094 
1095  return n;
1096  }
1097 }; // class MKLEngine
1098 
1099 template <MKL_INT BRNG, int Bits>
1100 inline void rand(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1102 {
1103  rng(n, r);
1104 }
1105 
1109 
1113 
1117 
1121 
1125 
1129 
1133 
1137 
1141 
1145 
1150 
1155 
1159 
1163 
1164 namespace internal {
1165 
1166 template <typename RNGType>
1168 {
1169  public:
1170  unsigned reserved1[2];
1171  unsigned reserved2[2];
1172  RNGType rng;
1173 }; // class MKLStreamState
1174 
1175 template <typename RNGType>
1176 inline constexpr int mkl_nseeds()
1177 {
1178  return sizeof(SeedType<RNGType>) < sizeof(unsigned) ?
1179  1 :
1180  sizeof(SeedType<RNGType>) / sizeof(unsigned);
1181 }
1182 
1183 template <typename RNGType>
1184 inline int mkl_init(RNGType &rng, int n, const unsigned *param, std::true_type)
1185 {
1186  if (n == 0) {
1187  new (static_cast<void *>(&rng)) RNGType();
1188  } else {
1189  new (static_cast<void *>(&rng))
1190  RNGType(static_cast<typename RNGType::result_type>(param[0]));
1191  }
1192 
1193  return 0;
1194 }
1195 
1196 template <typename RNGType>
1197 inline int mkl_init(
1198  int method, ::VSLStreamStatePtr stream, int n, const unsigned *param)
1199 {
1200  RNGType &rng = (*static_cast<MKLStreamState<RNGType> *>(stream)).rng;
1201 
1202  if (method == VSL_INIT_METHOD_STANDARD) {
1203  if (n == 0) {
1204  new (static_cast<void *>(&rng)) RNGType();
1205  } else {
1206  constexpr std::size_t ns = mkl_nseeds<RNGType>();
1207  union {
1208  SeedType<RNGType> seed;
1209  std::array<unsigned, ns> useed;
1210  } buf;
1211  std::copy_n(param, std::min(static_cast<std::size_t>(n), ns),
1212  buf.useed.data());
1213  new (static_cast<void *>(&rng)) RNGType(buf.seed);
1214  }
1215  }
1216 
1217  if (method == VSL_INIT_METHOD_LEAPFROG) {
1218  return VSL_RNG_ERROR_LEAPFROG_UNSUPPORTED;
1219  }
1220 
1221  if (method == VSL_INIT_METHOD_SKIPAHEAD) {
1222  rng.discard(static_cast<unsigned>(n));
1223  }
1224 
1225  return 0;
1226 }
1227 
1228 template <typename RNGType, typename RealType>
1229 inline int mkl_uniform_real(
1230  ::VSLStreamStatePtr stream, int n, RealType *r, RealType a, RealType b)
1231 {
1232  RNGType &rng = (*static_cast<MKLStreamState<RNGType> *>(stream)).rng;
1233  uniform_real_distribution(rng, static_cast<std::size_t>(n), r, a, b);
1234 
1235  return 0;
1236 }
1237 
1238 template <typename RNGType>
1239 inline int mkl_uniform_int(::VSLStreamStatePtr stream, int n, unsigned *r)
1240 {
1241  RNGType &rng = (*static_cast<MKLStreamState<RNGType> *>(stream)).rng;
1242  uniform_bits_distribution(rng, static_cast<std::size_t>(n), r);
1243 
1244  return 0;
1245 }
1246 
1247 } // namespace internal
1248 
1255 template <typename RNGType>
1256 inline int mkl_brng()
1257 {
1258  static ::VSLBRngProperties properties = {
1260  internal::mkl_nseeds<RNGType>(), 1, 4, 32, internal::mkl_init<RNGType>,
1261  internal::mkl_uniform_real<RNGType, float>,
1262  internal::mkl_uniform_real<RNGType, double>,
1263  internal::mkl_uniform_int<RNGType>};
1264  static int brng = ::vslRegisterBrng(&properties);
1265 
1266  return brng;
1267 }
1268 
1269 #if MCKL_USE_MKL_VSL
1270 
1271 template <MKL_INT BRNG, int Bits>
1272 inline void beta_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1273  float *r, float alpha, float beta)
1274 {
1275  internal::size_check<MKL_INT>(n, "beta_distribution");
1276  rng.stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
1277 }
1278 
1279 template <MKL_INT BRNG, int Bits>
1280 inline void beta_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1281  double *r, double alpha, double beta)
1282 {
1283  internal::size_check<MKL_INT>(n, "beta_distribution");
1284  rng.stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
1285 }
1286 
1287 template <MKL_INT BRNG, int Bits>
1289  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
1290 {
1291  internal::size_check<MKL_INT>(n, "cauchy_distribution");
1292  rng.stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
1293 }
1294 
1295 template <MKL_INT BRNG, int Bits>
1297  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
1298 {
1299  internal::size_check<MKL_INT>(n, "cauchy_distribution");
1300  rng.stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
1301 }
1302 
1303 template <MKL_INT BRNG, int Bits>
1305  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float lambda)
1306 {
1307  internal::size_check<MKL_INT>(n, "exponential_distribution");
1308  rng.stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
1309 }
1310 
1311 template <MKL_INT BRNG, int Bits>
1313  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double lambda)
1314 {
1315  internal::size_check<MKL_INT>(n, "exponential_distribution");
1316  rng.stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
1317 }
1318 
1319 template <MKL_INT BRNG, int Bits>
1321  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
1322 {
1323  internal::size_check<MKL_INT>(n, "extreme_value_distribution");
1324  rng.stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
1325  sub(n, 2 * a, r, r);
1326 }
1327 
1328 template <MKL_INT BRNG, int Bits>
1330  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
1331 {
1332  internal::size_check<MKL_INT>(n, "extreme_value_distribution");
1333  rng.stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
1334  sub(n, 2 * a, r, r);
1335 }
1336 
1337 template <MKL_INT BRNG, int Bits>
1338 inline void gamma_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1339  float *r, float alpha, float beta)
1340 {
1341  internal::size_check<MKL_INT>(n, "gamma_distribution");
1342  rng.stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
1343 }
1344 
1345 template <MKL_INT BRNG, int Bits>
1346 inline void gamma_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1347  double *r, double alpha, double beta)
1348 {
1349  internal::size_check<MKL_INT>(n, "gamma_distribution");
1350  rng.stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
1351 }
1352 
1353 template <MKL_INT BRNG, int Bits>
1354 inline void laplace_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1355  float *r, float location, float scale)
1356 {
1357  internal::size_check<MKL_INT>(n, "lapace_distribution");
1358  rng.stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
1359 }
1360 
1361 template <MKL_INT BRNG, int Bits>
1362 inline void laplace_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1363  double *r, double location, double scale)
1364 {
1365  internal::size_check<MKL_INT>(n, "lapace_distribution");
1366  rng.stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
1367 }
1368 
1369 template <MKL_INT BRNG, int Bits>
1371  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float m, float s)
1372 {
1373  internal::size_check<MKL_INT>(n, "lognormal_distribution");
1374  rng.stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
1375 }
1376 
1377 template <MKL_INT BRNG, int Bits>
1379  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double m, double s)
1380 {
1381  internal::size_check<MKL_INT>(n, "lognormal_distribution");
1382  rng.stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
1383 }
1384 
1385 template <MKL_INT BRNG, int Bits>
1386 inline void normal_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1387  float *r, float mean, float stddev)
1388 {
1389  internal::size_check<MKL_INT>(n, "normal_distribution");
1390  rng.stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
1391 }
1392 
1393 template <MKL_INT BRNG, int Bits>
1394 inline void normal_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1395  double *r, double mean, double stddev)
1396 {
1397  internal::size_check<MKL_INT>(n, "normal_distribution");
1398  rng.stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
1399 }
1400 
1401 template <MKL_INT BRNG, int Bits>
1402 inline void normal_mv_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1403  float *r, std::size_t m, const float *mean, const float *chol)
1404 {
1405  internal::size_check<MKL_INT>(n, "normal_mv_distribution");
1406  internal::size_check<MKL_INT>(m, "normal_mv_distribution");
1407  rng.stream().gaussian_mv(static_cast<MKL_INT>(n), r,
1408  static_cast<MKL_INT>(m), VSL_MATRIX_STORAGE_PACKED, mean, chol);
1409 }
1410 
1411 template <MKL_INT BRNG, int Bits>
1412 inline void normal_mv_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
1413  double *r, std::size_t m, const double *mean, const double *chol)
1414 {
1415  internal::size_check<MKL_INT>(n, "normal_mv_distribution");
1416  internal::size_check<MKL_INT>(m, "normal_mv_distribution");
1417  rng.stream().gaussian_mv(static_cast<MKL_INT>(n), r,
1418  static_cast<MKL_INT>(m), VSL_MATRIX_STORAGE_PACKED, mean, chol);
1419 }
1420 
1421 template <MKL_INT BRNG, int Bits>
1423  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float sigma)
1424 {
1425  internal::size_check<MKL_INT>(n, "rayleigh_distribution");
1426  rng.stream().rayleigh(
1427  static_cast<MKL_INT>(n), r, 0, const_sqrt_2<float>() * sigma);
1428 }
1429 
1430 template <MKL_INT BRNG, int Bits>
1432  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double sigma)
1433 {
1434  internal::size_check<MKL_INT>(n, "rayleigh_distribution");
1435  rng.stream().rayleigh(
1436  static_cast<MKL_INT>(n), r, 0, const_sqrt_2<double>() * sigma);
1437 }
1438 
1439 template <MKL_INT BRNG, int Bits>
1441  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
1442 {
1443  internal::size_check<MKL_INT>(n, "uniform_real_distribution");
1444  rng.stream().uniform(static_cast<MKL_INT>(n), r, a, b);
1445 }
1446 
1447 template <MKL_INT BRNG, int Bits>
1449  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
1450 {
1451  internal::size_check<MKL_INT>(n, "uniform_real_distribution");
1452  rng.stream().uniform(static_cast<MKL_INT>(n), r, a, b);
1453 }
1454 
1455 template <MKL_INT BRNG, int Bits>
1457  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
1458 {
1459  internal::size_check<MKL_INT>(n, "weibull_distribution");
1460  rng.stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
1461 }
1462 
1463 template <MKL_INT BRNG, int Bits>
1465  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
1466 {
1467  internal::size_check<MKL_INT>(n, "weibull_distribution");
1468  rng.stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
1469 }
1470 
1471 template <MKL_INT BRNG, int Bits>
1473  MKLEngine<BRNG, Bits> &rng, std::size_t n, int *r, double p)
1474 {
1475  internal::size_check<MKL_INT>(n, "bernoulli_distribution");
1476  rng.stream().bernoulli(static_cast<MKL_INT>(n), r, p);
1477 }
1478 
1479 template <MKL_INT BRNG, int Bits>
1481  MKLEngine<BRNG, Bits> &rng, std::size_t n, int *r, double p)
1482 {
1483  internal::size_check<MKL_INT>(n, "geometric_distribution");
1484  rng.stream().geometric(static_cast<MKL_INT>(n), r, p);
1485 }
1486 
1487 template <MKL_INT BRNG, int Bits>
1489  MKLEngine<BRNG, Bits> &rng, std::size_t n, int *r, int a, int b)
1490 {
1491  internal::size_check<MKL_INT>(n, "uniform_int_distribution");
1492  if (b < std::numeric_limits<int>::max()) {
1493  rng.stream().uniform(static_cast<MKL_INT>(n), r, a, b + 1);
1494  } else if (a > 0) {
1495  rng.stream().uniform(static_cast<MKL_INT>(n), r, a - 1, b);
1496  add(n, 1, r, r);
1497  } else {
1498  rng.stream().uniform_bits32(
1499  static_cast<MKL_INT>(n), reinterpret_cast<unsigned *>(r));
1500  }
1501 }
1502 
1503 #endif // MCKL_USE_MKL_VSL
1504 
1505 } // namespace mckl
1506 
1507 #endif // MCKL_RANDOM_MKL_HPP
int mkl_error_check(int status, const char *cpp, const char *c)
Definition: mkl.hpp:52
void seed(result_type s)
Definition: mkl.hpp:838
int binomial(MKL_INT n, int *r, int ntrial, double p, MKL_INT method=VSL_RNG_METHOD_BINOMIAL_BTPE)
viRngBinomial
Definition: mkl.hpp:576
MKLStream(::VSLStreamStatePtr ptr=nullptr)
Definition: mkl.hpp:81
void cauchy_distribution(RNGType &rng, std::size_t N, RealType *r, RealType a, RealType b)
int skip_ahead(long long nskip)
vslSkipAheadStream
Definition: mkl.hpp:244
void normal_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, float mean, float stddev)
Definition: mkl.hpp:1386
int lognormal(MKL_INT n, double *r, double a, double sigma, double b, double beta, MKL_INT method=VSL_RNG_METHOD_LOGNORMAL_BOXMULLER2)
vdRngLognormal
Definition: mkl.hpp:459
int gumbel(MKL_INT n, double *r, double a, double beta, MKL_INT method=VSL_RNG_METHOD_GUMBEL_ICDF)
vdRngGumbel
Definition: mkl.hpp:477
MKLStream(MKLStream &&other)
Definition: mkl.hpp:123
static constexpr result_type min()
Definition: mkl.hpp:768
friend bool operator!=(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
eng1 != eng2 is a necessary condition for subsequent call of operator() output different results...
Definition: mkl.hpp:1021
static MKL_INT eval(MKL_INT)
Definition: mkl.hpp:734
void normal_mv_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, std::size_t m, const float *mean, const float *chol)
Definition: mkl.hpp:1402
void uniform_int_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, int *r, int a, int b)
Definition: mkl.hpp:1488
void laplace_distribution(RNGType &rng, std::size_t N, RealType *r, RealType a, RealType b)
static constexpr result_type min()
Definition: mkl.hpp:987
constexpr double const_sqrt_2< double >() noexcept
Definition: constants.hpp:260
friend bool operator==(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
eng1 == eng2 is a sufficent condition for subsequent call of operator() output the same results...
Definition: mkl.hpp:1003
int laplace(MKL_INT n, float *r, float a, float beta, MKL_INT method=VSL_RNG_METHOD_LAPLACE_ICDF)
vsRngLaplace
Definition: mkl.hpp:378
int poisson_v(MKL_INT n, int *r, const double *lambda, MKL_INT method=VSL_RNG_METHOD_POISSONV_POISNORM)
viRngPoissonV
Definition: mkl.hpp:603
static bool has_skip_ahead(MKL_INT brng)
Test if vslSkipAheadStream is supported.
Definition: mkl.hpp:274
int beta(MKL_INT n, float *r, float p, float q, float a, float beta, MKL_INT method=VSL_RNG_METHOD_BETA_CJA)
vsRngBeta
Definition: mkl.hpp:504
MKLStream & stream()
Definition: mkl.hpp:997
void uniform_bits_distribution(RNGType &rng, std::size_t n, UIntType *r)
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
int gumbel(MKL_INT n, float *r, float a, float beta, MKL_INT method=VSL_RNG_METHOD_GUMBEL_ICDF)
vsRngGumbel
Definition: mkl.hpp:468
int reset(MKL_INT brng, MKL_INT n, unsigned *params)
vslNewStreamEx
Definition: mkl.hpp:162
constexpr float const_sqrt_2< float >() noexcept
Definition: constants.hpp:260
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, MKLEngine< BRNG, Bits > &eng)
Definition: mkl.hpp:1044
void exponential_distribution(RNGType &rng, std::size_t N, RealType *r, RealType lambda)
~MKLStream()
vslDeleteStream
Definition: mkl.hpp:137
int load_m(const char *memptr)
vslLoadStreamM
Definition: mkl.hpp:220
void gamma_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
int uniform_bits32(MKL_INT n, unsigned *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS32_STD)
viRngUniform32
Definition: mkl.hpp:540
int gamma(MKL_INT n, float *r, float alpha, float a, float beta, MKL_INT method=VSL_RNG_METHOD_GAMMA_GNORM)
vsRngGamma
Definition: mkl.hpp:486
int weibull(MKL_INT n, double *r, double alpha, double a, double beta, MKL_INT method=VSL_RNG_METHOD_WEIBULL_ICDF)
vdRngWeibull
Definition: mkl.hpp:405
void discard(long long nskip)
Definition: mkl.hpp:923
static int get_brng_properties(MKL_INT brng, ::VSLBRngProperties *properties)
vslGetBrngProperties
Definition: mkl.hpp:257
MKLEngine(result_type s=1)
Definition: mkl.hpp:809
MKLEngine(MKL_INT offset, result_type s)
Definition: mkl.hpp:819
int get_brng() const
vslGetStreamStateBrng
Definition: mkl.hpp:251
MKLStream(MKL_INT brng, MKL_INT n, unsigned *params)
vslNewStreamEx
Definition: mkl.hpp:93
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MKLEngine< BRNG, Bits > &eng)
Definition: mkl.hpp:1028
void seed(MKL_INT offset, SeedSeq &seq, std::enable_if_t< is_seed_seq< SeedSeq >::value > *=nullptr)
Definition: mkl.hpp:869
int reset(MKL_INT brng, MKL_UINT seed)
vslNewStream
Definition: mkl.hpp:148
void beta_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
int neg_binomial(MKL_INT n, int *r, double a, double p, MKL_INT method=VSL_RNG_METHOD_NEGBINOMIAL_NBAR)
viRngNegbinomial
Definition: mkl.hpp:612
void rayleigh_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, float sigma)
Definition: mkl.hpp:1422
int load_f(const std::string &fname)
vslSaveStreamF
Definition: mkl.hpp:199
int uniform(MKL_INT n, float *r, float a, float b, MKL_INT method=VSL_RNG_METHOD_UNIFORM_STD)
vsRngUniform
Definition: mkl.hpp:304
result_type operator()()
Definition: mkl.hpp:882
Use MKL BRNG as RNG engine.
Definition: mkl.hpp:795
const MKLStream & stream() const
Definition: mkl.hpp:998
int exponential(MKL_INT n, float *r, float a, float beta, MKL_INT method=VSL_RNG_METHOD_EXPONENTIAL_ICDF)
vsRngExponential
Definition: mkl.hpp:360
MKLStream(const MKLStream &other)
vslCopyStream
Definition: mkl.hpp:99
int weibull(MKL_INT n, float *r, float alpha, float a, float beta, MKL_INT method=VSL_RNG_METHOD_WEIBULL_ICDF)
vsRngWeibull
Definition: mkl.hpp:396
int laplace(MKL_INT n, double *r, double a, double beta, MKL_INT method=VSL_RNG_METHOD_LAPLACE_ICDF)
vdRngLaplace
Definition: mkl.hpp:387
MKLEngine(MKL_INT offset, SeedSeq &seq, std::enable_if_t< is_seed_seq< SeedSeq >::value > *=nullptr)
Definition: mkl.hpp:828
void sub(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:121
void bernoulli_distribution(RNGType &rng, std::size_t N, InType *r, double p)
static void eval(MKLStream &stream, MKL_INT n, result_type *r)
Definition: mkl.hpp:778
constexpr int mkl_nseeds()
Definition: mkl.hpp:1176
int save_f(const std::string &fname) const
vslSaveStreamF
Definition: mkl.hpp:192
std::size_t discard()
Discard the result.
Definition: mkl.hpp:915
void lognormal_distribution(RNGType &rng, std::size_t N, RealType *r, RealType m, RealType s)
int release()
vslDeleteStream
Definition: mkl.hpp:176
static bool has_uniform_bits32(MKL_INT brng, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS32_STD)
Test if viRngUniformBits32 is supported.
Definition: mkl.hpp:282
static bool has_leap_frog(MKL_INT brng)
Test if vslLeapfrogStream is supported.
Definition: mkl.hpp:266
static constexpr result_type min()
Definition: mkl.hpp:746
int save_m(char *memptr) const
vslSaveStreamM
Definition: mkl.hpp:213
static int get_num_reg_brngs()
vslGetNumRegBrngs
Definition: mkl.hpp:254
static constexpr result_type max()
Definition: mkl.hpp:773
int reset(::VSLStreamStatePtr ptr)
Definition: mkl.hpp:139
int bernoulli(MKL_INT n, int *r, double p, MKL_INT method=VSL_RNG_METHOD_BERNOULLI_ICDF)
viRngBernoulli
Definition: mkl.hpp:558
static constexpr result_type max()
Definition: mkl.hpp:992
int gaussian_mv(MKL_INT n, float *r, MKL_INT dimen, MKL_INT mstorage, const float *a, const float *t, MKL_INT method=VSL_RNG_METHOD_GAUSSIANMV_BOXMULLER2)
vsRngGaussianMV
Definition: mkl.hpp:340
int cauchy(MKL_INT n, float *r, float a, float beta, MKL_INT method=VSL_RNG_METHOD_CAUCHY_ICDF)
vsRngCauchy
Definition: mkl.hpp:414
int exponential(MKL_INT n, double *r, double a, double beta, MKL_INT method=VSL_RNG_METHOD_EXPONENTIAL_ICDF)
vdRngExponential
Definition: mkl.hpp:369
void weibull_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, float a, float b)
Definition: mkl.hpp:1456
void extreme_value_distribution(RNGType &rng, std::size_t N, RealType *r, RealType a, RealType b)
void seed(MKL_INT offset, result_type s)
Definition: mkl.hpp:857
int uniform(MKL_INT n, double *r, double a, double b, MKL_INT method=VSL_RNG_METHOD_UNIFORM_STD)
vdRngUniform
Definition: mkl.hpp:313
int beta(MKL_INT n, double *r, double p, double q, double a, double beta, MKL_INT method=VSL_RNG_METHOD_BETA_CJA)
vdRngBeta
Definition: mkl.hpp:513
MKLStream & operator=(MKLStream &&other)
Definition: mkl.hpp:125
int gamma(MKL_INT n, double *r, double alpha, double a, double beta, MKL_INT method=VSL_RNG_METHOD_GAMMA_GNORM)
vdRngGamma
Definition: mkl.hpp:495
std::integral_constant< bool, std::is_class< T >::value &&!std::is_convertible< T, RNGType >::value &&!std::is_convertible< T, typename RNGType::result_type >::value &&!std::is_convertible< T, KeyType >::value > is_seed_seq
Definition: traits.hpp:187
int mkl_init(RNGType &rng, int n, const unsigned *param, std::true_type)
Definition: mkl.hpp:1184
int uniform_bits(MKL_INT n, unsigned *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS_STD)
viRngUniform
Definition: mkl.hpp:531
int mkl_uniform_real(::VSLStreamStatePtr stream, int n, RealType *r, RealType a, RealType b)
Definition: mkl.hpp:1229
static bool has_uniform_bits64(MKL_INT brng, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS64_STD)
Test if viRngUniformBits64 is supported.
Definition: mkl.hpp:293
int mkl_brng()
Register an RNG as MKL BRNG.
Definition: mkl.hpp:1256
int geometric(MKL_INT n, int *r, double p, MKL_INT method=VSL_RNG_METHOD_GEOMETRIC_ICDF)
viRngGeometric
Definition: mkl.hpp:567
Definition: mcmc.hpp:40
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Matrix< T, Layout, Alloc > &mat)
Output operator.
Definition: matrix.hpp:745
void rand(RNGType &rng, ArcsineDistribution< RealType > &distribution, std::size_t N, RealType *r)
bool operator!=(const MKLStream &stream1, const MKLStream &stream2)
Inequality comparison of MKLStream.
Definition: mkl.hpp:651
int uniform_bits64(MKL_INT n, unsigned MKL_INT64 *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS64_STD)
viRngUniform64
Definition: mkl.hpp:549
int get_size() const
vslGetStreamSize
Definition: mkl.hpp:233
int uniform(MKL_INT n, int *r, int a, int b, MKL_INT method=VSL_RNG_METHOD_UNIFORM_STD)
viRngUniform
Definition: mkl.hpp:522
void uniform_real_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, float a, float b)
Definition: mkl.hpp:1440
static MKL_INT eval(MKL_INT offset)
Definition: mkl.hpp:727
int mkl_uniform_int(::VSLStreamStatePtr stream, int n, unsigned *r)
Definition: mkl.hpp:1239
bool operator==(const MKLStream &stream1, const MKLStream &stream2)
Equality comparison of MKLStream.
Definition: mkl.hpp:626
MKLStream & operator=(const MKLStream &other)
vslCopyStream/vslCopySreamState
Definition: mkl.hpp:109
int gaussian_mv(MKL_INT n, double *r, MKL_INT dimen, MKL_INT mstorage, const double *a, const double *t, MKL_INT method=VSL_RNG_METHOD_GAUSSIANMV_BOXMULLER2)
vdRngGaussianMV
Definition: mkl.hpp:350
MKLStream(MKL_INT brng, MKL_UINT seed)
vslNewStream
Definition: mkl.hpp:87
int rayleigh(MKL_INT n, double *r, double a, double beta, MKL_INT method=VSL_RNG_METHOD_RAYLEIGH_ICDF)
vdRngRayleigh
Definition: mkl.hpp:441
void operator()(std::size_t n, result_type *r)
Definition: mkl.hpp:892
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, Matrix< T, Layout, Alloc > &mat)
Input operator.
Definition: matrix.hpp:769
int lognormal(MKL_INT n, float *r, float a, float sigma, float b, float beta, MKL_INT method=VSL_RNG_METHOD_LOGNORMAL_BOXMULLER2)
vsRngLognormal
Definition: mkl.hpp:450
typename internal::MKLUniformBits< BRNG, Bits >::result_type result_type
Definition: mkl.hpp:802
bool empty() const
Definition: mkl.hpp:189
static constexpr result_type max()
Definition: mkl.hpp:751
int cauchy(MKL_INT n, double *r, double a, double beta, MKL_INT method=VSL_RNG_METHOD_CAUCHY_ICDF)
vdRngCauchy
Definition: mkl.hpp:423
void seed(SeedSeq &seq, std::enable_if_t< is_seed_seq< SeedSeq >::value > *=nullptr)
Definition: mkl.hpp:847
int rayleigh(MKL_INT n, float *r, float a, float beta, MKL_INT method=VSL_RNG_METHOD_RAYLEIGH_ICDF)
vsRngRayleigh
Definition: mkl.hpp:432
int gaussian(MKL_INT n, float *r, float a, float sigma, MKL_INT method=VSL_RNG_METHOD_GAUSSIAN_BOXMULLER2)
vsRngGaussian
Definition: mkl.hpp:322
typename SeedTrait< RNGType >::type SeedType
int poisson(MKL_INT n, int *r, double lambda, MKL_INT method=VSL_RNG_METHOD_POISSON_POISNORM)
viRngPoisson
Definition: mkl.hpp:594
int gaussian(MKL_INT n, double *r, double a, double sigma, MKL_INT method=VSL_RNG_METHOD_GAUSSIAN_BOXMULLER2)
vdRngGaussian
Definition: mkl.hpp:331
int hypergeometric(MKL_INT n, int *r, int l, int s, int m, MKL_INT method=VSL_RNG_METHOD_HYPERGEOMETRIC_H2PE)
viRngHypergeometric
Definition: mkl.hpp:585
void geometric_distribution(RNGType &rng, std::size_t N, InType *r, double p)
void runtime_assert(bool cond, const char *msg, bool soft=false)
Definition: assert.hpp:65
int leapfrog(MKL_INT k, MKL_INT nstreams)
vslLeapfrogStream
Definition: mkl.hpp:236
MKL VSLStreamStatePtr wrapper.
Definition: mkl.hpp:78
MKLEngine(SeedSeq &seq, std::enable_if_t< is_seed_seq< SeedSeq >::value > *=nullptr)
Definition: mkl.hpp:812
static void eval(MKLStream &stream, MKL_INT n, result_type *r)
Definition: mkl.hpp:756
void add(std::size_t n, const float *a, const float *b, float *y)
Definition: vmf.hpp:119