Last active
October 29, 2017 06:09
-
-
Save dnbaker/dea323b469a4861003ed0c95ea480cdd to your computer and use it in GitHub Desktop.
PRNVector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #ifndef _PRN_VECTOR_H__ | |
| #define _PRN_VECTOR_H__ | |
| template<typename RNG> | |
| struct UnchangedRNGDistribution { | |
| auto operator()(RNG &rng) const {return rng();} | |
| void reset() {} // For interface compatibility with generators with internal state. | |
| }; | |
| template<typename RNG=std::mt19937_64, typename Distribution=UnchangedRNGDistribution<RNG>> | |
| class PRNVector { | |
| // Vector of random values generated | |
| const uint64_t seed_; | |
| [dbaker49@jhu.edu@login-node01 gfrp]$ tail -n +156 include/gfrp/compact.h | |
| template<typename RNG> | |
| struct UnchangedRNGDistribution { | |
| auto operator()(RNG &rng) const {return rng();} | |
| void reset() {} // Because RNGs such as std::normal_distribution have an internal state to reset, this is provided for interface compatibility. | |
| }; | |
| template<typename RNG=aes::AesCtr, typename Distribution=UnchangedRNGDistribution<RNG>> | |
| class PRNVector { | |
| // Vector of random values generated | |
| const uint64_t seed_; | |
| uint64_t used_; | |
| uint64_t size_; | |
| RNG rng_; | |
| Distribution dist_; | |
| public: | |
| using ResultType = std::decay_t<decltype(dist_(rng_))>; | |
| private: | |
| ResultType val_; | |
| public: | |
| class PRNIterator { | |
| PRNVector<RNG, Distribution> *const ref_; | |
| public: | |
| auto operator*() const {return ref_->val_;} | |
| auto &operator ++() { | |
| inc(); | |
| return *this; | |
| } | |
| void inc() { | |
| ref_->gen(); | |
| ++ref_->used_; | |
| } | |
| void gen() {ref_->gen();} | |
| bool operator !=(const PRNIterator &other) const { | |
| return ref_->used_ < ref_->size_; // Doesn't even access the other iterator. Only used for `while(it < end)`. | |
| } | |
| PRNIterator(PRNVector<RNG, Distribution> *prn_vec): ref_(prn_vec) {} | |
| }; | |
| template<typename... DistArgs> | |
| PRNVector(uint64_t size, uint64_t seed=0, DistArgs &&... args): | |
| seed_{seed}, used_{0}, size_{size}, rng_(seed_), dist_(std::forward<DistArgs>(args)...), val_(gen()) {} | |
| auto begin() { | |
| reset(); | |
| return PRNIterator(this); | |
| } | |
| ResultType gen() {return val_ = dist_(rng_);} | |
| void reset() { | |
| rng_.seed(seed_); | |
| dist_.reset(); | |
| used_ = 0; | |
| gen(); | |
| } | |
| auto end() { | |
| return PRNIterator(static_cast<decltype(this)>(nullptr)); | |
| } | |
| auto end() const { | |
| return PRNIterator(static_cast<decltype(this)>(nullptr)); | |
| } | |
| auto size() const {return size_;} | |
| void resize(size_t newsize) {size_ = newsize;} | |
| }; | |
| #endif // #ifndef _PRN_VECTOR_H__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment