bab2min / EigenRand

Fastest Random Distribution Generator for Eigen
https://bab2min.github.io/eigenrand/
MIT License
90 stars 12 forks source link

Vectorisation over distribution parameters #46

Open mkcinu opened 1 year ago

mkcinu commented 1 year ago

Hi, fantastic work - it's making our code a lot faster! Having said that we got a bit stuck of generating an array/matrix of numbers from binomial distribution for different trials and probabilities. For example, in numpy you can run np.random.binomial(n, p) where n and p can either be a scalar (like in EigenRand) or arrays of the same dimensions. How difficult would it be to implement to implement a similar interface? Do you think it's possible to SIMD operations like this? Many thanks!

bab2min commented 1 year ago

Hi @mkcinu, Thanks for the nice suggestions. But Eigen::Rand::binomial uses different calculation methods depending on n and p values actually. Thus the vectorization over distribution parameters is quite difficult to implement. It seems hard to implement it in the near future, but I will leave it as a far future plan! Thank you again for your suggestion.

bab2min commented 1 year ago

Since version 0.5.0, some distributions including Eigen::Rand::binomial support Vectorization over Parameters(VoP). Please see the full list of distributions supporting VoP at here.

A simple usage is:

#include <iostream>
#include <Eigen/Dense>
#include <EigenRand/EigenRand>

using namespace Eigen;

int main()
{
  Rand::P8_mt19937_64 urng{ 42 };

  ArrayXf a{ 10 }, b{ 10 }, c{ 10 };
  a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
  b << 10, 12, 14, 16, 18, 20, 22, 24, 26, 28;

  // You can use two array parameters.
  // The shape of two parameters should be equal in this case.
  c = Rand::uniformReal(urng, a, b);
  std::cout << c << std::endl;

  // Or you can provide one parameter as a scalar
  // In this case, a scalar parameter is broadcast to the shape of the array parameter.
  c = Rand::uniformReal(urng, -5, b);
  std::cout << c << std::endl;

  c = Rand::uniformReal(urng, a, 11);
  std::cout << c << std::endl;
  return 0;
}
mkcinu commented 1 year ago

That's brilliant! Thanks so much, I'll give it a try soon!