问题
Eigen::Matrix has a setRandom() method which will set all coefficients of the matrix to random values. However, is there a built in way to set all the matrix coefficients to random values while specifying the distribution to use.
Is there a way to achieve something like the following:
Eigen::Matrix3f myMatrix;
std::tr1::mt19937 gen;
std::tr1::uniform_int<int> dist(0,MT_MAX);
myMatrix.setRandom(dist(gen));
回答1:
You can do what you want using Boost and unaryExpr. The function you pass to unaryExpr needs to accept a dummy input which you can just ignore.
#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;
}
回答2:
Apart the uniform distribution I am not aware of any other types of distribution that can be used directly on a matrix. What you could do is to map the uniform distribution provided by Eigen directly to your custom distribution (if the mapping exists).
Suppose that your distribution is a sigmoid. You can map an uniform distribution to the sigmoid distribution using the function y = a / ( b + c exp(x) ).
By temporary converting your matrix to array you can operate element-wise on all values of your matrix:
Matrix3f uniformM;
uniformM.setRandom();
Matrix3f sigmoidM;
sigmoidM.array() = a * ((0.5*uniformM+0.5).array().exp() * c + b).inv();
来源:https://stackoverflow.com/questions/11024820/set-coefficients-of-an-eigenmatrix-according-an-arbitrary-distribution