Set coefficients of an Eigen::Matrix according an arbitrary distribution

家住魔仙堡 提交于 2019-12-10 17:01:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!