Boost logo

Boost :

From: Matthias Troyer (troyer_at_[hidden])
Date: 2004-09-02 03:19:26


On Sep 2, 2004, at 4:27 AM, Neal Becker wrote:

> Matthias Troyer wrote:
>
>> On Sep 1, 2004, at 9:54 PM, Neal D. Becker wrote:
>>
>>> In order to serialize, it would be helpful to add an interface to
>>> mersenne_twister to get/set the state. I don't think there is any
>>> I/F
>>> to
>>> get the state.
>>
>> When we need to serialize RNGs we currently use the possibility to
>> convert the state to a string using operator <<(std::ostream&, const
>> RNG&) and operator >>(std::istream&, RNG&). A better serialization
>> mechanism should, in my opinion directly use the serialization library
>> and not go over some get_state/set_state functions, since the state
>> might be described by more than just a container.
>>
>
> Maybe this is generic enough for any use? It's not hard to make this
> work
> for boost::python pickle:
>
> *** mersenne_twister.hpp 2004-09-01 22:25:34.271533876 -0400
> --- mersenne_twister.hpp.new 2004-09-01 22:10:43.674599123 -0400
> ***************
> *** 133,138 ****
> --- 133,147 ----
> return os;
> }
>
> + template<class Archive>
> + Archive&
> + getstate(Archive& ar) const
> + {
> + for(int j = 0; j < state_size; ++j)
> + ar << compute(j);
> + return ar;
> + }
> +
> template<class CharT, class Traits>
> friend std::basic_istream<CharT,Traits>&
> operator>>(std::basic_istream<CharT,Traits>& is, mersenne_twister&
> mt)
> ***************
> *** 145,150 ****
> --- 154,172 ----
> mt.i = mt.state_size;
> return is;
> }
> +
> + template<class Archive>
> + Archive&
> + setstate(Archive& ar)
> + {
> + for(int j = 0; j < state_size; ++j)
> + ar >> x[j];
> + // MSVC (up to 7.1) and Borland (up to 5.64) don't handle the
> template
> + // value parameter "n" available from the class template scope,
> so use
> + // the static constant with the same value
> + i = state_size;
> + return ar;
> + }
> #endif
>
> friend bool operator==(const mersenne_twister& x, const
> mersenne_twister& y)

I see a problem also with this approach. Note that the state of the RNG
at time of serialization (time of call to get_state()) should be the
same as after deserialization (after call to set_state()). The fact
that the state was stored somewhere, and then set again should not make
a difference in the state, i.e. the next random number should be the
same in both cases. To be more concrete, the following two (pseudo-)
codes should print the same number:

version 1:

std::cout << rng();

version 2:

rng.get_state(archive);
rng.set_state(archive);
std::cout << rng();

This means that in addition to the state of the buffer, also the state
of the index i needs to be stored. This can be done without any problem
in the serialization approach but is harder to implement generically
when the state should be stored in a container.

Matthias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk