Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster alternative than using streams to save boost random generator state

I need to be able to save/load state of this boost random generator:

boost::variate_generator<boost::mt19937, boost::random::uniform_real_distribution<> > generator;

I do it this way:

std::ostringstream content;
content << this->generator.engine();

The problem is, that this is incredibly slow, isn't there some alternative way to store it? (Or access the random generator data in native format). This code is encapsulated in our RandomGenerator class, so it can be little bit nasty.

like image 836
kovarex Avatar asked Apr 07 '13 11:04

kovarex


1 Answers

A couple of approaches, both pretty hacky:

  1. Just grab the raw bytes using something like:

    typedef typename std::aligned_storage<sizeof(boost::mt19937)>::type mt19937_storage;
    mt19937_storage storage;
    std::memcpy(&storage, &generator, sizeof(generator));
    //...
    generator.engine() = *reinterpret_cast<boost::mt19937*>(storage);
    

    This works fine for in-memory saving and loading, but the exact format will obviously be compiler-and-architecture-dependent, so it won't work if you need portable persistence. For extra caution points, you could throw in a static_assert for something like is_trivially_copyable to guard against (unlikely) future changes to mt19937.

  2. Assuming the terms of the Boost license are acceptable (they probably are), make your own copy of Boost's mersenne_twister template and tweak it to accept a pointer to the state array and a reference to the array index. Then the state is completely external to the engine, and you can manage it any way you like.

Incidentally, if this is a very frequent operation and you don't need MT19937's uber-high-dimensional uniformity, you might consider using a different engine with smaller state requirements, such as taus88.

like image 157
dhaffey Avatar answered Oct 11 '22 06:10

dhaffey