32 #ifndef MCKL_RANDOM_NORMAL_MV_DISTRIBUTION_HPP 33 #define MCKL_RANDOM_NORMAL_MV_DISTRIBUTION_HPP 43 std::size_t n,
float *r, std::size_t dim,
const float *chol)
45 cblas_strmm(CblasRowMajor, CblasRight, CblasLower, CblasTrans,
46 CblasNonUnit, static_cast<MCKL_BLAS_INT>(n),
47 static_cast<MCKL_BLAS_INT>(dim), 1, chol,
48 static_cast<MCKL_BLAS_INT>(dim), r, static_cast<MCKL_BLAS_INT>(dim));
52 std::size_t n,
double *r, std::size_t dim,
const double *chol)
54 cblas_dtrmm(CblasRowMajor, CblasRight, CblasLower, CblasTrans,
55 CblasNonUnit, static_cast<MCKL_BLAS_INT>(n),
56 static_cast<MCKL_BLAS_INT>(dim), 1, chol,
57 static_cast<MCKL_BLAS_INT>(dim), r, static_cast<MCKL_BLAS_INT>(dim));
62 template <
typename RealType,
typename RNGType>
64 std::size_t dim, RealType mean, RealType chol)
66 internal::size_check<MCKL_BLAS_INT>(n,
"normal_mv_distribution");
67 internal::size_check<MCKL_BLAS_INT>(dim,
"normal_mv_distribution");
72 template <
typename RealType,
typename RNGType>
74 std::size_t dim, RealType mean,
const RealType *chol)
76 internal::size_check<MCKL_BLAS_INT>(n,
"normal_mv_distribution");
77 internal::size_check<MCKL_BLAS_INT>(dim,
"normal_mv_distribution");
80 rng, n * dim, r, const_zero<RealType>(), const_one<RealType>());
82 for (std::size_t i = 0; i != dim; ++i) {
83 for (std::size_t j = 0; j <= i; ++j) {
84 cholf[i * dim + j] = *chol++;
91 add(n * dim, mean, r, r);
97 template <
typename RealType,
typename RNGType>
99 std::size_t dim,
const RealType *mean, RealType chol)
101 internal::size_check<MCKL_BLAS_INT>(n,
"normal_mv_distribution");
102 internal::size_check<MCKL_BLAS_INT>(dim,
"normal_mv_distribution");
105 for (std::size_t i = 0; i != n; ++i, r += dim) {
106 add<RealType>(dim, mean, r, r);
110 template <
typename RealType,
typename RNGType>
112 std::size_t dim,
const RealType *mean,
const RealType *chol)
114 internal::size_check<MCKL_BLAS_INT>(n,
"normal_mv_distribution");
115 internal::size_check<MCKL_BLAS_INT>(dim,
"normal_mv_distribution");
118 rng, n * dim, r, const_zero<RealType>(), const_one<RealType>());
120 for (std::size_t i = 0; i != dim; ++i) {
121 for (std::size_t j = 0; j <= i; ++j) {
122 cholf[i * dim + j] = *chol++;
126 for (std::size_t i = 0; i != n; ++i, r += dim) {
127 add<RealType>(dim, mean, r, r);
138 template <
typename RealType>
156 , chol_(dim * (dim + 1) / 2, 0)
157 , is_scalar_mean_(true)
158 , is_scalar_chol_(true)
165 , chol_(dim * (dim + 1) / 2, 0)
166 , is_scalar_mean_(true)
167 , is_scalar_chol_(true)
174 , chol_(chol, chol + dim * (dim + 1) / 2)
175 , is_scalar_mean_(true)
176 , is_scalar_chol_(false)
181 : mean_(mean, mean + dim)
182 , chol_(dim * (dim + 1) / 2, 0)
183 , is_scalar_mean_(false)
184 , is_scalar_chol_(true)
191 : mean_(mean, mean + dim)
192 , chol_(chol, chol + dim * (dim + 1) / 2)
193 , is_scalar_mean_(false)
194 , is_scalar_chol_(false)
198 std::size_t
dim()
const {
return mean_.size(); }
205 const param_type ¶m1,
const param_type ¶m2)
207 if (param1.mean_ != param2.mean_) {
210 if (param1.chol_ != param2.chol_) {
213 if (param1.is_scalar_mean_ != param2.is_scalar_mean_) {
216 if (param1.is_scalar_chol_ != param2.is_scalar_chol_) {
223 const param_type ¶m1,
const param_type ¶m2)
225 return !(param1 == param2);
228 template <
typename CharT,
typename Traits>
230 std::basic_ostream<CharT, Traits> &os,
const param_type ¶m)
236 os << param.mean_ <<
' ';
237 os << param.chol_ <<
' ';
238 os << param.is_scalar_mean_ <<
' ';
239 os << param.is_scalar_chol_;
244 template <
typename CharT,
typename Traits>
246 std::basic_istream<CharT, Traits> &is, param_type ¶m)
254 is >> std::ws >> tmp.mean_;
255 is >> std::ws >> tmp.chol_;
256 is >> std::ws >> tmp.is_scalar_mean_;
257 is >> std::ws >> tmp.is_scalar_chol_;
260 param = std::move(tmp);
262 is.setstate(std::ios_base::failbit);
271 bool is_scalar_mean_;
272 bool is_scalar_chol_;
278 for (std::size_t i = 0; i != dim(); ++i) {
279 chol_[(i + 1) * (i + 2) / 2 - 1] = chol;
293 : param_(dim, mean, chol)
301 : param_(dim, mean, chol)
309 : param_(dim, mean, chol)
317 : param_(dim, mean, chol)
328 : param_(
std::move(param))
333 template <
typename OutputIter>
334 OutputIter
min(OutputIter first)
const 337 first, dim(), std::numeric_limits<result_type>::lowest());
340 template <
typename OutputIter>
341 OutputIter
max(OutputIter first)
const 344 first, dim(), std::numeric_limits<result_type>::max());
349 std::size_t
dim()
const {
return param_.dim(); }
365 param_ = std::move(param);
369 template <
typename RNGType>
372 operator()(rng, r, param_);
375 template <
typename RNGType>
378 generate(rng, r, param);
381 template <
typename RNGType>
384 operator()(rng, n, r, param_);
387 template <
typename RNGType>
391 if (param.is_scalar_mean_ && param.is_scalar_chol_) {
393 rng, n, r, param.
dim(), param.
mean()[0], param.
chol()[0]);
394 }
else if (param.is_scalar_mean_ && !param.is_scalar_chol_) {
396 rng, n, r, param.
dim(), param.
mean()[0], param.
chol());
397 }
else if (!param.is_scalar_mean_ && param.is_scalar_chol_) {
399 rng, n, r, param.
dim(), param.
mean(), param.
chol()[0]);
400 }
else if (!param.is_scalar_mean_ && !param.is_scalar_chol_) {
402 rng, n, r, param.
dim(), param.
mean(), param.
chol());
409 if (dist1.param_ != dist2.param_) {
418 return !(dist1 == dist2);
421 template <
typename CharT,
typename Traits>
434 template <
typename CharT,
typename Traits>
443 is >> std::ws >> param;
445 dist.param_ = std::move(param);
454 template <
typename RNGType>
459 if (param.is_scalar_mean_ && param.is_scalar_chol_) {
462 for (std::size_t i = 0; i != param.
dim(); ++i) {
465 }
else if (param.is_scalar_mean_ && !param.is_scalar_chol_) {
467 for (std::size_t i = 0; i != param.
dim(); ++i) {
471 if (param.
mean()[0] != 0) {
472 add<result_type>(param.
dim(), param.
mean(), r, r);
474 }
else if (!param.is_scalar_mean_ && param.is_scalar_chol_) {
476 for (std::size_t i = 0; i != param.
dim(); ++i) {
479 add<result_type>(param.
dim(), param.
mean(), r, r);
480 }
else if (!param.is_scalar_mean_ && !param.is_scalar_chol_) {
482 normal(rng, param.
dim(), r);
484 add<result_type>(param.
dim(), param.
mean(), r, r);
490 void mulchol(
float *r,
const param_type ¶m)
492 internal::cblas_stpmv(internal::CblasRowMajor, internal::CblasLower,
493 internal::CblasNoTrans, internal::CblasNonUnit,
494 static_cast<MCKL_BLAS_INT>(dim()), param.
chol(), r, 1);
497 void mulchol(
double *r,
const param_type ¶m)
499 internal::cblas_dtpmv(internal::CblasRowMajor, internal::CblasLower,
500 internal::CblasNoTrans, internal::CblasNonUnit,
501 static_cast<MCKL_BLAS_INT>(dim()), param.
chol(), r, 1);
505 template <
typename RealType,
typename RNGType>
509 distribution(rng, r);
512 template <
typename RealType,
typename RNGType>
514 std::size_t n, RealType *r)
516 distribution(rng, n, r);
521 #endif // MCKL_RANDOM_NORMAL_MV_DISTRIBUTION_HPP Multivariate Normal distribution.
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, distribution_type &dist)
friend bool operator!=(const param_type ¶m1, const param_type ¶m2)
NormalMVDistribution(std::size_t dim, result_type mean, result_type chol)
Construct a distribution with scalar mean and scalar covariance.
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const param_type ¶m)
const result_type * chol() const
void normal_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, float mean, float stddev)
void normal_mv_distribution_mulchol(std::size_t n, float *r, std::size_t dim, const float *chol)
NormalMVDistribution(const param_type ¶m)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, param_type ¶m)
const result_type * mean() const
void normal_mv_distribution(MKLEngine< BRNG, Bits > &rng, std::size_t n, float *r, std::size_t m, const float *mean, const float *chol)
void operator()(RNGType &rng, result_type *r, const param_type ¶m)
#define MCKL_PUSH_CLANG_WARNING(warning)
void param(const param_type ¶m)
friend bool operator==(const param_type ¶m1, const param_type ¶m2)
void param(param_type &¶m)
friend bool operator!=(const distribution_type &dist1, const distribution_type &dist2)
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
NormalMVDistribution(std::size_t dim, const result_type *mean, const result_type *chol)
Construct a distribution with vector mean and vector covariance.
void operator()(RNGType &rng, std::size_t n, result_type *r, const param_type ¶m)
NormalMVDistribution(std::size_t dim, const result_type *mean, result_type chol)
Construct a distribution with vector mean and scalar covariance.
const result_type * chol() const
NormalMVDistribution(std::size_t dim=1)
Construct a distribution with scalar mean and scalar covariance.
param_type(std::size_t dim, const result_type *mean, const result_type *chol)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const distribution_type &dist)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_ASSERT_BLAS_TYPE(Name)
const param_type & param() const
param_type(std::size_t dim=1)
param_type(std::size_t dim, const result_type *mean, result_type chol)
param_type(std::size_t dim, result_type mean, const result_type *chol)
param_type(std::size_t dim, result_type mean, result_type chol)
#define MCKL_PUSH_INTEL_WARNING(wid)
const result_type * mean() const
void rand(RNGType &rng, ArcsineDistribution< RealType > &distribution, std::size_t N, RealType *r)
#define MCKL_POP_CLANG_WARNING
friend bool operator==(const distribution_type &dist1, const distribution_type &dist2)
OutputIter min(OutputIter first) const
NormalMVDistribution(param_type &¶m)
NormalMVDistribution(std::size_t dim, result_type mean, const result_type *chol)
Construct a distribution with scalar mean and vector covariance.
OutputIter max(OutputIter first) const
void operator()(RNGType &rng, result_type *r)
#define MCKL_POP_INTEL_WARNING
void operator()(RNGType &rng, std::size_t n, result_type *r)
void add(std::size_t n, const float *a, const float *b, float *y)