Closed JohnPekl closed 2 years ago
Hello @JohnPekl,
Sorry, I'm not sure exactly what the vector log norm
that you asked. Could you clarify that? Is that different from log-normal distribution?
@bab2min Thanks for replying to my question.
(1) If I have a mean and standard deviation is a scalar (double, or float number), I can use your package to generate a matrix following normal distribution
and log-normal distribution
(below code).
Rand::P8_mt19937_64 urng{ 42 };
// constructs generator for normal distribution with mean=1.0, stdev=2.0
Rand::NormalGen<float> norm_gen{ 1.0, 2.0 };
// Generator classes have a template function `generate`.
// 10 by 10 random matrix will be assigned to `mat`.
MatrixXf mat = norm_gen.template generate<MatrixXf>(10, 10, urng);
std::cout << mat << std::endl;
// Generator classes also have `generateLike`.
mat = norm_gen.generateLike(mat, urng);
std::cout << mat << std::endl;
// constructs generator for normal distribution with mean=1.0, stdev=2.0
Rand::LognormalGen<float> lognorm_gen{ 1.0, 2.0 };
// Generator classes have a template function `generate`.
// 10 by 10 random matrix will be assigned to `mat`.
mat = norm_gen.template generate<MatrixXf>(10, 10, urng);
std::cout << mat << std::endl;
// Generator classes also have `generateLike`.
mat = norm_gen.generateLike(mat, urng);
std::cout << mat << std::endl;
(2) But if my input of mean is a vector and covariance is a matrix, I can generate a matrix that follows a multivariate normal distribution (below code)
Eigen::Vector3d mu{ 1, 2, 3};
Eigen::Matrix3d cov{
{1, 1, 0},
{0, 2, 0},
{0, 0, 1},
};
Eigen::Matrix<double, 3, -1> samples;
Eigen::Rand::MvNormalGen<double, 3> gen_init{ mu, cov };
std::random_device rd;
std::mt19937_64 genn(rd());
samples = gen_init.generate(genn, 5);
cout<<samples<<endl;
How can I generate a matrix that follows a multivariate log-normal distribution with mean is a vector and covariance is a matrix (similar (2))?
@JohnPekl , I see! Thank you for your detail explanation! Mathematically, the log-normal distribution is equivalent to taking the exp of the normal distribution. If you want to sample from multivariate log-normal distribution, there is no simple generator for it. So you should sample from multivariate normal distribution first, and put its result to exp function elementwise. (https://en.wikipedia.org/wiki/Log-normal_distribution#Multivariate_log-normal)
Eigen::Vector3d mu{ 1, 2, 3};
Eigen::Matrix3d cov{
{1, 1, 0},
{0, 2, 0},
{0, 0, 1},
};
Eigen::Matrix<double, 3, -1> samples;
Eigen::Rand::MvNormalGen<double, 3> gen_init{ mu, cov };
std::random_device rd;
std::mt19937_64 genn(rd());
samples = gen_init.generate(genn, 5);
samples = samples.array().exp().matrix(); // applying exp to samples elementwise
It seems your package does not support generating a vector log norm, Isn't it? I have checked, it can only generate a number following log-normal distribution
Eigen::Rand::LognormalGen
.