根据任意分布设置Eigen :: Matrix的系数

问题描述 投票:4回答:3

Eigen :: Matrix具有setRandom()方法,该方法会将矩阵的所有系数设置为随机值。但是,有一种内置的方式可以将所有矩阵系数设置为随机值,同时指定要使用的分布。

有没有办法实现以下目标:

Eigen::Matrix3f myMatrix;
std::tr1::mt19937 gen;
std::tr1::uniform_int<int> dist(0,MT_MAX);
myMatrix.setRandom(dist(gen));
random matrix eigen
3个回答
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
投票

除均匀分布外,我不知道可直接在矩阵上使用的任何其他类型的分布。您可以做的是将Eigen提供的统一分布直接映射到您的自定义分布(如果存在映射)。

假设您的分布是S型。您可以使用函数y = a /(b + c exp(x))将均匀分布映射到S型分布。

通过临时converting your matrix to array,您可以对矩阵的所有值进行逐元素运算:

Matrix3f uniformM;
uniformM.setRandom();

Matrix3f sigmoidM;
sigmoidM.array() = a * ((0.5*uniformM+0.5).array().exp() * c + b).inv();

0
投票

[如果有人遇到此问题,我将发布一个更简单的答案,该答案现在是可能的,不需要增强。我是在旧的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参数的签名是必需的。

© www.soinside.com 2019 - 2024. All rights reserved.