
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