Eigen :: Matrix有一个setRandom()方法,它将矩阵的所有系数设置为随机值。但是,是否有内置方法将所有矩阵系数设置为随机值,同时指定要使用的分布。
有没有办法实现以下目标:
Eigen::Matrix3f myMatrix;
std::tr1::mt19937 gen;
std::tr1::uniform_int<int> dist(0,MT_MAX);
myMatrix.setRandom(dist(gen));
答案 0 :(得分:3)
你可以使用Boost和unaryExpr做你想做的事。传递给unaryExpr的函数需要接受一个你可以忽略的虚拟输入。
#include <boost/random.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace boost;
using namespace Eigen;
double sample(double dummy)
{
static mt19937 rng;
static normal_distribution<> nd(3.0,1.0);
return nd(rng);
}
int main()
{
MatrixXd m =MatrixXd::Zero(2,3).unaryExpr(ptr_fun(sample));
cout << m << endl;
return 0;
}
答案 1 :(得分:1)
除了均匀分布之外,我不知道可以直接在矩阵上使用的任何其他类型的分布。 您可以做的是将Eigen提供的均匀分布直接映射到您的自定义分布(如果映射存在)。
假设您的发行版是一个sigmoid。 您可以使用函数y = a /(b + c exp(x))将均匀分布映射到sigmoid分布。
通过临时converting your matrix to array,您可以对矩阵的所有值进行逐元素操作:
Matrix3f uniformM;
uniformM.setRandom();
Matrix3f sigmoidM;
sigmoidM.array() = a * ((0.5*uniformM+0.5).array().exp() * c + b).inv();
答案 2 :(得分:1)
如果有人遇到此问题,我会发布一个更简单的答案,该答案现在是可能的,不需要增强。我是在旧的Eigen Bugzilla Report中找到的。所有的功劳归作者Gael Guennebaud提出以下简单方法:
#include <Eigen/Sparse>
#include <iostream>
#include <random>
using namespace Eigen;
int main() {
std::default_random_engine generator;
std::poisson_distribution<int> distribution(4.1);
auto poisson = [&] (int) {return distribution(generator);};
RowVectorXi v = RowVectorXi::NullaryExpr(10, poisson );
std::cout << v << "\n";
}
请注意,尽管示例中未在此处使用Eigen NullaryExpr,但lambda函数带有int
参数的签名是必需的。
答案 3 :(得分:0)
我也遇到类似的问题,并尝试使用NullaryExpr解决它。但是NullaryExpr的一个问题是无法将其显式矢量化。因此,使用NullaryExpr的解决方案运行速度很慢。
因此,我开发了EigenRand,这是Eigen随机分布的附加组件。我认为这将对希望快速轻松生成随机数的人有所帮助。
#include <Eigen/Dense>
#include <EigenRand/EigenRand>
#include <iostream>
using namespace Eigen;
int main() {
Rand::Vmt19937_64 generator;
// poisson distribution with rate = 4.1
MatrixXi v = Rand::poisson<MatrixXi>(4, 4, generator, 4.1);
std::cout << v << std::endl;
// normal distribution with mean = 3.0, stdev = 1.0
MatrixXf u = Rand::normal<MatrixXf>(4, 4, generator, 3.0, 1.0);
std::cout << u << std::endl;
return 0;
}